Chuck Conway

In The craft

Windows Azure: The Testing Story

September 22, 2011 · 3 minute read

Testing code outside Azure is a pain in the ass — my company is struggling with this issue. We are currently testing against Azure itself and are encountering issues: First, the tests are taking longer and longer, the latency between Azure and our network is too great. Our complete test suite takes 2 to 3 hours to run. Secondly, data is co-mingled. Unless we create a Queue for every test, the tests are not atomic. Creating a Queue for each test presents another problem: the management of Queue creation and deletion.

Ultimately we decided the optimal course is to mock and run the Azure tests locally.

Web Roles Under the covers Web Roles uses Hostable Web Core with an Azure Wrapper. IIS Express is also a wrapper for Hostable Web Core. It is possible to launch IIS Express from a test and then make a request to it and get a response back. There are drawbacks: First, with IIS Express a port can not be used concurrently. With thousands of tests this could become an issue. Second, IIS Express requires the full path to the root of the web role. Third, it requires we take a dependency on IIS Express.

In a proof of concept, from a test, IIS Express started up, the test made a request to IIS Express, IIS Express gave a response and the test shutdown IIS Express.

IIS Express Code (adapted from Reimers.dk):

using System;
using System.Diagnostics;
using System.Threading;

namespace IISExpress
{
    public class WebServer : IDisposable
    {
        private readonly string _appLocation;
        private readonly string _port;
        private Process _iisProcess;
        private Thread _thread;

       public WebServer(string appLocation, string port)
       {
           _appLocation = appLocation;
           _port = port;
       }

       public void Start()
       {
           _thread = new Thread(StartIISExpress) { IsBackground = true };
           _thread.Start();
       }

        private void StartIISExpress()
        {
            var startInfo = new ProcessStartInfo
                                {
                                    WindowStyle = ProcessWindowStyle.Hidden,
                                    ErrorDialog = false,
                                    LoadUserProfile = false,
                                    CreateNoWindow = false,
                                    UseShellExecute = false,
                                    Arguments = string.Format("/path:"{0}" /port:{1}", _appLocation, _port)
                                };

            var programfiles = string.IsNullOrEmpty(startInfo.EnvironmentVariables["programfiles"])
                                   ? startInfo.EnvironmentVariables["programfiles(x86)"]
                                   : startInfo.EnvironmentVariables["programfiles"];

            startInfo.FileName = programfiles + "IIS Expressiisexpress.exe";

            try
            {
                _iisProcess = new Process {StartInfo = startInfo};

                _iisProcess.Start();

            }
            catch
            {
                _iisProcess.Dispose();

                throw;
            }
        }

        public void Dispose()
        {
            if (_iisProcess != null)
            {
                _iisProcess.Kill();
            }
        }

        public void Stop()
        {
            Dispose();
        }
    }
}

Worker Roles

There are two components that need mocking:the Azure Queue and the Azure Table storage. Currently the ad server components are coupled to the Azure implementation. Mocking these components and using dependency injection would be a big step in decoupling the ad server components from Azure.

Windows Azure Storage: TDD and Mocks

http://blogs.southworks.net/fboerr/2010/07/23/windows-azure-storage-tdd-and-mocks/

http://compositecode.com/2011/01/18/windows-azure-unit-testing-dilemma/

As of this post, we have not implemented anything around Azure testing.