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
Vagrantfile
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).
Provisionning script
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.vagrant up
ofvagrant provision
) -
it can be called to run the test suite; to make invocation easier, it will copy itself to
/usr/local/bin/specs
Create the 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
$
Creating tests
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
).
Runing tests
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
assert_playbook_runs
(TEST: [Run playbook syntax check]
andTEST: [Run playbook]
) - check that the playbook is idempotent with
assert_playbook_idempotent
(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 assert_playbook_runs
test.
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 guard
and guard-shell
gems.
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.
Now run 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