[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:38 UTC 2010


The following commit has been merged in the upstream branch:
commit f2ed655d5e5a9b7c61b29cda229b63db2d73064e
Author: Luke Kanies <luke at madstop.com>
Date:   Sun Nov 1 13:28:49 2009 -0600

    Extracting event management into a separate class
    
    Thus pulls all event-related code out of Transaction.
    The Transaction class currently creates a single instance
    of this class, so it's nowhere near a "real" event manager,
    but at least it has very clean integration points and will
    be easy to upgrade as needed.
    
    Signed-off-by: Luke Kanies <luke at madstop.com>

diff --git a/lib/puppet/transaction.rb b/lib/puppet/transaction.rb
index 0a26e33..aee541f 100644
--- a/lib/puppet/transaction.rb
+++ b/lib/puppet/transaction.rb
@@ -7,16 +7,20 @@ require 'puppet/util/tagging'
 class Puppet::Transaction
     require 'puppet/transaction/change'
     require 'puppet/transaction/event'
+    require 'puppet/transaction/event_manager'
 
     attr_accessor :component, :catalog, :ignoreschedules
     attr_accessor :sorted_resources, :configurator
 
-    # The list of events generated in this transaction.
-    attr_reader :events
+    # The report, once generated.
+    attr_reader :report
 
     # Mostly only used for tests
     attr_reader :resourcemetrics, :changes
 
+    # Routes and stores any events and subscriptions.
+    attr_reader :event_manager
+
     include Puppet::Util
     include Puppet::Util::Tagging
 
@@ -157,7 +161,7 @@ class Puppet::Transaction
         eval_children_and_apply_resource(resource)
 
         # Check to see if there are any events queued for this resource
-        process_events(resource)
+        event_manager.process_events(resource)
     end
 
     def eval_children_and_apply_resource(resource)
@@ -230,6 +234,10 @@ class Puppet::Transaction
         Puppet.debug "Finishing transaction #{object_id} with #{@changes.length} changes"
     end
 
+    def events
+        event_manager.events
+    end
+
     # Determine whether a given resource has failed.
     def failed?(obj)
         if @failures[obj] > 0
@@ -345,14 +353,9 @@ class Puppet::Transaction
         # Metrics for distributing times across the different types.
         @timemetrics = Hash.new(0)
 
-        @event_queues = {}
-
         # The changes we're performing
         @changes = []
 
-        # The complete list of events generated.
-        @events = []
-
         # The resources that have failed and the number of failures each.  This
         # is used for skipping resources because of failed dependencies.
         @failures = Hash.new do |h, key|
@@ -360,6 +363,8 @@ class Puppet::Transaction
         end
 
         @report = Report.new
+
+        @event_manager = Puppet::Transaction::EventManager.new(self)
     end
 
     # Prefetch any providers that support it.  We don't support prefetching
@@ -400,56 +405,6 @@ class Puppet::Transaction
         @sorted_resources = relationship_graph.topsort
     end
 
-    # Respond to any queued events for this resource.
-    def process_events(resource)
-        restarted = false
-        queued_events(resource) do |callback, events|
-            r = process_callback(resource, callback, events)
-            restarted ||= r
-        end
-
-        if restarted
-            queue_event(resource, resource.event(:name => :restarted, :status => "success"))
-
-            @resourcemetrics[:restarted] += 1
-        end
-    end
-
-    # Queue events for other resources to respond to.  All of these events have
-    # to be from the same resource.
-    def queue_event(resource, event)
-        @events << event
-
-        # Collect the targets of any subscriptions to those events.  We pass
-        # the parent resource in so it will override the source in the events,
-        # since eval_generated children can't have direct relationships.
-        relationship_graph.matching_edges(events, resource).each do |edge|
-            next unless method = edge.callback
-            next unless edge.target.respond_to?(method)
-
-            queue_event_for_resource(resource, edge.target, method, event)
-        end
-
-        if resource.self_refresh? and ! resource.deleting?
-            queue_event_for_resource(resource, resource, :refresh, event)
-        end
-    end
-
-    def queue_event_for_resource(source, target, callback, event)
-        source.info "Scheduling #{callback} of #{target}"
-
-        @event_queues[target] ||= {}
-        @event_queues[target][callback] ||= []
-        @event_queues[target][callback] << event
-    end
-
-    def queued_events(resource)
-        return unless callbacks = @event_queues[resource]
-        callbacks.each do |callback, events|
-            yield callback, events
-        end
-    end
-
     def relationship_graph
         catalog.relationship_graph
     end
@@ -474,10 +429,10 @@ class Puppet::Transaction
             end
 
             # And queue the events
-            queue_event(change.resource, event)
+            event_manager.queue_event(change.resource, event)
 
             # Now check to see if there are any events for this child.
-            process_events(change.property.resource)
+            event_manager.process_events(change.property.resource)
         end
     end
 
@@ -540,30 +495,7 @@ class Puppet::Transaction
         else
             @failures[resource] += 1
         end
-        queue_event(resource, event)
-    end
-
-    def process_callback(resource, callback, events)
-        # XXX Should it be any event, or all events?
-        process_noop_events(resource, callback, events) and return false unless events.detect { |e| e.status != "noop" }
-        resource.send(callback)
-
-        resource.notice "Triggered '#{callback}' from #{events.length} events"
-        return true
-    rescue => detail
-        resource.err "Failed to call #{callback}: #{detail}"
-
-        @resourcemetrics[:failed_restarts] += 1
-        puts detail.backtrace if Puppet[:trace]
-        return false
-    end
-
-    def process_noop_events(resource, callback, events)
-        resource.notice "Would have triggered '#{callback}' from #{events.length} events"
-
-        # And then add an event for it.
-        queue_event(resource, resource.event(:status => "noop", :name => :noop_restart))
-        true # so the 'and if' works
+        event_manager.queue_event(resource, event)
     end
 end
 
diff --git a/lib/puppet/transaction/event_manager.rb b/lib/puppet/transaction/event_manager.rb
new file mode 100644
index 0000000..370938c
--- /dev/null
+++ b/lib/puppet/transaction/event_manager.rb
@@ -0,0 +1,90 @@
+require 'puppet/transaction'
+
+class Puppet::Transaction::EventManager
+    attr_reader :transaction, :events
+
+    def initialize(transaction)
+        @transaction = transaction
+        @event_queues = {}
+        @events = []
+    end
+
+    def relationship_graph
+        transaction.relationship_graph
+    end
+
+    # Respond to any queued events for this resource.
+    def process_events(resource)
+        restarted = false
+        queued_events(resource) do |callback, events|
+            r = process_callback(resource, callback, events)
+            restarted ||= r
+        end
+
+        if restarted
+            queue_event(resource, resource.event(:name => :restarted, :status => "success"))
+
+            transaction.resourcemetrics[:restarted] += 1
+        end
+    end
+
+    # Queue events for other resources to respond to.  All of these events have
+    # to be from the same resource.
+    def queue_event(resource, event)
+        @events << event
+
+        # Collect the targets of any subscriptions to those events.  We pass
+        # the parent resource in so it will override the source in the events,
+        # since eval_generated children can't have direct relationships.
+        relationship_graph.matching_edges(event, resource).each do |edge|
+            next unless method = edge.callback
+            next unless edge.target.respond_to?(method)
+
+            queue_event_for_resource(resource, edge.target, method, event)
+        end
+
+        if resource.self_refresh? and ! resource.deleting?
+            queue_event_for_resource(resource, resource, :refresh, event)
+        end
+    end
+
+    def queue_event_for_resource(source, target, callback, event)
+        source.info "Scheduling #{callback} of #{target}"
+
+        @event_queues[target] ||= {}
+        @event_queues[target][callback] ||= []
+        @event_queues[target][callback] << event
+    end
+
+    def queued_events(resource)
+        return unless callbacks = @event_queues[resource]
+        callbacks.each do |callback, events|
+            yield callback, events
+        end
+    end
+
+    private
+
+    def process_callback(resource, callback, events)
+        # XXX Should it be any event, or all events?
+        process_noop_events(resource, callback, events) and return false unless events.detect { |e| e.status != "noop" }
+        resource.send(callback)
+
+        resource.notice "Triggered '#{callback}' from #{events.length} events"
+        return true
+    rescue => detail
+        resource.err "Failed to call #{callback}: #{detail}"
+
+        transaction.resourcemetrics[:failed_restarts] += 1
+        puts detail.backtrace if Puppet[:trace]
+        return false
+    end
+
+    def process_noop_events(resource, callback, events)
+        resource.notice "Would have triggered '#{callback}' from #{events.length} events"
+
+        # And then add an event for it.
+        queue_event(resource, resource.event(:status => "noop", :name => :noop_restart))
+        true # so the 'and if' works
+    end
+end
diff --git a/spec/unit/transaction.rb b/spec/unit/transaction.rb
index d0b3a2d..3adecf6 100755
--- a/spec/unit/transaction.rb
+++ b/spec/unit/transaction.rb
@@ -5,6 +5,20 @@ require File.dirname(__FILE__) + '/../spec_helper'
 require 'puppet/transaction'
 
 describe Puppet::Transaction do
+    it "should delegate its event list to the event manager" do
+        @transaction = Puppet::Transaction.new(Puppet::Resource::Catalog.new)
+        @transaction.event_manager.expects(:events).returns %w{my events}
+        @transaction.events.should == %w{my events}
+    end
+
+    describe "when initializing" do
+        it "should create an event manager" do
+            @transaction = Puppet::Transaction.new(Puppet::Resource::Catalog.new)
+            @transaction.event_manager.should be_instance_of(Puppet::Transaction::EventManager)
+            @transaction.event_manager.transaction.should equal(@transaction)
+        end
+    end
+
     describe "when evaluating a resource" do
         before do
             @transaction = Puppet::Transaction.new(Puppet::Resource::Catalog.new)
@@ -27,7 +41,7 @@ describe Puppet::Transaction do
         end
 
         it "should process events" do
-            @transaction.expects(:process_events).with(@resource)
+            @transaction.event_manager.expects(:process_events).with(@resource)
 
             @transaction.eval_resource(@resource)
         end
@@ -47,7 +61,7 @@ describe Puppet::Transaction do
     describe "when applying changes" do
         before do
             @transaction = Puppet::Transaction.new(Puppet::Resource::Catalog.new)
-            @transaction.stubs(:queue_event)
+            @transaction.event_manager.stubs(:queue_event)
 
             @resource = stub 'resource'
             @property = stub 'property', :is_to_s => "is", :should_to_s => "should"
@@ -69,8 +83,8 @@ describe Puppet::Transaction do
             c1 = stub 'c1', :forward => stub("event1", :status => "success"), :property => @property, :changed= => nil
             c2 = stub 'c2', :forward => stub("event2", :status => "success"), :property => @property, :changed= => nil
 
-            @transaction.expects(:queue_event).with(@resource, c1.forward)
-            @transaction.expects(:queue_event).with(@resource, c2.forward)
+            @transaction.event_manager.expects(:queue_event).with(@resource, c1.forward)
+            @transaction.event_manager.expects(:queue_event).with(@resource, c2.forward)
 
             @transaction.apply_changes(@resource, [c1, c2])
         end
@@ -96,255 +110,12 @@ describe Puppet::Transaction do
             end
 
             it "should queue the event" do
-                @transaction.expects(:queue_event).with(@resource, @event)
+                @transaction.event_manager.expects(:queue_event).with(@resource, @event)
                 @transaction.apply_changes(@resource, [@change])
             end
         end
     end
 
-    describe "when queueing events" do
-        before do
-            @transaction = Puppet::Transaction.new(Puppet::Resource::Catalog.new)
-
-            @resource = stub("resource", :self_refresh? => false, :deleting => false)
-
-            @graph = stub 'graph', :matching_edges => [], :resource => @resource
-            @transaction.stubs(:relationship_graph).returns @graph
-
-            @event = Puppet::Transaction::Event.new(:name => :foo, :resource => @resource)
-        end
-
-        it "should store each event in its event list" do
-            @transaction.queue_event(@resource, @event)
-
-            @transaction.events.should include(@event)
-        end
-
-        it "should queue events for the target and callback of any matching edges" do
-            edge1 = stub("edge1", :callback => :c1, :source => stub("s1"), :target => stub("t1", :c1 => nil))
-            edge2 = stub("edge2", :callback => :c2, :source => stub("s2"), :target => stub("t2", :c2 => nil))
-
-            @graph.expects(:matching_edges).with { |events, resource| events == [@event] }.returns [edge1, edge2]
-
-            @transaction.expects(:queue_event_for_resource).with(@resource, edge1.target, edge1.callback, @event)
-            @transaction.expects(:queue_event_for_resource).with(@resource, edge2.target, edge2.callback, @event)
-
-            @transaction.queue_event(@resource, @event)
-        end
-
-        it "should queue events for the changed resource if the resource is self-refreshing and not being deleted" do
-            @graph.stubs(:matching_edges).returns []
-
-            @resource.expects(:self_refresh?).returns true
-            @resource.expects(:deleting?).returns false
-            @transaction.expects(:queue_event_for_resource).with(@resource, @resource, :refresh, @event)
-
-            @transaction.queue_event(@resource, @event)
-        end
-
-        it "should not queue events for the changed resource if the resource is not self-refreshing" do
-            @graph.stubs(:matching_edges).returns []
-
-            @resource.expects(:self_refresh?).returns false
-            @resource.stubs(:deleting?).returns false
-            @transaction.expects(:queue_event_for_resource).never
-
-            @transaction.queue_event(@resource, @event)
-        end
-
-        it "should not queue events for the changed resource if the resource is being deleted" do
-            @graph.stubs(:matching_edges).returns []
-
-            @resource.expects(:self_refresh?).returns true
-            @resource.expects(:deleting?).returns true
-            @transaction.expects(:queue_event_for_resource).never
-
-            @transaction.queue_event(@resource, @event)
-        end
-
-        it "should ignore edges that don't have a callback" do
-            edge1 = stub("edge1", :callback => :nil, :source => stub("s1"), :target => stub("t1", :c1 => nil))
-
-            @graph.expects(:matching_edges).returns [edge1]
-
-            @transaction.expects(:queue_event_for_resource).never
-
-            @transaction.queue_event(@resource, @event)
-        end
-
-        it "should ignore targets that don't respond to the callback" do
-            edge1 = stub("edge1", :callback => :c1, :source => stub("s1"), :target => stub("t1"))
-
-            @graph.expects(:matching_edges).returns [edge1]
-
-            @transaction.expects(:queue_event_for_resource).never
-
-            @transaction.queue_event(@resource, @event)
-        end
-    end
-
-    describe "when queueing events for a resource" do
-        before do
-            @transaction = Puppet::Transaction.new(Puppet::Resource::Catalog.new)
-        end
-
-        it "should do nothing if no events are queued" do
-            @transaction.queued_events(stub("target")) { |callback, events| raise "should never reach this" }
-        end
-
-        it "should yield the callback and events for each callback" do
-            target = stub("target")
-
-            2.times do |i|
-                @transaction.queue_event_for_resource(stub("source", :info => nil), target, "callback#{i}", ["event#{i}"])
-            end
-
-            @transaction.queued_events(target) { |callback, events| }
-        end
-
-        it "should use the source to log that it's scheduling a refresh of the target" do
-            target = stub("target")
-            source = stub 'source'
-            source.expects(:info)
-
-            @transaction.queue_event_for_resource(source, target, "callback", ["event"])
-
-            @transaction.queued_events(target) { |callback, events| }
-        end
-    end
-
-    describe "when processing events for a given resource" do
-        before do
-            @transaction = Puppet::Transaction.new(Puppet::Resource::Catalog.new)
-            @transaction.stubs(:queue_event)
-
-            @resource = stub 'resource', :notice => nil, :event => @event
-            @event = Puppet::Transaction::Event.new(:name => :event, :resource => @resource)
-        end
-
-        it "should call the required callback once for each set of associated events" do
-            @transaction.expects(:queued_events).with(@resource).multiple_yields([:callback1, [@event]], [:callback2, [@event]])
-
-            @resource.expects(:callback1)
-            @resource.expects(:callback2)
-
-            @transaction.process_events(@resource)
-        end
-
-        it "should update the 'restarted' metric" do
-            @transaction.expects(:queued_events).with(@resource).yields(:callback1, [@event])
-
-            @resource.stubs(:callback1)
-
-            @transaction.process_events(@resource)
-
-            @transaction.resourcemetrics[:restarted].should == 1
-        end
-
-        it "should queue a 'restarted' event generated by the resource" do
-            @transaction.expects(:queued_events).with(@resource).yields(:callback1, [@event])
-
-            @resource.stubs(:callback1)
-
-            @resource.expects(:event).with(:name => :restarted, :status => "success").returns "myevent"
-            @transaction.expects(:queue_event).with(@resource, "myevent")
-
-            @transaction.process_events(@resource)
-        end
-
-        it "should log that it restarted" do
-            @transaction.expects(:queued_events).with(@resource).yields(:callback1, [@event])
-
-            @resource.stubs(:callback1)
-
-            @resource.expects(:notice).with { |msg| msg.include?("Triggered 'callback1'") }
-
-            @transaction.process_events(@resource)
-        end
-
-        describe "and the events include a noop event and at least one non-noop event" do
-            before do
-                @event.stubs(:status).returns "noop"
-                @event2 = Puppet::Transaction::Event.new(:name => :event, :resource => @resource)
-                @event2.status = "success"
-                @transaction.expects(:queued_events).with(@resource).yields(:callback1, [@event, @event2])
-            end
-
-            it "should call the callback" do
-                @resource.expects(:callback1)
-
-                @transaction.process_events(@resource)
-            end
-        end
-
-        describe "and the events are all noop events" do
-            before do
-                @event.stubs(:status).returns "noop"
-                @resource.stubs(:event).returns(Puppet::Transaction::Event.new)
-                @transaction.expects(:queued_events).with(@resource).yields(:callback1, [@event])
-            end
-
-            it "should log" do
-                @resource.expects(:notice).with { |msg| msg.include?("Would have triggered 'callback1'") }
-
-                @transaction.process_events(@resource)
-            end
-
-            it "should not call the callback" do
-                @resource.expects(:callback1).never
-
-                @transaction.process_events(@resource)
-            end
-
-            it "should queue a new noop event generated from the resource" do
-                event = Puppet::Transaction::Event.new
-                @resource.expects(:event).with(:status => "noop", :name => :noop_restart).returns event
-                @transaction.expects(:queue_event).with(@resource, event)
-
-                @transaction.process_events(@resource)
-            end
-        end
-
-        describe "and the callback fails" do
-            before do
-                @resource.expects(:callback1).raises "a failure"
-                @resource.stubs(:err)
-
-                @transaction.expects(:queued_events).yields(:callback1, [@event])
-            end
-
-            it "should log but not fail" do
-                @resource.expects(:err)
-
-                lambda { @transaction.process_events(@resource) }.should_not raise_error
-            end
-
-            it "should update the 'failed_restarts' metric" do
-                @transaction.process_events(@resource)
-                @transaction.resourcemetrics[:failed_restarts].should == 1
-            end
-
-            it "should not queue a 'restarted' event" do
-                @transaction.expects(:queue_event).never
-                @transaction.process_events(@resource)
-            end
-
-            it "should not increase the restarted resource count" do
-                @transaction.process_events(@resource)
-                @transaction.resourcemetrics[:restarted].should == 0
-            end
-        end
-    end
-
-    describe "when initializing" do
-        it "should accept a catalog and set an instance variable for it" do
-            catalog = stub 'catalog', :vertices => []
-
-            trans = Puppet::Transaction.new(catalog)
-            trans.catalog.should == catalog
-        end
-    end
-
     describe "when generating resources" do
         it "should finish all resources" do
             generator = stub 'generator', :depthfirst? => true, :tags => []
diff --git a/spec/unit/transaction/event_manager.rb b/spec/unit/transaction/event_manager.rb
new file mode 100755
index 0000000..96dd37d
--- /dev/null
+++ b/spec/unit/transaction/event_manager.rb
@@ -0,0 +1,259 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+require 'puppet/transaction/event_manager'
+
+describe Puppet::Transaction::EventManager do
+    describe "at initialization" do
+        it "should require a transaction" do
+            Puppet::Transaction::EventManager.new("trans").transaction.should == "trans"
+        end
+    end
+
+    it "should delegate its relationship graph to the transaction" do
+        transaction = stub 'transaction'
+        manager = Puppet::Transaction::EventManager.new(transaction)
+
+        transaction.expects(:relationship_graph).returns "mygraph"
+
+        manager.relationship_graph.should == "mygraph"
+    end
+
+    describe "when queueing events" do
+        before do
+            @transaction = stub 'transaction'
+            @manager = Puppet::Transaction::EventManager.new(@transaction)
+
+            @resource = stub("resource", :self_refresh? => false, :deleting => false)
+
+            @graph = stub 'graph', :matching_edges => [], :resource => @resource
+            @manager.stubs(:relationship_graph).returns @graph
+
+            @event = Puppet::Transaction::Event.new(:name => :foo, :resource => @resource)
+        end
+
+        it "should store each event in its event list" do
+            @manager.queue_event(@resource, @event)
+
+            @manager.events.should include(@event)
+        end
+
+        it "should queue events for the target and callback of any matching edges" do
+            edge1 = stub("edge1", :callback => :c1, :source => stub("s1"), :target => stub("t1", :c1 => nil))
+            edge2 = stub("edge2", :callback => :c2, :source => stub("s2"), :target => stub("t2", :c2 => nil))
+
+            @graph.expects(:matching_edges).with { |event, resource| event == @event }.returns [edge1, edge2]
+
+            @manager.expects(:queue_event_for_resource).with(@resource, edge1.target, edge1.callback, @event)
+            @manager.expects(:queue_event_for_resource).with(@resource, edge2.target, edge2.callback, @event)
+
+            @manager.queue_event(@resource, @event)
+        end
+
+        it "should queue events for the changed resource if the resource is self-refreshing and not being deleted" do
+            @graph.stubs(:matching_edges).returns []
+
+            @resource.expects(:self_refresh?).returns true
+            @resource.expects(:deleting?).returns false
+            @manager.expects(:queue_event_for_resource).with(@resource, @resource, :refresh, @event)
+
+            @manager.queue_event(@resource, @event)
+        end
+
+        it "should not queue events for the changed resource if the resource is not self-refreshing" do
+            @graph.stubs(:matching_edges).returns []
+
+            @resource.expects(:self_refresh?).returns false
+            @resource.stubs(:deleting?).returns false
+            @manager.expects(:queue_event_for_resource).never
+
+            @manager.queue_event(@resource, @event)
+        end
+
+        it "should not queue events for the changed resource if the resource is being deleted" do
+            @graph.stubs(:matching_edges).returns []
+
+            @resource.expects(:self_refresh?).returns true
+            @resource.expects(:deleting?).returns true
+            @manager.expects(:queue_event_for_resource).never
+
+            @manager.queue_event(@resource, @event)
+        end
+
+        it "should ignore edges that don't have a callback" do
+            edge1 = stub("edge1", :callback => :nil, :source => stub("s1"), :target => stub("t1", :c1 => nil))
+
+            @graph.expects(:matching_edges).returns [edge1]
+
+            @manager.expects(:queue_event_for_resource).never
+
+            @manager.queue_event(@resource, @event)
+        end
+
+        it "should ignore targets that don't respond to the callback" do
+            edge1 = stub("edge1", :callback => :c1, :source => stub("s1"), :target => stub("t1"))
+
+            @graph.expects(:matching_edges).returns [edge1]
+
+            @manager.expects(:queue_event_for_resource).never
+
+            @manager.queue_event(@resource, @event)
+        end
+    end
+
+    describe "when queueing events for a resource" do
+        before do
+            @transaction = stub 'transaction'
+            @manager = Puppet::Transaction::EventManager.new(@transaction)
+        end
+
+        it "should do nothing if no events are queued" do
+            @manager.queued_events(stub("target")) { |callback, events| raise "should never reach this" }
+        end
+
+        it "should yield the callback and events for each callback" do
+            target = stub("target")
+
+            2.times do |i|
+                @manager.queue_event_for_resource(stub("source", :info => nil), target, "callback#{i}", ["event#{i}"])
+            end
+
+            @manager.queued_events(target) { |callback, events| }
+        end
+
+        it "should use the source to log that it's scheduling a refresh of the target" do
+            target = stub("target")
+            source = stub 'source'
+            source.expects(:info)
+
+            @manager.queue_event_for_resource(source, target, "callback", ["event"])
+
+            @manager.queued_events(target) { |callback, events| }
+        end
+    end
+
+    describe "when processing events for a given resource" do
+        before do
+            @transaction = Puppet::Transaction.new(Puppet::Resource::Catalog.new)
+            @manager = Puppet::Transaction::EventManager.new(@transaction)
+            @manager.stubs(:queue_event)
+
+            @resource = stub 'resource', :notice => nil, :event => @event
+            @event = Puppet::Transaction::Event.new(:name => :event, :resource => @resource)
+        end
+
+        it "should call the required callback once for each set of associated events" do
+            @manager.expects(:queued_events).with(@resource).multiple_yields([:callback1, [@event]], [:callback2, [@event]])
+
+            @resource.expects(:callback1)
+            @resource.expects(:callback2)
+
+            @manager.process_events(@resource)
+        end
+
+        it "should update the 'restarted' metric" do
+            @manager.expects(:queued_events).with(@resource).yields(:callback1, [@event])
+
+            @resource.stubs(:callback1)
+
+            @manager.process_events(@resource)
+
+            @transaction.resourcemetrics[:restarted].should == 1
+        end
+
+        it "should queue a 'restarted' event generated by the resource" do
+            @manager.expects(:queued_events).with(@resource).yields(:callback1, [@event])
+
+            @resource.stubs(:callback1)
+
+            @resource.expects(:event).with(:name => :restarted, :status => "success").returns "myevent"
+            @manager.expects(:queue_event).with(@resource, "myevent")
+
+            @manager.process_events(@resource)
+        end
+
+        it "should log that it restarted" do
+            @manager.expects(:queued_events).with(@resource).yields(:callback1, [@event])
+
+            @resource.stubs(:callback1)
+
+            @resource.expects(:notice).with { |msg| msg.include?("Triggered 'callback1'") }
+
+            @manager.process_events(@resource)
+        end
+
+        describe "and the events include a noop event and at least one non-noop event" do
+            before do
+                @event.stubs(:status).returns "noop"
+                @event2 = Puppet::Transaction::Event.new(:name => :event, :resource => @resource)
+                @event2.status = "success"
+                @manager.expects(:queued_events).with(@resource).yields(:callback1, [@event, @event2])
+            end
+
+            it "should call the callback" do
+                @resource.expects(:callback1)
+
+                @manager.process_events(@resource)
+            end
+        end
+
+        describe "and the events are all noop events" do
+            before do
+                @event.stubs(:status).returns "noop"
+                @resource.stubs(:event).returns(Puppet::Transaction::Event.new)
+                @manager.expects(:queued_events).with(@resource).yields(:callback1, [@event])
+            end
+
+            it "should log" do
+                @resource.expects(:notice).with { |msg| msg.include?("Would have triggered 'callback1'") }
+
+                @manager.process_events(@resource)
+            end
+
+            it "should not call the callback" do
+                @resource.expects(:callback1).never
+
+                @manager.process_events(@resource)
+            end
+
+            it "should queue a new noop event generated from the resource" do
+                event = Puppet::Transaction::Event.new
+                @resource.expects(:event).with(:status => "noop", :name => :noop_restart).returns event
+                @manager.expects(:queue_event).with(@resource, event)
+
+                @manager.process_events(@resource)
+            end
+        end
+
+        describe "and the callback fails" do
+            before do
+                @resource.expects(:callback1).raises "a failure"
+                @resource.stubs(:err)
+
+                @manager.expects(:queued_events).yields(:callback1, [@event])
+            end
+
+            it "should log but not fail" do
+                @resource.expects(:err)
+
+                lambda { @manager.process_events(@resource) }.should_not raise_error
+            end
+
+            it "should update the 'failed_restarts' metric" do
+                @manager.process_events(@resource)
+                @transaction.resourcemetrics[:failed_restarts].should == 1
+            end
+
+            it "should not queue a 'restarted' event" do
+                @manager.expects(:queue_event).never
+                @manager.process_events(@resource)
+            end
+
+            it "should not increase the restarted resource count" do
+                @manager.process_events(@resource)
+                @transaction.resourcemetrics[:restarted].should == 0
+            end
+        end
+    end
+end

-- 
Puppet packaging for Debian



More information about the Pkg-puppet-devel mailing list