Skip to content

Instantly share code, notes, and snippets.

@abrader
Last active August 29, 2015 14:03
Show Gist options
  • Select an option

  • Save abrader/6ed225045d528a65132e to your computer and use it in GitHub Desktop.

Select an option

Save abrader/6ed225045d528a65132e to your computer and use it in GitHub Desktop.
RSpec-Puppet Doc

RSpec-Puppet

Overview on how to use RSpec-Puppet.


What does it test?

Per Tim Sharpe, "RSpec-Puppet tests are there to test the behaviour of Puppet when it compiles your manifests into a catalogue of Puppet resources."


Setup

Install

Getting started

Setup module environment for testing

Composing

Write tests

Executing

Run your test(s)

##TODO

Henson

References


Install

This is how to install RSpec-Puppet and what is needed for this install.

For starters, a Linux virutal machine is necessary.

Prerequisite packages

Must be installed prior to installing RSpec-Puppet:

  • PE 3.2.1 (Agent)
  • git
  • gcc
  • gcc-c++
  • libxml2-devel (for Nokogiri, an often used Ruby parser with spec tests)
  • libxslt-devel (for Nokogiri, an often used Ruby parser with spec tests)

Nice if installed:

  • vim

Prerequisite gems

Must be installed prior to installing RSpec-Puppet

  • bundler (/opt/puppet/bin/gem install bundler)
  • puppetlabs_spec_helper (/opt/puppet/bin gem install puppetlabs_spec_helper)

Nice if you want to take advantage of stylistic linting for Puppet manfiests

  • puppet-lint (/opt/puppet/bin/gem install puppet-lint)

Install gem

On the command line:

/opt/puppet/bin/gem install rspec-puppet

Getting started

Initialize scaffolding

To initialize the spec test scaffolding inside the root directory of a module:

cd /root/of/module
/opt/puppet/bin/rspec-puppet-init

Setup module environment for testing

Fixture YAML

Create the following file in the root of the modules directory:

.fixture.yml

Here is an example of how the puppetlabs-apache module includes other modules as dependencies or fixtures:

fixtures:
  repositories:
    stdlib: "git://github.com/puppetlabs/puppetlabs-stdlib.git"
    concat: "git://github.com/puppetlabs/puppetlabs-concat.git"
  symlinks:
    apache: "#{source_dir}"

Create spec_helper.rb

If not auto-populated, add the following to your spec/spec_helper.rb file:

require 'rspec-puppet'

fixture_path = File.expand_path(File.join(__FILE__, '..', '..', 'fixtures'))

RSpec.configure do |c|
 c.module_path = File.join(fixture_path, 'modules')
 c.manifest_dir = File.join(fixture_path, 'manifests')
end

Create rake task

If not auto-populated, create a rake task to run all tests called Rakefile in the root directory of the module:

require 'rake'

require 'rspec/core/rake_task'

RSpec::Core::RakeTask.new(:spec) do |t|
 t.pattern = 'spec/*/*_spec.rb'
end

If you want to include puppet-lint to perform automatic lint testing of your manifests, add this require line at the top of your Rakefile:

require 'puppet-lint/tasks/puppet-lint'

If you choose to add this linter, be sure to complete the install of puppet-lint

Gemfile

The Gemfile contains all necessary gems required for ruby to be able to run your test(s). A Gemfile is prepoulated with items similar to this when you use the scafolding method:

source ENV['GEM_SOURCE'] || "https://rubygems.org"

group :development, :test do
  gem 'rake',                    :require => false
  gem 'rspec-puppet',            :require => false
  gem 'puppetlabs_spec_helper',  :require => false
  gem 'serverspec',              :require => false
  gem 'puppet-lint',             :require => false
  gem 'beaker',                  :require => false
  gem 'beaker-rspec',            :require => false
  gem 'pry',                     :require => false
  gem 'simplecov',               :require => false
end

if facterversion = ENV['FACTER_GEM_VERSION']
  gem 'facter', facterversion, :require => false
else
  gem 'facter', :require => false
end

if puppetversion = ENV['PUPPET_GEM_VERSION']
  gem 'puppet', puppetversion, :require => false
else
  gem 'puppet', :require => false
end

# vim:ft=ruby

Install necessary gems with bundler

Insure all of the necessary gems are installed, by running the following command in the root directory of the module:

/opt/puppet/bin/bundle install

Composing

Write tests

Additional Gems that might be of help in spec testing might be if you wanted to extend RSpec-Puppet with Pry in order to gain the advantages of this IRB alternative to do deep dive debugging.

Caveats

Remmeber when naming test files to end them with this suffix: _spec.rb

Class tests should exist in: ./spec/classes

Defined type classes should exist in: ./spec/defines

Host tests should exist in: ./spec/hosts

Function tests should exist in: ./spec/functions

Parameter injection

An example of how to inject parameter data into your test (at minimum, within the describe block):

let(:params) {
  {:foo => 'bar', :baz => 'gronk'}
}

Hiera inclusion

In order to include your Hiera hierachy into use with your RSpec-Puppet tests, the following examples would be entries in a particular spec test:

let(:hiera_config) { 'spec/fixtures/hiera/hiera.yaml' }
hiera = Hiera.new(:config => 'spec/fixtures/hiera/hiera.yaml')

and the following, as example, would be entered into the spec/fixtures/hiera/hiera.yaml file:

---
:backends:
  - yaml
:hierarchy:
  - test
:yaml:
  :datadir: 'spec/fixtures/hiera'

and then ultimately you would have data in spec/fixtures/hiera/test.yaml, in this instance:

---
ntpserver: ['ntp1.domain.com','ntpXX.domain.com']
user:
  oneuser:
    shell: '/bin/bash'
  twouser:
    shell: '/sbin/nologin'

Other ways to handle this would be to symlink your Hiera hierarchy into the spec test, or just copy the entire hierarchy into the test.

Fact injection

By default, the test environment contains only the $::hostname, $::domain and $::fqdn facts. If you want to specify additional facts, you can inject them into your tests (at minimum, within the describe block):

let(:facts) {
  {:operatingsystem => 'CentOS', :ipaddress => '192.168.0.1'}
}

Simple compilation test

An example of a simple compilation test would look something like this:

require 'spec_helper'

describe 'puppet-tas' do

  it { should compile }
  
end

Resource matcher

An example of a resource block to be contained within a describe block to test the Apache service:

it do
  should contain_service('apache').with(
    'ensure'     => 'running',
    'enable'     => 'true',
    'hasrestart' => 'true',
  )
end

Relationship matcher

An example of how to describe the require,before,notify, and subscribe relationships between resources in RSpec-Puppet:

it {
  should contain_service('sshd').that_requires('File[/etc/ssh/sshd_config]')
}

it {
  should contain_file('/etc/ssh/sshd_config').that_comes_before('Service[sshd]')
}

it {
  should contain_file('/etc/ssh/sshd_config').that_notifies('Service[sshd]')
}

it {
  should contain_service('sshd').that_subscribes_to('File[/etc/ssh/sshd_config]')
}

Additional matchers

If you want to explore more matchers, here is what RSpec provides beneath RSpec-Puppet, check out RSpec Built in Matchers


Executing

Run your tests

To execute you the tests you created in your spec/ directory, in the root directory of the module, enter the following:

/opt/puppet/bin/rake spec

References


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment