Playing with Ruby on Rails
I’ve been playing around with ruby on rails recently, partly to play around with rails and partly to take a run at a web app I’ve been considering (which I’ve open sourced because why not?).
It turns out the last time I played with it was back in 2005 and slightly amusingly my thoughts on it haven’t changed all that much. The lack of configuration is still good, but the amount of magic involved makes it hard to understand what’s going on. The ease of finding documentation has improved dramatically – 10 years of blog posts really help. I’m still using TextMate and it’s still annoying that I can’t click a method name to jump to it’s definition – I hear good things about RubyMine but I’m not keen to invest that kind of money in what may be a very short-lived experiment.
Testing@LMAX – Replacements in DSL
Given our DSL makes heavy use of aliases, we often have to provide a way to include the real name or ID as part of some string. For example, an audit record for a new account might be:
Created account 127322 with username someUser123.
But in our acceptance test we’d create the user with:
registrationAPI.createUser("someUser");
someUser is just an alias, the DSL creates a unique username to use and the system assigns a unique account ID that the DSL keeps track of for us. So to write a test that the new account audit record is written correctly, we need a way to build the expected audit string.
Miller – Command Line CSV Tool
Miller is like sed, awk, cut, join, and sort for name-indexed data such as CSV. Leaving this here for the next time I have to work with CSV files on the command line. It can do a lot more than just CSVs of course, but that’s likely to be the most useful to me.
Display Port Monitor Wakes Up a Few Seconds After Being Suspending on Linux
I have a dual monitor setup with Linux where one display is connected via DisplayPort and the other via DVI, both from an Nvidia graphics card. When the screen is locked both displays go black, the DVI monitor says it’s entering power save mode and the DisplayPort monitor says “No input” at which point both monitors turn back on displaying the unlock screen.
Playing with xset dpms force standby|suspend|off gave a variety of effects, sometimes the DisplayPort stayed off but the DVI turned back on, sometimes the DisplayPort went black but didn’t turn off etc.
End to End Tests @ LMAX Update
A little while back I said that LMAX ran around 11,000 end to end tests in around 50 minutes. Since then we’ve deployed some new hardware to run our continuous integration on, plus continued building new stuff and are now running about 11,500 tests in under 20 minutes.
A large part of the speed boost is extra VM instances but also the increased RAM allocation available to each VM has allowed us to increase a number of limits in the system and we can now run more tests concurrently against each VM instance.
Testing@LMAX – Aliases
Even after a magnum opus on the DSL LMAX uses for acceptance tests, there’s one crucial feature that I haven’t mentioned: the use of aliases to allow tests to use simple, meaningful names while ensuring that uniqueness constraints are met.
Creating a user with our DSL looks like:
registrationAPI.createUser("user");
You might expect this to create a user with the username ‘user’, but then we’d get conflicts between every test that wanted to call their user ‘user’ which would prevent tests from running safely against the same deployment of the exchange.
Testing@LMAX – Abstraction by DSL
At LMAX, all our acceptance tests are written using a high level DSL. This gives us two key advantages:
- Tests can focus on what they’re testing with the details and mechanics hidden behind the DSL
- When things change we can update the DSL implementation to match, avoiding the need to change each test that happens to touch on the area.
The DSL that LMAX uses is probably not what most people think of when hearing the term DSL – it doesn’t attempt to read like plain English, just simplifies things down significantly. We’ve actually open sourced the simple little library that is the entrance-way to what we think of as the DSL – creatively named simple-dsl. It’s essentially the glue between what we write in an acceptance test and the plain-java implementation behind that.
Making End-to-End Tests Work
The Google Testing Blog has an article “Just Say No to More End-to-End Tests” which winds up being a rather depressing evaluation of the testing capabilities, culture and infrastructure at Google. For example:
Let’s assume the team already has some fantastic test infrastructure in place. Every night:
- The latest version of the service is built.
- This version is then deployed to the team's testing environment.
- All end-to-end tests then run against this testing environment.
- An email report summarizing the test results is sent to the team.
If your idea of fantastic test infrastructure starts with the words “every night” and ends with an email being sent you’re doomed. Bryan Pendleton does a good job of analysing and correcting the details so I won’t recover that ground. Instead, let me provide a view of what reasonable test infrastructure looks like.
Printing Only Part of a grep Match
It’s not uncommon to want to find a particular line in a file and print just a part of it. For example, if we wanted to find the total memory on a machine we could use:
grep '^MemTotal:' /proc/meminfo |
sed -e 's/^MemTotal:\s*\([0-9]*\).*/\1/'
Which does the job but duplicates a bunch of the matching regex. If you’re using a reasonably recent gnu grep, you can use it’s support for perl regex syntax and the \K operator:
Emoji One – Open source emoji designed for the web.
Mostly so I can find this again later when I inevitably need it, Emoji One is a creative commons licensed collection of Emoji and related tools for the web.
Patterns are for People
Avdi Grimm in Patterns are for People:
Patterns aren’t tools for programming computers; they are tools for programming people. As such, to say that “patterns are a language smell” makes very little sense. Patterns are a tool for augmenting language: our language, the language we use to talk to each other about a problem and its solutions; the language we use to daydream new machines in our minds before committing them to code. Patterns aren’t a language smell; rather, patterns are by definition, [optional] language features. There’s so much we can learn if only we stop making everything into a battle between “new” tools or approaches and “old” ones. Patterns are relevant and useful in all forms of programming and we shouldn’t discard them just because they’re not “cool” anymore. Sadly we seem to throw out nearly all our experience and learning each time a new approach comes along rather than learning from and taking advantage of both.
New Favourite Little Java 8 Feature
Pre-Java 8:
ThreadLocal<Foo> foo = new ThreadLocal() {
@Override
protected Foo initialValue() {
return new Foo();
}
};
Post-Java 8:
ThreadLocal<Foo> foo = ThreadLocal.withInitial(Foo::new);
Nice.