diff options
| author | Luke Kanies <luke@reductivelabs.com> | 2010-01-19 15:43:48 -0800 |
|---|---|---|
| committer | test branch <puppet-dev@googlegroups.com> | 2010-02-17 06:50:53 -0800 |
| commit | 8d5f052b08078f0f356b30fb3fed60eab4490f6d (patch) | |
| tree | 1f1e45bebbbfb3b16790ddd6e72bdc2bb59f6ffb /spec/unit | |
| parent | 6651aa4fc84506b9d20076be28741516214c5d5d (diff) | |
| download | puppet-8d5f052b08078f0f356b30fb3fed60eab4490f6d.tar.gz puppet-8d5f052b08078f0f356b30fb3fed60eab4490f6d.tar.xz puppet-8d5f052b08078f0f356b30fb3fed60eab4490f6d.zip | |
Adding Transaction::ResourceHarness class
This is the interface class between Transactions and
Resources. It's a relatively ugly class, but it
will hopefully allow us to move most/all of the messy
interface code into this one, relatively small class.
Signed-off-by: Luke Kanies <luke@reductivelabs.com>
Diffstat (limited to 'spec/unit')
| -rwxr-xr-x | spec/unit/transaction/resource_harness.rb | 230 |
1 files changed, 230 insertions, 0 deletions
diff --git a/spec/unit/transaction/resource_harness.rb b/spec/unit/transaction/resource_harness.rb new file mode 100755 index 000000000..9d741260a --- /dev/null +++ b/spec/unit/transaction/resource_harness.rb @@ -0,0 +1,230 @@ +#!/usr/bin/env ruby + +require File.dirname(__FILE__) + '/../../spec_helper' + +require 'puppet/transaction/resource_harness' + +describe Puppet::Transaction::ResourceHarness do + before do + @transaction = Puppet::Transaction.new(Puppet::Resource::Catalog.new) + @resource = Puppet::Type.type(:file).new :path => "/my/file" + @harness = Puppet::Transaction::ResourceHarness.new(@transaction) + @current_state = Puppet::Resource.new(:file, "/my/file") + @resource.stubs(:retrieve).returns @current_state + @status = Puppet::Resource::Status.new(@resource) + Puppet::Resource::Status.stubs(:new).returns @status + end + + it "should accept a transaction at initialization" do + harness = Puppet::Transaction::ResourceHarness.new(@transaction) + harness.transaction.should equal(@transaction) + end + + it "should delegate to the transaction for its relationship graph" do + @transaction.expects(:relationship_graph).returns "relgraph" + Puppet::Transaction::ResourceHarness.new(@transaction).relationship_graph.should == "relgraph" + end + + describe "when evaluating a resource" do + it "should create and return a resource status instance for the resource" do + @harness.evaluate(@resource).should be_instance_of(Puppet::Resource::Status) + end + + it "should fail if no status can be created" do + Puppet::Resource::Status.expects(:new).raises ArgumentError + + lambda { @harness.evaluate(@resource) }.should raise_error + end + + it "should retrieve the current state of the resource" do + @resource.expects(:retrieve).returns @current_state + @harness.evaluate(@resource) + end + + it "should mark the resource as failed and return if the current state cannot be retrieved" do + @resource.expects(:retrieve).raises ArgumentError + @harness.evaluate(@resource).should be_failed + end + + it "should use the status and retrieved state to determine which changes need to be made" do + @harness.expects(:changes_to_perform).with(@status, @resource).returns [] + @harness.evaluate(@resource) + end + + it "should mark the status as out of sync and apply the created changes if there are any" do + changes = %w{mychanges} + @harness.expects(:changes_to_perform).returns changes + @harness.expects(:apply_changes).with(@status, changes) + @harness.evaluate(@resource).should be_out_of_sync + end + + it "should cache the last-synced time" do + changes = %w{mychanges} + @harness.stubs(:changes_to_perform).returns changes + @harness.stubs(:apply_changes) + @resource.expects(:cache).with { |name, time| name == :synced and time.is_a?(Time) } + @harness.evaluate(@resource) + end + + it "should flush the resource when applying changes if appropriate" do + changes = %w{mychanges} + @harness.stubs(:changes_to_perform).returns changes + @harness.stubs(:apply_changes) + @resource.expects(:flush) + @harness.evaluate(@resource) + end + + it "should use the status and retrieved state to determine which changes need to be made" do + @harness.expects(:changes_to_perform).with(@status, @resource).returns [] + @harness.evaluate(@resource) + end + + it "should not attempt to apply changes if none need to be made" do + @harness.expects(:changes_to_perform).returns [] + @harness.expects(:apply_changes).never + @harness.evaluate(@resource).should_not be_out_of_sync + end + end + + describe "when creating changes" do + before do + @current_state = Puppet::Resource.new(:file, "/my/file") + @resource.stubs(:retrieve).returns @current_state + Puppet::Util::SUIDManager.stubs(:uid).returns 0 + end + + it "should retrieve the current values from the resource" do + @resource.expects(:retrieve).returns @current_state + @harness.changes_to_perform(@status, @resource) + end + + it "should create changes with the appropriate property and current value" do + @resource[:ensure] = :present + @current_state[:ensure] = :absent + + change = stub 'change' + Puppet::Transaction::Change.expects(:new).with(@resource.parameter(:ensure), :absent).returns change + + @harness.changes_to_perform(@status, @resource)[0].should equal(change) + end + + describe "and the 'ensure' parameter is present but not in sync" do + it "should return a single change for the 'ensure' parameter" do + @resource[:ensure] = :present + @resource[:mode] = "755" + @current_state[:ensure] = :absent + @current_state[:mode] = :absent + + changes = @harness.changes_to_perform(@status, @resource) + changes.length.should == 1 + changes[0].property.name.should == :ensure + end + end + + describe "and the 'ensure' parameter is present, should be set to 'absent', and is correctly set to 'absent'" do + it "should return an empty array" do + @resource[:ensure] = :absent + @resource[:mode] = "755" + @current_state[:ensure] = :absent + @current_state[:mode] = :absent + + @harness.changes_to_perform(@status, @resource).should == [] + end + end + + describe "and non-'ensure' parameters are not in sync" do + it "should return a change for each parameter that is not in sync" do + @resource[:ensure] = :present + @resource[:mode] = "755" + @resource[:owner] = 0 + @current_state[:ensure] = :present + @current_state[:mode] = 0444 + @current_state[:owner] = 50 + + mode = stub 'mode_change' + owner = stub 'owner_change' + Puppet::Transaction::Change.expects(:new).with(@resource.parameter(:mode), 0444).returns mode + Puppet::Transaction::Change.expects(:new).with(@resource.parameter(:owner), 50).returns owner + + changes = @harness.changes_to_perform(@status, @resource) + changes.length.should == 2 + changes.should be_include(mode) + changes.should be_include(owner) + end + end + + describe "and all parameters are in sync" do + it "should return an empty array" do + @resource[:ensure] = :present + @resource[:mode] = "755" + @current_state[:ensure] = :present + @current_state[:mode] = 0755 + @harness.changes_to_perform(@status, @resource).should == [] + end + end + end + + describe "when applying changes" do + before do + @change1 = stub 'change1', :apply => stub("event") + @change2 = stub 'change2', :apply => stub("event") + @changes = [@change1, @change2] + end + + it "should apply the change" do + @change1.expects(:apply) + @change2.expects(:apply) + + @harness.apply_changes(@status, @changes) + end + + it "should mark the resource as changed" do + @harness.apply_changes(@status, @changes) + + @status.should be_changed + end + + it "should queue the resulting event" do + @harness.apply_changes(@status, @changes) + + @status.events.should be_include(@change1.apply) + @status.events.should be_include(@change2.apply) + end + end + + describe "when determining whether the resource can be changed" do + before do + @resource.stubs(:purging?).returns true + @resource.stubs(:deleting?).returns true + end + + it "should be true if the resource is not being purged" do + @resource.expects(:purging?).returns false + @harness.should be_allow_changes(@resource) + end + + it "should be true if the resource is not being deleted" do + @resource.expects(:deleting?).returns false + @harness.should be_allow_changes(@resource) + end + + it "should be true if the resource has no dependents" do + @harness.relationship_graph.expects(:dependents).with(@resource).returns [] + @harness.should be_allow_changes(@resource) + end + + it "should be true if all dependents are being deleted" do + dep = stub 'dependent', :deleting? => true + @harness.relationship_graph.expects(:dependents).with(@resource).returns [dep] + @resource.expects(:purging?).returns true + @harness.should be_allow_changes(@resource) + end + + it "should be false if the resource's dependents are not being deleted" do + dep = stub 'dependent', :deleting? => false, :ref => "myres" + @resource.expects(:warning) + @harness.relationship_graph.expects(:dependents).with(@resource).returns [dep] + @harness.should_not be_allow_changes(@resource) + end + end +end |
