59
Puppet RSpec Why You Should, Too

Puppet loves RSpec, why you should, too

  • Upload
    dennis

  • View
    412

  • Download
    0

Embed Size (px)

DESCRIPTION

A quick overview of using Puppet and RSpec given at Puppet Camp Austin, April 2013.

Citation preview

Page 1: Puppet loves RSpec, why you should, too

Puppet ❤ RSpecWhy You Should, Too

Page 2: Puppet loves RSpec, why you should, too

Dennis RoweSenior DevOps Engineer

Cirrus Logic (cirrus.com)

shr3kst3r on Twitter, Github, and Freenode

Page 3: Puppet loves RSpec, why you should, too

• Setup of Puppet RSpec

• Quick RSpec primer

• Review some RSpec code

• Opinions on testing

Page 4: Puppet loves RSpec, why you should, too

Testing is like free kittens

Page 5: Puppet loves RSpec, why you should, too
Page 6: Puppet loves RSpec, why you should, too

Not Testing?

Page 7: Puppet loves RSpec, why you should, too
Page 8: Puppet loves RSpec, why you should, too

So, RSpechttps://github.com/rodjek/rspec-puppet

http://rspec-puppet.com/tutorial/https://github.com/puppetlabs/puppetlabs_spec_helper

Page 9: Puppet loves RSpec, why you should, too

First, Install RVM

• RVM = Ruby Version Manager

• https://rvm.io/

• Allows us to manage ruby versions and gemsets

• Specify ruby version in repo/.rvmrc

• source ~/.rvm/scripts/rvm

Page 10: Puppet loves RSpec, why you should, too

% curl -L https://get.rvm.io | bash -s stable --rails --autolibs=enabled

% rvm use ruby-1.9.3@puppet-camp-austin --install --create 

% ruby -v

ruby 1.9.3p392 [x86_64-darwin12.2.1]

Page 11: Puppet loves RSpec, why you should, too

• http://rubygems.org

• Specifies exactly what gems are used

• `bundle install` installs the gems in our gemset

Gemfile Time

Page 12: Puppet loves RSpec, why you should, too

Example Gemfile

source :rubygems

gem "puppet", "~> 3.1.1"

gem "puppetlabs_spec_helper", "~> 0.4.1"

Page 13: Puppet loves RSpec, why you should, too

Gemfile.lock

GEM remote: http://rubygems.org/ specs: diff-lcs (1.2.4) facter (1.7.0) hiera (1.2.1) json_pure json_pure (1.7.7) puppet (3.1.1) facter (~> 1.6)

Page 14: Puppet loves RSpec, why you should, too

RSpec Prep

• mkdir -p spec/classes/puppet-camp-austin/

• Add Rakefilerequire 'rubygems'

require 'puppetlabs_spec_helper/rake_tasks'

• Add spec/spec_helper.rbrequire 'rubygems'

require 'puppetlabs_spec_helper/module_spec_helper'

Page 15: Puppet loves RSpec, why you should, too

Setup .fixtures.yml

% cat .fixtures.yml

fixtures:

symlinks:

puppet-camp-austin: "#{source_dir}"

Page 16: Puppet loves RSpec, why you should, too

Quick Overview of RSpec Constructs

Page 17: Puppet loves RSpec, why you should, too

describe

• Expresses the concept of the block

• They can be nested

• The first level describe should be a class, define, function, or host

Page 18: Puppet loves RSpec, why you should, too

Example describedescribe “myfunction” do

describe “it should do this” do

...

end

describe “it should also do this”

...

end

end

Page 19: Puppet loves RSpec, why you should, too

lets

let(:title) { ‘namevar’ }

let(:params) {{‘var1’ => ‘foo’, ...}}

let(:node) { ‘ahost.example.com’ }

let(:facts) {{:osfamily => 'Debian', ...}}

Page 20: Puppet loves RSpec, why you should, too

Matchers

• include_class

• contain_{package, service, user, etc}

Page 21: Puppet loves RSpec, why you should, too

should or should_not

it { should include_class(‘foobarz’) }

it { should_not include_class(‘foobarz’)}

it { should contain_package(‘fooz’) }

it { should contain_user(‘barz’) }

Page 22: Puppet loves RSpec, why you should, too

Now moving on

Page 23: Puppet loves RSpec, why you should, too

So, let us add an example class

Page 24: Puppet loves RSpec, why you should, too

% cat manifests/example1.pp

class puppet-camp-austin::example1 {

}

Page 25: Puppet loves RSpec, why you should, too

cat spec/classes/puppet-camp-austin/example1_spec.rb

require 'spec_helper'

describe 'puppet-camp-austin::example1' do

it 'should include git' do

should contain_package('git')

end

end

Page 26: Puppet loves RSpec, why you should, too

Let us run RSpec% rake spec

F

Failures:

1) puppet-camp-austin::example1 should include git

Failure/Error: should contain_package('git')

expected that the catalogue would contain Package[git]

# ./spec/classes/puppet-camp-austin/example1_spec.rb:5:in `block (2 levels) in <top (required)>'

Page 27: Puppet loves RSpec, why you should, too

Oh no! We Failed!

Page 28: Puppet loves RSpec, why you should, too

% cat manifests/example1.pp

class puppet-camp-austin::example1 {

package { 'git':

ensure => installed

}

}

Page 29: Puppet loves RSpec, why you should, too

% rake spec

.

Finished in 0.11266 seconds

1 example, 0 failures

Page 30: Puppet loves RSpec, why you should, too

Now we are cooking with peanut oil!

Page 31: Puppet loves RSpec, why you should, too

Happy Happy Happy

Page 32: Puppet loves RSpec, why you should, too

Deep Thoughts

Page 33: Puppet loves RSpec, why you should, too

“It is what you don’t expect that most

needs looking for.”-- Neal Stephenson, Anathem

Page 34: Puppet loves RSpec, why you should, too

What should we test?

• Non-obvious things

• Complex things

• Bugs

Page 35: Puppet loves RSpec, why you should, too

Time for something not obvious

Page 36: Puppet loves RSpec, why you should, too

Let us say we decided we wanted to let a puppet

forge module install git for us. Oh look, there is

a module called puppetlabs/git!

Page 37: Puppet loves RSpec, why you should, too

Let us add the module to .fixtures.yml

% cat .fixtures.yml

fixtures:

repositories:

git: git://github.com/puppetlabs/puppetlabs-git.git

symlinks:

puppet-camp-austin: "#{source_dir}"

Page 38: Puppet loves RSpec, why you should, too

Add the git class

% cat manifests/example2.pp

class puppet-camp-austin::example2 {

include 'git'}

Page 39: Puppet loves RSpec, why you should, too

Add a test% cat spec/classes/puppet-camp-austin/example2_spec.rb

require 'spec_helper'

describe 'puppet-camp-austin::example2' do

it 'should include git' do

should contain_package('git')

end

end

Page 40: Puppet loves RSpec, why you should, too

Run the Tests (I am sure they will pass)

% rake spec

.F

Failures:

1) puppet-camp-austin::example2 should include git

Failure/Error: should contain_package('git')

expected that the catalogue would contain Package[git]

# ./spec/classes/puppet-camp-austin/example2_spec.rb:5:in `block (2 levels) in <top (required)>'

Page 41: Puppet loves RSpec, why you should, too

What?

The git module doesn’t install git? Is this crazy??!

Page 42: Puppet loves RSpec, why you should, too

OK, let us go look

class git {

  package { 'git-core':    ensure => installed,

  }}

Page 43: Puppet loves RSpec, why you should, too

Should you be testing 3rd party modules

this way?Probably not.

It depends.

Page 44: Puppet loves RSpec, why you should, too

Has it burned you in the past?It did me :(

Page 45: Puppet loves RSpec, why you should, too

Let us try this again

Page 46: Puppet loves RSpec, why you should, too

We write a testdescribe 'puppet-camp-austin::example3' do describe 'operating system is Debian' do let(:facts) { {:operatingsystem => 'Debian'} }

it 'should include git' do should contain_package('git') end end

describe 'operating system is MINIX' do let(:facts) { {:operatingsystem => 'MINIX'} }

it 'should notify a warning' do should contain_notify('git cannot be install for this package') end endend

Page 47: Puppet loves RSpec, why you should, too

Maybe we go to lunch, forget about our test, come back, write some code...

Page 48: Puppet loves RSpec, why you should, too

This is the code we write

class puppet-camp-austin::example3 {

Package { ensure => "installed" }

case $operatingsystem {

'RedHat', 'CentOS': { package {'git': } }

/^(Debian|Ubuntu)$/:{ package {'git': } }

default: { package {'git-core': } }

}

}

Page 49: Puppet loves RSpec, why you should, too

Test it!

rspec ./spec/classes/puppet-camp-austin/example3_spec.rb:15 # puppet-camp-austin::example3 operating system is MINIX should notify a warning

Page 50: Puppet loves RSpec, why you should, too

D’oh!

Page 51: Puppet loves RSpec, why you should, too

Let us add that notify

class puppet-camp-austin::example3 {

Package { ensure => "installed" }

case $operatingsystem {

'RedHat', 'CentOS': { package {'git': } }

/^(Debian|Ubuntu)$/:{ package {'git': } }

default: { notify {'git cannot be install for this package': } }

}

}

Page 52: Puppet loves RSpec, why you should, too

It works!

% rake spec

..

Finished in 0.13768 seconds2 examples, 0 failures

Page 53: Puppet loves RSpec, why you should, too

In Retrospect

Page 54: Puppet loves RSpec, why you should, too

Puppet + RSpec Rocks

Page 55: Puppet loves RSpec, why you should, too

Why are you not doing it!!?

Page 56: Puppet loves RSpec, why you should, too

You should test interesting things

Page 57: Puppet loves RSpec, why you should, too

Don’t be scared to break it!

Page 58: Puppet loves RSpec, why you should, too

My contrived examples are at https://

github.com/shr3kst3r/puppet-camp-austin

Page 59: Puppet loves RSpec, why you should, too

Questions and maybe some answers?