
Testing Docker© Infrastructure with Serverspec
It’s already quite common to describe infrastructure in code with e.g. Puppet or Chef. These days there is another option for that: Docker©. Especially for Docker© it is important to keep track of the infrastructure’s configuration, because sources for your containers might have changed or vanished. Therefore, you should test your infrastructure to ensure that it is as expected. Serverspec offers you the ability to do exactly that.
Why Docker©? – A Wrap Up
Docker© is an open-source project that automates the deployment of applications inside software containers through virtualization. It allows you to run several different containers on the same node. This is more efficient than maintaining various virtual machines, because the containers share the nodes operating system (Linux).
Each container is independent from its environment, because it contains everything it needs to run: code, runtime, system tools and system libraries. This ensures that Docker© containers always run in a similar manner, no matter which environment they run in.
Because containers include everything they need, they also contain a lot of external references and libraries. This can lead to the problem that the external sources might change or vanish. Therefore, it’s important to ensure that the containers are as expected, to prevent unexpected behavior. A possible solution for that is to check the Docker© infrastructure with Serverspec tests.
Serverspec
Originally, Serverspec was developed to check the configuration of servers for their correctness. Nowadays, if you use Docker© to set up your infrastructure, you can also use it to check the specifications of your Docker© images and containers. With Serverspec you can write RSpec tests for checking your infrastructure and to make sure that it is configured as expected http://serverspec.org. It’s like writing unit tests for your infrastructure.
The syntax for RSpec tests is quite simple:
describe RESOURCE_TYPE ('RESOURCE NAME') do its(ATTRIBUTE) {should OPERATOR OPERAND} end
Instead of “should” you can also use “expect” or the negative “should_not”, that’s up to your preference. For “Resource Type”, “Attribute” and “Operand” you have various options:
Resource Type | Attribute | Operand | ||
|
|
|
List of all possible tests: http://serverspec.org/resource_types.html
Hint: The specified tests will be executed one after another. Serverspec waits until a test was executed before it starts with the next test. Sometimes it’s necessary to build in a timer or waiting period if you want to test a process that takes some time (e.g. if you have to wait until a container has started).
Example
At the beginning of each spec-file there is the require section. There you can specify which components are needed to execute the tests specified in the file.
After that, there comes the large part where you describe the tests.
Imagespec
Build Docker© image from Dockerfile
require "serverspec" require "Docker" describe "image specs" do image = Docker::Image.build_from_dir('.') set :os, family: :alpine set :backend, :Docker set :Docker_image, image.id
Execute your test 1. Check whether package is installed
describe package('mercurial') do it { should be_installed } end
2. Check status of file
describe file('/opt/scm-server') do it { should be_directory } it { should be_owned_by 'scm' } it { should be_grouped_into 'scm' } end
Containerspec
Start container
require "serverspec" require "Docker" equire_relative 'spec_helper' describe "container specs" do before(:all) do image = Docker::Image.build_from_dir('.') @container = image.run() set :os, family: :alpine set :backend, :Docker set :Docker_container, @container.id wait_for_open_port 8080, 30 end
Execute your tests …
describe port(8080) do it { should be_listening } end
…
Clean up
after(:all) do @container.kill @container.delete(:force => true) end
Advantages of Serverspec with RSpec Tests
Checking your infrastructure with RSpec tests has several advantages. For example, you can write tests that will be executed after each restart of a system, or you can write tests that will check your system frequently – as an early warning system. The tests can easily be adjusted to new conditions.
You can also start to apply TDD (Test Driven Development) for your infrastructure by first writing the tests (that will fail) and then start developing to successfully pass the tests.
A step towards TDD
The development of applications that use Docker© has the advantage that the infrastructure has a minimal overhead and that the components are portable between all different kinds of machines. Beyond that it’s possible to test Docker© containers with e.g. Serverspec to ensure that their configuration is as it was defined and that they’re running as expected.
If you already use Docker©, you should also consider writing RSpec tests and maybe even to apply TDD for your infrastructure. It will help you to develop and maintain your applications more easily. If you’re not using Docker© at all yet, maybe the ability to apply RSpec tests convinces you to consider using it.