RSpec tests for Augeas resources inside Puppet manifests
rspec-puppet-augeas is an extension of rodjek's popular rspec-puppet tool. It adds to your RSpec tests for a single class or define (or anything resulting in a catalog) and allows you to run and test individual Augeas resources within it.
It takes a set of input files (fixtures) that the resource(s) will modify, runs the resource, can verify it changed and is idempotent, then provides Augeas-based tools to help verify the modification was made.
Setting up
Install the gem first:
gem install rspec-puppet-augeas
Note: The augeas tools and development libraries are also required to install the ruby-augeas dependency.
Extend your usual rspec-puppet class test, e.g. for the 'sshd' class:
$ cat spec/classes/sshd_config_spec.rb
describe 'sshd' do
it 'should have an augeas resource' do
should contain_augeas('root login')
end
# Expects Augeas['root login']
describe_augeas 'root login', :lens => 'Sshd', :target => 'etc/ssh/sshd_config' do
it 'should change PermitRootLogin' do
# Run the resource against the fixtures, check it changed
should execute.with_change
# Check changes in the file with aug_get and aug_match
aug_get('PermitRootLogin').should == 'no'
# Verify idempotence last to prevent false positive
should execute.idempotently
end
end
end
Copy original input files to spec/fixtures/augeas using the same filesystem
layout that the resource expects:
$ tree spec/fixtures/augeas/
spec/fixtures/augeas/
`-- etc
`-- ssh
`-- sshd_config
Lastly, in your spec/spec_helper.rb, load ruby-puppet-augeas and configure the
fixtures directory.
require 'rspec-puppet-augeas'
RSpec.configure do |c|
c.augeas_fixtures = File.join(File.dirname(File.expand_path(__FILE__)), 'fixtures', 'augeas')
end
If you have custom lenses in your module dir, puppetlabs_spec_helper will deal with the augeas libdir. You will however have to let the rspec-puppet-augeas module know they are not in your default augeas lens dir. You can do so by using configuring the augeas_lensdir.
require 'rspec-puppet-augeas'
RSpec.configure do |c|
c.augeas_fixtures = File.join(File.dirname(File.expand_path(__FILE__)), 'fixtures', 'augeas')
c.augeas_lensdir = File.join(File.dirname(File.expand_path(__FILE__)), '..', 'lib/augeas/lenses')
end
Usage
Read the spec file(s) at spec/classes/*.rb to see various real-life examples
of the features below.
Also see rspec-puppet-augeas-example for a typical working project.
describe_augeas example group
describe_augeas adds an example group, like describe/context, but that describes
an Augeas resource from the catalog. The description given to run_augeas must
match the resource title. run_augeas is a synonym.
It takes optional hash arguments:
-
:fixturesmanages the files to run the resource against- a hash of fixtures to copy from the source (under augeas_fixtures) to a
destination path, e.g.
{ 'dest/file/location' => 'src/file/location' } - a string of the source path, copied to the path given by the resource's
inclparameter or:target - nil, by default copies all fixtures
- a hash of fixtures to copy from the source (under augeas_fixtures) to a
destination path, e.g.
-
:targetis the path of the file that the resource should modify -
:lensis the lens to use when opening the target file (foraug_*etc.)
It sets the following variables inside examples:
-
resourceto the Puppet resource object -
subject(used implicitly) to an object representing the resource -
output_rootto the path of the fixtures directory after one run
execute matcher
The execute matcher is used to check how a resource has run, e.g.
subject.should execute
(subject is implicit and so can be left out)
It has methods to add to the checks it performs:
-
with_changeensures the resource was "applied" and didn't no-op -
idempotentlyruns the resource again to ensure it applies a maximum of once
Test utilities
Helpers are provided to check the modifications made to files after applying
the resource. Some require certain options, which can be supplied in the
describe_augeas statement or as arguments to the method.
-
output_rootreturns the root directory of the modified fixtures -
open_targetopens the target file and returns the handle, closes it too if given a block (expects:targetoption) -
aug_openopens the target file and returns an Augeas object, closes it too if given a block (expects:targetand:lens) -
aug_get(path)runsAugeas#get(path)against the target file (expects:targetand:lens), returns the value of the node -
aug_match(path)runsAugeas#match(path)against the target file (expects:targetand:lens), returns an array of matches -
augparse(result)runs the augparse utility against the target file (expects:targetand:lens) and verifies the file matches the{ "key" = "value" }augparse tree notation. Call without an argument to get the current tree back.-
augparse()raises error containing{ "key" = "value" }tree for the whole file -
augparse('{ "key" = "value" }')verifies the target matches supplied tree
-
-
augparse_filter(filter, result)takes the target file and all nodes matching the given filter, then runs the resulting file through augparse as above.-
augparse_filter('*[label()!="#comment"]')raises error containing tree for the filtered file (all non-comment entries) -
augparse_filter('*[label()!="#comment"]', '{ "key" = "value" }')verifies the filtered file (all non-comment entries) matches supplied tree
-
RSpec configuration
New RSpec configuration options:
-
augeas_fixturesis the path to the root of the fixtures directory containing source files
Travis configuration
It is possible to add rspec-puppet-augeas to your Travis configuration. This requires the following additions to your Travis configuration files:
Changes to .travis.yml
The augeas packages need to be installed in the before_install block:
before_install:
- sudo apt-get install -qq augeas-tools augeas-lenses libaugeas-devChanges to Gemfile
The rspec-puppet-augeas gem needs to be added into the development and test group:
group :development, :test do
gem 'puppetlabs_spec_helper', :require => false
gem 'rspec-puppet-augeas', :require => false
endChanges to spec/spec_helper.rb
These changes bring the fixtures required for rspec-puppet-augeas to work:
require 'puppetlabs_spec_helper/module_spec_helper'
require 'rspec-puppet-augeas'
RSpec.configure do |c|
c.augeas_fixtures = File.join(File.dirname(File.expand_path(__FILE__)), 'fixtures', 'augeas')
endBackground reading
This module inherited code from the tests used in augeasproviders. The test methodology is described in Testing techniques for Puppet providers using Augeas.
Issues
Please file any issues or suggestions on GitHub.