puppet loves rspec, why you should, too
DESCRIPTION
"Puppet Loves RSpec, Why You Should, Too" by Dennis Rowe at Puppet Camp Austin 2013.TRANSCRIPT
![Page 1: Puppet Loves RSpec, Why You Should, Too](https://reader033.vdocuments.us/reader033/viewer/2022051818/54bd16564a7959ff308b460d/html5/thumbnails/1.jpg)
Puppet ❤ RSpecWhy You Should, Too
![Page 2: Puppet Loves RSpec, Why You Should, Too](https://reader033.vdocuments.us/reader033/viewer/2022051818/54bd16564a7959ff308b460d/html5/thumbnails/2.jpg)
Dennis RoweSenior DevOps Engineer
Cirrus Logic (cirrus.com)
shr3kst3r on Twitter, Github, and Freenode
![Page 3: Puppet Loves RSpec, Why You Should, Too](https://reader033.vdocuments.us/reader033/viewer/2022051818/54bd16564a7959ff308b460d/html5/thumbnails/3.jpg)
• Setup of Puppet RSpec
• Quick RSpec primer
• Review some RSpec code
• Opinions on testing
![Page 4: Puppet Loves RSpec, Why You Should, Too](https://reader033.vdocuments.us/reader033/viewer/2022051818/54bd16564a7959ff308b460d/html5/thumbnails/4.jpg)
Testing is like free kittens
![Page 5: Puppet Loves RSpec, Why You Should, Too](https://reader033.vdocuments.us/reader033/viewer/2022051818/54bd16564a7959ff308b460d/html5/thumbnails/5.jpg)
![Page 6: Puppet Loves RSpec, Why You Should, Too](https://reader033.vdocuments.us/reader033/viewer/2022051818/54bd16564a7959ff308b460d/html5/thumbnails/6.jpg)
Not Testing?
![Page 7: Puppet Loves RSpec, Why You Should, Too](https://reader033.vdocuments.us/reader033/viewer/2022051818/54bd16564a7959ff308b460d/html5/thumbnails/7.jpg)
![Page 8: Puppet Loves RSpec, Why You Should, Too](https://reader033.vdocuments.us/reader033/viewer/2022051818/54bd16564a7959ff308b460d/html5/thumbnails/8.jpg)
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](https://reader033.vdocuments.us/reader033/viewer/2022051818/54bd16564a7959ff308b460d/html5/thumbnails/9.jpg)
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](https://reader033.vdocuments.us/reader033/viewer/2022051818/54bd16564a7959ff308b460d/html5/thumbnails/10.jpg)
% 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](https://reader033.vdocuments.us/reader033/viewer/2022051818/54bd16564a7959ff308b460d/html5/thumbnails/11.jpg)
• 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](https://reader033.vdocuments.us/reader033/viewer/2022051818/54bd16564a7959ff308b460d/html5/thumbnails/12.jpg)
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](https://reader033.vdocuments.us/reader033/viewer/2022051818/54bd16564a7959ff308b460d/html5/thumbnails/13.jpg)
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](https://reader033.vdocuments.us/reader033/viewer/2022051818/54bd16564a7959ff308b460d/html5/thumbnails/14.jpg)
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](https://reader033.vdocuments.us/reader033/viewer/2022051818/54bd16564a7959ff308b460d/html5/thumbnails/15.jpg)
Setup .fixtures.yml
% cat .fixtures.yml
fixtures:
symlinks:
puppet-camp-austin: "#{source_dir}"
![Page 16: Puppet Loves RSpec, Why You Should, Too](https://reader033.vdocuments.us/reader033/viewer/2022051818/54bd16564a7959ff308b460d/html5/thumbnails/16.jpg)
Quick Overview of RSpec Constructs
![Page 17: Puppet Loves RSpec, Why You Should, Too](https://reader033.vdocuments.us/reader033/viewer/2022051818/54bd16564a7959ff308b460d/html5/thumbnails/17.jpg)
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](https://reader033.vdocuments.us/reader033/viewer/2022051818/54bd16564a7959ff308b460d/html5/thumbnails/18.jpg)
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](https://reader033.vdocuments.us/reader033/viewer/2022051818/54bd16564a7959ff308b460d/html5/thumbnails/19.jpg)
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](https://reader033.vdocuments.us/reader033/viewer/2022051818/54bd16564a7959ff308b460d/html5/thumbnails/20.jpg)
Matchers
• include_class
• contain_{package, service, user, etc}
![Page 21: Puppet Loves RSpec, Why You Should, Too](https://reader033.vdocuments.us/reader033/viewer/2022051818/54bd16564a7959ff308b460d/html5/thumbnails/21.jpg)
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](https://reader033.vdocuments.us/reader033/viewer/2022051818/54bd16564a7959ff308b460d/html5/thumbnails/22.jpg)
Now moving on
![Page 23: Puppet Loves RSpec, Why You Should, Too](https://reader033.vdocuments.us/reader033/viewer/2022051818/54bd16564a7959ff308b460d/html5/thumbnails/23.jpg)
So, let us add an example class
![Page 24: Puppet Loves RSpec, Why You Should, Too](https://reader033.vdocuments.us/reader033/viewer/2022051818/54bd16564a7959ff308b460d/html5/thumbnails/24.jpg)
% cat manifests/example1.pp
class puppet-camp-austin::example1 {
}
![Page 25: Puppet Loves RSpec, Why You Should, Too](https://reader033.vdocuments.us/reader033/viewer/2022051818/54bd16564a7959ff308b460d/html5/thumbnails/25.jpg)
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](https://reader033.vdocuments.us/reader033/viewer/2022051818/54bd16564a7959ff308b460d/html5/thumbnails/26.jpg)
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](https://reader033.vdocuments.us/reader033/viewer/2022051818/54bd16564a7959ff308b460d/html5/thumbnails/27.jpg)
Oh no! We Failed!
![Page 28: Puppet Loves RSpec, Why You Should, Too](https://reader033.vdocuments.us/reader033/viewer/2022051818/54bd16564a7959ff308b460d/html5/thumbnails/28.jpg)
% cat manifests/example1.pp
class puppet-camp-austin::example1 {
package { 'git':
ensure => installed
}
}
![Page 29: Puppet Loves RSpec, Why You Should, Too](https://reader033.vdocuments.us/reader033/viewer/2022051818/54bd16564a7959ff308b460d/html5/thumbnails/29.jpg)
% rake spec
.
Finished in 0.11266 seconds
1 example, 0 failures
![Page 30: Puppet Loves RSpec, Why You Should, Too](https://reader033.vdocuments.us/reader033/viewer/2022051818/54bd16564a7959ff308b460d/html5/thumbnails/30.jpg)
Now we are cooking with peanut oil!
![Page 31: Puppet Loves RSpec, Why You Should, Too](https://reader033.vdocuments.us/reader033/viewer/2022051818/54bd16564a7959ff308b460d/html5/thumbnails/31.jpg)
Happy Happy Happy
![Page 32: Puppet Loves RSpec, Why You Should, Too](https://reader033.vdocuments.us/reader033/viewer/2022051818/54bd16564a7959ff308b460d/html5/thumbnails/32.jpg)
Deep Thoughts
![Page 33: Puppet Loves RSpec, Why You Should, Too](https://reader033.vdocuments.us/reader033/viewer/2022051818/54bd16564a7959ff308b460d/html5/thumbnails/33.jpg)
“It is what you don’t expect that most
needs looking for.”-- Neal Stephenson, Anathem
![Page 34: Puppet Loves RSpec, Why You Should, Too](https://reader033.vdocuments.us/reader033/viewer/2022051818/54bd16564a7959ff308b460d/html5/thumbnails/34.jpg)
What should we test?
• Non-obvious things
• Complex things
• Bugs
![Page 35: Puppet Loves RSpec, Why You Should, Too](https://reader033.vdocuments.us/reader033/viewer/2022051818/54bd16564a7959ff308b460d/html5/thumbnails/35.jpg)
Time for something not obvious
![Page 36: Puppet Loves RSpec, Why You Should, Too](https://reader033.vdocuments.us/reader033/viewer/2022051818/54bd16564a7959ff308b460d/html5/thumbnails/36.jpg)
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](https://reader033.vdocuments.us/reader033/viewer/2022051818/54bd16564a7959ff308b460d/html5/thumbnails/37.jpg)
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](https://reader033.vdocuments.us/reader033/viewer/2022051818/54bd16564a7959ff308b460d/html5/thumbnails/38.jpg)
Add the git class
% cat manifests/example2.pp
class puppet-camp-austin::example2 {
include 'git'}
![Page 39: Puppet Loves RSpec, Why You Should, Too](https://reader033.vdocuments.us/reader033/viewer/2022051818/54bd16564a7959ff308b460d/html5/thumbnails/39.jpg)
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](https://reader033.vdocuments.us/reader033/viewer/2022051818/54bd16564a7959ff308b460d/html5/thumbnails/40.jpg)
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](https://reader033.vdocuments.us/reader033/viewer/2022051818/54bd16564a7959ff308b460d/html5/thumbnails/41.jpg)
What?
The git module doesn’t install git? Is this crazy??!
![Page 42: Puppet Loves RSpec, Why You Should, Too](https://reader033.vdocuments.us/reader033/viewer/2022051818/54bd16564a7959ff308b460d/html5/thumbnails/42.jpg)
OK, let us go look
class git {
package { 'git-core': ensure => installed,
}}
![Page 43: Puppet Loves RSpec, Why You Should, Too](https://reader033.vdocuments.us/reader033/viewer/2022051818/54bd16564a7959ff308b460d/html5/thumbnails/43.jpg)
Should you be testing 3rd party modules
this way?Probably not.
It depends.
![Page 44: Puppet Loves RSpec, Why You Should, Too](https://reader033.vdocuments.us/reader033/viewer/2022051818/54bd16564a7959ff308b460d/html5/thumbnails/44.jpg)
Has it burned you in the past?It did me :(
![Page 45: Puppet Loves RSpec, Why You Should, Too](https://reader033.vdocuments.us/reader033/viewer/2022051818/54bd16564a7959ff308b460d/html5/thumbnails/45.jpg)
Let us try this again
![Page 46: Puppet Loves RSpec, Why You Should, Too](https://reader033.vdocuments.us/reader033/viewer/2022051818/54bd16564a7959ff308b460d/html5/thumbnails/46.jpg)
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](https://reader033.vdocuments.us/reader033/viewer/2022051818/54bd16564a7959ff308b460d/html5/thumbnails/47.jpg)
Maybe we go to lunch, forget about our test, come back, write some code...
![Page 48: Puppet Loves RSpec, Why You Should, Too](https://reader033.vdocuments.us/reader033/viewer/2022051818/54bd16564a7959ff308b460d/html5/thumbnails/48.jpg)
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](https://reader033.vdocuments.us/reader033/viewer/2022051818/54bd16564a7959ff308b460d/html5/thumbnails/49.jpg)
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](https://reader033.vdocuments.us/reader033/viewer/2022051818/54bd16564a7959ff308b460d/html5/thumbnails/50.jpg)
D’oh!
![Page 51: Puppet Loves RSpec, Why You Should, Too](https://reader033.vdocuments.us/reader033/viewer/2022051818/54bd16564a7959ff308b460d/html5/thumbnails/51.jpg)
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](https://reader033.vdocuments.us/reader033/viewer/2022051818/54bd16564a7959ff308b460d/html5/thumbnails/52.jpg)
It works!
% rake spec
..
Finished in 0.13768 seconds2 examples, 0 failures
![Page 53: Puppet Loves RSpec, Why You Should, Too](https://reader033.vdocuments.us/reader033/viewer/2022051818/54bd16564a7959ff308b460d/html5/thumbnails/53.jpg)
In Retrospect
![Page 54: Puppet Loves RSpec, Why You Should, Too](https://reader033.vdocuments.us/reader033/viewer/2022051818/54bd16564a7959ff308b460d/html5/thumbnails/54.jpg)
Puppet + RSpec Rocks
![Page 55: Puppet Loves RSpec, Why You Should, Too](https://reader033.vdocuments.us/reader033/viewer/2022051818/54bd16564a7959ff308b460d/html5/thumbnails/55.jpg)
Why are you not doing it!!?
![Page 56: Puppet Loves RSpec, Why You Should, Too](https://reader033.vdocuments.us/reader033/viewer/2022051818/54bd16564a7959ff308b460d/html5/thumbnails/56.jpg)
You should test interesting things
![Page 57: Puppet Loves RSpec, Why You Should, Too](https://reader033.vdocuments.us/reader033/viewer/2022051818/54bd16564a7959ff308b460d/html5/thumbnails/57.jpg)
Don’t be scared to break it!
![Page 58: Puppet Loves RSpec, Why You Should, Too](https://reader033.vdocuments.us/reader033/viewer/2022051818/54bd16564a7959ff308b460d/html5/thumbnails/58.jpg)
My contrived examples are at https://
github.com/shr3kst3r/puppet-camp-austin
![Page 59: Puppet Loves RSpec, Why You Should, Too](https://reader033.vdocuments.us/reader033/viewer/2022051818/54bd16564a7959ff308b460d/html5/thumbnails/59.jpg)
Questions and maybe some answers?