Permalink
Browse files

Initial version of chefspec.

  • Loading branch information...
0 parents commit cf328bab8c9fc6a1785a9fc7e617064b51e1e6ae @acrmp acrmp committed Jul 31, 2011
@@ -0,0 +1,11 @@
+source "http://rubygems.org"
+gemspec
+gem "chef", "0.9.12"
+
+group :test do
+ gem "aruba", '>= 0.4.3'
+ gem "cucumber", '>= 1.0.1'
+ gem "i18n", '>= 0.5.0'
+ gem "rake", '>= 0.8.7'
+ gem "yard", '>= 0.7.2'
+end
@@ -0,0 +1,92 @@
+PATH
+ remote: .
+ specs:
+ chefspec (0.0.1)
+
+GEM
+ remote: http://rubygems.org/
+ specs:
+ aruba (0.4.3)
+ bcat (>= 0.6.1)
+ childprocess (>= 0.1.9)
+ cucumber (>= 0.10.7)
+ rdiscount (>= 1.6.8)
+ rspec (>= 2.6.0)
+ bcat (0.6.1)
+ rack (~> 1.0)
+ builder (2.1.2)
+ bunny (0.6.0)
+ chef (0.9.12)
+ bunny (>= 0.6.0)
+ erubis
+ extlib
+ highline
+ json (>= 1.4.4, <= 1.4.6)
+ mixlib-authentication (>= 1.1.0)
+ mixlib-cli (>= 1.1.0)
+ mixlib-config (>= 1.1.2)
+ mixlib-log (>= 1.2.0)
+ moneta
+ ohai (>= 0.5.7)
+ rest-client (>= 1.0.4, < 1.7.0)
+ uuidtools
+ childprocess (0.1.9)
+ ffi (~> 1.0.6)
+ cucumber (1.0.1)
+ builder (>= 2.1.2)
+ diff-lcs (>= 1.1.2)
+ gherkin (~> 2.4.5)
+ json (>= 1.4.6)
+ term-ansicolor (>= 1.0.5)
+ diff-lcs (1.1.2)
+ erubis (2.7.0)
+ extlib (0.9.15)
+ ffi (1.0.9)
+ gherkin (2.4.5)
+ json (>= 1.4.6)
+ highline (1.6.1)
+ i18n (0.5.0)
+ json (1.4.6)
+ mime-types (1.16)
+ mixlib-authentication (1.1.4)
+ mixlib-log
+ mixlib-cli (1.2.0)
+ mixlib-config (1.1.2)
+ mixlib-log (1.3.0)
+ moneta (0.6.0)
+ ohai (0.6.2)
+ mixlib-cli
+ mixlib-config
+ mixlib-log
+ systemu
+ yajl-ruby
+ rack (1.3.1)
+ rake (0.8.7)
+ rdiscount (1.6.8)
+ rest-client (1.6.1)
+ mime-types (>= 1.16)
+ rspec (2.6.0)
+ rspec-core (~> 2.6.0)
+ rspec-expectations (~> 2.6.0)
+ rspec-mocks (~> 2.6.0)
+ rspec-core (2.6.4)
+ rspec-expectations (2.6.0)
+ diff-lcs (~> 1.1.2)
+ rspec-mocks (2.6.0)
+ systemu (2.2.0)
+ term-ansicolor (1.0.5)
+ uuidtools (2.1.2)
+ yajl-ruby (0.8.2)
+ yard (0.7.2)
+
+PLATFORMS
+ ruby
+
+DEPENDENCIES
+ aruba (>= 0.4.3)
+ chef (= 0.9.12)
+ chefspec!
+ cucumber (>= 1.0.1)
+ i18n (>= 0.5.0)
+ rake (>= 0.8.7)
+ yard (>= 0.7.2)
@@ -0,0 +1,21 @@
+The MIT License
+
+Copyright (C) 2011 by Andrew Crump
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
@@ -0,0 +1,153 @@
+# ChefSpec
+ChefSpec is a gem that makes it easy to write [RSpec](http://rspec.info/) examples for
+[Opscode Chef](http://www.opscode.com/chef/) cookbooks. Get fast feedback on cookbook changes before you spin up a node to do integration testing against.
+
+ChefSpec runs your cookbook but without converging the node that your examples are being executed on. This allows you
+to write specs that make assertions about the created resources given the combination of your recipes and arbitrary node
+attributes that you provide.
+
+# Compatibility
+**This is alpha-quality at the moment**. The API is likely to change substantially. ChefSpec currently works only with Chef 0.9.12 and has been tested on Ruby 1.8.7. It may make your machine burst into flames or install OS X Lion.
+
+# Quick Start
+Given an existing cookbook directory structure, create a new `spec` directory within it to hold your specs.
+
+## Writing a cookbook example
+
+This is a recipe that installs the foo package, and the matching example that expresses that expectation.
+
+### cookbooks/example/recipes/default.rb
+
+ package "foo" do
+ action :install
+ end
+
+### cookbooks/example/spec/default_spec.rb
+
+ require "chefspec"
+
+ describe "example::default" do
+ before(:all) do
+ @chef_run = ChefSpec::ChefRunner.new
+ @chef_run.converge "example::default"
+ end
+
+ it "should install foo" do
+ @chef_run.should install_package "foo"
+ end
+ end
+
+## Setting node attributes
+
+ChefSpec lets you override node attributes (including [OHAI](http://wiki.opscode.com/display/chef/Ohai) attributes) as
+you'd expect:
+
+ it "should log the node platform" do
+ @chef_run = ChefSpec::ChefRunner.new
+ @chef_run.node.foo = "bar"
+ @chef_run.converge "example::default"
+ @chef_run.should log "The value of node.foo is: bar"
+ end
+
+# Matchers
+
+You can use RSpec `should` and `should_not` to define the expected outcome of applying your recipe using the following
+matchers:
+
+## Files and Directories
+
+Matchers for the Chef [File](http://wiki.opscode.com/display/chef/Resources#Resources-File) and [Directory](http://wiki.opscode.com/display/chef/Resources#Resources-Directory) resources.
+
+### create_file
+
+ @chef_run.should create_file "/var/log/bar.log"
+
+### delete_file
+
+ @chef_run.should delete_file "/var/log/bar.log"
+
+### create_directory
+
+ @chef_run.should create_directory "/var/lib/foo"
+
+### delete_directory
+
+ @chef_run.should delete_directory "/var/lib/foo"
+
+### be_owned_by
+
+ @chef_run.file("/var/log/bar.log").should be_owned_by("user", "group")
+ @chef_run.directory("/var/lib/foo").should be_owned_by("user", "group")
+
+## Packages
+Matchers for the Chef [Package](http://wiki.opscode.com/display/chef/Resources#Resources-Package) resource.
+
+### install_package
+
+ @chef_run.should install_package "foo"
+ @chef_run.should install_package_at_version "foo", "1.2.3"
+
+### purge_package
+
+ @chef_run.should purge_package "foo"
+
+### remove_package
+
+ @chef_run.should remove_package "foo"
+
+
+### upgrade_package
+
+ @chef_run.should upgrade_package "foo"
+
+## Execute
+Matcher for the Chef [Execute](http://wiki.opscode.com/display/chef/Resources#Resources-Execute) resource.
+
+### execute_command
+
+ @chef_run.should execute_command "whoami"
+
+## Logging
+Matcher for the Chef [Log](http://wiki.opscode.com/display/chef/Resources#Resources-Log) resource.
+
+### log
+
+ @chef_run.should log "A log message from my recipe"
+
+## Services
+Matchers for the Chef [Service](http://wiki.opscode.com/display/chef/Resources#Resources-Service) resource.
+
+### start_service
+
+ @chef_run.should start_service "food"
+
+### set_service_to_start_on_boot
+
+ @chef_run.should set_service_to_start_on_boot "food"
+
+### stop_service
+
+ @chef_run.should stop_service "food"
+
+### restart_service
+
+ @chef_run.should restart_service "food"
+
+### reload_service
+
+ @chef_run.should reload_service "food"
+
+# More Examples
+
+There are further examples of using ChefSpec in the `features` directory.
+
+# Building
+
+ $ bundle install
+ $ rake
+
+# License
+MIT - see the accompanying LICENSE file for details.
+
+# Contributing
+Additional matchers and bugfixes are welcome! Please fork and submit a pull request on an individual branch per change.
@@ -0,0 +1,16 @@
+require 'rubygems'
+require 'bundler'
+require 'cucumber'
+require 'cucumber/rake/task'
+require 'yard'
+
+task :default => [:install, :features]
+
+Bundler.setup
+Bundler::GemHelper.install_tasks
+
+Cucumber::Rake::Task.new(:features) do |t|
+ t.cucumber_opts = "features --format pretty"
+end
+
+YARD::Rake::YardocTask.new
@@ -0,0 +1,11 @@
+Gem::Specification.new do |s|
+ s.name = 'chefspec'
+ s.version = '0.0.1'
+ s.description = 'Write RSpec examples for Opscode Chef recipes'
+ s.summary = "chefspec-#{s.version}"
+ s.authors = ['Andrew Crump']
+ s.homepage = 'http://acrmp.github.com/chefspec'
+ s.license = 'MIT'
+ s.require_path = 'lib'
+ s.files = Dir['lib/**/*.rb']
+end
@@ -0,0 +1,17 @@
+Feature: Set node attributes
+
+ In order to have examples that thoroughly exercise my recipes
+ As a developer
+ I want to be able to set all node attributes within the example (including automatic)
+
+ Scenario: Set node attribute
+ Given a Chef cookbook with a recipe that logs a node attribute
+ And the recipe has a spec example that sets a node attribute
+ When the recipe example is successfully run
+ Then the recipe will see the node attribute set in the spec example
+
+ Scenario: Override automatic attributes
+ Given a Chef cookbook with a recipe that has conditional execution based on operating system
+ And the recipe has a spec example that overrides the operating system to 'leprechaun'
+ When the recipe example is successfully run
+ Then the resources declared for the operating system will be available within the example
Oops, something went wrong.

0 comments on commit cf328ba

Please sign in to comment.