Wednesday, September 17, 2014

Auto-Choosing Xvfb Display Ports

My current plan is to work through every chapter in Patterns in Polymer, getting the code and tests up to date with the latest Polymer and Karma + Jasmine. Once I have a regular build in place, I will revisit each chapter's content to ensure that it too is up-to-snuff, then perhaps add a chapter or two.

As an aside, I have encountered my share of annoyances with minor Polymer breakages but I can accept those—this is, after all an alpha release of the library. More frustrating is the syntax in Jasmine changing with every patch release (e.g. andReturn() becomes and.returnValue() is my latest favorite). Between this and major syntax changes in other testing libraries for no apparent reason, it almost enough to put me off testing.

Despite the various annoyances, things are moving steadily. I have an outside chance of getting all of the JavaScript code and tests fixed tonight. Except the Dart build randomly breaks for no apparent reason.

The book is written in both Dart and JavaScript so I need to run tests for both sample codebases. Unlike JavaScript testing libraries and JavaScript expectation libraries and JavaScript test runners, Dart's testing has been quite stable. So what gives?

Well, Dart tests, like JavaScript tests, require a windowing environment in which to execute browser tests. On Linux, this is normally done with Xvfb and on Ubuntu/Debian I have been using the nifty little xvfb-run run script to execute tests:

It turns out that the Dart build, which I delay for unrelated reasons, is conflicting with the windowing display port being used by my JavaScript build.

Ugh. I start dreaming up how I might retry the build with a different port or additional delay or maybe even run only one build at a time. Mercifully, before I get around to attempting to implement any of that, I read the xvfb-run man page (to be honest, I was reading it to figure out how to implement some of those crazy ideas). In addition to making it easy to wrap processes inside a windowing environment, the xvfb-run script also has a flag to do just what I need:

-a, --auto-servernum

Try to get a free server number, starting at 99, or the argument to --server-num.

I can even verify this by running my Dart tests several times during the JavaScript build (did I mention that Dart tests tend to be markedly faster than their JavaScript counterparts?). During most builds, there is a note about RANDR missing from the Xvfb windowing environment (which is perfectly OK):

Xlib: extension "RANDR" missing on display ":99".

During most of the test runs, I see the message on port :99, but on one I see:

Xlib: extension "RANDR" missing on display ":100".

In other words, the -a flag detected in this case that the JavaScript tests were currently being run on display port :99 and automatically ran on :100 instead. Cool!

With that, I can get back to fixing tests and code without the worry of seemingly random failures.