[Pkg-puppet-devel] [SCM] Puppet packaging for Debian branch, upstream, updated. 0.25.5-639-g8f94f35

test branch puppet-dev at googlegroups.com
Wed Jul 14 10:30:56 UTC 2010


The following commit has been merged in the upstream branch:
commit 8d5f052b08078f0f356b30fb3fed60eab4490f6d
Author: Luke Kanies <luke at reductivelabs.com>
Date:   Tue Jan 19 15:43:48 2010 -0800

    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 at reductivelabs.com>

diff --git a/lib/puppet/transaction/resource_harness.rb b/lib/puppet/transaction/resource_harness.rb
new file mode 100644
index 0000000..da85991
--- /dev/null
+++ b/lib/puppet/transaction/resource_harness.rb
@@ -0,0 +1,62 @@
+require 'puppet/resource/status'
+
+class Puppet::Transaction::ResourceHarness
+    extend Forwardable
+    def_delegators :@transaction, :relationship_graph
+
+    attr_reader :transaction
+
+    def allow_changes?(resource)
+        return true unless resource.purging? and resource.deleting?
+        return true unless deps = relationship_graph.dependents(resource) and ! deps.empty? and deps.detect { |d| ! d.deleting? }
+
+        deplabel = deps.collect { |r| r.ref }.join(",")
+        plurality = deps.length > 1 ? "":"s"
+        resource.warning "#{deplabel} still depend#{plurality} on me -- not purging"
+        return false
+    end
+
+    def apply_changes(status, changes)
+        changes.each do |change|
+            status << change.apply
+        end
+        status.changed = true
+    end
+
+    def changes_to_perform(status, resource)
+        current = resource.retrieve
+
+        if param = resource.parameter(:ensure)
+            insync = param.insync?(current[:ensure])
+            return [Puppet::Transaction::Change.new(param, current[:ensure])] unless insync
+            return [] if param.should == :absent
+        end
+
+        resource.properties.reject { |p| p.name == :ensure }.find_all do |param|
+            ! param.insync?(current[param.name])
+        end.collect do |param|
+            Puppet::Transaction::Change.new(param, current[param.name])
+        end
+    end
+
+    def evaluate(resource)
+        status = Puppet::Resource::Status.new(resource)
+
+        if changes = changes_to_perform(status, resource) and ! changes.empty?
+            status.out_of_sync = true
+            apply_changes(status, changes)
+            resource.cache(:synced, Time.now)
+            resource.flush if resource.respond_to?(:flush)
+        end
+        return status
+    rescue => detail
+        resource.fail "Could not create resource status: #{detail}" unless status
+        resource.err "Could not evaluate: #{detail}"
+        status.failed = true
+        return status
+    end
+
+    def initialize(transaction)
+        @transaction = transaction
+    end
+end
diff --git a/spec/unit/transaction/resource_harness.rb b/spec/unit/transaction/resource_harness.rb
new file mode 100755
index 0000000..9d74126
--- /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

-- 
Puppet packaging for Debian



More information about the Pkg-puppet-devel mailing list