summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/chef/handler.rb33
-rw-r--r--spec/unit/handler_spec.rb87
2 files changed, 120 insertions, 0 deletions
diff --git a/lib/chef/handler.rb b/lib/chef/handler.rb
index b720a11a45..100ed23d9e 100644
--- a/lib/chef/handler.rb
+++ b/lib/chef/handler.rb
@@ -57,16 +57,47 @@ class Chef
#
class Handler
+ def self.handler_for(*args)
+ if args.include?(:start)
+ Chef::Config[:start_handlers] ||= []
+ Chef::Config[:start_handlers] |= [self]
+ end
+ if args.include?(:report)
+ Chef::Config[:report_handlers] ||= []
+ Chef::Config[:report_handlers] |= [self]
+ end
+ if args.include?(:exception)
+ Chef::Config[:exception_handlers] ||= []
+ Chef::Config[:exception_handlers] |= [self]
+ end
+ end
+
# The list of currently configured start handlers
def self.start_handlers
Array(Chef::Config[:start_handlers])
end
+ def self.resolve_handler_instance(handler)
+ if handler.is_a?(Class)
+ if handler.respond_to?(:instance)
+ # support retrieving a Singleton reporting object
+ handler.instance
+ else
+ # just a class with no way to insert data
+ handler.new
+ end
+ else
+ # the Chef::Config array contains an instance, not a class
+ handler
+ end
+ end
+
# Run the start handlers. This will usually be called by a notification
# from Chef::Client
def self.run_start_handlers(run_status)
Chef::Log.info("Running start handlers")
start_handlers.each do |handler|
+ handler = resolve_handler_instance(handler)
handler.run_report_safely(run_status)
end
Chef::Log.info("Start handlers complete.")
@@ -90,6 +121,7 @@ class Chef
events.handlers_start(report_handlers.size)
Chef::Log.info("Running report handlers")
report_handlers.each do |handler|
+ handler = resolve_handler_instance(handler)
handler.run_report_safely(run_status)
events.handler_executed(handler)
end
@@ -115,6 +147,7 @@ class Chef
events.handlers_start(exception_handlers.size)
Chef::Log.error("Running exception handlers")
exception_handlers.each do |handler|
+ handler = resolve_handler_instance(handler)
handler.run_report_safely(run_status)
events.handler_executed(handler)
end
diff --git a/spec/unit/handler_spec.rb b/spec/unit/handler_spec.rb
index 65c3ddc4cb..a56645fa78 100644
--- a/spec/unit/handler_spec.rb
+++ b/spec/unit/handler_spec.rb
@@ -212,4 +212,91 @@ describe Chef::Handler do
end
end
+ describe "library report handler" do
+ before do
+ # we need to lazily declare this after we have reset Chef::Config in the default rspec before handler
+ class MyTestHandler < Chef::Handler
+ handler_for :report, :exception, :start
+
+ class << self
+ attr_accessor :ran_report
+ end
+
+ def report
+ self.class.ran_report = true
+ end
+ end
+ end
+
+ it "gets added to Chef::Config[:report_handlers]" do
+ expect(Chef::Config[:report_handlers].include?(MyTestHandler)).to be true
+ end
+
+ it "gets added to Chef::Config[:exception_handlers]" do
+ expect(Chef::Config[:exception_handlers].include?(MyTestHandler)).to be true
+ end
+
+ it "gets added to Chef::Config[:start_handlers]" do
+ expect(Chef::Config[:start_handlers].include?(MyTestHandler)).to be true
+ end
+
+ it "runs the report handler" do
+ Chef::Handler.run_report_handlers(@run_status)
+ expect(MyTestHandler.ran_report).to be true
+ end
+
+ it "runs the exception handler" do
+ Chef::Handler.run_exception_handlers(@run_status)
+ expect(MyTestHandler.ran_report).to be true
+ end
+
+ it "runs the start handler" do
+ Chef::Handler.run_start_handlers(@run_status)
+ expect(MyTestHandler.ran_report).to be true
+ end
+ end
+
+ describe "library singleton report handler" do
+ before do
+ # we need to lazily declare this after we have reset Chef::Config in the default rspec before handler
+ class MyTestHandler < Chef::Handler
+ handler_for :report, :exception, :start
+
+ include Singleton
+
+ attr_accessor :ran_report
+
+ def report
+ self.ran_report = true
+ end
+ end
+ end
+
+ it "gets added to Chef::Config[:report_handlers]" do
+ expect(Chef::Config[:report_handlers].include?(MyTestHandler)).to be true
+ end
+
+ it "gets added to Chef::Config[:exception_handlers]" do
+ expect(Chef::Config[:exception_handlers].include?(MyTestHandler)).to be true
+ end
+
+ it "gets added to Chef::Config[:start_handlers]" do
+ expect(Chef::Config[:start_handlers].include?(MyTestHandler)).to be true
+ end
+
+ it "runs the report handler" do
+ Chef::Handler.run_report_handlers(@run_status)
+ expect(MyTestHandler.instance.ran_report).to be true
+ end
+
+ it "runs the exception handler" do
+ Chef::Handler.run_exception_handlers(@run_status)
+ expect(MyTestHandler.instance.ran_report).to be true
+ end
+
+ it "runs the start handler" do
+ Chef::Handler.run_start_handlers(@run_status)
+ expect(MyTestHandler.instance.ran_report).to be true
+ end
+ end
end