Thursday, November 05, 2009

Working with bugs

No, this is not a post on entymology; rather, it’s a bit of a lament on the lost art of filing bug reports. Though they may bestride the programming world like a colossus, even the best programmers will eventually leave bugs in their code. Sooner or later, some poor user will fall foul of it.

You then have a number of solutions, depending on where the product came from. For a commercial product, you can:

  1. ignore it and hope it goes away;
  2. file a bug report, and hope that the provider will fix it;
  3. find some sort of workaround, or just learn to live with it;
  4. vote with your wallet, and switch to a competitor’s product

For an open-source product,, you have an extra option:

  1. download the source code, and fix it yourself, and preferably submitting your fix back to the community.

In my case, it was a bug in a Microsoft development tool, the succinctly named Microsoft Visual Studio Team System 2008 Database Edition GDR R2. As an aside, let me say that I’ve been using it for all of 2 days, and I absolutely love its functionality. It finally makes versioning and deploying databases a delight rather than a painful chore. There is now no excuse for organisations not to have their databases under version control, or for having painful manual deployment processes.

Anyway, it has a bug in it which is holding up a particular project at work. I searched for a solution, and found someone who had reported the same issue some 9 months ago. Unfortunately the bug report that they filed was so lacking of information that Microsoft promptly closed the bug as Not Reproducible. In fact, it’s not 100% certain that the bug relates to my issue because it is so light on details – it just reports the same error message.

As it happens, the steps required to reproduce the bug were incredibly trivial, so I opened a new bug, and gave the sort of details that a developer trying to fix a bug needs to see – in other words, I described what I was doing, what I expected to see happening, and what actually was happening. More to the point, I list the steps that the developer should take to make the same thing happen for them.

The first step to being able to resolve a bug is to be able to reproduce it. If you can’t reproduce it, how can you work out what is going wrong, and how can you prove that you’ve fixed the bug? And if the bug reporter doesn’t tell you how to reproduce the bug, what chance do you have of being able to fix it?

So please – if you want your bug to be fixed, consider the poor developer who has to fix it, and tell them what they need to know to get the job done. Anything less, and you’ll have a 9 month wait before someone else with the same problem files the same issue again.

Wednesday, September 23, 2009

Weird Sydney morning weather

The joys of parenthood include many early mornings. This is what awaited me this morning when Samuel woke us up. Most freaky! Any ideas what's causing this?
Update : apparently it's a dust storm. Western Australia is missing several hundred tonnes of dust and topsoil.

Monday, June 29, 2009

iPhone on 3

When the iPhone 3G was originally released in Australia, I and many others complained that 3, who provide some of the best 3G data plans in the country, did not sell it. There were ways around it,which kind of suggest that it was a problem at Apple's end rather than 3's, but it seems that with the release of the updated iPhone 3GS, users of the 3 network are finally getting some Apple love. And of course, it's at this point that I notice that my elderly Nokia N95 8Gb is finally fully supported by OS X, including syncing from iTunes and iPhoto. Now where was that a year ago when I really needed it? Never mind; just as soon as I can sell a kidney on Ebay, I'll have his'n'hers iPhone 3GS's, and the Nokia can go in the phone recycling bin.

Wednesday, May 20, 2009

SvnRevisionLabeller makes its v2 release

Recently Thoughtworks started to make available release candidates for version 1.4.4 of CruiseControl.NET. Tucked away inside there though are some changes to some of the core components, that break compatibility with SvnRevisionLabeller.

This gave me the proper motivation to find some time to finish off the packaging of a fairly major change to the way the labeller constructs build labels. The real work was actually done by another developer, fezguy - I just had to integrate his patch, tweak it to the way I like things (hey, it is my project after all!), and finally start work on some automated tests. I like automated tests.

Since the two changes combined do break backwards compatibility, it's good to take a step back and see where we are now.

Before, SvnRevisionLabeller was quite opinionated about how it thought build labels should be structured. With version 1.1, it was {major}.{minor}.{svnRevision}.{build} - {build} would start at 0, then if you forced another build without another commit having taken place, it would be incremented by one. A commit would then reset {build} back to 0, so you had a good idea how often the build was being forced. I later added the ability to specify prefix and suffix text for the label.

Version 1.3 saw me rethink things a bit, with the label now defaulting to {major}.{minor}.{build}.{svnRevision}; now, successive forced builds made no difference to the label. What it did give me was that when I deployed a hotfix to production (usually designated by the incremented {build} number), I could tell immediately which Subversion revision it was built with.

So it obviously works the way I wanted it to - but what about other people? Version 2.0 makes the label scheme very flexible - some tokens are defined, and you just position the tokens wherever you want them in a string pattern. So for instance, if I set my configuration thusly:

<labeller type="svnRevisionLabeller">
<major>1</major>
<minor>4</minor>
<build>2</build>
<pattern>Release v{major}.{minor}.{build} from {revision}</pattern>
</labeller>

then when revision 42 is committed, the build label will become Release v1.4.2 from 42. At work, I use the {build} number to represent the sprint number since we began working on the {minor} release.

Finally, I noticed that my project was not the only one to be caught out by CC.NET's upgrade - Codeplex's CC.NET Community Plugins are also broken by the change; unfortunately, they have a little more work to do, as it's not just a question of updating their external libraries and recompiling. I'm rather underwhelmed by the amount of activity on the site: I raised an issue earlier this month, and then submitted a patch to fix the issue, and it still hasn't been acknowledged yet, let alone added to the repository. For the time being, I won't be upgrading to v1.4.4 at work, since we need that library for our deployments.

Tuesday, April 14, 2009

An afternoon at Lake Parramatta

The Easter weekend was a good opportunity to get out of the house for a while and enjoy some of what Sydney has to offer. Several friends have recommended Lake Parramatta, a small dam and reservoir less than 10 minutes from our house, but we've never been there before. It was built in the late 19th century to provide drinking water for Parramatta, but these days it's a recreation area. It's sometimes swimmable, I think they're still working on the general cleanliness of the water (lots of stormwater drains etc empty into the catchment area).

The reservoir of Lake Parramatta

There's plenty of parking etc at the entrance, barbecue areas, covered seating, even a playground for the little 'uns. It was quite busy considering sunset was less than an hour away, lots of families having picnics and so on.

The dam wall of Lake Parramatta

We took a brief walk round the easy part of the reservoir, down to the dam wall itself. There's a small creek at the base of the dam, with some pretty lush vegetation from the water that trickles down from the dam (although the picture above doesn't explicitly show it, the wall is constantly damp, as the water finds its way through and down).

Stepping stones

The creek at the bottom is crossed with a line of stepping stones. There's a lot of brown algae in the water, so it doesn't look very pleasant, but I think I got enough of an angle above so that it doesn't show. The full circuit around the reservoir is about 4.2km (I did say it was a little reservoir!), and although some of it is paved and flat, some of it requires a bit of a scramble. We'll have to save that for another time, because we got there not long before sunshot, and also because Emily is a bit too pregnant to be climbing anything at the moment.

Tuesday, March 31, 2009

MassTransit

Earlier this month, I mentioned the MassTransit project, an open-source .NET Enterprise Service Bus implementation, a topic sure to break the ice at a many a party.

We've been getting stuck into MassTransit at work for a major project, and had all sorts of problems along the way, mainly due to the youth of the project and the general lack of documentation. Where there were code samples, sometimes the code just plain didn't work.

Blog postings need images, apparently; so here's one that's distantly related to the topic under discussion - it's a restaurant tram in MelbourneThe two main developers, Dru and Chris, have been a fountain of knowledge and general helpfulness, responding quickly to my sometimes continuous barrage of questions, not helped of course by our being on opposite sides of the planet. I've been able to chip in with the occasional patch, nothing to fancy at this stage, but at least enough for me to feel like it's not a completely one-way street.

Anyway, congratulations to MassTransit for shipping their v0.6 release candidate. I've been running it for a few days now, although without using some of the cooler pieces of new technology, such as the saga state machines. Hopefully with their help, I'll be able to get our project back on track and heading in the right direction.

Thursday, March 19, 2009

Topshelf

At work, I'm currently working on a project which requires the integration of several different systems, some of them hosted on the internet, and some on different sides of the corporate firewalls. This means that we can expect to lose connections between systems, which naturally pointed us in the direction of message queues, which are designed for such scenarios. A chat with a former colleague pointed me in the direction of enterprise service buses as the core technology to take care of all the plumbing; and after comparing feature sets with our requirements, I downloaded MassTransit.

What interested me was a spin-off from the MassTransit project, called Topshelf, which has a single and simple aim - to get rid of all the cruft associated with actually launching .NET programs, especially all the boilerplate code you have to come up with to run services.

I ran into a few issues though: the first was that before, I had been using the WiX's ServiceInstall code to handle all the service registration, such as setting the service name, description and credentials. However, Topshelf provides its own code to do that, and the two aren't compatible. In the end, the solution I came up with was to remove the WiX code and use Topshelf's, which would be invoked by a custom action in the WiX script:

<CustomAction Id="InstallService" FileKey="ServiceExe" ExeCommand="/install" />
<InstallExecuteSequence>
    <Custom Action="InstallService" After="InstallFinalize" />
</InstallExecuteSequence>

FileKey is just a reference to the Id of the executable for the service, and ExeCommand contains the parameter(s) to pass to it.

All well and good, but unfortunately, Topshelf's implementation currently launches the same dialog box that installutil does, and if you're trying to produce an unattended install file, a dialog box is the last thing you want. I've had a little play around with the source code and came up with something which would technically work, but was nowhere near as elegant as the rest of the code, so I'm not planning on submitting it.

I did add a few refactorings and documentation into the codebase, nothing clever or anything; I then submitted the changes as a patch to Dru, and within the hour, they had been committed to trunk. This really reminds me why I love open-source programming so much - if the application doesn't do quite what you want it to do, you can download the source code and modify it, and if it works well, you can contribute that change back to the community. Talk about a win-win situation. Non-open source companies have to think about every way that people will use their software, and then program all that functionality in, thus proving the 80-20 rule - 80% of your users are only using 20% of your application's functionality. Did you know that Microsoft Word has a Japanese Greeting dialog box, which allows you to select a greeting specific to the month of the year?! I wonder even how many Japanese people know it exists?

Japanese Greeting dialog box from Microsoft Word 2003

Speaking of contributing to open source, I've accepted a couple of patches to my SvnRevisionLabeller project, and should be releasing a new build soon, once I've figured how to get some good tests in there. You are testing your software, right?!