summaryrefslogtreecommitdiffstats
path: root/spec/unit
diff options
context:
space:
mode:
authorLuke Kanies <luke@reductivelabs.com>2010-01-19 15:43:48 -0800
committertest branch <puppet-dev@googlegroups.com>2010-02-17 06:50:53 -0800
commit8d5f052b08078f0f356b30fb3fed60eab4490f6d (patch)
tree1f1e45bebbbfb3b16790ddd6e72bdc2bb59f6ffb /spec/unit
parent6651aa4fc84506b9d20076be28741516214c5d5d (diff)
downloadpuppet-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-xspec/unit/transaction/resource_harness.rb230
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