1

Unix Freak: Puppet rspec testing and hiera

 11 months ago
source link: http://tuxmea.blogspot.com/2013/12/puppet-rspec-testing-and-hiera.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Rspec testing your puppet modules supports you in having stable and functional modules.
For a couple of weeks there is hiera integration in rspec-puppet.

Basic Spec setup

You will need a couple of files for puppet module rspec testing:

Gemfile

# Install via
# bundle install --path vendor/gems
#
source "https://rubygems.org"

gem "mocha", :require => false
gem 'puppet',       '>= 3.1.1'
gem 'puppet-lint'
gem 'facter',       '>= 1.6.10'
gem 'rspec-puppet', :git => "https://github.com/rodjek/rspec-puppet.git"
gem 'rake',         '>= 0.9.2'
gem 'puppetlabs_spec_helper', '0.3.0'
gem 'test-unit'

Rakefile

require 'rake'
require 'rake/tasklib'
require 'rspec/core/rake_task'
require 'rubygems'
require 'puppetlabs_spec_helper/rake_tasks'
require 'puppet-lint'

desc "Run the tests"
RSpec::Core::RakeTask.new(:test) do |t|
  t.rspec_opts = ['--color', '-f d']
  t.pattern = 'spec/*/*_spec.rb'
end

desc 'Run puppet-lint on the one manifests'
task :onelint do
  PuppetLint.configuration.with_filename = true

linter = PuppetLint.new
  matched_files = FileList['spec/fixtures/modules/one/manifests/**/*.pp']

matched_files.to_a.each do |puppet_file|
    linter.file = puppet_file
    linter.run
  end

fail if linter.errors? || (
    linter.warnings? && PuppetLint.configuration.fail_on_warnings
    )
end

task :default => [:spec_prep, :test, :onelint, :spec_clean]

spec/spec_helper.rb

require 'test/unit'
require 'mocha/setup'
require 'puppetlabs_spec_helper/module_spec_helper'
require 'puppet/indirector/hiera'
require 'hiera'


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

# include common helpers
support_path = File.expand_path(File.join(File.dirname(__FILE__), '..',
                                          'spec/support/*.rb'))
Dir[support_path].each {|f| require f}

RSpec.configure do |c|
  c.config = '/doesnotexist'
  c.manifest_dir = File.join(fixture_path, 'manifests')
  c.mock_with :mocha
end

Fixtures

If your module require other modules (e.g. stdlib functions) you have to include them using fixtures repositories. Add your own module as a symlink:

.fixtures.yaml

fixtures:
    repositories:
        stdlib: "https://github.com/puppetlabs/puppetlabs-stdlib.git"
        concat: "https://github.com/puppetlabs/puppetlabs-concat.git"
    symlinks:
        <your module name>: "#{source_dir}"

 This will create all required directory structures in spec/fixtures/modules.

Hiera Configuration

Add a hiera.yaml and a hiera data file to your spec/fixtures:

spec/fixtures/hiera/hiera.yaml

---
:backends:
  - yaml
:hierarchy:
  - test

:yaml:
    :datadir: 'spec/fixtures/hiera'

spec/fixtures/hiera/test.yaml

---
myvariable: 'myvalue'

Hiera Integration

Only minor changes are required to integrate hiera lookups into your spec tests.
The following example is taken from my stdmodule on github (https://github.com/tuxmea/tuxmea-stdmodule.git)

spec/classes/<classname>_spec.rb

require 'spec_helper'
hiera_file = 'spec/fixtures/hiera/hiera.yaml'   # <- required to find hiera configuration file

# test our main class (init.pp)
describe 'stdmodule', :type => :class  do     # <- set the class name

# test without hiera lookup (using class defaults)
    context 'without hiera data' do
        it { should contain_class('stdmodule') }                        # <- check for classes included
        it { should contain_class('stdmodule').with_myparam('foo') }    # <- check for classes with parameters
        it { should contain_class('stdmodule::basic') }                 # <- check for subclasses
        it { should contain_class('stdmodule::package_file_service') }
        it { should contain_stdmodule__defines('foobar_define') }       # <- check for defines
    end

# test with explicit params given on class definition
    context 'with explicit data' do
        let(:params) {{                                                 # <- set explizit params
            :myparam => 'newvalue'
        }}
        it { should contain_class('stdmodule').with_myparam('newvalue') }
    end

# test with explicit hiera lookup
    context 'with explicit hiera lookup' do
        # set hiera_config
        let (:hiera_config) { hiera_file }

hiera = Hiera.new(:config => hiera_file)                        # <- use Hiera ruby class
        variable = hiera.lookup('stdmodule::myparam', nil, nil)         # <- do hiera lookup
        let (:params) {{
            :myparam => variable                                        # <- set parameter to hiera lookup
        }}
        it { should contain_class('stdmodule').with_myparam(variable) }
    end
end

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK