View on GitHub

Pinocchio

Automate behavior testing for Puppet modules using Cucumber, Vagrant, and a little magic.

Download this project as a .zip file Download this project as a tar.gz file
Given a centos6 machine
When I apply the apache module
Then I should magically be able to connect to a webserver

Why "Behavior" Tests?

Because this has happened to all of us:

# puppet agent -t
...
Error: /Stage[main]/Apache/Service[httpd]/ensure: change from stopped to running failed: Could not start Service[httpd]: Execution of '/sbin/service httpd start' returned 1

But I Already Have Rspec-Puppet. Won't That Catch These Kinds Of Errors?

Nope! Puppet doesn't care that your Apache config is listening to the same port twice in two different files, but Apache sure does and will refuse to start.

Tim Sharpe did the entire Puppet community a great service by bringing us rspec-puppet. It has helped usher in what is likely the golden age of sane configuration management. But it only covers one side of the story...

Anatomy Of A Puppet Run

  1. Catalog Compile
    • Executed on master
    • Validates syntax
    • Performs hiera lookups
    • Builds resource dependency graph
    • Renders ERB templates
  2. Implementation
    • Executed on agent
    • checks state of each resource
    • remediates if necessary
    • actually runs provider code

Why Cucumber?

Because it's very readable, especially for those without a strong development background.

Isn't This Just Cucumber-Puppet? Someone Already Wrote That, Dummy

NO U

cucumber-puppet, like rspec-puppet, only tested the catalog compilation phase of the puppet run. With Pinocchio you are testing for the actual final results of applying the module.

Installation

You can't install pinocchio from rubygems yet, but you can still add it into your Gemfile like so:

gem 'pinocchio', :git => 'http://github.com/justinclayton/pinocchio.git'

And then execute:

$ bundle

Usage

Add this to your module's Rakefile:

require 'pinocchio/rake'

And this to your module's features/support/env.rb:

require 'pinocchio'
require 'pinocchio/cucumber'

If you will be testing network connections, you will need to specify what ports to expose to your machine in your env.rb as well, like this:

Pinocchio.config do |config|
  config.exposed_ports = ['80', '443']
end

Look at the provided test puppet module for a complete example of usage.

Assumptions

Pinocchio is a stupid wooden puppet, and therefore makes many assumptions about your workflow: