Building Windows Azure Services Without Compromising Testability

April 14, 2013 — 6 Comments

boy-taking-exam

Do you feel helpless when you think about testing your project’s code base? Does testing your Windows Azure solution involve deploying to Windows Azure?

Then you’re probably wasting precious time. Granted that we can’t go without testing code that consumes Windows Azure Services like the Windows Azure Queue Storage Service, but they can be abstracted and removed from our core business logic!

A few weeks back I wrote about wrapping third parties to protect against breaking changes. This post follows a similar path and will demonstrate how the Unity Application Block can be used to build a testable Windows Azure Service.

Disclaimer

I personally do not use IoC (Inversion of Control) Containers on projects that do not absolutely require them. In some cases it ends up creating lots of accidental complexity.

Using an IoC Container like the Unity Application Block can greatly benefit a project if techniques like mocking and test driven development are used to help drive quality throughout the application’s development. On the other hand, if your application is tested by a Quality Assurance team through the UI (User Interface), then your application may not absolutely need the extra complexity created by the use of an IoC Container.

Demo Project

To demonstrate how to use the Unity Application Block in order to build Windows Azure Services without compromising testability I built the Message Processor. Get the source from https://github.com/brisebois/WindowsAzure.Unity.Demo

The Message Processor is a component that is responsible for reading messages from a Windows Azure Queue Storage Service, decoding the messages and processing them using Message Handlers.

2013-04-14_23h32_56

The Worker Role uses the Unity Application Block to wire up the Message Processor’s dependencies. Consequently, a team of developers can build and test it’s dependencies independently. Furthermore, the only dependency on the Unity Application Block should belong the Worker Role project. Other project should not be aware that you are using an IoC Container. Keeping this dependency to a minimum will help reduce the risks of additional complexity, which could be added to you application due to the miss use of the Unity Application Block. Consequently, keeping the dependencies to the Unity Application Block to a minimum, will also give you the flexibility to change your IoC Container in the future.

public class WorkerRole : RoleEntryPoint
{
 public override void Run()
 {
     // This is a sample worker implementation. Replace with your logic.
     Trace.WriteLine("Worker entry point called", "Information");

     using (var uc = new UnityContainer())
     {
         uc.RegisterType<ILogger, TableStorageLogger>();
         uc.RegisterType<IMessageSource, QueueMessageSource>();
         uc.RegisterType<IMessageDecoder, QueueMessageDecoder>();
         uc.RegisterType<IMessageHandler, CommandHandler>("CommandHandler");
         uc.RegisterType<IEnumerable<IMessageHandler>, IMessageHandler[]>();

         var processor = uc.Resolve<MessageProcessor>();

         while (true)
         {
             processor.Process();
             Thread.Sleep(10000);
             Trace.WriteLine("Working", "Information");
         }
     }
 }

 public override bool OnStart()
 {
     // Set the maximum number of concurrent connections 
     ServicePointManager.DefaultConnectionLimit = 1000;

     // For information on handling configuration changes
     // see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.

     return base.OnStart();
 }
}

Test Driven Development (aka. TDD)

Test driven development (TDD) is often spoken of as the ultimate solution to a project’s quality problems. I agree that it’s one of the many ways to address quality issues, but I don’t think that it starts with TDD. I personally think that quality starts with coding standards. Microsoft Visual Studio Premium and above present developer with tools like Code Analysis, which help teams to enforce coding standards. Consequently, teams who follow these standards produce code that is easier to maintain.

From a code base which follows good coding standards, you can start to refactor your way into TDD. Much of the work will be concentrated into tasks that produce seams by breaking down dependencies. At first it will seem overwhelming, but things will get better as you progress. I won’t go much further into refactoring code to get it under tests, but if you are interested in learning more about seams, enabling points and getting your legacy code under tests I recommend reading Working Effectively with Legacy Code by Michael Feathers. You can also have a look at Andrea Polci’s presentation based on Working Effectively with Legacy Code.

Unit testing is often overlooked, take a moment to observe the following tests.

2013-04-15_00h14_12

The first thing that comes to mind when I look at these tests, is the time it took to execute them. The important lesson here is that Unit Tests should be fast! I mean really fast! The time it takes to execute a complete suite of tests is very important because if your tests are slow, developers won’t take the time to execute them.

Tests create a feedback loop for developers. When this feedback loop is short, developers execute the tests on a regular basis in order to rapidly spot issues.

Microsoft Visual Studio 2012 has a new feature which runs Unit Tests every time the solution is built. This is an amazing source of feedback for the developer! Ensuring that Unit Tests run fast becomes even more crucial with these kinds of tools because developers don’t like to wait around. Consequently, anything that seems to slow them down will most likely end up not being used…

The second thing that comes to mind when I look at these tests, is that they each have names that describes what the tests do. By reading the tests names, we should be able to grasp the business rules of a system.

When ever you create a new Unit Tests be sure to test for positives. By this I mean that you should be testing your requirements and for expected outcomes.

 

Testing The MessageProcessor

public class MessageProcessor
{
    public MessageProcessor(IMessageSource source,
                            IMessageDecoder decoders, 
                            IEnumerable<IMessageHandler> handlers,
                            ILogger logger)
    {
        MessageSource = source;
        MessageDecoder = decoders;
        MessageHandlers = handlers;
        Logger = logger;
    }

    public IMessageSource MessageSource { get; private set; }

    public IMessageDecoder MessageDecoder { get; private set; }

    public IEnumerable<IMessageHandler> MessageHandlers { get; private set; }
        
    public ILogger Logger { get; private set; }

    public void Process()
    {
        var messages = MessageSource.GetMessages(32);
        foreach (var message in messages)
            ProcessMessage(message);
    }

    private void ProcessMessage(string message)
    {
        var msg = MessageDecoder.Decode(message);
            
        var handlers = GetMessageHandlers(msg);

        if (!handlers.Any())
        {
            Logger.Write("Unable to process message : " + message);
            return;
        }

        HandleMessage(handlers, msg);
        MessageSource.RemoveMessage(message);
    }

    private List<IMessageHandler> GetMessageHandlers(IMessage msg)
    {
        var handlers = MessageHandlers.Where(h => h.CanHandle(msg)).ToList();
        return handlers;
    }

    private void HandleMessage(IEnumerable<IMessageHandler> handlers, IMessage msg)
    {
        foreach (var h in handlers)
            TryHandleMessage(msg, h);
    }

    private void TryHandleMessage(IMessage msg, IMessageHandler h)
    {
        try
        {
            h.Handle(msg);
        }
        catch (MessageHandlerException ex)
        {
            Logger.Write(ex.ToString());
        }
    }
}

You probably noticed that the dependencies of the MessageProcessor are injected through the constructor. There are two main reasons why I chose to do this. The first is performance, by satisfying it’s dependencies at the constructor level, the Unity Container seems to be working less to construct the object. The second reason, is that by passing through the constructor I am effectively removing possible dependencies on the Unity Application Block assembly. To inject dependencies through properties, it is required to declare public mutable properties which are decorated with a Dependency attribute. Placing this attribute on properties will create a strong dependency on the Unity Application Block assembly. This dependency isn’t something that we want. Furthermore, injecting the dependencies through the constructor also allows us to expose our dependencies through read only properties, protecting the MessageProcessor against other code that may try to modify its internal state through its properties.

I created a first test in order to create a test MessageDecoder, which will be used in future tests.

[TestMethod]
public void TestWhenDecodingMessageThenShouldReturnATestMessage()
{
    var decoder = new TestMessageDecoder();
    const string testMessage = "message content:0";
    var message = decoder.Decode(testMessage);
    Assert.IsInstanceOfType(message, typeof(TestMessage));
}

The following MessageDecoder implementation created to test the MessageProcessor. Consequently, it’s very basic and should not contain any additional complexity. Therefore, it only contains the logic necessary to make the first Unit Test pass.

public class TestMessageDecoder : IMessageDecoder
{
    public IMessage Decode(string message)
    {
        if(string.IsNullOrWhiteSpace(message))
            throw new ArgumentNullException("message");

        var values = message.Split(':');
        return new TestMessage
            {       
                Id = values[1],
                Message = values[0]
            };
    }
}

I created the next test in order to create a test MessageSource, which will be used in future tests. This implementation is required generate a certain number of in-memory messages which are decodable by the TestMessageDecoder.

[TestMethod]
public void TestWhenGetOneMessageFromMessageSourceThenReceivedOneMessage()
{
    var source = new TestMessageSource();
    source.Load(1);
    var message = source.GetMessages(1);
    Assert.IsTrue(message.Count() == 1);
}

The following MessageSource implementation is responsible for generating a certain number of messages. Furthermore, it’s responsible for keeping track of each message so that it may be removed from the source once it’s successfully been processed.

public class TestMessageSource : IMessageSource
{
    readonly HashSet<string> messages = new HashSet<string>();

    public void Load(int count)
    {
        Enumerable.Range(0, count)
                    .ToList()
                    .ForEach(index => messages.Add("message content:" + index));
    }

    public IEnumerable<string> GetMessages(int numberOfMessages)
    {
        return messages.Take(numberOfMessages).ToList();
    }

    public void RemoveMessage(string message)
    {
        messages.Remove(message);
    }
}

Then I created a test whose sole responsibility was to help implement logic to track messages in the TestMessageSource. Furthermore, the test ensures that the TestMessageSource behaves as expected when we remove messages from it.

[TestMethod]
public void TestWhenRemoveMessagesFromMessageSourceThenShouldBeEmpty()
{
    var source = new TestMessageSource();
    source.Load(32);
    var message = source.GetMessages(32);
    foreach (var m in message)
    {
        source.RemoveMessage(m);
    }
    message = source.GetMessages(32);
    Assert.IsFalse(message.Any());
}

The next test Is responsible for validating that the TestMessageSource is producing TestMessage instances that the TestMessageDecoder is able to decode. This test is necessary to ensure that our future tests will be valid.

[TestMethod]
public void TestWhenTestMessageSourceReturnsMessageThenDecodeMessage()
{
    var source = new TestMessageSource();
    source.Load(1);
    var message = source.GetMessages(1);
    var decoder = new TestMessageDecoder();
    foreach (var m in message)
    {
        var decodedMessage = decoder.Decode(m);
        Assert.IsInstanceOfType(decodedMessage, typeof(TestMessage));
    }
}

Next I created a test to help me implement a TestMessageHandler. The TestMessageHandler is responsible for validating that it can handle a specific message and for handling the message.

[TestMethod]
public void TestWhenTestMessageCanBeHandledThenIsProcessed()
{
    var source = new TestMessageSource();
    source.Load(1);
    var decoder = new TestMessageDecoder();
    var handler = new TestMessageHandler();

    var message = source.GetMessages(1);
    foreach (var m in message)
    {
        var decodedMessage = decoder.Decode(m);
        var canHandle = handler.CanHandle(decodedMessage);
        Assert.IsTrue(canHandle);

        handler.Handle(decodedMessage);
    }
}

The resulting TestMessageHandler implementation is simple. It could be augmented in order to validate that the Handle method has completed correctly. The current implementation will throw an exception if the message instance is not of type TestMessage. Consequently, an exception would cause the test to fail.

public class TestMessageHandler : IMessageHandler
{
    public bool CanHandle(IMessage message)
    {
        return message is TestMessage;
    }

    public void Handle(IMessage message)
    {
        var m = (TestMessage)message;
        Console.WriteLine(m.Message);
    }
}

The next test brings everything together in order to test the MessageProcessor without the Unity Application Block. In this test we create instances of the test implementations of our dependencies and we inject them into the MessageProcessor. At this point we are able to call the Process method and assert that it has functioned properly by validating that all the messages have been removed from the TestMessageSource.

[TestMethod]
public void TestWhenTestSourceHasMessagesAndHandlerIsPresentThenMessageIsRemovedFromSource()
{
    var source = new TestMessageSource();
    source.Load(1);
    var decoder = new TestMessageDecoder();
    var handler = new TestMessageHandler();
    var logger = new TestLogger();

    var handlers = new List<IMessageHandler> {handler};
    var processor = new MessageProcessor(source, decoder, handlers, logger);

    processor.Process();

    Assert.IsFalse(source.GetMessages(1).Any());
}

The next test validates that when there are no Message Handler instances to handle messages, they are not removed from the Message Source when the Process method is called on the MessageProcessor.

[TestMethod]
public void TestWhenTestSourceHasMessagesAndNoHandlerIsPresentThenMessageIsNotRemovedFromSource()
{
    var source = new TestMessageSource();
    source.Load(1);
    var decoder = new TestMessageDecoder();
    var logger = new TestLogger();

    var handlers = new List<IMessageHandler>();
    var messageProcessor = new MessageProcessor(source, decoder, handlers, logger);

    messageProcessor.Process();

    Assert.IsTrue(source.GetMessages(1).Any());
}

This last test is what we have been working for since we began writing these tests. This test uses the Unity Application Block to configure and inject the MessageProcessor dependencies and allows us to test its logic. There’s another noteworthy aspect to using the MessageProcessor’s contructor to inject its dependencies, if for some reason we forget to configure one of its dependencies, the Unity Container will throw an exception when it tries to Resolve an instance of MessageProcessor.

[TestMethod]
public void TestWhenUsingUnityTestSourceHasMessageAndMessageProcessorIsExecutedThenMessagesAreRemovedFromSource()
{
    using (var uc = new UnityContainer())
    {
        uc.RegisterType<ILogger, TestLogger>();
        uc.RegisterType<IMessageSource, TestMessageSource>();
        uc.RegisterType<IMessageDecoder, TestMessageDecoder>();
        uc.RegisterType<IMessageHandler, TestMessageHandler>("test");
        uc.RegisterType<IEnumerable<IMessageHandler>, IMessageHandler[]>();

        var ms = new TestMessageSource();
        ms.Load(1);

        uc.RegisterInstance(typeof(IMessageSource), ms);

        var messageProcessor = uc.Resolve<MessageProcessor>();

        messageProcessor.Process();

        Assert.IsFalse(ms.GetMessages(1).Any());
    }
}

For the purpose our this demo, I did not implement a Logger that could be observed to see it anything was written to it. It would have been better to implement the logger with an internal collection that could be observed by an Assert statement in order to validate that something was or was not written to it.

public class TestLogger : ILogger
{
    public void Write(string entry)
    {
        Console.WriteLine(entry);
    }
}

In Conclusion

Using the Unity Application Block I was able to implement the MessageProcessor and test it’s logic without having to launch the Windows Azure Emulator and without publishing to Windows Azure.

The next steps in the development of the MessageProcessor would be to implement each of its dependencies and test them against the targeted Windows Azure services through integration tests.

Using the Unity Application Block as your IoC container along with Unit Tests has other benefits. It can help you define and decouple your application’s architecture. By breaking your application code into testable modules, your application will naturally tend to evolve into a maintainable solution. Furthermore, it will help the developers identify code that has similar responsibilities, which they can regroup and create components.

This type of loosely coupled architecture will allow your application to evolve overtime, it will lower the barrier to entry for new members of your team and it will ultimately reduce your future development costs by helping you catch bug earlier in the development process.

 

References

6 responses to Building Windows Azure Services Without Compromising Testability

  1. 

    Good article. Another good way I use to increase testability and aid fast development is to split my host entry point away from the RoleEntryPoint provided by Azure SDK. As such, I have a “HostEntryPoint” that is very similar but can be used from both a Console app, Windows Service *and* an Azure Worker Role. This is also useful if you need to create an app that can be deployed outside of the Azure cloud environment, or you wish to host your app as a Windows Service on an Azure IaaS VM instead.

    Ever since I made these changes I’ve not needed to use the Azure Emulator at all.

    Like

  2. 

    Great post Alex, I really like what you’ve done with the worker role and Unity.

    Just as side note Unity 3 was just released so you can point to that as well.

    Nice work.

    Like

    • 

      I will have to look into Unity 3. At the time of writing this post, I was working with .Net 4.0 and 3.5 and was unable to use Unity 3.
      Do you have any feedback on Unity 3 ?

      Like

      • 

        Insofar as what I’ve used it to do it’s been great. I was using Ninject prior to this and thought I’d try a different, and mature, DI container. If there is one bit of feedback it’d be in the lack of helpful documentation, most of the answers I have to go hunting for in the usual places.

        Like

Trackbacks and Pingbacks:

  1. Dew Drop – April 15, 2013 (#1,527) | Alvin Ashcraft's Morning Dew - April 15, 2013

    […] Building Windows Azure Services Without Compromising Testability (Alexandre Brisebois) […]

    Like

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.