Publishing Python unit test results in Jenkins

When I switched to developing on an OS stack one of the first things I look for was a $g(Continuous Integration server) and settled on Hudson which, after some tumult with surrounding Oracle’s acquisition of Sun, was forked into Jenkins. Getting jenkins setup couldn’t be easier and the web UI is comprehensive and full of options.

My day-to-day development is in Python and I’ve written a bunch of tests based on the core unittest module though it doesn’t natively produce results that can be consumed by Jenkins. To that end, I searched around and found the necessary pieces which I wanted to capture.

First, you need to install the unittest-xml-reporting package which is described as:

PyUnit-based test runner with JUnit like XML reporting.

sudo easy_install unittest-xml-reporting

Once installed you need to add the following to your unittests so they will produce the necessary XML result output:

import xmlrunner


if __name__ == '__main__':

Next, in Jenkins click the configure link for your project and check the Publish JUnit test result report and set the path to the output location for the unit tests. In my case the full path to the XML output is /.hudson/jobs/publishing/workspace/trunk/test/test-reports. In Jenkins the path to use for publishing is **/trunk/test/test-reports/*.xml

Jenkins JUnit publisher settings

This will also add a chart to the project page in Jenkins:


Using the TFS source control provider in CCNET v1.5 with 2010

Recently I helped a client of Falafel’s get up and running with Continuous Integration using CCNET v1.5. They’re running Team Foundation Server 2010 using TFS for their source repository and fortunately CruiseControl.NET includes a source control provider for TFS. Having tried this configuration and successfully we configured the server but ran into the following error:

Source control failure (GetModifications): Unable to find TF.exe and it was not defined in Executable Parameter


Reviewing the code for the TFS plugin we can see why this happens for 2010:

private string ReadTFFromRegistry()
    string registryValue = null;

    registryValue = registry.GetLocalMachineSubKeyValue(VS2008_64_REGISTRY_PATH, VS_REGISTRY_KEY);

    if (registryValue == null)
        registryValue = registry.GetLocalMachineSubKeyValue(VS2005_64_REGISTRY_PATH, VS_REGISTRY_KEY);

    if (registryValue == null)
        registryValue = registry.GetLocalMachineSubKeyValue(VS2008_32_REGISTRY_PATH, VS_REGISTRY_KEY);

    if (registryValue == null)
        registryValue = registry.GetLocalMachineSubKeyValue(VS2005_32_REGISTRY_PATH, VS_REGISTRY_KEY);

    if (registryValue == null)
        Log.Debug("Unable to find TF.exe and it was not defined in Executable Parameter");
        throw new Exception("Unable to find TF.exe and it was not defined in Executable Parameter");

    return Path.Combine(registryValue, TF_EXE);

As of this writing the CCNET documentation does not include the Executable parameter for this source control provider though the fix is easy enough.

Building a TFS project using CruiseControl.NET v1.5

While setting up a continuous integration (CI) build in CruiseControl.NET on a project checked into Team Foundation Server (TFS) I had to make several “adjustments” to get the build working properly. This post documents the errors and what I did to get a successful build.

First, in VS.NET 2010 I created a simple WPF test project and checked it into TFS. Next, updated my CCNET server to v1.5 (v1.5.72256.1 to be exact) and edited the ccnet.config file to point to my project which looks like:

<cruisecontrol xmlns:cb="urn:ccnet.config.builder">
    <project name="WPFTest">
        <sourcecontrol type="vsts" autoGetSource="true" applyLabel="true">
          <project>$/CI WPF Test</project>

              <buildArgs>/p:Configuration=Debug /v:diag</buildArgs>
          <xmllogger />
          <statistics />
          <modificationHistory  onlyLogWhenChangesFound="true" />

At that point I fired up the CCNet server from the command line and hit the Web Dashboard to force a build of the project which resulted in the error “Team Foundation Server myserver-tfs does not exist or is not accessible at this time.
Technical information (for administrator)
The request failed with HTTP status 404: Not found”

CCNET Console

The problem was the <server> tag from the ccnet.config file was missing part of the URL which should have included “/tfs” on the end. My bad.

After correcting the server URL I ran into the next error “TFS30063: You are not authorized to access http://myserver-tfs:8080/tfs.” A bit of research and I found this issue in the CCENT Jira bug database regarding a bug (and patch) for an issue in CCNET’s VS TFS source control plugin. My search also lead me to a post titled CCNET 1.5 and TFS 2010 Integration that mentions the same problem with a workaround which is to run the CCNET server under the account that has access to the TFS server.

TFS Not authorized

I fired up a new console window using my TFS account credentials with the runas.exe command as follows:

C:\Windows\System32\runas.exe /netonly /user:MYDOMAIN\STrefethen cmd.exe

I then updated my ccnet.config file removing the <username> and <password> settings from the <sourcecontrol> block. After forcing yet another build the next problem I encountered read:

“Team Foundation Server http://myserver-tfs:8080/tfs does not exist or is not accessible at this time. Technical Information (for administrator):

Team Foundation services are not available from the server.

Technical Information (for administrator):

TF253022: You must update your client with the Forward Compatibility Update in order to connect to the Team Foundation Server that you selected. To obtain this update, go to the Microsoft Web site:

Here are more explicit details of that update:

Visual Studio Team System 2008 Service Pack 1 Forward Compatibility Update for Team Foundation Server 2010 (Installer)

After downloading and installing the update then forcing yet another build all is now working:

CCNET Web Dashboard

Hope this helps you in the event you’ve run into similar problems.

CruiseControl.NET VS.NET Starter Kit for plugin development

At the Silicon Valley Code Camp 2009 I gave a talk called Extending CruiseControl.NET through the use of plugins. I discussed the necessary steps and illustrated with an example ISourceControl provider using the LinqToTwitter OS project on Codeplex. The provider polls a configurable Twitter account looking for Tweets that that start with “CI:” allowing the Tweeter to trigger a build of the project simply be tweeting something like: “CI:Start the build”.

It’s a simple example but illustrates how easy it is to create CC.NET plugins an extend the platform to uses beyond classic Continuous Integration.

Here is a link to the Starter Kit. Btw, you will need to update the ThoughtWorks assembly references to match your build of CCNET.

Using CruiseControl.NET to manage EDI Invoice processing

A few months ago I started working in an area I previously knew little about, EDI. EDI stands for Electronic Data Interchange and it defines standards for how businesses communicate with one another electronically. The basic flow of information for what I’m working on looks like this:

The document numbers above correspond to the following:

  • EDI 850 = Purchase Order (PO)
  • EDI 810 = Invoice
  • EDI 997 = Functional Acknowledgement

My client represents the seller’s side of this diagram and I’m specifically working on the lower half of this picture, the invoicing portion, as there is existing software which handles PO’s. As indicated in light red there is a trading partner involved which brokers various services between buyers and sellers including providing EDI services. The EDI “documents” are cryptic delimited text files exchanged via numerous transport mechanisms though FTP is used in this case.

The Flow

Basically, there is a system which polls the trading partner, again via FTP, looking for new purchase orders. When one is found the file is downloaded, validated, processed and an acknowledged (EDI 997) is transmitted back to the trading partner. Eventually, the order works it’s way through the system and an invoice is generated at which point, an EDI 810 is generated and transmitted to the trading partner, validated and again acknowledged with an EDI 997, a mirror image of the EDI 850 processing. For brevities sake I’m glossing over parts of this process but you get the gist of what’s going on.

When I first was assigned to start working on EDI invoicing I had a lot of things to learn including EDI, the current processes involved in invoicing and the software that handled purchase orders among others. I quickly learned via not so subtle hints that the existing software which handles PO’s wasn’t considered maintainable and is badly in need of replacement.

Using CruiseControl.NET

Once I got my feet grounded I realized this system closely resembled a continuous integration process and started investigating using CruiseControl.NET as the primary engine to drive invoice handling. I already knew CruiseControl.NET brought a number of interesting features to the table including:

  • Open Source
  • Polling architecture for trigging task execution
  • Open plug-in architecture for things like source control providers and task execution
  • Easily configured using XML (ccnet.config)
  • A customizable web based portal for monitoring projects
  • Email publishing for notifications
  • Logging

Basically, you can envision CruiseControl.NET as the two blue circular arrows in the middle of the above diagram. In a future, post talk more about the specific implementations of ISourceControl and ITask that I’ve written to manage this EDI process.