When I started writing Puppet manifests, I soon figured out, that there are
many possibilities for mistakes, which I usually found when test-applying
(--noop) changes to a machine. This manual process was quite cumbersome, only
to find a missing comma. So I wondered how I could test manifests more easily
and on my development machine.
After playing with existing tools like Ohad Levy’s Manitest, I stumbled upon Cucumber and wrote some glue code, so that I could write cucumber features for my manifests.
In my first round of testing, I wrote features like this one:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | |
If you compare this to the puppet code being tested
1 2 3 4 5 6 7 8 | |
you will notice, that the scenario is basically a reimplementation of the puppet code. This doesn’t make much sense.
To start over, I collected my actual problems when developing manifests in order to think of a more sensible approach to writing Cucumber features.
catalog does not compile
- syntax errors
- missing template files (locally or in repository)
catalog compiles, but cannot be applied
- unreachable or non-existent resources are referenced (
before,notify, …) - missing file sources in repository
- unreachable or non-existent resources are referenced (
catalog applies but is faulty
- faulty files due to empty manifest variables or wrong values
- missing dependencies between resources (wrong order, missing service restarts after config file changes, …)
- files are installed without ensuring directory creation beforehand
In order to deal with these issues, I first expanded cucumber-puppet to permit defining a host by its YAML node file. This way local (on my development machine) catalog compilation can be verified easily. For remote catalog compilation, I added a step ensuring files and templates are checked into git. Finally I added a step to ensure resolvability of all referenced resources. Looks like issues 1 and 2 are solved. :-)
Catalogs can now be verified like this:
1 2 3 4 5 6 7 8 9 10 11 12 | |
My new way of writing cucumber features thus is to move away from single resources and instead concentrate on the BDD principle of Outside-In specification. Above feature specifies a generic policy regarding catalog compilation. This specification could be augmented with rules like each file should have group, mode and owner set explicitly or each file written to directory “/etc/apache2” should require “Package[apache2]”.
This new approach does not solve all issues mentioned above, there is still more than enough room for manually verifying catalogs on real target hosts, but it is in my opinion much more useful than my first attempt.