diff options
-rw-r--r-- | .expeditor/release.omnibus.yml | 4 | ||||
-rw-r--r-- | CHANGELOG.md | 9 | ||||
-rw-r--r-- | Gemfile.lock | 22 | ||||
-rw-r--r-- | VERSION | 2 | ||||
-rw-r--r-- | chef-bin/lib/chef-bin/version.rb | 2 | ||||
-rw-r--r-- | chef-config/lib/chef-config/version.rb | 2 | ||||
-rw-r--r-- | chef-utils/lib/chef-utils/version.rb | 2 | ||||
-rw-r--r-- | lib/chef/action_collection.rb | 23 | ||||
-rw-r--r-- | lib/chef/data_collector/run_end_message.rb | 10 | ||||
-rw-r--r-- | lib/chef/event_dispatch/base.rb | 3 | ||||
-rw-r--r-- | lib/chef/provider.rb | 12 | ||||
-rw-r--r-- | lib/chef/resource/action_class.rb | 46 | ||||
-rw-r--r-- | lib/chef/resource/chef_vault_secret.rb | 2 | ||||
-rw-r--r-- | lib/chef/version.rb | 2 | ||||
-rw-r--r-- | spec/integration/recipes/resource_load_spec.rb | 141 | ||||
-rw-r--r-- | spec/unit/data_collector_spec.rb | 57 | ||||
-rw-r--r-- | spec/unit/resource/chocolatey_source_spec.rb | 5 |
17 files changed, 264 insertions, 80 deletions
diff --git a/.expeditor/release.omnibus.yml b/.expeditor/release.omnibus.yml index 470a5c0f63..1b744416fc 100644 --- a/.expeditor/release.omnibus.yml +++ b/.expeditor/release.omnibus.yml @@ -42,10 +42,12 @@ builder-to-testers-map: # - solaris2-5.11-i386 # solaris2-5.11-sparc: # - solaris2-5.11-sparc + ubuntu-18.04-aarch64: + - ubuntu-18.04-aarch64 ubuntu-16.04-x86_64: - ubuntu-16.04-x86_64 - ubuntu-18.04-x86_64 -# - ubuntu-20.04-x86_64 # waiting on AMI update + - ubuntu-20.04-x86_64 windows-2012r2-i386: - windows-2012r2-i386 windows-2012r2-x86_64: diff --git a/CHANGELOG.md b/CHANGELOG.md index 0abe8f1062..efc57a4188 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,15 +1,18 @@ <!-- usage documentation: http://expeditor-docs.es.chef.io/configuration/changelog/ --> -<!-- latest_release 16.0.176 --> -## [v16.0.176](https://github.com/chef/chef/tree/v16.0.176) (2020-04-02) +<!-- latest_release 16.0.179 --> +## [v16.0.179](https://github.com/chef/chef/tree/v16.0.179) (2020-04-02) #### Merged Pull Requests -- Convert more resources to unified_mode [#9570](https://github.com/chef/chef/pull/9570) ([lamont-granquist](https://github.com/lamont-granquist)) +- Add Ubuntu 20.04 x86_64 and Ubuntu 18.04 aarch64 testers [#9584](https://github.com/chef/chef/pull/9584) ([tas50](https://github.com/tas50)) <!-- latest_release --> <!-- release_rollup since=15.6.10 --> ### Changes not yet released to stable #### Merged Pull Requests +- Add Ubuntu 20.04 x86_64 and Ubuntu 18.04 aarch64 testers [#9584](https://github.com/chef/chef/pull/9584) ([tas50](https://github.com/tas50)) <!-- 16.0.179 --> +- fix chef_vault_secret after_resource breakage [#9574](https://github.com/chef/chef/pull/9574) ([lamont-granquist](https://github.com/lamont-granquist)) <!-- 16.0.178 --> +- Add after_resource to pair with current_resource [#9562](https://github.com/chef/chef/pull/9562) ([lamont-granquist](https://github.com/lamont-granquist)) <!-- 16.0.177 --> - Convert more resources to unified_mode [#9570](https://github.com/chef/chef/pull/9570) ([lamont-granquist](https://github.com/lamont-granquist)) <!-- 16.0.176 --> - Update Nokogiri to 1.11.0.rc2 [#9572](https://github.com/chef/chef/pull/9572) ([tas50](https://github.com/tas50)) <!-- 16.0.175 --> - Update Ruby to 2.7.1 / bundler to 2.1.4 [#9569](https://github.com/chef/chef/pull/9569) ([tas50](https://github.com/tas50)) <!-- 16.0.174 --> diff --git a/Gemfile.lock b/Gemfile.lock index aeb3c2d283..50f585a214 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -27,12 +27,12 @@ GIT PATH remote: . specs: - chef (16.0.176) + chef (16.0.179) addressable bcrypt_pbkdf (~> 1.0) bundler (>= 1.10) - chef-config (= 16.0.176) - chef-utils (= 16.0.176) + chef-config (= 16.0.179) + chef-utils (= 16.0.179) chef-vault chef-zero (>= 14.0.11) diff-lcs (~> 1.2, >= 1.2.4) @@ -61,12 +61,12 @@ PATH train-winrm (>= 0.2.5) tty-screen (~> 0.6) uuidtools (~> 2.1.5) - chef (16.0.176-universal-mingw32) + chef (16.0.179-universal-mingw32) addressable bcrypt_pbkdf (~> 1.0) bundler (>= 1.10) - chef-config (= 16.0.176) - chef-utils (= 16.0.176) + chef-config (= 16.0.179) + chef-utils (= 16.0.179) chef-vault chef-zero (>= 14.0.11) diff-lcs (~> 1.2, >= 1.2.4) @@ -111,15 +111,15 @@ PATH PATH remote: chef-bin specs: - chef-bin (16.0.176) - chef (= 16.0.176) + chef-bin (16.0.179) + chef (= 16.0.179) PATH remote: chef-config specs: - chef-config (16.0.176) + chef-config (16.0.179) addressable - chef-utils (= 16.0.176) + chef-utils (= 16.0.179) fuzzyurl mixlib-config (>= 2.2.12, < 4.0) mixlib-shellout (>= 2.0, < 4.0) @@ -128,7 +128,7 @@ PATH PATH remote: chef-utils specs: - chef-utils (16.0.176) + chef-utils (16.0.179) GEM remote: https://rubygems.org/ @@ -1 +1 @@ -16.0.176
\ No newline at end of file +16.0.179
\ No newline at end of file diff --git a/chef-bin/lib/chef-bin/version.rb b/chef-bin/lib/chef-bin/version.rb index e4f10648b4..fd7d6c122e 100644 --- a/chef-bin/lib/chef-bin/version.rb +++ b/chef-bin/lib/chef-bin/version.rb @@ -21,7 +21,7 @@ module ChefBin CHEFBIN_ROOT = File.expand_path("../..", __FILE__) - VERSION = "16.0.176".freeze + VERSION = "16.0.179".freeze end # diff --git a/chef-config/lib/chef-config/version.rb b/chef-config/lib/chef-config/version.rb index f5de419f33..c761c8c135 100644 --- a/chef-config/lib/chef-config/version.rb +++ b/chef-config/lib/chef-config/version.rb @@ -15,5 +15,5 @@ module ChefConfig CHEFCONFIG_ROOT = File.expand_path("../..", __FILE__) - VERSION = "16.0.176".freeze + VERSION = "16.0.179".freeze end diff --git a/chef-utils/lib/chef-utils/version.rb b/chef-utils/lib/chef-utils/version.rb index 585631535e..3180cf1f3c 100644 --- a/chef-utils/lib/chef-utils/version.rb +++ b/chef-utils/lib/chef-utils/version.rb @@ -15,5 +15,5 @@ module ChefUtils CHEFUTILS_ROOT = File.expand_path("../..", __FILE__) - VERSION = "16.0.176".freeze + VERSION = "16.0.179".freeze end diff --git a/lib/chef/action_collection.rb b/lib/chef/action_collection.rb index 7b1997cfaf..eb0d3bef58 100644 --- a/lib/chef/action_collection.rb +++ b/lib/chef/action_collection.rb @@ -1,5 +1,5 @@ # -# Copyright:: Copyright 2018-2019, Chef Software Inc. +# Copyright:: Copyright 2018-2020, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -24,10 +24,6 @@ class Chef class ActionRecord - # XXX: this is buggy since we (ab)use this resource for "after" state and it may be - # inaccurate and it may be mutated by the user. A third after_resource should be added - # to new_resource + current_resource to properly implement this. - # # @return [Chef::Resource] The declared resource state. # attr_accessor :new_resource @@ -38,6 +34,10 @@ class Chef # implementation, but must be handled), or for unprocessed resources. attr_accessor :current_resource + # @return [Chef::Resource] the after_resource object (after-state). This can be nil for + # non custom-resources or resources that do not implement load_after_resource. + attr_accessor :after_resource + # @return [Symbol] # The action that was run (or scheduled to run in the case of "unprocessed" resources). attr_accessor :action @@ -161,7 +161,7 @@ class Chef pending_updates << ActionRecord.new(new_resource, action, pending_updates.length) end - # Hook called after a resource is loaded. If load_current_resource fails, this hook will + # Hook called after a current resource is loaded. If load_current_resource fails, this hook will # not be called and current_resource will be nil, and the resource_failed hook will be called. # # (see EventDispatch::Base#) @@ -172,6 +172,17 @@ class Chef current_record.current_resource = current_resource end + # Hook called after an after resource is loaded. If load_after_resource fails, this hook will + # not be called and after_resource will be nil, and the resource_failed hook will be called. + # + # (see EventDispatch::Base#) + # + def resource_after_state_loaded(new_resource, action, after_resource) + return if consumers.empty? + + current_record.after_resource = after_resource + end + # Hook called after an action is determined to be up to date. # # (see EventDispatch::Base#) diff --git a/lib/chef/data_collector/run_end_message.rb b/lib/chef/data_collector/run_end_message.rb index 762058bfdb..cfd4b9d8b3 100644 --- a/lib/chef/data_collector/run_end_message.rb +++ b/lib/chef/data_collector/run_end_message.rb @@ -1,5 +1,5 @@ # -# Copyright:: Copyright 2012-2019, Chef Software Inc. +# Copyright:: Copyright 2012-2020, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -106,12 +106,13 @@ class Chef def action_record_for_json(action_record) new_resource = action_record.new_resource current_resource = action_record.current_resource + after_resource = action_record.after_resource hash = { "type" => new_resource.resource_name.to_sym, "name" => new_resource.name.to_s, "id" => safe_resource_identity(new_resource), - "after" => safe_state_for_resource_reporter(new_resource), + "after" => safe_state_for_resource_reporter(after_resource || new_resource), "before" => safe_state_for_resource_reporter(current_resource), "duration" => action_record.elapsed_time.nil? ? "" : (action_record.elapsed_time * 1000).to_i.to_s, "delta" => new_resource.respond_to?(:diff) && updated_or_failed?(action_record) ? new_resource.diff : "", @@ -120,6 +121,11 @@ class Chef "status" => action_record_status_for_json(action_record), } + # don't use the new_resource for the after_resource if it is skipped or failed + if action_record.status == :skipped || action_record.status == :failed || action_record.status == :unprocessed + hash["after"] = {} + end + if new_resource.cookbook_name hash["cookbook_name"] = new_resource.cookbook_name hash["cookbook_version"] = new_resource.cookbook_version.version diff --git a/lib/chef/event_dispatch/base.rb b/lib/chef/event_dispatch/base.rb index cb1cc80017..f7b706cb2c 100644 --- a/lib/chef/event_dispatch/base.rb +++ b/lib/chef/event_dispatch/base.rb @@ -266,6 +266,9 @@ class Chef # Called after #load_current_resource has run. def resource_current_state_loaded(resource, action, current_resource); end + # Called after #load_after_resource has run. + def resource_after_state_loaded(resource, action, after_resource); end + # Called when resource current state load is skipped due to the provider # not supporting whyrun mode. def resource_current_state_load_bypassed(resource, action, current_resource); end diff --git a/lib/chef/provider.rb b/lib/chef/provider.rb index 07cdea6dfc..3783bd9d5f 100644 --- a/lib/chef/provider.rb +++ b/lib/chef/provider.rb @@ -35,6 +35,7 @@ class Chef attr_accessor :new_resource attr_accessor :current_resource + attr_accessor :after_resource attr_accessor :run_context attr_reader :recipe_name @@ -94,6 +95,7 @@ class Chef @new_resource = new_resource @action = action @current_resource = nil + @after_resource = nil @run_context = run_context @converge_actions = nil @@ -148,6 +150,13 @@ class Chef def cleanup_after_converge; end + def load_after_resource + # This is a backwards compatible hack, custom resources properly wire up a new after_resource + # via load_current_value. It is acceptible for old style resources that cannot be easily made + # into custom resources to override this method and provide a proper after_resource. + @after_resource = @new_resource + end + # the :nothing action which is available on all resources by default def action_nothing logger.trace("Doing nothing for #{@new_resource}") @@ -191,6 +200,9 @@ class Chef set_updated_status cleanup_after_converge + + load_after_resource + events.resource_after_state_loaded(@new_resource, @action, @after_resource) end def process_resource_requirements diff --git a/lib/chef/resource/action_class.rb b/lib/chef/resource/action_class.rb index 1b4ddd453b..eefa968197 100644 --- a/lib/chef/resource/action_class.rb +++ b/lib/chef/resource/action_class.rb @@ -29,42 +29,44 @@ class Chef "#{new_resource || "<no resource>"} action #{action ? action.inspect : "<no action>"}" end - # - # If load_current_value! is defined on the resource, use that. - # - def load_current_resource + def return_load_current_value + resource = nil if new_resource.respond_to?(:load_current_value!) - # dup the resource and then reset desired-state properties. - current_resource = new_resource.dup + resource = new_resource.class.new(new_resource.name, new_resource.run_context) - # We clear desired state in the copy, because it is supposed to be actual state. - # We keep identity properties and non-desired-state, which are assumed to be - # "control" values like `recurse: true` - current_resource.class.properties.each_value do |property| - if property.desired_state? && !property.identity? && !property.name_property? - property.reset(current_resource) + # copy the non-desired state, the identity properties and name property to the new resource + # (the desired state values must be loaded by load_current_value) + resource.class.properties.each_value do |property| + if !property.desired_state? || property.identity? || property.name_property? + property.set(resource, new_resource.send(property.name)) if new_resource.class.properties[property.name].is_set?(new_resource) end end - # Call the actual load_current_value! method. If it raises - # CurrentValueDoesNotExist, set current_resource to `nil`. + # we support optionally passing the new_resource as an arg to load_current_value and + # load_current_value can raise in order to clear the current_resource to nil begin - # If the user specifies load_current_value do |desired_resource|, we - # pass in the desired resource as well as the current one. - if current_resource.method(:load_current_value!).arity > 0 - current_resource.load_current_value!(new_resource) + if resource.method(:load_current_value!).arity > 0 + resource.load_current_value!(new_resource) else - current_resource.load_current_value! + resource.load_current_value! end rescue Chef::Exceptions::CurrentValueDoesNotExist - current_resource = nil + resource = nil end end + resource + end + + # build the before state (current_resource) + def load_current_resource + @current_resource = return_load_current_value + end - @current_resource = current_resource + # build the after state (after_resource) + def load_after_resource + @after_resource = return_load_current_value end - # @todo: remove in Chef-15 def self.include_resource_dsl? true end diff --git a/lib/chef/resource/chef_vault_secret.rb b/lib/chef/resource/chef_vault_secret.rb index 8652dc1c98..a48503b1bf 100644 --- a/lib/chef/resource/chef_vault_secret.rb +++ b/lib/chef/resource/chef_vault_secret.rb @@ -79,6 +79,8 @@ class Chef clients item.get_clients admins item.get_admins search item.search + rescue ChefVault::Exceptions::SecretDecryption + current_value_does_not_exist! rescue ChefVault::Exceptions::KeysNotFound current_value_does_not_exist! rescue Net::HTTPClientException => e diff --git a/lib/chef/version.rb b/lib/chef/version.rb index 3657e33ce5..c801fd7248 100644 --- a/lib/chef/version.rb +++ b/lib/chef/version.rb @@ -23,7 +23,7 @@ require_relative "version_string" class Chef CHEF_ROOT = File.expand_path("../..", __FILE__) - VERSION = Chef::VersionString.new("16.0.176") + VERSION = Chef::VersionString.new("16.0.179") end # diff --git a/spec/integration/recipes/resource_load_spec.rb b/spec/integration/recipes/resource_load_spec.rb index 3ca71c3a03..52a108a766 100644 --- a/spec/integration/recipes/resource_load_spec.rb +++ b/spec/integration/recipes/resource_load_spec.rb @@ -65,17 +65,17 @@ describe "Resource.load_current_value" do end it "current_resource is passed name but not x" do - expect(resource.current_value.x).to eq "loaded 2 (name=blah)" + expect(resource.current_value.x).to eq "loaded 3 (name=blah)" end it "resource.current_value returns a different resource" do - expect(resource.current_value.x).to eq "loaded 2 (name=blah)" + expect(resource.current_value.x).to eq "loaded 3 (name=blah)" expect(resource.x).to eq "desired" end it "resource.current_value constructs the resource anew each time" do - expect(resource.current_value.x).to eq "loaded 2 (name=blah)" expect(resource.current_value.x).to eq "loaded 3 (name=blah)" + expect(resource.current_value.x).to eq "loaded 4 (name=blah)" end it "the provider accesses the current value of x" do @@ -96,7 +96,7 @@ describe "Resource.load_current_value" do end it "i, name and d are passed to load_current_value, but not x" do - expect(resource.current_value.x).to eq "loaded 2 (d=desired_d, i=desired_i, name=blah)" + expect(resource.current_value.x).to eq "loaded 3 (d=desired_d, i=desired_i, name=blah)" end end @@ -114,7 +114,7 @@ describe "Resource.load_current_value" do end it "i, name and d are passed to load_current_value, but not x" do - expect(resource.current_value.x).to eq "loaded 2 (d=desired_d, i=desired_i, name=blah)" + expect(resource.current_value.x).to eq "loaded 3 (d=desired_d, i=desired_i, name=blah)" end end end @@ -146,7 +146,7 @@ describe "Resource.load_current_value" do context "and a child resource class with no load_current_value" do it "the parent load_current_value is used" do - expect(subresource.current_value.x).to eq "loaded 2 (name=blah)" + expect(subresource.current_value.x).to eq "loaded 3 (name=blah)" end it "load_current_value yields a copy of the child class" do expect(subresource.current_value).to be_kind_of(subresource_class) @@ -165,8 +165,8 @@ describe "Resource.load_current_value" do it "the overridden load_current_value is used" do current_resource = subresource.current_value - expect(current_resource.x).to eq "default 3" - expect(current_resource.y).to eq "loaded_y 2 (name=blah)" + expect(current_resource.x).to eq "default 4" + expect(current_resource.y).to eq "loaded_y 3 (name=blah)" end end @@ -183,10 +183,131 @@ describe "Resource.load_current_value" do it "the original load_current_value is called as well as the child one" do current_resource = subresource.current_value - expect(current_resource.x).to eq "loaded 3 (name=blah)" - expect(current_resource.y).to eq "loaded_y 4 (name=blah, x=loaded 3 (name=blah))" + expect(current_resource.x).to eq "loaded 5 (name=blah)" + expect(current_resource.y).to eq "loaded_y 6 (name=blah, x=loaded 5 (name=blah))" + end + end + end +end + +describe "simple load_current_value tests" do + let(:resource_class) do + Class.new(Chef::Resource) do + attr_writer :index # this is our hacky global state + def index; @index ||= 1; end + + property :myindex, Integer + + load_current_value do |new_resource| + myindex new_resource.index + end + + action :run do + new_resource.index += 1 + end + end + end + + let(:node) { Chef::Node.new } + let(:events) { Chef::EventDispatch::Dispatcher.new } + let(:run_context) { Chef::RunContext.new(node, {}, events) } + let(:new_resource) { resource_class.new("test", run_context) } + let(:provider) { new_resource.provider_for_action(:run) } + + it "calling the action on the provider sets the current_resource" do + expect(events).to receive(:resource_current_state_loaded).with(new_resource, :run, anything) + provider.run_action(:run) + expect(provider.current_resource.myindex).to eql(1) + end + + it "calling the action on the provider sets the after_resource" do + expect(events).to receive(:resource_after_state_loaded).with(new_resource, :run, anything) + provider.run_action(:run) + expect(provider.after_resource.myindex).to eql(2) + end +end + +describe "simple load_current_resource tests" do + let(:provider_class) do + Class.new(Chef::Provider) do + provides :no_load_current_value + def load_current_resource + @current_resource = new_resource.dup + @current_resource.myindex = 1 + end + action :run do + end + end + end + + let(:resource_class) do + provider_class # vivify the provider_class + Class.new(Chef::Resource) do + provides :no_load_current_value + property :myindex, Integer + end + end + + let(:node) { Chef::Node.new } + let(:events) { Chef::EventDispatch::Dispatcher.new } + let(:run_context) { Chef::RunContext.new(node, {}, events) } + let(:new_resource) { resource_class.new("test", run_context) } + let(:provider) { new_resource.provider_for_action(:run) } + + it "calling the action on the provider sets the current_resource" do + expect(events).to receive(:resource_current_state_loaded).with(new_resource, :run, anything) + provider.run_action(:run) + expect(provider.current_resource.myindex).to eql(1) + end + + it "calling the action on the provider sets the after_resource" do + expect(events).to receive(:resource_after_state_loaded).with(new_resource, :run, new_resource) + provider.run_action(:run) + expect(provider.after_resource.myindex).to eql(nil) + end +end + +describe "simple load_current_resource and load_after_resource tests" do + let(:provider_class) do + Class.new(Chef::Provider) do + provides :load_after + def load_current_resource + @current_resource = new_resource.dup + @current_resource.myindex = 1 + end + + def load_after_resource + @after_resource = new_resource.dup + @after_resource.myindex = 2 end + action :run do + end + end + end + + let(:resource_class) do + provider_class # autovivify provider class + Class.new(Chef::Resource) do + provides :load_after + property :myindex, Integer end end + let(:node) { Chef::Node.new } + let(:events) { Chef::EventDispatch::Dispatcher.new } + let(:run_context) { Chef::RunContext.new(node, {}, events) } + let(:new_resource) { resource_class.new("test", run_context) } + let(:provider) { new_resource.provider_for_action(:run) } + + it "calling the action on the provider sets the current_resource" do + expect(events).to receive(:resource_current_state_loaded).with(new_resource, :run, anything) + provider.run_action(:run) + expect(provider.current_resource.myindex).to eql(1) + end + + it "calling the action on the provider sets the after_resource" do + expect(events).to receive(:resource_after_state_loaded).with(new_resource, :run, anything) + provider.run_action(:run) + expect(provider.after_resource.myindex).to eql(2) + end end diff --git a/spec/unit/data_collector_spec.rb b/spec/unit/data_collector_spec.rb index 3a1eb5b521..bc234d56aa 100644 --- a/spec/unit/data_collector_spec.rb +++ b/spec/unit/data_collector_spec.rb @@ -1,5 +1,5 @@ # -# Copyright:: Copyright 2019-2019, Chef Software Inc. +# Copyright:: Copyright 2019-2020, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -19,6 +19,12 @@ require_relative "../spec_helper" require "chef/data_collector" require "socket" +# +# FIXME FIXME FIXME: What we need to do here is have the ability to construct a real resource collection +# with some test resources that will correctly be up-to-date/updated/skipped/failed/unprocessed and really +# converge a client with them (sort of chefspec-like construction of a Chef::Client but with the actions +# actually running -- another testing requirement similar to the integration testing framework in cheffish as well) +# describe Chef::DataCollector do before(:each) do Chef::Config[:enable_reporting] = true @@ -30,9 +36,23 @@ describe Chef::DataCollector do let(:data_collector) { Chef::DataCollector::Reporter.new(events) } - let(:new_resource) { Chef::Resource::File.new("/tmp/a-file.txt") } + let(:new_resource) do + new_resource = Chef::Resource::File.new("/tmp/a-file.txt") + new_resource.checksum nil + new_resource + end + + let(:current_resource) do + current_resource = Chef::Resource::File.new("/tmp/a-file.txt") + current_resource.checksum "1234123412341234123412341234123412341234123412341234123412341234" + current_resource + end - let(:current_resource) { Chef::Resource::File.new("/tmp/a-file.txt") } + let(:after_resource) do + after_resource = Chef::Resource::File.new("/tmp/a-file.txt") + after_resource.checksum "6789678967896789678967896789678967896789678967896789678967896789" + after_resource + end let(:events) { Chef::EventDispatch::Dispatcher.new } @@ -130,10 +150,10 @@ describe Chef::DataCollector do new_resource.respond_to?(:diff) && %w{updated failed}.include?(status) end - def resource_record_for(current_resource, new_resource, action, status, duration) + def resource_record_for(new_resource, before_resource, after_resource, action, status, duration) { - "after" => new_resource.state_for_resource_reporter, - "before" => current_resource&.state_for_resource_reporter, + "after" => after_resource&.state_for_resource_reporter || {}, + "before" => before_resource&.state_for_resource_reporter || {}, "cookbook_name" => cookbook_name, "cookbook_version" => cookbook_version.version, "delta" => resource_has_diff(new_resource, status) ? new_resource.diff : "", @@ -634,13 +654,14 @@ describe Chef::DataCollector do context "when the run contains a file resource that is up-to-date" do let(:total_resource_count) { 1 } let(:updated_resource_count) { 0 } - let(:resource_record) { [ resource_record_for(current_resource, new_resource, :create, "up-to-date", "1234") ] } + let(:resource_record) { [ resource_record_for(new_resource, current_resource, after_resource, :create, "up-to-date", "1234") ] } let(:status) { "success" } before do events.resource_action_start(new_resource, :create) events.resource_current_state_loaded(new_resource, :create, current_resource) events.resource_up_to_date(new_resource, :create) + events.resource_after_state_loaded(new_resource, :create, after_resource) new_resource.instance_variable_set(:@elapsed_time, 1.2345) events.resource_completed(new_resource) events.converge_complete @@ -653,13 +674,14 @@ describe Chef::DataCollector do context "when the run contains a file resource that is updated" do let(:total_resource_count) { 1 } let(:updated_resource_count) { 1 } - let(:resource_record) { [ resource_record_for(current_resource, new_resource, :create, "updated", "1234") ] } + let(:resource_record) { [ resource_record_for(new_resource, current_resource, after_resource, :create, "updated", "1234") ] } let(:status) { "success" } before do events.resource_action_start(new_resource, :create) events.resource_current_state_loaded(new_resource, :create, current_resource) events.resource_updated(new_resource, :create) + events.resource_after_state_loaded(new_resource, :create, after_resource) new_resource.instance_variable_set(:@elapsed_time, 1.2345) events.resource_completed(new_resource) events.converge_complete @@ -679,7 +701,7 @@ describe Chef::DataCollector do allow(r).to receive(:cookbook_version).and_return(cookbook_version) r end - let(:resource_record) { [ resource_record_for(implementation_resource, implementation_resource, :create, "updated", "2345"), resource_record_for(current_resource, new_resource, :create, "updated", "1234") ] } + let(:resource_record) { [ resource_record_for(implementation_resource, implementation_resource, implementation_resource, :create, "updated", "2345"), resource_record_for(new_resource, current_resource, after_resource, :create, "updated", "1234") ] } let(:status) { "success" } before do @@ -689,10 +711,12 @@ describe Chef::DataCollector do events.resource_action_start(implementation_resource , :create) events.resource_current_state_loaded(implementation_resource, :create, implementation_resource) events.resource_updated(implementation_resource, :create) + events.resource_after_state_loaded(implementation_resource, :create, implementation_resource) implementation_resource.instance_variable_set(:@elapsed_time, 2.3456) events.resource_completed(implementation_resource) events.resource_updated(new_resource, :create) + events.resource_after_state_loaded(new_resource, :create, after_resource) new_resource.instance_variable_set(:@elapsed_time, 1.2345) events.resource_completed(new_resource) events.converge_complete @@ -706,7 +730,7 @@ describe Chef::DataCollector do let(:total_resource_count) { 1 } let(:updated_resource_count) { 0 } let(:resource_record) do - rec = resource_record_for(current_resource, new_resource, :create, "skipped", "1234") + rec = resource_record_for(new_resource, nil, nil, :create, "skipped", "1234") rec["conditional"] = "not_if { #code block }" # FIXME: "#code block" is poor, is there some way to fix this? [ rec ] end @@ -715,7 +739,6 @@ describe Chef::DataCollector do before do conditional = (new_resource.not_if { true }).first events.resource_action_start(new_resource, :create) - events.resource_current_state_loaded(new_resource, :create, current_resource) events.resource_skipped(new_resource, :create, conditional) new_resource.instance_variable_set(:@elapsed_time, 1.2345) events.resource_completed(new_resource) @@ -730,7 +753,7 @@ describe Chef::DataCollector do let(:total_resource_count) { 1 } let(:updated_resource_count) { 0 } let(:resource_record) do - rec = resource_record_for(current_resource, new_resource, :create, "skipped", "1234") + rec = resource_record_for(new_resource, nil, nil, :create, "skipped", "1234") rec["conditional"] = 'not_if "true"' [ rec ] end @@ -739,7 +762,6 @@ describe Chef::DataCollector do before do conditional = (new_resource.not_if "true").first events.resource_action_start(new_resource, :create) - events.resource_current_state_loaded(new_resource, :create, current_resource) events.resource_skipped(new_resource, :create, conditional) new_resource.instance_variable_set(:@elapsed_time, 1.2345) events.resource_completed(new_resource) @@ -756,7 +778,7 @@ describe Chef::DataCollector do let(:total_resource_count) { 1 } let(:updated_resource_count) { 0 } let(:resource_record) do - rec = resource_record_for(current_resource, new_resource, :create, "failed", "1234") + rec = resource_record_for(new_resource, current_resource, nil, :create, "failed", "1234") rec["error_message"] = "imperial to metric conversion error" [ rec ] end @@ -783,7 +805,7 @@ describe Chef::DataCollector do let(:total_resource_count) { 1 } let(:updated_resource_count) { 0 } let(:resource_record) do - rec = resource_record_for(current_resource, new_resource, :create, "failed", "1234") + rec = resource_record_for(new_resource, nil, nil, :create, "failed", "1234") rec["before"] = {} rec["error_message"] = "imperial to metric conversion error" [ rec ] @@ -818,10 +840,9 @@ describe Chef::DataCollector do res end let(:resource_record) do - rec1 = resource_record_for(current_resource, new_resource, :create, "failed", "1234") + rec1 = resource_record_for(new_resource, current_resource, nil, :create, "failed", "1234") rec1["error_message"] = "imperial to metric conversion error" - rec2 = resource_record_for(nil, unprocessed_resource, :nothing, "unprocessed", "") - rec2["before"] = {} + rec2 = resource_record_for(unprocessed_resource, nil, nil, :nothing, "unprocessed", "") [ rec1, rec2 ] end let(:status) { "failure" } diff --git a/spec/unit/resource/chocolatey_source_spec.rb b/spec/unit/resource/chocolatey_source_spec.rb index 60bd773594..aad9c4c283 100644 --- a/spec/unit/resource/chocolatey_source_spec.rb +++ b/spec/unit/resource/chocolatey_source_spec.rb @@ -1,5 +1,5 @@ # -# Copyright:: Copyright 2018, Chef Software, Inc. +# Copyright:: Copyright 2018-2020, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -49,9 +49,10 @@ describe Chef::Resource::ChocolateySource do before(:each) do disable_provider # vivify before mocking enable_provider + current_resource allow(resource).to receive(:provider_for_action).and_return(disable_provider) allow(resource).to receive(:provider_for_action).and_return(enable_provider) - allow(resource).to receive(:dup).and_return(current_resource) + allow(resource.class).to receive(:new).and_return(current_resource) @original_env = ENV.to_hash ENV["ALLUSERSPROFILE"] = 'C:\ProgramData' end |