October 28, 2009

Testing Asynchronous Code

Today I was trying to apply TDD to a piece of code that executes on a separate thread.  The code in question basically creates a new thread and specifies a delegate to be executed on the background thread.

To give you some detail – as part of the login process for the application I’m working on I need to load several external references after authenticating the user.  The problem is that the external system I’m working on is incredibly slow – therefore I need to load these in the background.  I have created an example to illustrate the problem.

public class Loader
{
    private readonly IExternalService service;

    public Loader(IExternalService service)
    {
        this.service = service;
    }

    public void LoadUserExternals(User user)
    {
        ThreadStart loadExternals = delegate
        {
            var externals = new List<External>();
            foreach (var externalReference in user.ExternalReferences)
            {
                externals.Add(service.GetExternal(externalReference));
            }

            user.Externals = externals;
        };
        new Thread(loadExternals).Start();
    }
}

The problem

There is an obvious problem when testing this type of scenario.  We can’t really verify that the externals have been loaded since the test will usually complete before the references have been loaded.  I have seen various clumsy solutions to this problem – the most obvious being the use of Thread.Sleep to wait until the background process completes.

While this would probably work it’s a little fragile and definitely not the most elegant solution to the problem at hand.  A quick Google and a search on StackOverflow gave me quite a few results but no real answers.  (Although this link on Multithreaded Testing and this series on Unit Testing threads came close)

The solution

I basically wanted to allow the code to run synchronously while testing and asynchronously when I’m not.  The solution I came up with was to inject a Thread Factory into the class that would simply execute the code synchronously when testing.  The ThreadFactory would be the default concrete implementation and the MockThreadFactory would be used for testing.

public class ThreadFactory : IThreadFactory
{
    public void StartThread(ThreadStart start)
    {
        new Thread(start).Start();
    }
}
public class MockThreadFactory : IThreadFactory
{
    public void StartThread(ThreadStart start)
    {
        start.Invoke();
    }
}

Now I simply need to use this factory in my code – the line where I create a new thread changes to the following.

threadFactory.StartThread(loadExternals);

Conclusion

Obviously this solution won’t work for everyone – in many cases testing the asynchronous scenario is important.  Regardless, allowing the code to switch from asynchronous to synchronous in this fashion is pretty cool.

I have attached the code here.  Be sure to take a look at the test fixture I included to demonstrate how to use the factory.

Happy coding.

October 13, 2009

Authentication using LDAP

I recently had to rewrite a legacy library for authenticating users against Active Directory (AD).  Having almost no previous knowledge of this type of authentication I turned to Google – assuming that samples and examples would be readily available.

To my surprise (and annoyance) I found that LDAP authentication using C# was rather cumbersome and I couldn’t find a really good example for doing simple authentication.  The closest thing I found was this article on the Microsoft support site (most other examples were simply duplicating this code).  I wasn’t a big fan of this example either – the code seems to depend on the consumer code calling the methods in the correct order – bad design in my opinion.

So using a combination from the legacy code and this article I wrote a simple class for performing authentication against AD.  I would appreciate any comments to point out any possible mistakes or improvements.

private static User AuthenticateUser(string username, string password, string activeDirectoryPath)
{
    var directoryEntry = new DirectoryEntry(activeDirectoryPath, username, password);
    try
    {
        // Bind to the native object to force authentication
        var nativeObject = directoryEntry.NativeObject;

        var search = new DirectorySearcher(directoryEntry);

        search.Filter = string.Format("(SAMAccountName={0})", username);
        search.PropertiesToLoad.Add("SAMAccountName");
        search.PropertiesToLoad.Add("givenName");
        search.PropertiesToLoad.Add("sn");
        search.PropertiesToLoad.Add("mail");
        search.PropertiesToLoad.Add("telephoneNumber");                

        var result = search.FindOne();
        if (result == null)
        {
            return null;
        }
        else
        {
            var user = new User();

            user.Username = GetPropertyValue(result, "SAMAccountName");
            user.Name = GetPropertyValue(result, "givenName");
            user.Surname = GetPropertyValue(result, "sn");
            user.Email = GetPropertyValue(result, "mail");
            user.TelephoneNumber = GetPropertyValue(result, "telephoneNumber");

            user.Groups = GetGroups(result);

            return user;
        }
    }
    catch
    {
        // TODO:  Log the exception
        return null;
    }
}

private static IList<string> GetGroups(SearchResult result)
{
    var groups = new List<string>();

    if (result.Properties["memberOf"] != null && result.Properties["memberOf"].Count > 0)
    {
        foreach (string dn in result.Properties["memberOf"])
        {
            var equalsIndex = dn.IndexOf("=", 1);
            var commaIndex = dn.IndexOf(",", 1);
            if (equalsIndex != -1)
            {
                groups.Add(dn.Substring((equalsIndex + 1), (commaIndex - equalsIndex) - 1));
            }
        }
    }

    return groups;
}

private static string GetPropertyValue(SearchResult result, string property)
{
    if (result.Properties[property] != null && result.Properties[property].Count > 0)
    {
        return result.Properties[property][0].ToString();
    }
    else
    {
        return string.Empty;
    }
}

Happy coding.

October 8, 2009

Re-throwing Exceptions

This is one of my favourite interview questions – I’m often surprised by the number of candidates who get this wrong.  Let’s see how you do.

What’s the difference between the following code snippets?

try
{
    DoSomething();
}
catch (SomeException ex)
{
    throw ex;
}
try
{
    DoSomething();
}
catch (SomeException ex)
{
    throw;
}

The answer is that the first snippet destroys the stack trace for the exception while the second snippet keeps it intact.  This can be a real pain when trying to track down a specific issue – in this case the log files will point you to the line of code where you are re-throwing the exception instead of the line where the original exception occurs.  So always use the second code snippet.

Happy coding.

October 7, 2009

Exceptions in a Distributed Environment

In my previous post I covered some of the basics around throwing and handling exceptions.  In this post I’m going to take a look at what happens when an exception occurs during a remoting call.

Remoting Call throwing an Exception

For this example I setup a single server-side object - published through a shared interface and registered for singlecall remoting.

public void ThrowApplicationException()
{
    throw new ApplicationException("Message from the server");
}

My client is a WinForms application with global exception handling.  When I invoke the method the exception is thrown on the server and propagated to the client.

ServerApplicationException
The really cool part is that I even get a full stack trace – including the trace on the server!  Both the server and client also keep running – the exception didn’t cause either of the processes to crash.  Let’s take a look at what happens when we throw some custom exceptions into the mix.

Remote Call throwing a Custom Exception

For this example I have created 2 custom exceptions – the first resides in a shared assembly (reference by both the server and the client) and the other resides only in the server assembly.  They are aptly named SharedException and ServerException.

Let’s see what happens when we throw a new ServerException.

CustomServerException 
Not quite what we wanted.  Let’s see what happens when we throw a new SharedException.

CustomSharedException 
That’s more like it.  The behaviour here makes perfect sense – the client application receives the serialized information for a ServerException object, but has no way of knowing how to deserialize this object.  The SharedException type also needs to be marked with the Serializable attribute – otherwise this operation would have failed in a similar manner.

Summary

The default behaviour of remoting (propagating exceptions that occur on the server) is very useful – especially in a rich-client environment.  You simply need to ensure that custom exceptions reside in a shared assembly and are serializable – remoting takes care of the rest.

Unfortunately we cannot duplicate this behaviour with WCF applications – the SOA-nature of WCF dictates that all exceptions need to be caught and propagated as faults (which are declared on the service contract).  This is one of the reasons why remoting is probably better suited for rich-client applications that WCF.

You can find the code here.  Happy coding.

October 5, 2009

Exceptions should be Exceptional

One of the common mistakes I see in beginner programmers is a lack of understanding around exceptions and how to handle them.  Two years ago I started working on a project where every single server-side method (accessed via a remoting call) was surrounded by a try-catch block.  When I discussed this with the project leader I was told that this was a done to “prevent the application from crashing when an exception occurs”.  If you have seen code like this or you are simply unsure of when to handle exceptions, read on.

What happens to our application when an Unhandled Exception occurs?

To get started, let’s create an application and see what happens when an exception occurs.  I created a simple WinForms application that throws an exception when I click a button.

private void button1_Click(object sender, EventArgs e)
{
    throw new ArgumentException("Clicked the button");
}

If you run this from within Visual Studio you should get a message informing you that an unhandled exception has occurred.  If you run this from outside Visual Studio you will either get the same message from the JIT-compiler or the application will simply disappear.  In short, the application is crashing due to the unhandled exception.

So can we prevent the application from crashing without having to wrap every single method in a try-catch block?  The answer is quite tricky.  There is an interesting article on MSDN that explains it quite well – here are a few excerpts from the article.

  • Unhandled exceptions that occur on the application's main thread cause the application to terminate
  • Unhandled exceptions that occur in threads other than the application’s main thread are swallowed by the CLR and can be displayed in a manner of your choosing

Let’s take a look at how I would handle the exception that is occurring in the sample application.

Handling Exceptions in a WinForms application

The .NET framework exposes 2 events to allow us to handle exceptions at the application level.  This is usually the first thing I do when I create a WinForms application.

static class Program
{
    [STAThread]
    static void Main()
    {
        AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
        Application.ThreadException += Application_ThreadException;

        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Main());

        Application.ThreadException -= Application_ThreadException;
        AppDomain.CurrentDomain.UnhandledException -= CurrentDomain_UnhandledException;
    }

    static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
    {
        HandleException(e.Exception);
    }

    static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
        HandleException((Exception) e.ExceptionObject);
    }

    static void HandleException(Exception ex)
    {
        MessageBox.Show(ex.ToString(), "An unhandled exception has occurred");
    }
}

If I re-run the sample application I now get a message showing the exception and the stack trace.  More importantly, the application keeps running!

HandledException

You probably want to write a form for displaying this information to the user in a consistent fashion.

So when should we handle exceptions?

So now that we have a mechanism for handling exceptions at the application level we need to decide when to throw and when to handle exceptions.  The golden rule for deciding when to throw exceptions is that exceptions should be exceptional.  Simply ask yourself if this is truly an exceptional case and you should have a pretty good idea of whether to throw an exception or not.

If the config file is missing or corrupt – that’s exceptional.  If the application can’t establish a connection to the database – that’s exceptional.  If the user mistypes his password – that’s not exceptional.  (Although if he/she mistypes it more that a certain threshold limit – that’s exceptional)

And now for the other side of the coin – when should we handle exceptions?  There is another golden rule I try to adhere to for exception handlingonly catch exceptions that you are able to handle.  To clarify, here is another extract from the MSDN article:

There are only a miniscule number of cases in which your code can be sure that it knows how to appropriately handle any possible exception that escapes a try block. There are far more unexpected exception cases than you might imagine. In managed code, even code that doesn't call any methods could throw a variety of exceptions, including security exceptions, out-of-memory exceptions, execution-engine exceptions, and the like. It is best for your applications to always catch specific exceptions and leave all other unexpected exceptions as unhandled.

This rule dictates that you should never catch System.Exception.  Once you get used doing exception handling in this way you will notice that you mostly either handle exceptions to add extra information to the exception or execute a different block of code depending on the occurrence of a specific type of exception.

Summary

I think the tricky part of exception management is that you need to evaluate every situation on a case-by-case basis.  This simply means that experience is quite influential in making a decision in each scenario.  But that’s what programming is all about!

Keep in mind that you don’t need to break your back to stick to the rules I have outlined here – after all, there are exceptions to every rule!  Happy coding.