George V. Reilly

Odds and Ends #5

Mis­cel­la­neous links.

NUnit calling CppUnit

Over the last few days, I've been adapting an existing native C++ library so that it can be called from managed code. I had written a large number of unit tests with CppUnit and I wanted to be able to call the tests from NUnit.

I suppose that I could have written a new CppUnit TestRunner so that I could call it from NUnit. Instead, I took the cheap-n-dirty route, playing with #define and include paths. It took less time to get working than it did to write this blog post.

Here's the original native CppUnit test code

// native\FooTest.h

#include <cppunit/extensions/HelperMacros.h>

class FooTest : public CppUnit::TestFixture

NVelocity: loading templates from embedded resources

In last week's tip on using the NVelocity template formatting engine, I described what to set to load a template from an absolute path.

Here's the magic necessary to get NVelocity to load a template from an embedded resource:

VelocityEngine engine = new VelocityEngine();
ExtendedProperties properties = new ExtendedProperties();
properties.AddProperty("resource.loader", "assembly");
    "NVelocity.Runtime.Resource.Loader.AssemblyResourceLoader, NVelocity");
properties.AddProperty("assembly.resource.loader.assembly", "StencilFormatter");

NVelocity templates and absolute paths

We've started using the NVelocity template formatting engine. We were absolutely stymied for an hour, trying to figure out how to get it working with an absolute path to the template file, instead of the relative path shown in the doc­u­men­ta­tion.

The trick is to set file.resource.loader.path. Here's how to load C:\foo\bar\­some­file.vm:

ExtendedProperties props = new ExtendedProperties();
props.AddProperty("file.resource.loader.path", new ArrayList(new string[]{".", "C:\\"}));

template = velocity.GetTemplate("foo\\bar\\somefile.vm");

Upgrade your installation of NAnt

My colleague, Greg, and I spent all day debugging a build break in some unit tests that exercise a webservice interface in legacy .NET 1.1 code. Last night, the tests stopped working on our CruiseC­on­trol.NET build server. We couldn't understand it. The tests had been working for months. Now we were getting timeouts in SOAP. The tests es­sen­tial­ly mock a SOAP service using the soap.inproc transport and a stub im­ple­men­ta­tion that signaled an event to ac­knowl­edge a method being called.

The only thing that had changed in the code tree was that another colleague, Pavel, had discovered that two of our .csproj files somehow shared the same GUID, and had repaired continue.

Using Log4Net from a COM+ Application

I spent far too much time on Friday trying to make log4net work in a COM+ ap­pli­ca­tion.

Someone else had done part of the work necessary, by creating an ap­pli­ca­tion.config for the COM+ ap­pli­ca­tion and setting a custom Ap­pli­ca­tion Root Directory. This was enough to ensure that most of the managed code in the ap­pli­ca­tion got their con­fig­u­ra­tion settings; log4net being the exception.

It took some additional work to realize that we needed to add two assembly attributes:

[assembly: log4net.Config.Repository("unique-name")]
[assembly: log4net.Config.XmlConfigurator(ConfigFile="application.config")]

The repository name just needs to be a unique string. We used the name of the assembly.