Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for chef_gem resource #66

Closed
wants to merge 9 commits into from
12 changes: 11 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -295,12 +295,18 @@ Assert that a file would have the correct ownership:
chef_run.file('/var/log/bar.log').should be_owned_by('user', 'group')
```

Assert that a file would have the expected content:
Assert that a file would have the expected content (matches on partial content):

```ruby
chef_run.should create_file_with_content 'hello-world.txt', 'hello world'
```

Assert that a remote file would be created:

```ruby
chef_run.should create_remote_file '/tmp/foo.tar.gz'
```

## Packages

Note that only packages explicitly declared in the cookbook will be matched by
Expand Down Expand Up @@ -343,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
Expand Down
1 change: 1 addition & 0 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
63 changes: 63 additions & 0 deletions features/step_definitions/chef_gem_package_steps.rb
Original file line number Diff line number Diff line change
@@ -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
6 changes: 6 additions & 0 deletions features/step_definitions/notification_steps.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,9 @@
Then /the notify assertion will be succesfully evaluated/ do
end

Given /^a Chef cookbook with a recipe in which a template notifies a service having braces in its name$/ do
recipe_with_template_notifying_service_having_braces_in_name
end
Given /^the recipe has a spec example that assert on the notification service having braces in its name$/ do
spec_expects_template_notifies_service_having_braces_in_its_name
end
67 changes: 67 additions & 0 deletions features/support/example_helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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"'
Expand All @@ -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
Expand Down Expand Up @@ -358,6 +413,18 @@ def recipe_with_template_notifying_service
end
}
end

def recipe_with_template_notifying_service_having_braces_in_name
write_file 'cookbooks/example/recipes/default.rb', %q{
template "/etc/foo" do
notifies :restart ,"service[bar[v1.1]]"
end
service "bar[v1.1]" do
action :start
end
}
end

def recipe_includes_another_recipe
write_file 'cookbooks/example/recipes/default.rb', %q{
include_recipe 'example::foo'
Expand Down
20 changes: 20 additions & 0 deletions features/support/minitest_helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down
39 changes: 39 additions & 0 deletions features/support/rspec_helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -366,6 +392,19 @@ def spec_expects_template_notifies_service
}
end

def spec_expects_template_notifies_service_having_braces_in_its_name
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 "template 'foo' should notify resource 'bar'" do
chef_run.template('/etc/foo').should notify('service[bar[v1.1]]',:restart)
end
end
}
end

def spec_expects_include_recipe
write_file 'cookbooks/example/spec/default_spec.rb', %Q{
require "chefspec"
Expand Down
48 changes: 48 additions & 0 deletions features/write_examples_for_chef_gem_packages.feature
Original file line number Diff line number Diff line change
@@ -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
6 changes: 6 additions & 0 deletions features/write_examples_for_notification.feature
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,9 @@ Feature: Write examples for notifcations
And the recipe has a spec example that assert on the notification
When the recipe example is successfully run
Then the notify assertion will be succesfully evaluated

Scenario: Notify a resource having square braces in its name
Given a Chef cookbook with a recipe in which a template notifies a service having braces in its name
And the recipe has a spec example that assert on the notification service having braces in its name
When the recipe example is successfully run
Then the notify assertion will be succesfully evaluated
12 changes: 11 additions & 1 deletion lib/chefspec/matchers/package.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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|
Expand All @@ -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
Loading