Tuesday 11 October 2011

Broken Toys

The keen might have noticed this site has been coming and going for the past fortnight :-(

The cause is yet to be determined - I attempted to log in on Monday and nothing was there - although I could SSH in to a different machine on my home network, the blog server was unpingable. I half-expected it to be smouldering from a particularly brutal DOS attack when I came home, but nothing so spectacular. It was just locked up.

I decided to take the opportunity and use this downtime to do some comprehensive upgrades I'd been wanting to perform for a while:

  • Move the server to Debian to match my other Debian/Ubuntu boxen
  • Upgrade my web platform to the latest-and-greatest Tomcat 7.0.22
  • Upgrade the blog software to Pebble 2.6.2 to get lots of fixes/improvements

Such big plans expose one to potential big failures. And I had a lot of them. Firstly, my wonderful, faithful little NetVista just simply didn't have the grunt to run anything much bigger than a "Hello World" webapp on the shiny new Tomcat/Debian stack - its 256Mb of RAM and puny 233MHz CPU had no chance against the might of a full JEE application like Pebble as well as running a beefcake OS like Debian (as opposed to the super-slender Puppy Linux it had before). So I moved the whole thing to a VM on a much gruntier Ubuntu Server I have. It remains to be seen what will happen to the little IBM - it's not adding much to the party at this point ...

So after migrating to the new hardware, and getting the new Pebble going, I had to bring in the performance improvements I blogged about a while ago, which still don't exist in the official Pebble codebase. (Note to self: must contribute those fixes back!). Initially it seemed all good - my YSlow score of 99 is mighty pleasing - but there was an elephant in the room.

Why the hell was it taking 8.5 seconds to serve up the home page?

Extensive (frustrating) investigation has shown that something added to Pebble since v2.4 has pretty badly borked the performance when hitting /. Fully-specified URLs are fine. I'm suspecting the new-in-2.5 SEO-friendly URL generator, but that's pure speculation. So until the bad interaction between Tomcat 7 and Pebble > 2.4 is sorted out, I'm stuck with icky URLs and no OAuth logins :-(

Tuesday 4 October 2011

Make Sure You're Testing The Right Things

I'm going to come right out and say it. I love Unit Tests.

I love mocking the collaborators with Mockito (especially the annotation-driven mode). I love the small but oh-so-valuable mini-refactors that are sometimes necessary to make a class testable. And I love watching the code coverage march inexorably to the 100% asymptote.

What makes me very sad is seeing a sorry set of unit tests, and/or a poor development environment for testing. What do I mean?

  • If you're not mocking your collaborators, you're not unit testing. And if you're not unit testing, your code is Instant Legacy Code™. You cannot properly test any non-trivial class without needing to mock its dependencies.

  • Tests should be named in terms of expected behaviour. Method name testParseIntNullString() says nothing that couldn't be gleaned from looking at the test code itself. Method name shouldThrowFormatExceptionWhenParsingNullString() tells you the intention of both the code under test and the test itself. It's documentation that won't get out of sync with the code.

  • Use the facilities provided by your testing package. I'm a TestNG fan, but recent JUnit versions are pretty good too. I use TestNG's groups option in the @Test annotation to specify the style and/or scope of each test method. Another good one is the expected or expectedException annotation option that states what is going to be thrown. Much, much tidier than having try..catch blocks in test methods.

  • Code coverage is more than just a percentage. I use the eCobertura Cobertura plugin for Eclipse while I'm writing tests - to visually indicate which parts of the code I'm actually hitting. I've lost count of the number of times it's shown me an if I thought I had covered is still "red" due to a missing precondition.