summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortyler-ball <tyleraball@gmail.com>2014-11-17 13:24:54 -0800
committertyler-ball <tyleraball@gmail.com>2014-11-17 13:24:54 -0800
commit646b976732720c7e12ef98a0876e241142c23e47 (patch)
tree1be0cef509e3eaa27e4da424783cf6639ef6e7db
parentf1a188f6e3855d4ba0a31b64d447324661037d26 (diff)
downloadchef-646b976732720c7e12ef98a0876e241142c23e47.tar.gz
Finishing duplication tests
-rw-r--r--lib/chef/audit.rb1
-rw-r--r--lib/chef/audit/audit_event_proxy.rb1
-rw-r--r--lib/chef/dsl/audit.rb1
-rw-r--r--spec/unit/audit/duplication.rb89
4 files changed, 79 insertions, 13 deletions
diff --git a/lib/chef/audit.rb b/lib/chef/audit.rb
index 1c28e7ea75..d6084b52ea 100644
--- a/lib/chef/audit.rb
+++ b/lib/chef/audit.rb
@@ -16,6 +16,5 @@
# limitations under the License.
#
-require 'chef/dsl/audit'
require 'chef/audit/controls'
require 'chef/audit/runner'
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 520a667cd4..841d141ccb 100644
--- a/lib/chef/dsl/audit.rb
+++ b/lib/chef/dsl/audit.rb
@@ -17,6 +17,7 @@
#
require 'rspec/core'
+require 'chef/audit/controls'
class Chef
module DSL
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