Over at Mozilla's Engagement Engineering we use Docker to ship our websites. We build the docker images in CI and then we run tests against them. Our tests usually need a database or a cache server which you can get it running simply with a single command:
docker run -d mariadb
The problem is that this container will take some time to initialize and become available to accept connections. Depending on what your test and how you run your tests this delay can cause a test failure to due database connection timeouts.
We used to wait on executing our tests with sleep
command but that -besides
being an ugly hack- will not always work. For example you may set sleep timeout
to 10 seconds and due to CI server load database initialization takes 11
seconds. And nobody wants a non-deterministic test suite.
Meet Takis. Takis checks once per
second if a host:port is open. Once it's open, it just returns. It blocks the
execution of your pipeline until services become available. No messages or other
output to get in the way of your build logs. No complicated configuration
either: It reads CHECK_PORT
and optionally CHECK_HOST
environment variables,
waits and eventually returns.
Takis is build using Go and it's fully statically linked as Adriaan explains in this intriguing read. You can download it and directly use it in your scripts
~$ wget https://github.com/glogiotatidis/takis/raw/master/bin/takis
~$ chmod +x takis
~$ CHECK_PORT=3306 ./takis
or use it's super small Docker image
docker run -e CHECK_PORT=3306 -e CHECK_HOST=database.example.com giorgos/takis
For example here's how we use it to build Snippets Service in TravisCI:
script:
- docker run -d --name mariadb -e MYSQL_ALLOW_EMPTY_PASSWORD=yes -e MYSQL_DATABASE=snippets mariadb:10.0
# Wait mariadb to initialize.
- docker run --link mariadb:db -e CHECK_PORT=3306 -e CHECK_HOST=db giorgos/takis
- docker run --env-file .env --link mariadb:db mozorg/snippets:latest coverage run ./manage.py test
My colleague Paul also build urlwait, a Python utility and library with similar functionality that can be nicely added to your docker-compose workflow to fight the same problem. Neat!
Go Top