I’ve recently started working with Subversion (a version control system) and FitNesse (the Fit acceptance testing framework based in a wiki). FitNesse has a primitive version control system built into it, where it builds zip files of previous versions of pages. It’s all a bit messy though, and it’s not likely to be the version control system used by the rest of your source code. Why wouldn’t you want your acceptance tests in the same repository you use for the rest of your source and tests?
So, arming myself with JavaSVN (a pure Java Subversion client library) I went looking
at the FitNesse source code. I’m sorry to say it’s not everything I’d hoped for – lots of methods declared to just throw
Exception, using streams with no
try/finally blocks and (I suspect) a rather gaping potential for things to go seriously wrong if someone commits a page at the same time as someone else deletes it. However, life goes on – fortunately I was able to find the entry point I needed fairly quickly.
In this case, it was
fitnesse.wiki.FileSystemPage, which dealt with both the writing of the “plain” contents/metadata files, along with the versioning. It was only a matter of a few hours to refactor that to allow the versioning piece to be pluggable. Adding Subversion support took another few hours, and the result works reasonably well. A few things to note:
I could possibly have used an existing plugin point instead of creating a versioning system off
I didn’t know that at the time, and I’m not sure how much it would have helped me. I’m not sure whether JavaSVN would have
let me get away with making changes to the repository without having a working copy at all, but if so that would have been
quite a nice solution. There’s no real need for a directory hierarchy – just a file per page, and Subversion properties to
store the FitNesse metadata. With the sort of load I’m expecting the server at work to have, performance wouldn’t have been
an issue, and it would quite possibly have simplified things a bit. On the other hand, what I’ve got works and was probably
a bit simpler to implement. On the other hand, it means changing FitNesse :(
I’ve currently implemented the new interface in the
fitnesse.wikinamespace, and I build it within the same
Eclipse project as the rest of the FitNesse code. It should really be in its own separate jar file, but that seemed overkill for what I was doing at the moment (especially as it’s only one source file).
I’ve only done manual testing on this. I don’t know enough about either FitNesse or JavaSVN to sanely test what I’ve done.
I’m sure it’s possible, and I hope that if others find this hack useful, they could help me to test it properly. I’m somewhat ashamed of this situation, given my firm belief in TDD – it’s due to a lack of understanding of where to go, not a belief that I’ll have magically got the code right. On the plus side, all the built-in FitNesse tests still pass, so I’m reasonably confident that if you run it without actually using the Subversion code, it’ll still work.
I’m really worried about threading. It’s unlikely to be a problem unless you happen to get two users doing things to the same pages at the same time, but the level of locking present in
FileSystemPagedoesn’t really cut it. That level is too low to be particularly useful, as one responder may need to change several pages on disk, and that should be done reasonably atomically. (I don’t even try to do it in an atomic way in terms of Subversion, but stopping other disk activity from interfering would be helpful.) Of course, you should never end up with a hosed Subversion repository (I really hope the server just wouldn’t let you do that) but it may be possible to get into a situation where you need to either do some delicate work updating the working copy manually, or just check the whole tree out again.
Currently, files (the ones under the files directory) aren’t versioned. I’m not sure how easy that will be to fix, but it’s
obviously something which is needed before it’s really production-ready. Hooks are needed for upload, delete and rename. Creating a directory probably doesn’t need to be versioned, so long as the directory is put under version control when the first file is created.
The whole change (a total of seven files – it’s a relatively small code change, all things considered) is available along with installation instructions on my main web site. It’s pretty basic at the moment, but if it all takes off, who knows what could happen?