Touching Legacy Code

I agree with Adrian. Refactoring without tests is possibly the worst mistake you can make with a legacy codebase. I have been in situations where I really hated a piece of code I was working with, and so I mistakenly decided to refactor it. Sure, I cut the SLOC by 75%, and it worked better than it ever did before, and I found bugs and fixed them.

Doing it took much longer than I intended, introduced new bugs, and introduced a new maintenance cost. The code had been running fine, now it was not, and I had to fix it.

In my experience, legacy code should be touched as little as possible, and when it is touched, the part that's changed should be tested properly, and the entire thing should have some form of smoketest to make sure you didn't expose bugs elsewhere in the system.

I will now recite the Ode To The Maintenance Programmer

Once more I travel that long dark road
  into someone elses impossible code.
Through "if" and "switch" and "do" and "while"
  that twist and turn for mile and mile.
Clever code full of traps and tricks
  and you must discover how it ticks.
Once again I emerge to ask anew
  "What the HECK does this program DO?"
'rati tags:


Adventures using Darcs

I've been playing with darcs lately. It's a really cool version control system that has some wicked features, but somehow has managed to get not just the really insane stuff (really complicated patch management and conflict resolution) right, but also managed to get the little details right.

I had a situation yesterday that involved a conversation that went like this:

Friend: I can't find something that will let me give it a bunch of urls in a web browser and let me download all of them!
Me: I have an hour. Lets write it. Give me a PC.
Friend: Okay!

And so it was on. I had a couple hours to churn out a piece of software, and I wanted to do it in such a way as they could use it and I could maintain it. I also knew that any software I wrote in the space of an hour was going to be a steaming pile of crap.

My weapons of choice: Python, Twisted, Darcs, Putty, Vim.

I wrote most of it over SSH to my OSX machine where I had all the tools installed. Before I started, I created a new directory and typed darcs init. This initialised that directory as a darcs repo.

When I got it working for the first time (runnable code that did what was required) I typed darcs record -am "first iteration".

After a few more things I fixed up, I copied it to the windows machine I was doing my work from. I installed Python in C:\Python24, I grabbed the non-cygwin version of darcs and dragged the contents of that to the same directory. I added C:\Python24 to the $Path, and killed two birds with one stone. Now pythom and darcs were both in my path, and I could wreak havoc.

darcs get http://shiny.thorne.id.au/~stephen/Downloader/
cd Downloader
python downloader.py

It worked. I found and fixed bugs using vim on OSX, via putty. Every major change was accompanied by darcs record.

To test the code on win32, I used darcs pull -a to suck down the new patches.

Great. It worked. I wanted to show the person I wrote the code for how to use darcs, just in case he made modifications (he intended to do so), so I showed him how to run darcs record and darcs send. I operated under the assumption that because he was on a win32 box without an MTA set up correctly, it would fail horribly.

darcs send is a killer feature. Anyone with a checked out darcs repo can use it to send all the darcs patches upstream via SMTP. The patches arrive in the mailbox of the leader developer, and he can choose to apply them or not. No commit access is required. Anyone can do this. People can trade patches in high-fidelity, version controlled fashion.

I could not have been more wrong. It worked fine. It launched thunderbird and sent the email after simple thunderbird "[x] don't ask me again, okay/cancel" click through.

Oh Emm Eff Gee. It worked. Not only did it work, it REALLY worked. No hacking, no unix software installed, no SSH keys or logins. It just worked.

I intend to give a talk at humbug about darcs at some point in the next few weeks. I just have to write up some slides I guess.

'rati tags:


Mr Doctorow

Rohan has been ranting and raving about this Cory Doctorow dude for ages. I finally had a chance to go to his website and read some of his works. In fact, I've only read just one

It happened to be about my favourite topic. Printers.


Exporting from SF CVS to Darcs

Branedump of the steps to export from cvs.sf.net to darcs:

darcs get --partial http://darcs.arstecnica.it/tailor
cd tailor
chmod +x tailor
export PROJECT=netrek
export MODULE=client
export CVSUSER=jerub
export WEBPATH=$HOME/Sites
./tailor --verbose --source-kind=cvs --repository=:ext:$CVSUSER@cvs.sf.net:/cvsroot/$PROJECT --module=$MODULE --target-repository=$PROJECT-$MODULE > $PROJECT-$MODULE.config
sed -ie "s@$(pwd)@$WEBPATH@" $PROJECT-$MODULE.config
./tailor --configfile $PROJECT-$MODULE.config

Now. Once sf decides to accept my SSH key and stick it on the CVS servers, I'll be able to dump CVS to darcs, in both senses.

Updated: added the annoying looking sed command.

'rati tags:


Firebug for all

Debugging web pages is a pain. I have two major tricks I use:

  • Mochikit Logging Pane
  • Select stuff on the page->Right Click->View Selection Source...

But today glyph introduced my to the bees knees of firefox javascript debugging, FireBug.

I just wish the bastard had told me earlier.

If you develop for the web, firebug is for you.

'rati tags: ,


Hamachi vs. The Pink Robots

So, I had a good experience with technology tonight. Not a stellar experience, but good. I set up Hamachi on my OS X machine tonight. Hamachi is a VPN system that does lots of interesting stuff. If you haven't heard about it, please go read about it.

Hamachi isn't properly supported on mac, probably because of little things like driver installation and the non-existant GUI, but it works, and this is how to set it up:

Download tuntap (tiger) and hamachi ( There may be more a more up to date hamachi in the osx directory so check there if you want to.

I put those in ~/src/, so I did this:

# extract files into ~/src/tuntap_tiger and ~/src/hamachi-
cd ~/src/
tar -zxvf hamachi-
tar -zxvf tuntap_tiger.tar.gz

# hit next etc on the installer
open ~/src/tuntap_tiger/tuntap_installer.mpkg

# install hamachi
sudo ~/src/hamachi-

# config the tun device
sudo ~/src/hamachi-

# initialise, start, login, set a name
hamachi start
hamachi login
hamachi set-nick Jerub

# create a network, join it, go online, list other users...
hamachi create mynetwork mypassword
hamachi join mynetwork
hamachi go-online mynetwork
hamachi list

As I said. It wasn't incredibly painful. My initial test was initiating a VPN between two NAT'd connections, then contacting another host participating in the connection. I was running OS X and she was using the windows hamachi client.

'rati tags: ,


Twill and py.test

The latest tool in my arsenal is twill. It's a cross between a web browser and a testing framework. I think it works quite well, and I use it in conjunction with Buildbot, for testing the web interfaces at work.

Twill allows you to use a trivial little script like:

go http://myhost.exmaple.com/
formvalue login username "stephen"
formvalue login password "secr3t"
code 200
find "Login Successful"

And that will go to a website, login, check that a HTTP 200 code was returned, and verify that the words "Login Succesful" appeared on the page. If any problems occur, then the script will exit with a non-zero exit code, and an error message. This makes buildbot integration trivial.

But why twill is so nice, is because it's completely python. Instead of taking the long way around and invoking twill-sh, you can access the web browser directly, like so.

from twill import commands as web web.go('http://myhost.exmaple.com/')
web.formvalue('login', 'username', "stephen")
web.formvalue('login', ' password', "secr3t")
web.find('Login Successful')

And where this comes in real handy, is when I use it in a test suite such as py.test. py.test -ls --looponfailing is a command that really needs a post of its own to both explain and exclaim about, but suffice it to say that it's lifechanging.

import py.test
from twill.errors import TwillAssertionError
from twill import commands as web

def test_login():
    web.formvalue('login', 'username', "stephen")
    web.formvalue('login', ' password', "secr3t")
    web.find('Login Successful')
    py.test.raises(TwillAssertionError, web.find, 'Login Failed')

def test_failed_login():     web.go('http://myhost.exmaple.com/')
    web.formvalue('login', 'username', "stephen")
    web.formvalue('login', ' password', "notmypassword")
    web.find('Login Failed')
    py.test.raises(TwillAssertionError, web.find, 'Login Successful')

There, tests. Easy to write, easy to read, all written in python, I can leverage as much of python as I want, while still having a quick and easy way of puppeting a website, and testing that it works.

'rati tags: , ,