Running a console app programmatically (within a test)

This is a follow up to a comment on my recent post Debugging Child Processes in Visual Studio

I created a couple of helpful methods to run my console app within my acceptance test. This allows me to run the console app and see the output from it all from within my test runner.

private void RunConsoleApp(string filename, string arguments, int timeout = 60000)
{
    using (var process = new Process())
    {
        process.StartInfo.FileName = filename;
        process.StartInfo.Arguments = arguments;
        process.StartInfo.UseShellExecute = false;
        process.StartInfo.RedirectStandardOutput = true;
        process.StartInfo.RedirectStandardError = true;

        var output = new StringBuilder();
        var error = new StringBuilder();

        using (var outputWaitHandle = new AutoResetEvent(false))
        using (var errorWaitHandle = new AutoResetEvent(false))
        {
            process.OutputDataReceived += (sender, e) =>
            {
                if (e.Data == null)
                {
                    outputWaitHandle.Set();
                }
                else
                {
                    output.AppendLine(e.Data);
                }
            };
            process.ErrorDataReceived += (sender, e) =>
            {
                if (e.Data == null)
                {
                    errorWaitHandle.Set();
                }
                else
                {
                    error.AppendLine(e.Data);
                }
            };

            process.Start();

            process.BeginOutputReadLine();
            process.BeginErrorReadLine();

            if (process.WaitForExit(timeout) &&
                outputWaitHandle.WaitOne(timeout) &&
                errorWaitHandle.WaitOne(timeout))
            {
                // Process completed. Check process.ExitCode here.
            }
            else
            {
                throw new Exception("Process timed out.");
                // Timed out.
            }
        }
        DumpString(output.ToString(), "Standard Output");
        DumpString(error.ToString(), "Standard Error");
    }
}

private static void DumpString(string content, string name)
{
    if (string.IsNullOrWhiteSpace(content)) return;

    Console.WriteLine();
    Console.WriteLine(name);
    Console.WriteLine(new string('+', 40));
    Console.WriteLine(content);
    Console.WriteLine(new string('-', 40));
    Console.WriteLine();
}
Advertisements

Debugging Child Processes in Visual Studio

I am currently on a mission to create acceptance tests for all new development I embark upon. Well, where it makes sense to do so.

Up until very recently when I encountered a problem and I needed to debug the target application I would take one of two approaches.

  1. Create an acceptance test to get me far enough, in terms of setting up test data/environment, to be able to debug the app and see what was going on.
  2. Put a breakpoint on the step within the acceptance test that executed my target application and stop the debugger.

Neither of these are ideal, or indeed, a very nice work flow experience.

So, I decided to hunt down a way to debug both my acceptance test code and my target application. The ideal situation would be for me to click the little bug icon in my resharper test runner.

Debug Unit Tests Button

After practising a bit of google-fu, I stumbled across this little gem.

https://blogs.msdn.microsoft.com/visualstudioalm/2014/11/24/introducing-the-child-process-debugging-power-tool/

Basically, it adds the ability for child processes spawned during a debugging session to be automatically included in your current session. There are other tricks around forcing apps to be automatically debugged, by hacking the registry, but that involves some awful workflow things. Namely …

  • Having to chose which debugger instance to use, or create a new one
  • Hacking the registry!

Also, it doesn’t attach to the process quite soon enough if your target application, spins up quickly and gets on with it’s job too fast for the attachment process.

This tool copes with that situation and it “just works”. Providing you set up a few things in your acceptance test project.

Firstly, you need to install the tool and go into the “Child Process Debugging Settings…”

Child Process Debugging Settings Menu

Then you need to “Enable child process debugging” …

Enable child process debugging

Next, go to the properties of your acceptance test project, and enable native code debugging …

Enable native code debugging

and, you’re all set.

You can now set breakpoints inside your target application, debug your acceptance test in your favourite test runner, and you will be able to step through the code in your target application using whatever test data/environment you set up in your acceptance test.

I hope you’ll agree this is a much nicer workflow.

NancyFx & Castle Windsor

I’ve just managed to fix a very odd problem with Castle Windsor and NancyFx. The error I was getting wasn’t much help at all really!

Can’t create component ‘Nancy.Routing.DefaultRouteCacheProvider’ as it has dependencies to be satisfied.
‘Nancy.Routing.DefaultRouteCacheProvider’ is waiting for the following dependencies:
– Service ‘System.Func`1[[Nancy.Routing.IRouteCache, Nancy, Version=0.22.2.0, Culture=neutral, PublicKeyToken=null]]’ which was not registered.

I’ve created a bootstrapper which among other this allows me to use a pre-existing container.

    public class NancyBootstrapper : WindsorNancyBootstrapper
    {
        private readonly IWindsorContainer _container;

        public NancyBootstrapper(IWindsorContainer container)
        {
            _container = container;
        }

        protected override IWindsorContainer GetApplicationContainer()
        {
            if (ApplicationContainer != null)
            {
                return ApplicationContainer;
            }

            _container.Kernel.Resolver.AddSubResolver(new CollectionResolver(_container.Kernel, true));
            _container.Register(Component.For<NancyRequestScopeInterceptor>());
            _container.Kernel.ProxyFactory.AddInterceptorSelector(new NancyRequestScopeInterceptorSelector());
            return _container;
        }

        protected override void RegisterBootstrapperTypes(IWindsorContainer applicationContainer)
        {
            // Note: Do NOT do the line below, this will cause the container to be registered twice and Windsor will throw an exception
            // applicationContainer.Register(Component.For<INancyModuleCatalog>().Instance(this));
        }
    }

Thanks to Ricardo Campos for getting me started! But whenever I tried starting nancy in self-host mode I immediately got the “missing IRouteCache” problem.

            var bootstrapper = _container.Resolve<INancyBootstrapper>();

            var uri = WebServerUri;
            _nancyHost = new NancyHost(uri, bootstrapper);

After much googling, head scratching, silent cursing and putting the world to rights a few times, I stumbled across a Stack Overflow answer. After reading through the link provided in the answer (https://github.com/NancyFx/Nancy.Bootstrappers.Windsor/pull/8). I tried adding the suggested fix.

        protected override void ConfigureApplicationContainer(IWindsorContainer existingContainer)
        {
            existingContainer.AddFacility<TypedFactoryFacility>();

            // some other cool stuff!
        }

Hey presto, it was all working and all is well with the world once more, until I hit the next bug that defies logic!

Testing CORS with POSTman

I’ve just added CORS support to my Web API and have spend a not inconsiderable amount of time chasing my tail and trying all sorts of different things to try and get it working. Let me explain …

I use the POSTman chrome extension to test my API (outside of unit/integration tests) and whenever I made a request I wasn’t getting back the expected Access-Control-Allow-Origin header in the response. So, I loaded up fiddler after scratching my head for a while and I could see the Origin header wasn’t being sent in the request. Apparently chrome restricts that header, so it was getting stripped out. I could have used the POSTman python proxy (https://github.com/a85/POSTMan-Chrome-Extension/wiki/Postman-Proxy) but since I already have fiddler I simply customised it a little. I started off by adding a new RulesOption and hard-coding the Origin in fiddler, like so …

    class Handlers
    {
        ...
        public static RulesOption("Add Origin Header")
        var m_AddOriginHeader: boolean = false;
        ...
        static function OnBeforeRequest(oSession: Session) {
        ...
            if (m_AddOriginHeader)
            {
                oSession.oRequest["Origin"] = "http://localhost/";
            }
        ...
        }
    ...
    }

But, that didn’t allow me to control the origin. It’s not applicable in this instance, but I figured I might want to add specific origins in other instances, so I came up with this …

    class Handlers
    {
        ...
        static function OnBeforeRequest(oSession: Session) {
        ...
            if (oSession.oRequest.headers.Exists("X-Origin"))
            {
                oSession.oRequest["Origin"] = oSession.oRequest["X-Origin"];
                oSession.oRequest.headers.Remove("X-Origin");
            }
        ...
        }
    ...
    }

So, all I need to do now is add the X-Origin header in place of the Origin header and I’m good to go. Obviously, I will need fiddler to be running and capturing traffic in order it to work. But, if fiddler is not running then the request still works but without the CORS header being returned in the response.

Using Moq to check the values of an object passed to a method

In order to test individual properties of an object passed to a method using Moq I have been making use of my Assert.IsFieldEqual method. See here for details.

Because I can’t call the Assert.IsFieldEqual inside a lambda, like so …


    _mockBus
        .Verify(x => x.Send(It.Is<MyMessage>(m => Assert.IsFieldEqual(m, propertyName, expectedValue))), Times.Once());

Obviously, since makes no sense as the Assert.IsFieldEqual is a void method. So, I’ve made use of Moq’s callback facility.


    MyMessage sentMessage = null;

    _mockBus
        .Setup(x => x.Send(It.IsAny<MyMessage>()))
        .Callback<object>((m) => sentMessage = (MyMessage) (((object[]) m)[0]));

    Assert.IsFieldEqual(sentMessage, propertyName, expectedValue);

This allows me to have a TestCase for each property in the message, so I have one test method for all the properties.

Thinktecture IdentityModel with ASP.NET Web Api

I’m writing this post as a reminder to myself on how to fix the following error message …

Attempted to access an element as a type incompatible with the array

… when firing up a Web Api project which is using Thinktecture IdentityModel.

My initialisation code looks like this …

                    var authenticationConfig = CreateAuthenticationConfiguration();
                    var handler = new AuthenticationHandler(authenticationConfig);
                    configuration.MessageHandlers.Add(handler);

The problem is caused by the wrong version of the System.Net.Http being used. The solution is to remove the bindingRedirect you see below.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

Note to future me: You will eventually remember this without having to come and look at this blog post!

I’m all Moq’d out!

I’m currently working on creating a Hypermedia API, or at least getting as close as I can to one!

In order to avoid the client hitting a dead end when an error occurs, either internally within my code or as a result of a bad request from the client, I wanted to provide links that the client can follow. So, I created an ApiError model class to send in my response in such a case.

    [Hypermedia]
    public class ApiError : Resource
    {
        public string ParentId { get; set; }
        public string ErrorMessage { get; set; }
    }

The [Hypermedia] attribute is just a place holder I use within my Delegating Handler which “enriches” the resources with links. The ParentId is the id used in order to construct links to the home resource and it’s also used for constructing self links and so on.

The links are generated by way of Mark Seamann’s excellent HyprLinkr library, available via Nuget (http://nuget.org/packages/Hyprlinkr/).

My first attempt was to create an extension method to create the response, much like the built in HttpRequestMessage.CreateErrorResponse extension method. This worked great when I tested it using my current favourite chrome extension, POSTman. It returned the error, along with a “back” and “home” link so the client didn’t just hit a dead-end.

For example …

  "errorMessage" : "The was an error, run for the hills!",
  "_links" :
  [
    {
      "rel" : "home",
      "href" : "http://server/api/home/someone@example.com",
      "title" : "home",
      "verb" : "GET"
    }
  ]

So, all is well. I’m a happy bunny….

Until I run my unit tests.

What The Flip?

Why is there red everywhere?!

As it turns out I wrote some legacy (read: un-testable) code. Here’s what I’d come up with …

    public static class HttpRequestMessageExtensions
    {
        public static HttpResponseMessage CreateErrorResponse(
            this HttpRequestMessage request,
            HttpStatusCode statusCode,
            string parentId,
            string errorMessage,
            Action<IResourceLinker, ApiError> addLinks)
        {
            var apiError = new ApiError
            {
                ParentId = parentId,
                ErrorMessage = errorMessage
            };

            if (addLinks != null)
            {
                var routeLinker = _resourceLinkerFactory.GetResourceLinker(request);
                addLinks(routeLinker, apiError);
            }

            return request.CreateResponse(statusCode, apiError);
        }

After spending some time in the debugger trying to figure out why I was getting a null reference exception, I started looking at Mark’s code on github and eventually figured out that the GetRouteData() call was returning null. So, I spent more time trying to figure out a way of getting that to *not* be null. I ended up getting the source code for the aspnetwebstack from codeplex and looking at the code for GetRouteData().

Veering off-topic slightly, I didn’t have git installed on my pc, so I fired up powershell and …

  PS> cinst git

… I used chocolately to install it, restarted powershell and …

  PS> git clone https://git01.codeplex.com/aspnetwebstack

… I was rummaging around the asp.net web stack code 😀

Back on to topic …

After a few failed attempts at getting the null reference to go away it dawned on me that with another layer or two or abstraction I could Moq (on nuget too – https://www.nuget.org/packages/moq) my way out of trouble.

So, thinking about it for a little while I came up with a way of doing all this so I could moq it. Firstly I needed to change CreateApiErrorResponse from an extension method into a “service”, which I could then pass into the relevant controllers. Once I get past the unit test stage I could easily set it up using Castle Windsor. I would also need an IResourceLinker factory.

The Service

    public interface IHttpRequestMessageService
    {
        HttpResponseMessage CreateErrorResponse(
            HttpRequestMessage request,
            HttpStatusCode statusCode,
            string parentId,
            string errorMessage,
            Action<IResourceLinker, ApiError> addLinks);
    }

    public class HttpRequestMessageService : IHttpRequestMessageService
    {
        private readonly IResourceLinkerFactory _resourceLinkerFactory;

        public HttpRequestMessageService(IResourceLinkerFactory resourceLinkerFactory)
        {
            _resourceLinkerFactory = resourceLinkerFactory;
        }

        public HttpResponseMessage CreateErrorResponse(
            HttpRequestMessage request,
            HttpStatusCode statusCode,
            string parentId,
            string errorMessage,
            Action<IResourceLinker, ApiError> addLinks)
        {
            var apiError = new ApiError
            {
                ParentId = parentId,
                ErrorMessage = errorMessage
            };

            if (addLinks != null)
            {
                var routeLinker = _resourceLinkerFactory.GetResourceLinker(request);
                addLinks(routeLinker, apiError);
            }

            return request.CreateResponse(statusCode, apiError);
        }
    }

The Factory

    public interface IResourceLinkerFactory
    {
        IResourceLinker GetResourceLinker(HttpRequestMessage request);
    }

    public class ResourceLinkerFactory : IResourceLinkerFactory
    {
        public IResourceLinker GetResourceLinker(HttpRequestMessage request)
        {
            return new RouteLinker(request, new AttributeBasedRouteDispatcher());
        }
    }

Once I sorted out a few built errors it was time to do some Moqing…

    public class MyControllerTests
    {
        private Mock<IResourceLinkerFactory> _mockResourceLinkerFactory;
        private Mock<IResourceLinker> _mockResourceLinker;
        private IHttpRequestMessageService _httpRequestMessageService;
        private MyController _controller;

        [SetUp]
        public void SetUp()
        {
            const string id = "john.doe@example.com";

            var config = new HttpConfiguration();
            var request = new HttpRequestMessage(HttpMethod.Post, string.Format("http://localhost/api/user/{0}", id));

            _mockResourceLinkerFactory = new Mock<IResourceLinkerFactory>();
            _mockResourceLinker = new Mock<IResourceLinker>();
            _httpRequestMessageService = new HttpRequestMessageService(_mockResourceLinkerFactory.Object);

            _mockResourceLinkerFactory.Setup(x => x.GetResourceLinker(It.IsAny<HttpRequestMessage>()))
                                      .Returns(_mockResourceLinker.Object);

            _mockResourceLinker.Setup(x => x.GetUri(It.IsAny<Expression<Action<MyController>>>()))
                           .Returns(new Uri(string.Format("http://localhost/api/user/{0}", id)));

            _controller = new MyController(_httpRequestMessageService);
        }
    }

Hurrah! It all worked and I could get back to testing what I was actually trying to, which was unrelated to providing links when sending errors to the client. But, I needed this anyway 😀

Since the tests I was working on weren’t testing the presence of the links, I suppose I could have done something like this …

    var _mockHttpRequestMessageService = new Mock<IHttpRequestMessageService>();
    _mockHttpRequestMessageService
        .Setup(x => x.CreateErrorResponse(
            It.IsAny<HttpRequestMessage>(),
            It.IsAny<HttpStatusCode>(),
            It.IsAny<string>(),
            It.IsAny<string>(),
            It.IsAny<Action<IResourceLinker, ApiError>>())
        .Returns(new HttpResponseMessage(...));

Anyway, I hope that helps someone out. It’ll probably be me at some point in the future as my memory is not the best 😉

Displaying embedded web pages in Winforms

I had an application/plugin I wanted to display some license information in and also attribute my use of a public API. So, I figured a nice way to do that would be to drop a web browser control in my winform and then have an embedded resource as the content. So, I created a little webpage and set it’s Build Action to Embedded Resource. A tiny bit of css in the head section and it looked good.

But, I wanted to also display an image in there. I tried a few different ways, but eventually stumbled upon an answer on stackoverflow which suggested encoding the image as a Base64 string. So, I set to work creating a little helper method to load my embedded web page and automatically encode all images on it. I decided to go with using a placeholder to the image, like so …

%IMG("MyProgram.Images.logo.png")%

In order to find out the name of the resource, you may find running this little piece of code helpful …

var names = Assembly.GetExecutingAssembly().GetManifestResourceNames();

So, I used a little regex magic (courtesey of regexhero.net) to find those placeholders, extract the path and do the encoding for me.

    public static class EmbeddedWebPageLoader
    {
        public static string LoadWebPage(string name)
        {
            const string regexPattern = @"%IMG\(\""(?<ImagePath>[^\""]*)\""\)%";
            var assembly = Assembly.GetExecutingAssembly();
            var pageStream = assembly.GetManifestResourceStream(name);
            if (pageStream != null)
            {
                using (var webPageStreamReader = new StreamReader(pageStream))
                {
                    var pageContent = webPageStreamReader.ReadToEnd();
                    var matches = Regex.Matches(pageContent, regexPattern);
                    foreach (Match match in matches)
                    {
                        var imagePath = match.Groups["ImagePath"];
                        var extension = Path.GetExtension(imagePath.Value).Trim(".".ToCharArray());
                        var imageStream = assembly.GetManifestResourceStream(imagePath.Value);
                        if (imageStream != null)
                        {
                            var buffer = new byte[imageStream.Length];
                            imageStream.Read(buffer, 0, (int) imageStream.Length);
                            var imageBase64String = Convert.ToBase64String(buffer);
                            var imgTag = string.Format("<img src='data:image/{0};base64,{1}'/>", extension, imageBase64String);

                            pageContent = Regex.Replace(pageContent, regexPattern, imgTag);
                        }
                    }
                    return pageContent;
                }
            }
            return null;
        }
    }

It works like a dream, I can now use images inside my about box, like so …

webBrowser.DocumentText = EmbeddedWebPageLoader.LoadWebPage("MyProgram.About.html");

Running Raven DB Server from VS2012 Solution Explorer

I needed to run the full RavenDB Server as part of a development I’m currently working on. So, I knocked up a little powershell script to do that for me …

$path = (gci packages\RavenDB.Server.* | select -First 1).FullName
$exe = (gci $path -Recurse -Include Raven.Server.exe).FullName
cmd.exe /c start "$exe"

It assumes you’ve installed the nuget package into your solution. This shouldn’t be done via the package manager, as stated on the nuget page.

Use this package if you want to run RavenDB as a standalone application. This package is not intented to be used in Visual Studio. RavenDB is a document database for the .NET platform, offering a flexible data model design to fit the needs of real world systems.

PM> Install-Package RavenDB.Server

So, I added the script (at the top of this post) as a solution item. I also have an external tool defined like so …

Powershell External Tool in VS2012

So, to run my RavenDB Server I just highlight “Raven.ps1” in the solution explorer …

Solution Explorer - Solution Items - Raven.ps1

… and select Run Powershell (x64) Script (output window)

VS2012 Tools Menu

… and there you have it. Full RavenDB Server running.

I hope that helps someone else out there.

Have fun with RavenDB, it’s pretty awesome from what I’ve seen so far.

msdeploy.exe pushed me to the brink of insanity before powershell saved my life!

I spent most of yesterday fighting against a combination of powershell and msdeploy.exe while trying to pass values to it containing embedded spaces.

I even tried using EchoArgs.exe to check if my parameters were being passed correctly, and they were!

I eventually reached the point where I began to question my own sanity in choosing software development as a career. That is until I tried a slightly different search in google and stumbled across an interesting blog post by James Coo.

Rather than calling msdeploy.exe I am now loading the assembly it uses and performing a sync …

	[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Web.Deployment")
	$baseOptions = New-Object Microsoft.Web.Deployment.DeploymentBaseOptions
	$syncOptions = New-Object Microsoft.Web.Deployment.DeploymentSyncOptions
	$deploymentObject = [Microsoft.Web.Deployment.DeploymentManager]::CreateObject("contentPath", $sourceFolder) 
	$deploymentObject.SyncTo("package", $packageName, $baseOptions, $syncOptions)

I hope this information will help someone else avoid insanity!