From e58ccb82dc062cb081c3a2be0130aeb52d30f8f3 Mon Sep 17 00:00:00 2001 From: tyler-ball Date: Fri, 14 Nov 2014 12:45:53 -0800 Subject: Adding test for duplicated DSL --- spec/integration/solo/solo_spec.rb | 2 +- spec/unit/audit/duplication.rb | 50 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 spec/unit/audit/duplication.rb diff --git a/spec/integration/solo/solo_spec.rb b/spec/integration/solo/solo_spec.rb index 9500e7a1ca..cc9ba1abb2 100644 --- a/spec/integration/solo/solo_spec.rb +++ b/spec/integration/solo/solo_spec.rb @@ -92,7 +92,7 @@ EOM # We have a timeout protection here so that if due to some bug # run_lock gets stuck we can discover it. expect { - Timeout.timeout(1200) do + Timeout.timeout(120) do chef_dir = File.join(File.dirname(__FILE__), "..", "..", "..") # Instantiate the first chef-solo run diff --git a/spec/unit/audit/duplication.rb b/spec/unit/audit/duplication.rb new file mode 100644 index 0000000000..0d66a2e06c --- /dev/null +++ b/spec/unit/audit/duplication.rb @@ -0,0 +1,50 @@ +# +# Author:: Tyler Ball () +# Copyright:: Copyright (c) 2014 Chef, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require 'spec_helper' +require 'chef/dsl/audit' +require 'chef/dsl/recipe' +# This includes the Serverspec DSL +require 'chef/audit' + +describe "Duplicated `package` DSL in Chef and Serverspec" do + # This includes the Chef DSL + include Chef::DSL::Recipe + # TODO why do I need this? Should I wrap below in calls to Recipe.instance_eval? + include Chef::DSL::Audit + + # TODO disable rspec global DSL + # TODO disable serverspec global DSL + + it "Should call the Chef Recipe DSL in a Chef Recipe" do + expect(Chef::Resource).to receive(:resource_for_node).with(:package) { Chef::Resource::Package } + expect(Chef::Resource::Package).to receive(:new).with("foo").and_call_original + + package "foo" + end + + it "Should call the Serverspec DSL in a `controls` Recipe" do + #expect(Chef::Resource).to receive(:resource_for_node).with(:package) { Chef::Resource::Package } + #expect(Chef::Resource::Package).to receive(:new).with("foo").and_call_original + + controls "some controls" do + package "foo" + end + end + +end -- cgit v1.2.1 From ce9e67a990f4833b49a9d9427ffa901edc4f454e Mon Sep 17 00:00:00 2001 From: tyler-ball Date: Mon, 17 Nov 2014 13:24:54 -0800 Subject: Finishing duplication tests --- lib/chef/audit/audit_event_proxy.rb | 1 + lib/chef/dsl/audit.rb | 12 ++--- spec/unit/audit/duplication.rb | 89 ++++++++++++++++++++++++++++++++----- 3 files changed, 82 insertions(+), 20 deletions(-) diff --git a/lib/chef/audit/audit_event_proxy.rb b/lib/chef/audit/audit_event_proxy.rb index 71d1e2aa50..6b66b70b6c 100644 --- a/lib/chef/audit/audit_event_proxy.rb +++ b/lib/chef/audit/audit_event_proxy.rb @@ -1,3 +1,4 @@ +require 'rspec' RSpec::Support.require_rspec_core "formatters/base_text_formatter" class Chef diff --git a/lib/chef/dsl/audit.rb b/lib/chef/dsl/audit.rb index e22c38f587..78a747aa1f 100644 --- a/lib/chef/dsl/audit.rb +++ b/lib/chef/dsl/audit.rb @@ -17,6 +17,7 @@ # require 'chef/exceptions' +require 'chef/audit/controls' class Chef module DSL @@ -25,16 +26,11 @@ class Chef # Can encompass tests in a `control` block or `describe` block # Adds the controls group and block (containing controls to execute) to the runner's list of pending examples def controls(*args, &block) - raise Chef::Exceptions::NoAuditsProvided unless block - + raise ::Chef::Exceptions::NoAuditsProvided unless block name = args[0] - if name.nil? || name.empty? - raise Chef::Exceptions::AuditNameMissing - elsif run_context.controls.has_key?(name) - raise Chef::Exceptions::AuditControlGroupDuplicate.new(name) - end + raise AuditNameMissing if name.nil? || name.empty? - run_context.controls[name] = { :args => args, :block => block } + run_context.controls_groups << Chef::Audit::Controls.new(run_context, args, &block) end end diff --git a/spec/unit/audit/duplication.rb b/spec/unit/audit/duplication.rb index 0d66a2e06c..3dfcee3d8d 100644 --- a/spec/unit/audit/duplication.rb +++ b/spec/unit/audit/duplication.rb @@ -19,32 +19,97 @@ require 'spec_helper' require 'chef/dsl/audit' require 'chef/dsl/recipe' -# This includes the Serverspec DSL -require 'chef/audit' describe "Duplicated `package` DSL in Chef and Serverspec" do # This includes the Chef DSL include Chef::DSL::Recipe - # TODO why do I need this? Should I wrap below in calls to Recipe.instance_eval? include Chef::DSL::Audit - # TODO disable rspec global DSL + # TODO disable rspec global DSL - but do we want it enabled for OUR rspecs? No, because we always have a runner? # TODO disable serverspec global DSL + let(:run_context) { + node = Chef::Node.new + Chef::RunContext.new(node, {}, nil) + } + it "Should call the Chef Recipe DSL in a Chef Recipe" do - expect(Chef::Resource).to receive(:resource_for_node).with(:package) { Chef::Resource::Package } - expect(Chef::Resource::Package).to receive(:new).with("foo").and_call_original + # Chef::DSL::Recipe#method_missing calls #resource_for_node twice when looking up the Resource instance - once in + # #have_resource_class_for? and once in #declare_resource. Chef::DSL::Recipe#resource_class_for calls + # Chef::Resource#resource_for_node + expect(Chef::Resource).to receive(:resource_for_node).with(:package, instance_of(Chef::Node)).exactly(2).times.and_return(Chef::Resource::Package) + expect(Chef::Resource::Package).to receive(:new).with("foo1", run_context).and_call_original + + Chef::Recipe.new("cookbook", "recipe", run_context).instance_eval do + # Inside a recipe self refers to a Recipe object, so it calls the correct #method_missing chain to find the + # package resource + package "foo1" + end + end + + it "Should call the Serverspec DSL in a `controls` block" do + expect(Chef::Resource).to_not receive(:resource_for_node) + # Waiting until here to require this because otherwise it complains that it hasn't been configured yet + # and configuration takes place in the `controls` method + require 'serverspec' - package "foo" + Chef::Recipe.new("cookbook", "recipe", run_context).instance_eval do + # Inside a `controls` block, self refers to a subclass of RSpec::ExampleGroups so `package` calls the correct + # serverspec helper + controls "some controls" do + package "foo2" + end + end end - it "Should call the Serverspec DSL in a `controls` Recipe" do - #expect(Chef::Resource).to receive(:resource_for_node).with(:package) { Chef::Resource::Package } - #expect(Chef::Resource::Package).to receive(:new).with("foo").and_call_original + it "Should still use the recipe DSL outside of a controls block after a controls block has ran" do + expect(Serverspec::Type::Package).to receive(:new).with("foo3") + expect(Serverspec::Type::Package).to receive(:new).with("baz") + expect(Chef::Resource).to receive(:resource_for_node).with(:package, instance_of(Chef::Node)).exactly(4).times.and_return(Chef::Resource::Package) + expect(Chef::Resource::Package).to receive(:new).with("bar", run_context).and_call_original + expect(Chef::Resource::Package).to receive(:new).with("bang", run_context).and_call_original + + Chef::Recipe.new("cookbook", "recipe", run_context).instance_eval do + controls "some controls" do + package "foo3" + end + + package "bar" - controls "some controls" do - package "foo" + controls "some more controls" do + package "baz" + end + + package "bang" end end + it "Should not allow `control` or `__controls__` to be defined outside of a `controls` block" do + expect { control("foo4") }.to raise_error(NoMethodError, /No resource or method named `control'/) + + controls "some more controls" do + control "foo5" + end + + # Even after seeing a `controls` block these methods should not work - even when running in rspec + expect { control("foo6") }.to raise_error(NoMethodError, /No resource or method named `control'/) + end + + it "Should include serverspec specific matchers only inside `controls` block" do + # cgroup is a rspec matcher I'm assuming we won't define elsewhere + # TODO this is currently failing because the RSpec::Core::ExampleGroup has already been extended with + # the serverspec helpers + expect { cgroup('group1') }.to raise_error(NoMethodError, /No resource or method named `cgroup'/) + + expect(self).to receive(:cgroup).and_call_original + controls "cgroup controls" do + describe cgroup('group1') do + true + end + end + + expect { cgroup('group1') }.to raise_error(NoMethodError, /No resource or method named `cgroup'/) + end + + # TODO write cookbook which actually tests both `package` DSLs end -- cgit v1.2.1 From a92f65f26bada5b769a5fb3900b299ddfe604a44 Mon Sep 17 00:00:00 2001 From: tyler-ball Date: Mon, 17 Nov 2014 13:39:48 -0800 Subject: Fixing a test that was written wrong --- spec/unit/audit/duplication.rb | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/spec/unit/audit/duplication.rb b/spec/unit/audit/duplication.rb index 3dfcee3d8d..f5a98ecde7 100644 --- a/spec/unit/audit/duplication.rb +++ b/spec/unit/audit/duplication.rb @@ -18,12 +18,9 @@ require 'spec_helper' require 'chef/dsl/audit' -require 'chef/dsl/recipe' +require 'chef/recipe' describe "Duplicated `package` DSL in Chef and Serverspec" do - # This includes the Chef DSL - include Chef::DSL::Recipe - include Chef::DSL::Audit # TODO disable rspec global DSL - but do we want it enabled for OUR rspecs? No, because we always have a runner? # TODO disable serverspec global DSL @@ -85,14 +82,24 @@ describe "Duplicated `package` DSL in Chef and Serverspec" do end it "Should not allow `control` or `__controls__` to be defined outside of a `controls` block" do - expect { control("foo4") }.to raise_error(NoMethodError, /No resource or method named `control'/) + expect { + Chef::Recipe.new("cookbook", "recipe", run_context).instance_eval do + control("foo4") + end + }.to raise_error(NoMethodError, /No resource or method named `control'/) - controls "some more controls" do - control "foo5" + Chef::Recipe.new("cookbook", "recipe", run_context).instance_eval do + controls "some more controls" do + control "foo5" + end end # Even after seeing a `controls` block these methods should not work - even when running in rspec - expect { control("foo6") }.to raise_error(NoMethodError, /No resource or method named `control'/) + expect { + Chef::Recipe.new("cookbook", "recipe", run_context).instance_eval do + control("foo4") + end + }.to raise_error(NoMethodError, /No resource or method named `control'/) end it "Should include serverspec specific matchers only inside `controls` block" do -- cgit v1.2.1 From d8ea8574d1c717a1786267d0e0b4f86a508592e0 Mon Sep 17 00:00:00 2001 From: tyler-ball Date: Mon, 17 Nov 2014 13:41:45 -0800 Subject: Removing required that was not used --- spec/unit/audit/duplication.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/spec/unit/audit/duplication.rb b/spec/unit/audit/duplication.rb index f5a98ecde7..aff5cb500a 100644 --- a/spec/unit/audit/duplication.rb +++ b/spec/unit/audit/duplication.rb @@ -17,7 +17,6 @@ # require 'spec_helper' -require 'chef/dsl/audit' require 'chef/recipe' describe "Duplicated `package` DSL in Chef and Serverspec" do -- cgit v1.2.1 From aa0d1c65a8418426bfdff1d7b61a768305b40c3d Mon Sep 17 00:00:00 2001 From: tyler-ball Date: Thu, 20 Nov 2014 10:23:34 -0800 Subject: Updating duplication tests to levage a cookbook, so we can use the same cookbook for an integration test --- lib/chef/dsl.rb | 1 + spec/data/cookbooks/audit/metadata.rb | 2 + spec/data/cookbooks/audit/recipes/default.rb | 3 + .../audit/recipes/defined_outside_block.rb | 6 ++ .../cookbooks/audit/recipes/multiple_controls.rb | 11 +++ .../cookbooks/audit/recipes/serverspec_helpers.rb | 9 +++ .../cookbooks/audit/recipes/single_controls.rb | 5 ++ spec/unit/audit/duplication.rb | 94 ++++++++-------------- 8 files changed, 71 insertions(+), 60 deletions(-) create mode 100644 spec/data/cookbooks/audit/metadata.rb create mode 100644 spec/data/cookbooks/audit/recipes/default.rb create mode 100644 spec/data/cookbooks/audit/recipes/defined_outside_block.rb create mode 100644 spec/data/cookbooks/audit/recipes/multiple_controls.rb create mode 100644 spec/data/cookbooks/audit/recipes/serverspec_helpers.rb create mode 100644 spec/data/cookbooks/audit/recipes/single_controls.rb diff --git a/lib/chef/dsl.rb b/lib/chef/dsl.rb index 7717d99113..7ff605e466 100644 --- a/lib/chef/dsl.rb +++ b/lib/chef/dsl.rb @@ -4,3 +4,4 @@ require 'chef/dsl/data_query' require 'chef/dsl/include_recipe' require 'chef/dsl/include_attribute' require 'chef/dsl/registry_helper' +require 'chef/dsl/audit' diff --git a/spec/data/cookbooks/audit/metadata.rb b/spec/data/cookbooks/audit/metadata.rb new file mode 100644 index 0000000000..763c6f6675 --- /dev/null +++ b/spec/data/cookbooks/audit/metadata.rb @@ -0,0 +1,2 @@ +name "audit" +version "1.0.0" diff --git a/spec/data/cookbooks/audit/recipes/default.rb b/spec/data/cookbooks/audit/recipes/default.rb new file mode 100644 index 0000000000..66a6341d5f --- /dev/null +++ b/spec/data/cookbooks/audit/recipes/default.rb @@ -0,0 +1,3 @@ +# Inside a recipe self refers to a Recipe object, so it calls the correct #method_missing chain to find the +# package resource +package "foo1" diff --git a/spec/data/cookbooks/audit/recipes/defined_outside_block.rb b/spec/data/cookbooks/audit/recipes/defined_outside_block.rb new file mode 100644 index 0000000000..2f4245c8ee --- /dev/null +++ b/spec/data/cookbooks/audit/recipes/defined_outside_block.rb @@ -0,0 +1,6 @@ +controls "some more controls" do + control "foo5" +end + +# Even after seeing a `controls` block `control` should not work outside the block - even when running in rspec +control("foo4") diff --git a/spec/data/cookbooks/audit/recipes/multiple_controls.rb b/spec/data/cookbooks/audit/recipes/multiple_controls.rb new file mode 100644 index 0000000000..14538d9f65 --- /dev/null +++ b/spec/data/cookbooks/audit/recipes/multiple_controls.rb @@ -0,0 +1,11 @@ +controls "some controls" do + package "foo3" +end + +package "bar" + +controls "some more controls" do + package "baz" +end + +package "bang" diff --git a/spec/data/cookbooks/audit/recipes/serverspec_helpers.rb b/spec/data/cookbooks/audit/recipes/serverspec_helpers.rb new file mode 100644 index 0000000000..329a8545d1 --- /dev/null +++ b/spec/data/cookbooks/audit/recipes/serverspec_helpers.rb @@ -0,0 +1,9 @@ +# Serverspec helper `cgroup` should only be defined in controls block, not Chef::Recipe + +controls "cgroup controls" do + describe cgroup('group1') do + true + end +end + +cgroup('group1') diff --git a/spec/data/cookbooks/audit/recipes/single_controls.rb b/spec/data/cookbooks/audit/recipes/single_controls.rb new file mode 100644 index 0000000000..5bd8600326 --- /dev/null +++ b/spec/data/cookbooks/audit/recipes/single_controls.rb @@ -0,0 +1,5 @@ +# Inside a `controls` block, self refers to a subclass of RSpec::ExampleGroups so `package` calls the correct +# serverspec helper +controls "some controls" do + package "foo2" +end diff --git a/spec/unit/audit/duplication.rb b/spec/unit/audit/duplication.rb index aff5cb500a..e3ffd5bc29 100644 --- a/spec/unit/audit/duplication.rb +++ b/spec/unit/audit/duplication.rb @@ -21,13 +21,31 @@ require 'chef/recipe' describe "Duplicated `package` DSL in Chef and Serverspec" do - # TODO disable rspec global DSL - but do we want it enabled for OUR rspecs? No, because we always have a runner? - # TODO disable serverspec global DSL + # TODO (?) disable rspec global DSL - but do we want it enabled for OUR rspecs? No, because we always have a runner? + # TODO (?) disable serverspec global DSL - let(:run_context) { - node = Chef::Node.new - Chef::RunContext.new(node, {}, nil) - } + let(:cookbook_repo) { File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "data", "cookbooks")) } + let(:audit_recipes) { File.join(cookbook_repo, "audit", "recipes") } + + let(:cookbook_loader) do + loader = Chef::CookbookLoader.new(cookbook_repo) + loader.load_cookbooks + loader + end + + let(:cookbook_collection) { Chef::CookbookCollection.new(cookbook_loader) } + + let(:node) do + Chef::Node.new.tap {|n| n.normal[:tags] = [] } + end + + let(:events) do + Chef::EventDispatch::Dispatcher.new + end + + let(:run_context) do + Chef::RunContext.new(node, cookbook_collection, events) + end it "Should call the Chef Recipe DSL in a Chef Recipe" do # Chef::DSL::Recipe#method_missing calls #resource_for_node twice when looking up the Resource instance - once in @@ -36,11 +54,7 @@ describe "Duplicated `package` DSL in Chef and Serverspec" do expect(Chef::Resource).to receive(:resource_for_node).with(:package, instance_of(Chef::Node)).exactly(2).times.and_return(Chef::Resource::Package) expect(Chef::Resource::Package).to receive(:new).with("foo1", run_context).and_call_original - Chef::Recipe.new("cookbook", "recipe", run_context).instance_eval do - # Inside a recipe self refers to a Recipe object, so it calls the correct #method_missing chain to find the - # package resource - package "foo1" - end + Chef::Recipe.new("audit", "default", run_context).from_file(File.join(audit_recipes, "default.rb")) end it "Should call the Serverspec DSL in a `controls` block" do @@ -49,13 +63,7 @@ describe "Duplicated `package` DSL in Chef and Serverspec" do # and configuration takes place in the `controls` method require 'serverspec' - Chef::Recipe.new("cookbook", "recipe", run_context).instance_eval do - # Inside a `controls` block, self refers to a subclass of RSpec::ExampleGroups so `package` calls the correct - # serverspec helper - controls "some controls" do - package "foo2" - end - end + Chef::Recipe.new("audit", "single_controls", run_context).from_file(File.join(audit_recipes, "single_controls.rb")) end it "Should still use the recipe DSL outside of a controls block after a controls block has ran" do @@ -65,57 +73,23 @@ describe "Duplicated `package` DSL in Chef and Serverspec" do expect(Chef::Resource::Package).to receive(:new).with("bar", run_context).and_call_original expect(Chef::Resource::Package).to receive(:new).with("bang", run_context).and_call_original - Chef::Recipe.new("cookbook", "recipe", run_context).instance_eval do - controls "some controls" do - package "foo3" - end - - package "bar" - - controls "some more controls" do - package "baz" - end - - package "bang" - end + Chef::Recipe.new("audit", "multiple_controls", run_context).from_file(File.join(audit_recipes, "multiple_controls.rb")) end it "Should not allow `control` or `__controls__` to be defined outside of a `controls` block" do - expect { - Chef::Recipe.new("cookbook", "recipe", run_context).instance_eval do - control("foo4") - end - }.to raise_error(NoMethodError, /No resource or method named `control'/) - - Chef::Recipe.new("cookbook", "recipe", run_context).instance_eval do - controls "some more controls" do - control "foo5" - end - end + expect_any_instance_of(Chef::Recipe).to receive(:controls).with("some more controls").and_call_original + expect_any_instance_of(Chef::Recipe).to receive(:control).with("foo4").and_call_original - # Even after seeing a `controls` block these methods should not work - even when running in rspec expect { - Chef::Recipe.new("cookbook", "recipe", run_context).instance_eval do - control("foo4") - end + Chef::Recipe.new("audit", "defined_outside_block", run_context).from_file(File.join(audit_recipes, "defined_outside_block.rb")) }.to raise_error(NoMethodError, /No resource or method named `control'/) end it "Should include serverspec specific matchers only inside `controls` block" do # cgroup is a rspec matcher I'm assuming we won't define elsewhere - # TODO this is currently failing because the RSpec::Core::ExampleGroup has already been extended with - # the serverspec helpers - expect { cgroup('group1') }.to raise_error(NoMethodError, /No resource or method named `cgroup'/) - - expect(self).to receive(:cgroup).and_call_original - controls "cgroup controls" do - describe cgroup('group1') do - true - end - end - - expect { cgroup('group1') }.to raise_error(NoMethodError, /No resource or method named `cgroup'/) + expect(Serverspec::Type::Cgroup).to receive(:new).with("group1").and_call_original + expect { + Chef::Recipe.new("audit", "serverspec_helpers", run_context).from_file(File.join(audit_recipes, "serverspec_helpers.rb")) + }.to raise_error(NoMethodError, /No resource or method named `cgroup' for `Chef::Recipe/) end - - # TODO write cookbook which actually tests both `package` DSLs end -- cgit v1.2.1 From 42fce097acdb599892001b611fe96d8ece3f884f Mon Sep 17 00:00:00 2001 From: tyler-ball Date: Thu, 20 Nov 2014 13:49:13 -0800 Subject: Oops - this was causing output to be an array instead of a string --- lib/chef/dsl/audit.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/chef/dsl/audit.rb b/lib/chef/dsl/audit.rb index 78a747aa1f..54e0d34ba1 100644 --- a/lib/chef/dsl/audit.rb +++ b/lib/chef/dsl/audit.rb @@ -30,7 +30,7 @@ class Chef name = args[0] raise AuditNameMissing if name.nil? || name.empty? - run_context.controls_groups << Chef::Audit::Controls.new(run_context, args, &block) + run_context.controls_groups << Chef::Audit::Controls.new(run_context, *args, &block) end end -- cgit v1.2.1 From c0ad2ed4b990528b507a409abf8c5378a9998461 Mon Sep 17 00:00:00 2001 From: tyler-ball Date: Fri, 21 Nov 2014 13:38:10 -0800 Subject: cleaning up bad rebase merge --- lib/chef/dsl/audit.rb | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/chef/dsl/audit.rb b/lib/chef/dsl/audit.rb index 54e0d34ba1..e22c38f587 100644 --- a/lib/chef/dsl/audit.rb +++ b/lib/chef/dsl/audit.rb @@ -17,7 +17,6 @@ # require 'chef/exceptions' -require 'chef/audit/controls' class Chef module DSL @@ -26,11 +25,16 @@ class Chef # Can encompass tests in a `control` block or `describe` block # Adds the controls group and block (containing controls to execute) to the runner's list of pending examples def controls(*args, &block) - raise ::Chef::Exceptions::NoAuditsProvided unless block + raise Chef::Exceptions::NoAuditsProvided unless block + name = args[0] - raise AuditNameMissing if name.nil? || name.empty? + if name.nil? || name.empty? + raise Chef::Exceptions::AuditNameMissing + elsif run_context.controls.has_key?(name) + raise Chef::Exceptions::AuditControlGroupDuplicate.new(name) + end - run_context.controls_groups << Chef::Audit::Controls.new(run_context, *args, &block) + run_context.controls[name] = { :args => args, :block => block } end end -- cgit v1.2.1 From cab251da780504bdff85e53f47f4974befa6b791 Mon Sep 17 00:00:00 2001 From: tyler-ball Date: Fri, 21 Nov 2014 13:40:47 -0800 Subject: this spec file should have the correct name type --- spec/unit/audit/duplication.rb | 95 ------------------------------------- spec/unit/audit/duplication_spec.rb | 95 +++++++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+), 95 deletions(-) delete mode 100644 spec/unit/audit/duplication.rb create mode 100644 spec/unit/audit/duplication_spec.rb diff --git a/spec/unit/audit/duplication.rb b/spec/unit/audit/duplication.rb deleted file mode 100644 index e3ffd5bc29..0000000000 --- a/spec/unit/audit/duplication.rb +++ /dev/null @@ -1,95 +0,0 @@ -# -# Author:: Tyler Ball () -# Copyright:: Copyright (c) 2014 Chef, Inc. -# License:: Apache License, Version 2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -require 'spec_helper' -require 'chef/recipe' - -describe "Duplicated `package` DSL in Chef and Serverspec" do - - # TODO (?) disable rspec global DSL - but do we want it enabled for OUR rspecs? No, because we always have a runner? - # TODO (?) disable serverspec global DSL - - let(:cookbook_repo) { File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "data", "cookbooks")) } - let(:audit_recipes) { File.join(cookbook_repo, "audit", "recipes") } - - let(:cookbook_loader) do - loader = Chef::CookbookLoader.new(cookbook_repo) - loader.load_cookbooks - loader - end - - let(:cookbook_collection) { Chef::CookbookCollection.new(cookbook_loader) } - - let(:node) do - Chef::Node.new.tap {|n| n.normal[:tags] = [] } - end - - let(:events) do - Chef::EventDispatch::Dispatcher.new - end - - let(:run_context) do - Chef::RunContext.new(node, cookbook_collection, events) - end - - it "Should call the Chef Recipe DSL in a Chef Recipe" do - # Chef::DSL::Recipe#method_missing calls #resource_for_node twice when looking up the Resource instance - once in - # #have_resource_class_for? and once in #declare_resource. Chef::DSL::Recipe#resource_class_for calls - # Chef::Resource#resource_for_node - expect(Chef::Resource).to receive(:resource_for_node).with(:package, instance_of(Chef::Node)).exactly(2).times.and_return(Chef::Resource::Package) - expect(Chef::Resource::Package).to receive(:new).with("foo1", run_context).and_call_original - - Chef::Recipe.new("audit", "default", run_context).from_file(File.join(audit_recipes, "default.rb")) - end - - it "Should call the Serverspec DSL in a `controls` block" do - expect(Chef::Resource).to_not receive(:resource_for_node) - # Waiting until here to require this because otherwise it complains that it hasn't been configured yet - # and configuration takes place in the `controls` method - require 'serverspec' - - Chef::Recipe.new("audit", "single_controls", run_context).from_file(File.join(audit_recipes, "single_controls.rb")) - end - - it "Should still use the recipe DSL outside of a controls block after a controls block has ran" do - expect(Serverspec::Type::Package).to receive(:new).with("foo3") - expect(Serverspec::Type::Package).to receive(:new).with("baz") - expect(Chef::Resource).to receive(:resource_for_node).with(:package, instance_of(Chef::Node)).exactly(4).times.and_return(Chef::Resource::Package) - expect(Chef::Resource::Package).to receive(:new).with("bar", run_context).and_call_original - expect(Chef::Resource::Package).to receive(:new).with("bang", run_context).and_call_original - - Chef::Recipe.new("audit", "multiple_controls", run_context).from_file(File.join(audit_recipes, "multiple_controls.rb")) - end - - it "Should not allow `control` or `__controls__` to be defined outside of a `controls` block" do - expect_any_instance_of(Chef::Recipe).to receive(:controls).with("some more controls").and_call_original - expect_any_instance_of(Chef::Recipe).to receive(:control).with("foo4").and_call_original - - expect { - Chef::Recipe.new("audit", "defined_outside_block", run_context).from_file(File.join(audit_recipes, "defined_outside_block.rb")) - }.to raise_error(NoMethodError, /No resource or method named `control'/) - end - - it "Should include serverspec specific matchers only inside `controls` block" do - # cgroup is a rspec matcher I'm assuming we won't define elsewhere - expect(Serverspec::Type::Cgroup).to receive(:new).with("group1").and_call_original - expect { - Chef::Recipe.new("audit", "serverspec_helpers", run_context).from_file(File.join(audit_recipes, "serverspec_helpers.rb")) - }.to raise_error(NoMethodError, /No resource or method named `cgroup' for `Chef::Recipe/) - end -end diff --git a/spec/unit/audit/duplication_spec.rb b/spec/unit/audit/duplication_spec.rb new file mode 100644 index 0000000000..e3ffd5bc29 --- /dev/null +++ b/spec/unit/audit/duplication_spec.rb @@ -0,0 +1,95 @@ +# +# Author:: Tyler Ball () +# Copyright:: Copyright (c) 2014 Chef, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require 'spec_helper' +require 'chef/recipe' + +describe "Duplicated `package` DSL in Chef and Serverspec" do + + # TODO (?) disable rspec global DSL - but do we want it enabled for OUR rspecs? No, because we always have a runner? + # TODO (?) disable serverspec global DSL + + let(:cookbook_repo) { File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "data", "cookbooks")) } + let(:audit_recipes) { File.join(cookbook_repo, "audit", "recipes") } + + let(:cookbook_loader) do + loader = Chef::CookbookLoader.new(cookbook_repo) + loader.load_cookbooks + loader + end + + let(:cookbook_collection) { Chef::CookbookCollection.new(cookbook_loader) } + + let(:node) do + Chef::Node.new.tap {|n| n.normal[:tags] = [] } + end + + let(:events) do + Chef::EventDispatch::Dispatcher.new + end + + let(:run_context) do + Chef::RunContext.new(node, cookbook_collection, events) + end + + it "Should call the Chef Recipe DSL in a Chef Recipe" do + # Chef::DSL::Recipe#method_missing calls #resource_for_node twice when looking up the Resource instance - once in + # #have_resource_class_for? and once in #declare_resource. Chef::DSL::Recipe#resource_class_for calls + # Chef::Resource#resource_for_node + expect(Chef::Resource).to receive(:resource_for_node).with(:package, instance_of(Chef::Node)).exactly(2).times.and_return(Chef::Resource::Package) + expect(Chef::Resource::Package).to receive(:new).with("foo1", run_context).and_call_original + + Chef::Recipe.new("audit", "default", run_context).from_file(File.join(audit_recipes, "default.rb")) + end + + it "Should call the Serverspec DSL in a `controls` block" do + expect(Chef::Resource).to_not receive(:resource_for_node) + # Waiting until here to require this because otherwise it complains that it hasn't been configured yet + # and configuration takes place in the `controls` method + require 'serverspec' + + Chef::Recipe.new("audit", "single_controls", run_context).from_file(File.join(audit_recipes, "single_controls.rb")) + end + + it "Should still use the recipe DSL outside of a controls block after a controls block has ran" do + expect(Serverspec::Type::Package).to receive(:new).with("foo3") + expect(Serverspec::Type::Package).to receive(:new).with("baz") + expect(Chef::Resource).to receive(:resource_for_node).with(:package, instance_of(Chef::Node)).exactly(4).times.and_return(Chef::Resource::Package) + expect(Chef::Resource::Package).to receive(:new).with("bar", run_context).and_call_original + expect(Chef::Resource::Package).to receive(:new).with("bang", run_context).and_call_original + + Chef::Recipe.new("audit", "multiple_controls", run_context).from_file(File.join(audit_recipes, "multiple_controls.rb")) + end + + it "Should not allow `control` or `__controls__` to be defined outside of a `controls` block" do + expect_any_instance_of(Chef::Recipe).to receive(:controls).with("some more controls").and_call_original + expect_any_instance_of(Chef::Recipe).to receive(:control).with("foo4").and_call_original + + expect { + Chef::Recipe.new("audit", "defined_outside_block", run_context).from_file(File.join(audit_recipes, "defined_outside_block.rb")) + }.to raise_error(NoMethodError, /No resource or method named `control'/) + end + + it "Should include serverspec specific matchers only inside `controls` block" do + # cgroup is a rspec matcher I'm assuming we won't define elsewhere + expect(Serverspec::Type::Cgroup).to receive(:new).with("group1").and_call_original + expect { + Chef::Recipe.new("audit", "serverspec_helpers", run_context).from_file(File.join(audit_recipes, "serverspec_helpers.rb")) + }.to raise_error(NoMethodError, /No resource or method named `cgroup' for `Chef::Recipe/) + end +end -- cgit v1.2.1 From edbf71e853762915901526215dd0e11c47fe6882 Mon Sep 17 00:00:00 2001 From: tyler-ball Date: Fri, 21 Nov 2014 14:29:45 -0800 Subject: Fixing failing tests after claire's refactor - controls block not evaluated until runner is ran --- spec/data/cookbooks/audit/recipes/serverspec_helpers.rb | 2 +- spec/unit/audit/duplication_spec.rb | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/spec/data/cookbooks/audit/recipes/serverspec_helpers.rb b/spec/data/cookbooks/audit/recipes/serverspec_helpers.rb index 329a8545d1..c82411eb9d 100644 --- a/spec/data/cookbooks/audit/recipes/serverspec_helpers.rb +++ b/spec/data/cookbooks/audit/recipes/serverspec_helpers.rb @@ -6,4 +6,4 @@ controls "cgroup controls" do end end -cgroup('group1') +cgroup('group2') diff --git a/spec/unit/audit/duplication_spec.rb b/spec/unit/audit/duplication_spec.rb index e3ffd5bc29..78027a6bf7 100644 --- a/spec/unit/audit/duplication_spec.rb +++ b/spec/unit/audit/duplication_spec.rb @@ -18,6 +18,7 @@ require 'spec_helper' require 'chef/recipe' +require 'chef/audit/runner' describe "Duplicated `package` DSL in Chef and Serverspec" do @@ -47,6 +48,13 @@ describe "Duplicated `package` DSL in Chef and Serverspec" do Chef::RunContext.new(node, cookbook_collection, events) end + let(:auditor) do + auditor = Chef::Audit::Runner.new(run_context) + allow(auditor).to receive(:configure_rspec).and_return(true) + allow(auditor).to receive(:do_run).and_return(true) + auditor + end + it "Should call the Chef Recipe DSL in a Chef Recipe" do # Chef::DSL::Recipe#method_missing calls #resource_for_node twice when looking up the Resource instance - once in # #have_resource_class_for? and once in #declare_resource. Chef::DSL::Recipe#resource_class_for calls @@ -74,6 +82,9 @@ describe "Duplicated `package` DSL in Chef and Serverspec" do expect(Chef::Resource::Package).to receive(:new).with("bang", run_context).and_call_original Chef::Recipe.new("audit", "multiple_controls", run_context).from_file(File.join(audit_recipes, "multiple_controls.rb")) + # Have to run the auditor because we have logic inside a `controls` block to test - that doesn't get evaluated + # until the auditor is ran + auditor.run end it "Should not allow `control` or `__controls__` to be defined outside of a `controls` block" do @@ -91,5 +102,6 @@ describe "Duplicated `package` DSL in Chef and Serverspec" do expect { Chef::Recipe.new("audit", "serverspec_helpers", run_context).from_file(File.join(audit_recipes, "serverspec_helpers.rb")) }.to raise_error(NoMethodError, /No resource or method named `cgroup' for `Chef::Recipe/) + auditor.run end end -- cgit v1.2.1