featured image

October 06, 2016 / by Daniel Huchthausen / In Quality

Testing Docker Infrastructure with Serverspec

+++This post was migrated from our former blog about SCM-Manager Universe. Therefore, it is only available in English.+++

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 OpenSource 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

  • file
  • docker_container
  • docker_image
  • cron
  • mysql_config
  • host
  • ...
  • it
  • its(:md5sum)
  • its(:size)
  • its(:content_as_json)
  • its(:ipaddress)
  • its(:speed)
  • ...
  • exist
  • have_entry
  • match
  • be_readable.by
  • contain
  • include
  • ...

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.


Daniel Huchthausen

- Consultant -

When he is not exploring the wilderness, Daniel keeps himself busy with topics such as quality assurance, testing and PM methods.


©2018 Cloudogu GmbH. All rights reserved.
Legal Notice | Privacy Policy

Cloudogu™, Cloudogu EcoSystem™ and the Cloudogu™ logo are registered trademarks of Cloudogu GmbH, Germany.