Skip to content
This repository has been archived by the owner on Nov 2, 2019. It is now read-only.

ServerSpec Testing

Demitri Swan edited this page Aug 12, 2016 · 8 revisions

The goal of this section is to create some basic ServerSpec tests so we can automate the functionality of the system. By the end of this section, you should be able to:

  • Write a ServerSpec Test
  • Configure the Vagrantfile for SeverSpec Testing

Writing ServerSpec

First, create a directory called serverspec. This is the default testing directory for serverspec files. Next, create a file in this directory called mesos_spec.rb with the following contents:

describe 'mesos_masters' do
  it 'port 5050 is open' do
    expect(port(5050)).to be_listening
  end

  it 'service mesos-master is running' do
    expect(service('mesos-master')).to be_running
  end
end

Let's break this down.

The describe method takes a parameter that describes what we are testing within its block. In this case, we are testing the mesos_masters that we've deployed via Ansible.

Each it method takes a string parameter that describes what we are actually testing. In RSpec we use expectations and matchers to validate the functionality of anything within our code. In the context of serverspec, we are using ServerSpec matchers to validate that Server resources are in the desired state.

The first test expects that port 5050 is listening on each node. port is a serverspec method that takes an integer as the port number. be_running is the matcher to use to validate if the port is running.

In the second test, we validate that the service master-master is running. We use the ServerSpec method service to pass in the mesos-master service name and use the be_running matcher to validate that the service is indeed running.

A full list of ServerSpec resources and their corresponding matchers can be found here.

Tip: ServerSpec supports a command method that allows you to validate the standard output, standard error, and exit code of a command. You can leverage this method and matcher set to test just about anything you would need on each system in your fleet.

Note: You will notice that the ServerSpec documentation uses the should syntax instead of the expect syntax. In the world of RSpec testing, should syntax is considered deprecated in favor of expect. Take a look at Better Specs to get a handle on RSpec best practices for a clean code base.

Routing Tests to Nodes

Now, we'll want to tell Vagrant how to handle testing for each of our nodes. Open up your Vagrantfile and edit it to look like so:

Vagrant.configure('2') do |config|
  config.vm.box = 'ubuntu/trusty64'

  config.hostmanager.enabled      = true
  config.hostmanager.manage_host  = true
  config.hostmanager.manage_guest = true

  (1..3).each do |i|
    name = "mesos#{i}"
    config.vm.define name.to_sym do |node|
      node.vm.hostname = name
      node.vm.network(:private_network, ip: "192.168.33.#{i*10}")
    end
  end

  config.spec.ansible_inventory = {
    'mesos-masters' => %w(mesos1 mesos2 mesos3),
    'zookeeper'     => %w(mesos1 mesos2 mesos3)
  }

  config.spec.test_plan = [
    {
      'nodes' => %w(mesos1 mesos2 mesos3),
      'flags' => '--format documentation --color --pattern serverspec/mesos_spec.rb'
    }
  ]
end

config.spec.test_plan accepts an Array of Hashes. Each Hash requires a nodes key and a flags key. The nodes key is an Array of Strings matching the names of machines you wish to test. The flags key maps to a String of command line flags to pass to RSpec, specifically, the RSpec::Core::Runner.run method that vagrant_spec uses under the hood. The parameters and arguments accepted by the rspec command line tool should work about the same.

Each hash in the Array is a test plan. If you have more than one application you need to configure, you can use each plan to route tests to the appropriate nodes. This becomes critical as orchestration between many applications and nodes becomes non-trivial.

Run the Tests

Now that we have our simple RSpec tests written and Vagrantfile configured, run the following command:

vagrant spec test

This command will run all of the tests specified in the Vagrantfile. If any of the tests fail, the command will exit non-zero. This becomes increasingly helpful in a Continuous Integration and Continuous Deployment scenario.

Next, we will setup a Makefile to help with the automation of these execution tasks