summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Keiser <john@johnkeiser.com>2015-04-20 16:41:36 -0700
committerJohn Keiser <john@johnkeiser.com>2015-05-13 13:42:32 -0700
commit644342358dcd7202c24f731eae498db1ec46db3d (patch)
tree3524a4e65c52250d77f47379d32bcdadf3f619f4
parentbf45150b190afa90a69c4317b0a89c4f8ebd20fa (diff)
downloadchef-644342358dcd7202c24f731eae498db1ec46db3d.tar.gz
Add tests for resource naming and creation
-rw-r--r--Gemfile1
-rw-r--r--chef.gemspec1
-rw-r--r--spec/integration/recipes/lwrp_inline_resources_spec.rb2
-rw-r--r--spec/integration/recipes/recipe_dsl_spec.rb277
-rw-r--r--spec/support/shared/integration/integration_helper.rb11
5 files changed, 286 insertions, 6 deletions
diff --git a/Gemfile b/Gemfile
index 1418235ebc..b9ac623296 100644
--- a/Gemfile
+++ b/Gemfile
@@ -10,6 +10,7 @@ end
group(:development, :test) do
gem "simplecov"
gem 'rack', "~> 1.5.1"
+ gem 'cheffish', github: 'chef/cheffish', branch: 'jk/chef_run_additions'
gem 'ruby-shadow', :platforms => :ruby unless RUBY_PLATFORM.downcase.match(/(aix|cygwin)/)
end
diff --git a/chef.gemspec b/chef.gemspec
index 7cf6380062..2f8fabcec8 100644
--- a/chef.gemspec
+++ b/chef.gemspec
@@ -44,6 +44,7 @@ Gem::Specification.new do |s|
s.add_dependency "syslog-logger", "~> 1.6"
s.add_development_dependency "rack"
+ s.add_development_dependency "cheffish", "~> 1.1"
# Rake 10.2 drops Ruby 1.8 support
s.add_development_dependency "rake", "~> 10.1.0"
diff --git a/spec/integration/recipes/lwrp_inline_resources_spec.rb b/spec/integration/recipes/lwrp_inline_resources_spec.rb
index b4c4e6ca11..e70605d3d3 100644
--- a/spec/integration/recipes/lwrp_inline_resources_spec.rb
+++ b/spec/integration/recipes/lwrp_inline_resources_spec.rb
@@ -5,7 +5,7 @@ describe "LWRPs with inline resources" do
include IntegrationSupport
include Chef::Mixin::ShellOut
- let(:chef_dir) { File.join(File.dirname(__FILE__), "..", "..", "..", "bin") }
+ let(:chef_dir) { File.expand_path("../../../../bin", __FILE__) }
# Invoke `chef-client` as `ruby PATH/TO/chef-client`. This ensures the
# following constraints are satisfied:
diff --git a/spec/integration/recipes/recipe_dsl_spec.rb b/spec/integration/recipes/recipe_dsl_spec.rb
new file mode 100644
index 0000000000..5442aeffc0
--- /dev/null
+++ b/spec/integration/recipes/recipe_dsl_spec.rb
@@ -0,0 +1,277 @@
+require 'support/shared/integration/integration_helper'
+
+describe "Recipe DSL methods" do
+ include IntegrationSupport
+
+ context "With resource 'base_thingy' declared as BaseThingy" do
+ before(:context) {
+
+ class BaseThingy < Chef::Resource
+ def initialize(*args, &block)
+ super
+ @resource_name = 'base_thingy'
+ @allowed_actions = [ :create ]
+ @action = :create
+ end
+
+ class<<self
+ attr_accessor :created_resource
+ attr_accessor :created_provider
+ end
+
+ def provider
+ Provider
+ end
+ class Provider < Chef::Provider
+ def load_current_resource
+ end
+ def action_create
+ BaseThingy.created_resource = new_resource.class
+ BaseThingy.created_provider = self.class
+ end
+ end
+ end
+
+ # Modules to put stuff in
+ module Foo; end
+ module Foo::Bar; end
+
+ }
+
+ before :each do
+ BaseThingy.created_resource = nil
+ BaseThingy.created_provider = nil
+ end
+
+ context "Automatic resource DSL" do
+ context "With a resource 'backcompat_thingy' declared in Chef::Resource and Chef::Provider" do
+ before(:context) {
+
+ class Chef::Resource::BackcompatThingy < Chef::Resource
+ def initialize(*args, &block)
+ super
+ @resource_name = 'backcompat_thingy'
+ @allowed_actions = [ :create ]
+ @action = :create
+ end
+ end
+ class Chef::Provider::BackcompatThingy < Chef::Provider
+ def load_current_resource
+ end
+ def action_create
+ BaseThingy.created_resource = new_resource.class
+ BaseThingy.created_provider = self.class
+ end
+ end
+
+ }
+
+ it "backcompat_thingy creates a Chef::Resource::BackcompatThingy" do
+ expect_recipe {
+ backcompat_thingy 'blah' do; end
+ }.to emit_no_warnings_or_errors
+ expect(BaseThingy.created_resource).to eq Chef::Resource::BackcompatThingy
+ expect(BaseThingy.created_provider).to eq Chef::Provider::BackcompatThingy
+ end
+
+ context "And another resource 'backcompat_thingy' in BackcompatThingy with 'provides'" do
+ before(:context) {
+
+ class Foo::BackcompatThingy < BaseThingy; end
+
+ }
+
+ it "backcompat_thingy creates a BackcompatThingy and warns about ambiguity" do
+ recipe = converge {
+ backcompat_thingy 'blah' do; end
+ }
+ expect(recipe.logged_warnings).to match /ambiguous resource precedence/i
+ expect(BaseThingy.created_resource).not_to be_nil
+ end
+ end
+ end
+
+ context "With a resource 'thingy' declared in Foo::Bar::Thingy2" do
+ before(:context) {
+
+ class Foo::Bar::Thingy < BaseThingy; end
+
+ }
+
+ it "thingy creates a Foo::Bar::Thingy" do
+ expect_recipe {
+ thingy 'blah' do; end
+ }.to emit_no_warnings_or_errors
+ expect(BaseThingy.created_resource).to eq Foo::Bar::Thingy
+ end
+ end
+
+ it "When resource 'thingy2' does not exist and is created during the recipe, it still works" do
+ expect_recipe {
+ class Foo::Thingy2 < BaseThingy; end
+ thingy2 'blah' do; end
+ }.to emit_no_warnings_or_errors
+ expect(BaseThingy.created_resource).to eq Foo::Thingy2
+ end
+ end
+
+ context "provides" do
+ context "When MySupplier provides :hemlock" do
+ before(:context) {
+
+ class Foo::MySupplier < BaseThingy
+ provides :hemlock
+ end
+
+ }
+
+ it "my_supplier does not work in a recipe" do
+ expect_converge {
+ my_supplier 'blah' do; end
+ }.to raise_error(NoMethodError)
+ end
+
+ it "hemlock works in a recipe" do
+ expect_recipe {
+ hemlock 'blah' do; end
+ }.to emit_no_warnings_or_errors
+ expect(BaseThingy.created_resource).to eq Foo::MySupplier
+ end
+ end
+
+ context "When Thingy3 provides :thingy3" do
+ before(:context) {
+
+ class Foo::Thingy3 < BaseThingy
+ provides :thingy3
+ end
+
+ }
+
+ it "thingy3 works in a recipe" do
+ expect_recipe {
+ thingy3 'blah' do; end
+ }.to emit_no_warnings_or_errors
+ expect(BaseThingy.created_resource).to eq Foo::Thingy3
+ end
+
+ context "And Thingy4 provides :thingy3" do
+ before(:context) {
+
+ class Foo::Thingy4 < Chef::Resource
+ provides :thingy3
+ end
+
+ }
+
+ it "thingy3 works in a recipe and yields " do
+ recipe = converge {
+ thingy3 'blah' do; end
+ }
+ expect(recipe.logged_warnings).to match /ambiguous resource precedence/i
+ expect(BaseThingy.created_resource).not_to be_nil
+ end
+
+ it "thingy4 does not work in a recipe" do
+ expect_converge {
+ thingy4 'blah' do; end
+ }.to raise_error(NoMethodError)
+ end
+ end
+ end
+
+ context "When Thingy5 provides :thingy5, :twizzle and :twizzle2" do
+ before(:context) {
+
+ class Foo::Thingy5 < BaseThingy
+ provides :thingy5
+ provides :twizzle
+ provides :twizzle2
+ end
+
+ }
+
+ it "thingy5 works in a recipe and yields Thingy5" do
+ expect_recipe {
+ thingy5 'blah' do; end
+ }.to emit_no_warnings_or_errors
+ expect(BaseThingy.created_resource).to eq Foo::Thingy5
+ end
+
+ it "twizzle works in a recipe and yields Thingy5" do
+ expect_recipe {
+ twizzle 'blah' do; end
+ }.to emit_no_warnings_or_errors
+ expect(BaseThingy.created_resource).to eq Foo::Thingy5
+ end
+
+ it "twizzle2 works in a recipe and yields Thingy5" do
+ expect_recipe {
+ twizzle2 'blah' do; end
+ }.to emit_no_warnings_or_errors
+ expect(BaseThingy.created_resource).to eq Foo::Thingy5
+ end
+ end
+
+ context "When Thingy6 uses provides_nothing" do
+ before(:context) {
+
+ class Foo::Thingy6 < Chef::Resource
+ provides_nothing
+ end
+
+ }
+
+ it "thingy6 does not work in a recipe" do
+ expect_converge {
+ thingy6 'blah' do; end
+ }.to raise_error(NoMethodError)
+ end
+ end
+
+ context "With platform-specific resources 'my_super_thingy_foo' and 'my_super_thingy_bar'" do
+ before(:context) {
+ class MySuperThingyFoo < BaseThingy
+ provides :my_super_thingy, platform: 'foo'
+ end
+
+ class MySuperThingyBar < BaseThingy
+ provides :my_super_thingy, platform: 'bar'
+ end
+ }
+
+ it "A run with platform 'foo' uses MySuperThingyFoo" do
+ r = Cheffish::ChefRun.new(chef_config)
+ r.client.run_context.node.automatic['platform'] = 'foo'
+ r.compile_recipe {
+ my_super_thingy 'blah' do; end
+ }
+ r.converge
+ expect(r).to emit_no_warnings_or_errors
+ expect(BaseThingy.created_resource).to eq MySuperThingyFoo
+ end
+
+ it "A run with platform 'bar' uses MySuperThingyBar" do
+ r = Cheffish::ChefRun.new(chef_config)
+ r.client.run_context.node.automatic['platform'] = 'bar'
+ r.compile_recipe {
+ my_super_thingy 'blah' do; end
+ }
+ r.converge
+ expect(r).to emit_no_warnings_or_errors
+ expect(BaseThingy.created_resource).to eq MySuperThingyBar
+ end
+
+ it "A run with platform 'x' reports that my_super_thingy is not supported" do
+ r = Cheffish::ChefRun.new(chef_config)
+ r.client.run_context.node.automatic['platform'] = 'x'
+ expect {
+ r.compile_recipe {
+ my_super_thingy 'blah' do; end
+ }
+ }.to raise_error(Chef::Exceptions::NoSuchResourceType)
+ end
+ end
+ end
+ end
+end
diff --git a/spec/support/shared/integration/integration_helper.rb b/spec/support/shared/integration/integration_helper.rb
index e6942c62af..927ff2f42b 100644
--- a/spec/support/shared/integration/integration_helper.rb
+++ b/spec/support/shared/integration/integration_helper.rb
@@ -22,14 +22,19 @@ require 'fileutils'
require 'chef/config'
require 'chef/json_compat'
require 'chef/server_api'
-require 'chef_zero/rspec'
require 'support/shared/integration/knife_support'
require 'support/shared/integration/app_server_support'
+require 'cheffish/rspec/chef_run_support'
require 'spec_helper'
module IntegrationSupport
include ChefZero::RSpec
+ def self.included(includer_class)
+ includer_class.extend(Cheffish::RSpec::ChefRunSupport)
+ includer_class.extend(ClassMethods)
+ end
+
module ClassMethods
include ChefZero::RSpec
@@ -49,10 +54,6 @@ module IntegrationSupport
end
end
- def self.included(includer_class)
- includer_class.extend(ClassMethods)
- end
-
def api
Chef::ServerAPI.new
end