Friday, November 16, 2007

Get your build fixed faster... broadcast your failures!

We've been talking about setting up a build box light for ages.

The other day my project manager bought a USB Visual Signal Indicator. An hour of hacking .. and we now have a light that's green on a passing build and flashes red on a breaking build.

We are using CruiseControl.Net as our build machine, so I controled the light using a custom build publisher.

The result we are experiencing is the build is gets fixed faster. I have a few theories as to why.

Here is the code...

using System;
using System.Text;
using Exortech.NetReflector;
using ThoughtWorks.CruiseControl.Core;
using ThoughtWorks.CruiseControl.Remote;


namespace FlashLightPublisher
{
[ReflectorType("flashlight")]
public class FlashLightPublisher : ITask
{
[ReflectorProperty("goGreenOnPass", Required = false)] public bool GoGreenOnPass = true;

public void Run(IIntegrationResult result)
{
StringBuilder DeviceName = new StringBuilder(Delcom.MAXDEVICENAMELEN);

int Result = Delcom.DelcomGetNthDevice(Delcom.USBDELVI, 0, DeviceName);

if (Result == 0)
{
throw new Exception("no usb device");
}

uint hUSB = Delcom.DelcomOpenDevice(DeviceName, 0);
switch (result.Status)
{
case IntegrationStatus.Success:
if (GoGreenOnPass)
{
Delcom.DelcomLEDControl(hUSB, Delcom.REDLED, Delcom.LEDOFF);
Delcom.DelcomLEDControl(hUSB, Delcom.GREENLED, Delcom.LEDON);
Delcom.DelcomLEDControl(hUSB, Delcom.BLUELED, Delcom.LEDOFF);
}
break;
case IntegrationStatus.Exception:
case IntegrationStatus.Failure:
Delcom.DelcomLEDControl(hUSB, Delcom.GREENLED, Delcom.LEDOFF);
Delcom.DelcomLEDControl(hUSB, Delcom.REDLED, Delcom.LEDFLASH);
Delcom.DelcomLEDControl(hUSB, Delcom.BLUELED, Delcom.LEDOFF);
break;
case IntegrationStatus.Unknown:
Delcom.DelcomLEDControl(hUSB, Delcom.BLUELED, Delcom.LEDON);
break;
}

Delcom.DelcomCloseDevice(hUSB);
}
}
}


Our ccnet.config file contains the following snippet...


...
<publishers>
<flashlight/>
...
</publishers>


Note: We have few sequencial builds set up so we don't class the build as green until all the builds have passed. I therefore have all the builds able to make the light go red, but only the last build make it go green.

Wednesday, November 14, 2007

Conduit Design Pattern

I love dependency injection. Specifically I like constructor dependency injection.

Sometimes however you have two objects that need to talk to each other. This means you need create each before the other to use constructor injection.

What I have been doing instead is creating a class I call a conduit.

The Conduit class implements one of the interfaces and delegates to another instance of that interface. It also provies a setter injection method to allow you to initialize the conduit.

To use it therefore you do the following:
1/ Create an instance of IXConduit
2/ create an instance of class Y passing in the IXConduit as an instance of IX
3/ create an instance of class X passing in Y
4/ call the setter injection method on the conduit passing X in.

When Y calls a method on the IX it has (the conduit) it passes on the call the the IX it has (the real instance of X), and X can call method on Y directly.

This means the compilcation of instantiation is not part of class X or Y so they don't get polluted by this design issue.

MockingTestFixture makes NMock tests simpler

I just noticed that not everyone is using a helper class when using NMock2. It seriously makes your code cleaner. Here is the one I use.

using System;
using NMock2;
using NUnit.Framework;


namespace Tests.Utilities
{
public abstract class MockingTestFixture
{
private Mockery mockery;

protected IDisposable Ordered
{
get { return mockery.Ordered; }
}

[SetUp]
public void MockSetUp()
{
mockery = new Mockery();
SetUp();
}

protected abstract void SetUp();

[TearDown]
public virtual void MockTearDown()
{
TearDown();
VerifyExpectations();
}

protected virtual void TearDown()
{
}

public T NewMock()
{
return mockery.NewMock();
}

public void VerifyExpectations()
{
mockery.VerifyAllExpectationsHaveBeenMet();
}

protected static void IgnoreReturnValue(object ignored)
{
}
}
}

Derive your test fixture from this class. Override the abstract setup method... there you go. No more need to worry about the Mockery.

Thursday, September 13, 2007

Tip#3: Extend your mocking framework

Currently I am using NMock2 in my C# development. I have however made a few extensions to allow me to test some edge cases. Due to the clean design of NMock extending it is really easy.

IAction


A normal use of NMock looks like this:

Expect.Once.On(someObject).Method("methodName").WithAnyArguments().Will(Return.Value("value"));


In this statement the 'Return.Value' method returns an object that implements the IAction interface. The job of this object is to perform some action at the point the expectation matches. In this example the effect is to set the return value of the method to a known string.

However... any class implementing the IAction interface can be passed to the 'Will' method, so if you have some special need to execute code at the point the method is matched, then here is a great place to put it.

Here is an example...
[Test]
public void Move_Sleeps_UntilUpdatedWithTrue
{
Expect.Once.On(sleeper).Method("Sleep").Will(Execute.Delegate(delegate { mono.Update(false); }));
Expect.Once.On(sleeper).Method("Sleep").Will(Execute.Delegate(delegate { mono.Update(false); }));
Expect.Once.On(sleeper).Method("Sleep").Will(Execute.Delegate(delegate { mono.Update(true); }));
mono.Move(120);
}


Here I have used an IAction class that invokes a delegate at the point your expectation is met. In this case I am using it to test a piece of code that repeatedly sleeps (using a sleeper service) until the object is updated with true. I am intercepting the call to sleep and instead taking the opportunity to update the object.

Here is the code that makes that possible.
public class Execute : IAction
{
public delegate void DelegateAction();
private readonly DelegateAction action;

public static IAction Delegate(DelegateAction action)
{return new Execute(action);}

private Execute(DelegateAction action)
{this.action = action;}

public void Invoke(Invocation invocation)
{action();}

public void DescribeTo(TextWriter writer)
{}
}
So in way of explanation: the invoke method is want gets called when the expectation is met. It just invokes the delegate the 'Execute' object was constructed with. The rest is just static methods to allow you to say Execute.Delegate(...) rather than new Execute(...)

Next post I'll explain how I test firing events using another extension to NMock.

Wednesday, September 05, 2007

Installing simple_helpful without edge Rails

DHH has helpfully moved the simply_helpful Ruby on Rails plugin.
If you are not running edge you can still install, you just have to use:

script/plugin install http://dev.rubyonrails.org/svn/rails/plugins/legacy/simply_helpful/

GitHub Projects