spec/unit/runner_spec.rb in chef-10.34.6 vs spec/unit/runner_spec.rb in chef-11.0.0.beta.0
- old
+ new
@@ -50,17 +50,44 @@
self.class.action_called(:third)
end
end
+class FailureResource < Chef::Resource
+
+ attr_accessor :action
+
+ def initialize(*args)
+ super
+ @action = :fail
+ end
+
+ def provider
+ FailureProvider
+ end
+end
+
+class FailureProvider < Chef::Provider
+
+ class ChefClientFail < StandardError; end
+
+ def load_current_resource
+ true
+ end
+
+ def action_fail
+ raise ChefClientFail, "chef had an error of some sort"
+ end
+end
+
describe Chef::Runner do
before(:each) do
@node = Chef::Node.new
@node.name "latte"
- @node.platform "mac_os_x"
- @node.platform_version "10.5.1"
+ @node.automatic[:platform] = "mac_os_x"
+ @node.automatic[:platform_version] = "10.5.1"
@events = Chef::EventDispatch::Dispatcher.new
@run_context = Chef::RunContext.new(@node, Chef::CookbookCollection.new({}), @events)
@first_resource = Chef::Resource::Cat.new("loulou1", @run_context)
@run_context.resource_collection << @first_resource
Chef::Platform.set(
@@ -161,9 +188,81 @@
@run_context.resource_collection << second_resource
second_resource.notifies(:purr, @first_resource, :delayed)
@runner.converge
+
+ @first_resource.should be_updated
+ end
+
+ it "should execute delayed notifications when a failure occurs in the chef client run" do
+ @first_resource.action = :nothing
+ second_resource = Chef::Resource::Cat.new("peanut", @run_context)
+ second_resource.action = :purr
+
+ @run_context.resource_collection << second_resource
+ second_resource.notifies(:purr, @first_resource, :delayed)
+
+ third_resource = FailureResource.new("explode", @run_context)
+ @run_context.resource_collection << third_resource
+
+ lambda {@runner.converge}.should raise_error(FailureProvider::ChefClientFail)
+
+ @first_resource.should be_updated
+ end
+
+ it "should execute delayed notifications when a failure occurs in a notification" do
+ @first_resource.action = :nothing
+ second_resource = Chef::Resource::Cat.new("peanut", @run_context)
+ second_resource.action = :purr
+
+ @run_context.resource_collection << second_resource
+
+ third_resource = FailureResource.new("explode", @run_context)
+ third_resource.action = :nothing
+ @run_context.resource_collection << third_resource
+
+ second_resource.notifies(:fail, third_resource, :delayed)
+ second_resource.notifies(:purr, @first_resource, :delayed)
+
+ lambda {@runner.converge}.should raise_error(FailureProvider::ChefClientFail)
+
+ @first_resource.should be_updated
+ end
+
+ it "should execute delayed notifications when a failure occurs in multiple notifications" do
+ @first_resource.action = :nothing
+ second_resource = Chef::Resource::Cat.new("peanut", @run_context)
+ second_resource.action = :purr
+
+ @run_context.resource_collection << second_resource
+
+ third_resource = FailureResource.new("explode", @run_context)
+ third_resource.action = :nothing
+ @run_context.resource_collection << third_resource
+
+ fourth_resource = FailureResource.new("explode again", @run_context)
+ fourth_resource.action = :nothing
+ @run_context.resource_collection << fourth_resource
+
+ second_resource.notifies(:fail, third_resource, :delayed)
+ second_resource.notifies(:fail, fourth_resource, :delayed)
+ second_resource.notifies(:purr, @first_resource, :delayed)
+
+ exception = nil
+ begin
+ @runner.converge
+ rescue => e
+ exception = e
+ end
+ exception.should be_a(Chef::Exceptions::MultipleFailures)
+
+ expected_message =<<-E
+Multiple failures occurred:
+* FailureProvider::ChefClientFail occurred in delayed notification: [explode] (dynamically defined) had an error: FailureProvider::ChefClientFail: chef had an error of some sort
+* FailureProvider::ChefClientFail occurred in delayed notification: [explode again] (dynamically defined) had an error: FailureProvider::ChefClientFail: chef had an error of some sort
+E
+ exception.message.should == expected_message
@first_resource.should be_updated
end
it "does not duplicate delayed notifications" do