docker run ` --name firebird257 ` -p 3050:3050 ` -p 13050:13050 ` --tmpfs /databases:rw ` -e ISC_PASSWORD=masterkey ` -e TZ=Europe/Amsterdam ` -d ` jacobalberty/firebird:2.5.7-ss
26 May 2017
Vlad Mihalcea recently posted the blog How to run integration tests at warp speed using Docker and tmpfs, and I thought it would be interesting to see what needed to be done to run the Jaybird tests against a Firebird instance on docker.
I am writing this post as documentation for myself, but I hope it might be useful for others as well. Note that I don’t have a lot of experience with docker, so do not assume that things in this blog are docker best practices. |
As a baseline, a normal test run from IntelliJ on my local machine takes about 10 - 11 minutes for Jaybird master (Jaybird 3.1).
For this experiment, I used the jacobalberty/firebird image.
The Jaybird tests include tests for events, and the documentation of the image suggests that to use events, you need to add --net=host
to the docker run
command, or RemoteAuxPort
must be set and mapped. I use Docker for Windows, and unfortunately --net=host
is not supported on Windows.
I started the image with:
docker run ` --name firebird257 ` -p 3050:3050 ` -p 13050:13050 ` --tmpfs /databases:rw ` -e ISC_PASSWORD=masterkey ` -e TZ=Europe/Amsterdam ` -d ` jacobalberty/firebird:2.5.7-ss
I’m using powershell, which uses |
Note the use of --tmpfs /databases:rw
to ensure the databases folder is using tmpfs, which is in-memory.
To get events to work I edited the /var/firebird/etc/firebird.conf
(which, btw, is not a best practice!) to set RemoteAuxPort=13050
, and stopped and started the image with docker stop firebird257
and docker start firebird257
. A better solution would be to overlay the config file, but my docker-fu is lacking in this area for the moment.
As I’m binding port 3050 directly in this example, I need to make sure that no other instance of Firebird is running on that port locally.
As my configuration above binds the image to 127.0.0.1:3050
, I had assumed I could just run all tests from my IDE and be done with it, unfortunately this failed with:
SEVERE: Exception creating database java.sql.SQLException: unavailable database [SQLState:08001, ISC error code:335544375] at org.firebirdsql.gds.ng.FbExceptionBuilder$Type$1.createSQLException(FbExceptionBuilder.java:498) at org.firebirdsql.gds.ng.FbExceptionBuilder.toFlatSQLException(FbExceptionBuilder.java:299) ...
Oops. When Jaybird is run against a database on 127.0.0.1
or localhost
, the test harness will try to put the database in the current working directory by transforming the relative path to an absolute path. And this obviously fails when you try to pass that absolute Windows path to a Linux image.
Fortunately, all 127.x.x.x
addresses point to the local loopback, so running the tests against 127.0.0.2
should work just fine.
Adding -Dtest.db.host=127.0.0.2
to the run configuration of the tests should do the trick.
And it seems to work, although a number of tests fail. These failures can be explained though, as these tests expect the database or backup file to exist on the local filesystem, which now is not the case (just like when testing against a real remote database server). We’ll ignore these failures for now.
Unfortunately, the runtime of the test is 9+ minutes, and that is not significantly different from the original results. Inspection of the image using docker exec -i -t firebird257 /bin/bash
and checking the /databases
folder shows that the databases aren’t created in the /databases
folder. It turns out they are being created in /tmp
instead. This is probably caused by Jaybird using /fbtest.fdb
as the database name instead of just fbtest.fdb
, or maybe that is a result of the configuration in the image, I’m not sure. Explicitly specifying the /databases
path should do the trick.
This time we also add -Dtest.db.dir=/databases
to the run configuration.
And finally, we hit pay dirt: a run time of 3 minutes and 30 seconds. A reduction of about 7 minutes.
Up to now I have run the tests from my IDE, to run the ant build this way:
build -Dtest.db.host=127.0.0.2 -Dtest.db.dir=/databases
The performance improvement from running the tests from ant seems to be the same in absolute terms (from 12 minutes to 6-7 minutes without the build itself).
The results are certainly interesting. I will now need to find a cleaner way to change the configuration, and also run the tests against Firebird 3 (which requires additional configuration changes to work with Jaybird). To be continued.