From 6f955972033c5117ef83010977a2aa1ff023e691 Mon Sep 17 00:00:00 2001 From: tyler-ball Date: Mon, 5 Jan 2015 14:54:44 -0800 Subject: Fixing #2694 - resource guards are executed in why_run mode --- .../resource_guard_interpreter.rb | 1 + lib/chef/mixin/why_run.rb | 2 +- lib/chef/resource/execute.rb | 7 ++++++ spec/functional/resource/execute_spec.rb | 26 ++++++++++++++++++++++ spec/unit/resource/execute_spec.rb | 4 ++++ 5 files changed, 39 insertions(+), 1 deletion(-) diff --git a/lib/chef/guard_interpreter/resource_guard_interpreter.rb b/lib/chef/guard_interpreter/resource_guard_interpreter.rb index 346b585d8c..7d9bccb6ca 100644 --- a/lib/chef/guard_interpreter/resource_guard_interpreter.rb +++ b/lib/chef/guard_interpreter/resource_guard_interpreter.rb @@ -95,6 +95,7 @@ class Chef empty_events = Chef::EventDispatch::Dispatcher.new anonymous_run_context = Chef::RunContext.new(parent_resource.node, {}, empty_events) interpreter_resource = resource_class.new('Guard resource', anonymous_run_context) + interpreter_resource.is_guard_interpreter = true interpreter_resource end diff --git a/lib/chef/mixin/why_run.rb b/lib/chef/mixin/why_run.rb index d650e3332f..d3acea5490 100644 --- a/lib/chef/mixin/why_run.rb +++ b/lib/chef/mixin/why_run.rb @@ -48,7 +48,7 @@ class Chef # block/proc that implements the action. def add_action(descriptions, &block) @actions << [descriptions, block] - if !Chef::Config[:why_run] + if (@resource.respond_to?(:is_guard_interpreter) && @resource.is_guard_interpreter) || !Chef::Config[:why_run] block.call end events.resource_update_applied(@resource, @action, descriptions) diff --git a/lib/chef/resource/execute.rb b/lib/chef/resource/execute.rb index 6853b62887..9f8b629fb8 100644 --- a/lib/chef/resource/execute.rb +++ b/lib/chef/resource/execute.rb @@ -26,6 +26,12 @@ class Chef identity_attr :command + # The ResourceGuardInterpreter wraps a resource's guards in another resource. That inner resource + # needs to behave differently during (for example) why_run mode, so we flag it here. For why_run mode + # we still want to execute the guard resource even if we are not executing the wrapping resource. + # Only execute resources (and subclasses) can be guard interpreters. + attr_accessor :is_guard_interpreter + def initialize(name, run_context=nil) super @resource_name = :execute @@ -43,6 +49,7 @@ class Chef @allowed_actions.push(:run) @umask = nil @default_guard_interpreter = :execute + @is_guard_interpreter = false end def umask(arg=nil) diff --git a/spec/functional/resource/execute_spec.rb b/spec/functional/resource/execute_spec.rb index cebcc52fcf..2483472374 100644 --- a/spec/functional/resource/execute_spec.rb +++ b/spec/functional/resource/execute_spec.rb @@ -34,6 +34,32 @@ describe Chef::Resource::Execute do end end + describe "when why_run is enabled" do + before do + Chef::Config[:why_run] = true + end + + let(:guard) { "ruby -e 'exit 0'" } + let!(:guard_resource) { + interpreter = Chef::GuardInterpreter::ResourceGuardInterpreter.new(resource, guard, nil) + interpreter.send(:get_interpreter_resource, resource) + } + + it "executes the guard and not the regular resource" do + expect_any_instance_of(Chef::GuardInterpreter::ResourceGuardInterpreter).to receive(:get_interpreter_resource).and_return(guard_resource) + + # why_run mode doesn't disable the updated_by_last_action logic, so we really have to look at the provider action + # to see if why_run correctly disabled the resource. It should shell_out! for the guard but not the resource. + expect_any_instance_of(Chef::Provider::Execute).to receive(:shell_out!).once + + resource.only_if guard + resource.run_action(:run) + + expect(resource).to be_updated_by_last_action + expect(guard_resource).to be_updated_by_last_action + end + end + describe "when parent resource sets :cwd" do let(:guard) { %{ruby -e 'exit 1 unless File.exists?("./big_json_plus_one.json")'} } diff --git a/spec/unit/resource/execute_spec.rb b/spec/unit/resource/execute_spec.rb index 70b9d87d4c..09160ddbd0 100644 --- a/spec/unit/resource/execute_spec.rb +++ b/spec/unit/resource/execute_spec.rb @@ -28,4 +28,8 @@ describe Chef::Resource::Execute do expect(execute_resource.guard_interpreter).to be(:execute) end + it "defaults to not being a guard interpreter" do + expect(execute_resource.is_guard_interpreter).to eq(false) + end + end -- cgit v1.2.1