Now that we have created our basic role in part 1, we need to set-up a Vagrant machine and some tooling to run our tests.
Creating the Vagrant machine
To spin up a Vagrant machine, we need to create a
Vagrantfile. We’ll create it in our role top directory:
You can change
config.vm.box to another Vagrant box that better suits your
needs, but keep in mind RoleSpec is very Debian/Ubuntu inclined. We’ll provision
this machine with a shell script (not with Ansible, so we don’t end up in an
inception style situation).
The provisionning script,
vagrant_specs.sh serves two purposes:
it takes care of installing RoleSpec and setting up the test directory when called with
--install. This happens only at vagrant provisionning time (e.g.
it can be called to run the test suite; to make invocation easier, it will copy itself to
vagrant_specs.sh with the following content:
and make it executable (
chmod +x vagrant_specs.sh).
Running the Vagrat box
Now, let’s check this ! It might take a while if you don’t already have the vagrant image on your box:
$ vagrant up Bringing machine 'nginx' up with 'virtualbox' provider... ==> nginx: Importing base box 'ubuntu/trusty64'... ==> nginx: Matching MAC address for NAT networking... ==> nginx: Checking if box 'ubuntu/trusty64' is up to date... ==> nginx: Setting the name of the VM: ansible-nginx_nginx_1426331325901_88232 ... ==> nginx: Cloning into 'rolespec'... ==> nginx: Installing RoleSpec scripts in /usr/local/bin ... ==> nginx: Installing RoleSpec libs in /usr/local/lib/rolespec ... ==> nginx: Initialized new RoleSpec directory in /home/vagrant/testdir $
We’re almost done. Only two files left to create. First, we RoleSpec needs an inventory. Nothing fancy here, we just need to create an inventory file with a single host,
placeholder_fqdn, RoleSpec will take care of the rest:
Writing the test file
And finally, we need a test file, where we can check if our playbook works. We can check the syntax, the idempotency, the resulting templates, etc…
This test file is simply a bash script, in which we include some RoleSpec files to get access to its DSL.
Let’s start with a simple one, and create
tests/ansible-nginx/test with the following content:
Don’t forget to make the test file executable (
chmod +x tests/ansible-nginx/test).
Our simple tests are setup. To run them, we need to execute
/usr/local/bin/specs in the Vagrant host.
RoleSpecs will then download Ansible (version 1.8.3 since this is what we asked for), install it, and run our test case.
As you can see in the recording, RoleSpec:
- installs Ansible (
ROLESPEC: [Install Ansible - v1.8.3])
- executes the playbook with
TEST: [Run playbook syntax check]and
TEST: [Run playbook])
- check that the playbook is idempotent with
TEST: [Re-run playbook])
Pretty neat !
Runing tests faster
There is one downside though: it takes almost 3 minutes to run. However, you can
speed up subsequent runs as long as you don’t have to change the Ansible
version: since Ansible is already installed, there is no need to install it
again every time. Using the
-p option will run in playbook mode, which means
it will only run
25 seconds only, we cut the runtime by six, not bad.
Local continuous integration
Now that we have reasonable playbook test run time, we can add local continuous integration to our setup. We will use Guard for this.
Assuming you have a ruby environment setup, just install
Then create a
Guardfile in the roles top directory, with the following content:
This file will ask
guard to execute
vagrant ssh -c "specs -p" everytime it
detects a change in a file ending with
.yml in the project’s subdirectories.
Note that we excluded the
tests directory since it contains somewhere a
test.yml playbook file generated by RoleSpec at run time. If we don’t exclude
it from the guard watch, the test will loop forever.
guard, change a file (.e.g.
touch tasks/main.yml), and see what happens.
In the next part, we will add some more tests, and see what we can do with RoleSpec.comments powered by Disqus