Permalink
Browse files

Add support for chef_gem resource

The chef_gem resource was added in chef 0.10.10. The chef_gem matcher is added only if
the chef version supports it.
  • Loading branch information...
1 parent c282d53 commit ddc37ad5d77dabccaa673532f56584167cc6a389 @jimhopp-lookout jimhopp-lookout committed Nov 9, 2012
View
@@ -349,6 +349,10 @@ All of the assertions above are also valid for use with RubyGems:
chef_run.should install_gem_package 'foo'
```
+```ruby
+chef_run.should install_chef_gem_package 'chef-foo'
+```
+
## Execute
If you make use of the `execute` resource within your cookbook recipes it is
View
@@ -19,6 +19,7 @@ def register_spec_features(spec_type)
"Run Cucumber features (#{spec_type} support only)") do |t|
t.cucumber_opts = "CS_SPEC_TYPE=#{spec_type} features --format pretty"
t.cucumber_opts << ' -t ~@requires_chef_10' if Chef::VERSION.start_with? '0.9.'
+ t.cucumber_opts << ' -t ~@chefgem' unless defined?(Chef::Resource::ChefGem)
t.cucumber_opts << " -t ~@not_implemented_#{spec_type.downcase}"
end
end
@@ -0,0 +1,63 @@
+Given 'a Chef cookbook with a recipe that declares a chef gem package resource' do
+ recipe_installs_chef_gem
+end
+
+Given 'a Chef cookbook with a recipe that declares a chef gem package resource with no action specified' do
+ recipe_with_chef_gem_no_action
+end
+
+Given 'a Chef cookbook with a recipe that declares a chef gem package resource at a fixed version' do
+ recipe_installs_specific_chef_gem_version
+end
+
+Given 'a Chef cookbook with a recipe that declares a chef gem package resource at a fixed version with no action specified' do
+ recipe_installs_specific_chef_gem_version_with_no_action
+end
+
+Given 'a Chef cookbook with a recipe that upgrades a chef gem package' do
+ recipe_upgrades_chef_gem
+end
+
+Given 'a Chef cookbook with a recipe that removes a chef gem package' do
+ recipe_removes_chef_gem
+end
+
+Given 'a Chef cookbook with a recipe that purges a chef gem package' do
+ recipe_purges_chef_gem
+end
+
+Given 'the recipe has a spec example that expects the chef gem package to be installed' do
+ spec_expects_chef_gem_action(:install)
+end
+
+Given 'the recipe has a spec example that expects the chef gem package to be upgraded' do
+ spec_expects_chef_gem_action(:upgrade)
+end
+
+Given 'the recipe has a spec example that expects the chef gem package to be removed' do
+ spec_expects_chef_gem_action(:remove)
+end
+
+Given 'the recipe has a spec example that expects the chef gem package to be purged' do
+ spec_expects_chef_gem_action(:purge)
+end
+
+Given 'the recipe has a spec example that expects the chef gem package to be installed at that version' do
+ spec_expects_chef_gem_at_specific_version
+end
+
+Then 'the chef gem package will not have been installed' do
+ # chef gem package installation would fail
+end
+
+Then 'the chef gem package will not have been upgraded' do
+ # chef gem package upgrade would fail
+end
+
+Then 'the chef gem package will not have been removed' do
+ # chef gem package removal would fail
+end
+
+Then 'the chef gem package will not have been purged' do
+ # chef gem package purge would fail
+end
@@ -104,6 +104,14 @@ def recipe_installs_gem
}
end
+ def recipe_installs_chef_gem
+ write_file 'cookbooks/example/recipes/default.rb', %q{
+ chef_gem "chef_gem_does_not_exist" do
+ action :install
+ end
+ }
+ end
+
def recipe_installs_package
write_file 'cookbooks/example/recipes/default.rb', %q{
package "package_does_not_exist" do
@@ -127,6 +135,15 @@ def recipe_installs_specific_gem_version
}
end
+ def recipe_installs_specific_chef_gem_version
+ write_file 'cookbooks/example/recipes/default.rb', %q{
+ chef_gem "chef_gem_does_not_exist" do
+ version "1.2.3"
+ action :install
+ end
+ }
+ end
+
def recipe_installs_specific_package_version
write_file "cookbooks/example/recipes/default.rb", %q{
package "package_does_not_exist" do
@@ -144,6 +161,14 @@ def recipe_installs_specific_gem_version_with_no_action
}
end
+ def recipe_installs_specific_chef_gem_version_with_no_action
+ write_file 'cookbooks/example/recipes/default.rb', %q{
+ chef_gem "chef_gem_does_not_exist" do
+ version "1.2.3"
+ end
+ }
+ end
+
def recipe_installs_specific_package_version_with_no_action
write_file 'cookbooks/example/recipes/default.rb', %q{
package "package_does_not_exist" do
@@ -166,6 +191,14 @@ def recipe_purges_gem
}
end
+ def recipe_purges_chef_gem
+ write_file 'cookbooks/example/recipes/default.rb', %q{
+ chef_gem "chef_gem_does_not_exist" do
+ action :purge
+ end
+ }
+ end
+
def recipe_purges_package
write_file "cookbooks/example/recipes/default.rb", %q{
package "package_does_not_exist" do
@@ -199,6 +232,14 @@ def recipe_removes_gem
}
end
+ def recipe_removes_chef_gem
+ write_file 'cookbooks/example/recipes/default.rb', %q{
+ chef_gem "chef_gem_does_not_exist" do
+ action :remove
+ end
+ }
+ end
+
def recipe_removes_package
write_file "cookbooks/example/recipes/default.rb", %q{
package "package_does_not_exist" do
@@ -304,6 +345,14 @@ def recipe_upgrades_gem
}
end
+ def recipe_upgrades_chef_gem
+ write_file 'cookbooks/example/recipes/default.rb', %q{
+ chef_gem "chef_gem_does_not_exist" do
+ action :upgrade
+ end
+ }
+ end
+
def recipe_with_cookbook_file
write_file 'cookbooks/example/files/default/hello-world.txt', 'hello world!'
write_file 'cookbooks/example/recipes/default.rb', 'cookbook_file "hello-world.txt"'
@@ -324,6 +373,12 @@ def recipe_with_gem_no_action
}
end
+ def recipe_with_chef_gem_no_action
+ write_file 'cookbooks/example/recipes/default.rb', %q{
+ chef_gem "chef_gem_does_not_exist"
+ }
+ end
+
def recipe_with_remote_file
write_file 'cookbooks/example/recipes/default.rb', %q{
remote_file "hello-world.txt" do
@@ -101,6 +101,26 @@ def spec_expects_gem_at_specific_version
}
end
+ def spec_expects_chef_gem_action(action)
+ assertion = case action
+ when :remove, :purge then 'wont_be_installed'
+ else 'must_be_installed'
+ end
+ generate_spec %Q{
+ it "#{action}s the chef gem" do
+ chef_gem("chef_gem_does_not_exist").#{assertion}
+ end
+ }
+ end
+
+ def spec_expects_chef_gem_at_specific_version
+ generate_spec %q{
+ it "installs the chef gem at a specific version" do
+ chef_gem("chef_gem_does_not_exist").must_be_installed.with(:version, '1.2.3')
+ end
+ }
+ end
+
def spec_expects_package_action(action)
assertion = case action
when :remove, :purge then 'wont_be_installed'
@@ -205,6 +205,32 @@ def spec_expects_gem_at_specific_version
}
end
+ def spec_expects_chef_gem_action(action)
+ write_file 'cookbooks/example/spec/default_spec.rb', %Q{
+ require "chefspec"
+
+ describe "example::default" do
+ let(:chef_run) { ChefSpec::ChefRunner.new.converge 'example::default' }
+ it "should #{action.to_s} package_does_not_exist" do
+ chef_run.should #{action.to_s}_chef_gem 'chef_gem_does_not_exist'
+ end
+ end
+ }
+ end
+
+ def spec_expects_chef_gem_at_specific_version
+ write_file 'cookbooks/example/spec/default_spec.rb', %q{
+ require "chefspec"
+
+ describe "example::default" do
+ let(:chef_run) {ChefSpec::ChefRunner.new.converge 'example::default'}
+ it "should install chef_gem_does_not_exist at a specific version" do
+ chef_run.should install_chef_gem_at_version 'chef_gem_does_not_exist', '1.2.3'
+ end
+ end
+ }
+ end
+
def spec_expects_package_action(action)
write_file 'cookbooks/example/spec/default_spec.rb', %Q{
require "chefspec"
@@ -0,0 +1,48 @@
+@chefgem
+Feature: Write examples for chef gem packages
+
+ Express an expectation that a chef gem package will be installed:
+
+ chef_run.should install_chef gem_package 'foo'
+
+ Scenario: chef gem package resource
+ Given a Chef cookbook with a recipe that declares a chef gem package resource
+ And the recipe has a spec example that expects the chef gem package to be installed
+ When the recipe example is successfully run
+ Then the chef gem package will not have been installed
+
+ Scenario: Package resource with default action
+ Given a Chef cookbook with a recipe that declares a chef gem package resource with no action specified
+ And the recipe has a spec example that expects the chef gem package to be installed
+ When the recipe example is successfully run
+ Then the chef gem package will not have been installed
+
+ Scenario: Package resource with fixed version
+ Given a Chef cookbook with a recipe that declares a chef gem package resource at a fixed version
+ And the recipe has a spec example that expects the chef gem package to be installed at that version
+ When the recipe example is successfully run
+ Then the chef gem package will not have been installed
+
+ Scenario: Package resource with fixed version and default action
+ Given a Chef cookbook with a recipe that declares a chef gem package resource at a fixed version with no action specified
+ And the recipe has a spec example that expects the chef gem package to be installed at that version
+ When the recipe example is successfully run
+ Then the chef gem package will not have been installed
+
+ Scenario: Upgrade a package
+ Given a Chef cookbook with a recipe that upgrades a chef gem package
+ And the recipe has a spec example that expects the chef gem package to be upgraded
+ When the recipe example is successfully run
+ Then the chef gem package will not have been upgraded
+
+ Scenario: Remove a package
+ Given a Chef cookbook with a recipe that removes a chef gem package
+ And the recipe has a spec example that expects the chef gem package to be removed
+ When the recipe example is successfully run
+ Then the chef gem package will not have been removed
+
+ Scenario: Purge a package
+ Given a Chef cookbook with a recipe that purges a chef gem package
+ And the recipe has a spec example that expects the chef gem package to be purged
+ When the recipe example is successfully run
+ Then the chef gem package will not have been purged
@@ -3,7 +3,10 @@
module ChefSpec
module Matchers
- define_resource_matchers([:install, :remove, :upgrade, :purge], [:package, :gem_package], :package_name)
+ CHEF_GEM_SUPPORTED = defined?(::Chef::Resource::ChefGem)
+ PACKAGE_TYPES = [:package, :gem_package, :chef_gem]
+ PACKAGE_TYPES << :chef_gem if CHEF_GEM_SUPPORTED
+ define_resource_matchers([:install, :remove, :upgrade, :purge], PACKAGE_TYPES, :package_name)
RSpec::Matchers.define :install_package_at_version do |package_name, version|
match do |chef_run|
@@ -19,5 +22,12 @@ module Matchers
end
end
end
+ RSpec::Matchers.define :install_chef_gem_at_version do |package_name, version|
+ match do |chef_run|
+ chef_run.resources.any? do |resource|
+ resource_type(resource) == 'chef_gem' and resource.package_name == package_name and resource.action.to_s.include? 'install' and resource.version == version
+ end
+ end
+ end if CHEF_GEM_SUPPORTED
end
end
@@ -0,0 +1,27 @@
+require 'spec_helper'
+
+module ChefSpec
+ module Matchers
+ describe :install_chef_gem_at_version, :if => defined?(::Chef::Resource::ChefGem) do
+ describe "#match" do
+ let(:matcher) { install_chef_gem_at_version('foo', '1.2.3') }
+ it "should not match when no resources exist" do
+ matcher.matches?({:resources => []}).should be false
+ end
+ it "should not match when there are no chef gem packages" do
+ matcher.matches?({:resources => [{:resource_name => 'template', :path => '/tmp/config.conf',
+ :source => 'config.conf.erb'}]}).should be false
+ end
+ it "should not match if is a different chef gem package and an unspecified version" do
+ matcher.matches?({:resources => [{:resource_name => 'chef_gem', :package_name => 'bar', :version => nil, :action => :install}]}).should be false
+ end
+ it "should not match if it is the same chef gem package and version but a different action" do
+ matcher.matches?({:resources => [{:resource_name => 'chef_gem', :package_name => 'foo', :version => '1.2.3', :action => :upgrade}]}).should be false
+ end
+ it "should match if is the same chef gem package, the correct version and the install action" do
+ matcher.matches?({:resources => [{:resource_name => 'chef_gem', :package_name => 'foo', :version => '1.2.3', :action => :install}]}).should be true
+ end
+ end
+ end
+ end
+end

0 comments on commit ddc37ad

Please sign in to comment.