diff options
| author | Lamont Granquist <lamont@scriptkiddie.org> | 2020-03-31 18:01:44 -0700 |
|---|---|---|
| committer | Lamont Granquist <lamont@scriptkiddie.org> | 2020-03-31 18:01:44 -0700 |
| commit | b2366a11103a53518704b54ab58c5b9b8e45a241 (patch) | |
| tree | 320be5a050f0822ed614ee3eb432a9915ce1a101 /spec/integration | |
| parent | 6ae856dc424d42154f73a225f4fb71196c4c2f23 (diff) | |
| download | chef-b2366a11103a53518704b54ab58c5b9b8e45a241.tar.gz | |
Add after_resource to pair with current_resource
For custom resources which correctly implement load_current_value the
new after_resource comes for "free" and load_current_value will be
called twice to load the current_resource (should be renamed the
"before_resource" but that ship sailed) and then the after_resource.
Appropriate wiring is added for a new event and capturing that into
the action_collection and then the data_collector. The resource_reporter
has not and will not be updated.
For old style resources which are difficult to convert to custom
resources (thinking here particularly of the 1:N model of the service
resource in core chef, or stuff that just may be a lot of work like the
file resource) then they can override the load_after_resource to
manually wire up their own after_resource.
Signed-off-by: Lamont Granquist <lamont@scriptkiddie.org>
Diffstat (limited to 'spec/integration')
| -rw-r--r-- | spec/integration/recipes/resource_load_spec.rb | 141 |
1 files changed, 131 insertions, 10 deletions
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 |
