Cucumber-puppet is a tool for specifying Puppet catalog behavior. It uses Cucumber features as specifications and provides the necessary glue to access a node’s catalog from Cucumber’s step definitions.
Cucumber-puppet is distributed as a gem and can be installed as usual.
$ gem install cucumber-puppet
Before writing your first feature, you have to setup the infrastructure in your Puppet directory. Assuming you develop your Puppet manifests in ~/puppet/.
$ cd ~/puppet $ cucumber-puppet-gen world
This installs some example step definitions for cucumber to ./features/steps/ and ensures the cucumber-puppet glue code is available. You can adapt cucumber-puppet to your needs in the
Before block in ./features/support/hooks.rb with the following variables:
@puppetcfg this is a hash of command line options defaults to 'confdir' => '/etc/puppet' 'manifest' => '/etc/puppet/manifests/site.pp' @facts this is a hash of facter facts defaults to 'architecture' => '' 'domain' => 'no.domain' 'environment' => 'production' 'hostname' => 'testnode' 'lsbdistcodename' => '' 'network_eth0' => '127.0.0.0' 'operatingsystem' => ''
Facts can either be set globally as described above or from
Given steps which makes them specific to that scenario. It is also possible to load a node’s yaml file and compile a catalog for that specific node. See provided step definitions for further details.
Writing a catalog policy¶
A catalog policy is a list of rules that apply to all catalogs. Here is a simple policy that is distributed with cucumber-puppet:
$ cucumber-puppet-gen policy $ cat features/catalog/policy.feature Feature: General catalog policy In order to ensure applicability of a host's catalog As a manifest developer I want all catalogs to obey some general rules Scenario Outline: Compile and verify catalog Given a node specified by "features/yaml/<hostname>.example.com.yaml" When I compile its catalog Then compilation should succeed And all resource dependencies should resolve Examples: | hostname | | localhost |
There is one
Scenario per node and all policy rules (
Then steps) apply equally to all of them.
For catalog policies it makes sense to specify facts from a node file, so that Puppet compiles exactly the catalog that is later used by that node. Node files can be copied from your Puppet master, on Ubuntu systems they reside in /var/lib/puppet/yaml/node/ (sample).
If you have many nodes, it makes sense to generate Scenarios from a script and to limit scenario creation to unique nodes, that is if you have 100 identical desktop PCs, just verify the catalog against one of them. Catalog compilation is quite CPU-intense, so you want to keep the amount of catalogs to compile to a minimum.
Applying the policy¶
To apply the policy, execute it with
$ cucumber-puppet features/catalog/policy.feature
When you add further rules to your policy, cucumber-puppet will complain about missing step definitions. Add these to your step files as necessary and make your policy green.
For more information about writing cucumber features, see cucumber tutorials.
Writing fine-grained resource specifications¶
Another way of using cucumber-puppet is to specify classes explicitly. You can generate a template file bar.feature for module foo like this
$ cucumber-puppet-gen feature foo bar $ vim features/modules/foo/bar.feature
If you call
cucumber-puppet-gen inside Puppet’s modules folder, it will create files inside a module’s features directory.
Resource specifications can be useful for documentation purposes or refactorings. However, there is a risk of reimplementing your Puppet manifest, so be wary.
For more information on using cucumber-puppet, have a look at the git history of cucumber-puppet.example. It walks you through different puppet test cases.
Source code is available from github.
Gems are available from rubygems.