summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRanjib Dey <ranjib@pagerduty.com>2015-06-19 15:32:04 -0700
committerRanjib Dey <ranjib@pagerduty.com>2015-06-23 23:03:02 -0700
commit9f0ea8aa0ec05819e242dedaa85fe731dca3146c (patch)
tree028c8ca206e3503243aeb50cfc7a2aa37995823a
parent3769bf187130c95d5ef2575a0f4ac9e06b197f5c (diff)
downloadchef-9f0ea8aa0ec05819e242dedaa85fe731dca3146c.tar.gz
add name class attribute for user defined handlers. more readable invalid event handler exception name.
-rw-r--r--lib/chef/chef_class.rb4
-rw-r--r--lib/chef/event_dispatch/dsl.rb37
-rw-r--r--lib/chef/exceptions.rb2
-rw-r--r--spec/unit/chef_class_spec.rb2
-rw-r--r--spec/unit/event_dispatch/dsl_spec.rb43
5 files changed, 70 insertions, 18 deletions
diff --git a/lib/chef/chef_class.rb b/lib/chef/chef_class.rb
index c490615861..d9c141b85d 100644
--- a/lib/chef/chef_class.rb
+++ b/lib/chef/chef_class.rb
@@ -51,8 +51,10 @@ class Chef
attr_reader :run_context
# Register an event handler with user specified block
+ #
+ # @return[Chef::EventDispatch::Base] handler object
def event_handler(&block)
- dsl = Chef::EventDispatch::DSL.new
+ dsl = Chef::EventDispatch::DSL.new('Chef client DSL')
dsl.instance_eval(&block)
end
diff --git a/lib/chef/event_dispatch/dsl.rb b/lib/chef/event_dispatch/dsl.rb
index e700fd1640..98854a4716 100644
--- a/lib/chef/event_dispatch/dsl.rb
+++ b/lib/chef/event_dispatch/dsl.rb
@@ -22,32 +22,43 @@ require 'chef/config'
class Chef
module EventDispatch
class DSL
+ attr_reader :handler
+
+ def initialize(name)
+ klass = Class.new(Chef::EventDispatch::Base) do
+ def self.name
+ @@name
+ end
+ end
+ klass.class_variable_set(:@@name, name)
+ @handler = klass.new
+ # Use current event.register API to add anonymous handler if
+ # run_context and associated event dispatcher is set, else fallback to
+ # Chef::Config[:hanlder].
+ if Chef.run_context && Chef.run_context.events
+ Chef::Log.debug("Registering handler '#{name}' using events api")
+ Chef.run_context.events.register(handler)
+ else
+ Chef::Log.debug("Registering handler '#{name}' using global config")
+ Chef::Config[:event_handlers] << handler
+ end
+ end
+
# Adds a new event handler derived from base handler
# with user defined block against a chef event
#
# @return [Chef::EventDispatch::Base] a base handler object
def on(event_type, &block)
validate!(event_type)
- handler = Chef::EventDispatch::Base.new
handler.define_singleton_method(event_type) do |*args|
- block.call(args)
- end
- # Use current event dispatch system is run_context and associated event
- # dispatcher is set else fall back to Chef::Config[:hanlder]
- if Chef.run_context && Chef.run_context.events
- Chef::Log.debug('Registering handler using run_context')
- Chef.run_context.events.register(handler)
- else
- Chef::Log.debug('Registering handler using config, this will only work inside config file')
- Chef::Config[:event_handlers] << handler
+ instance_exec(*args, &block)
end
- handler
end
private
def validate!(event_type)
all_event_types = (Chef::EventDispatch::Base.instance_methods - Object.instance_methods)
- raise Chef::Exceptions::UnknownEventType unless all_event_types.include?(event_type)
+ raise Chef::Exceptions::InvalidEventType, "Invalid event type: #{event_type}" unless all_event_types.include?(event_type)
end
end
end
diff --git a/lib/chef/exceptions.rb b/lib/chef/exceptions.rb
index f38bc32571..0857a9e75e 100644
--- a/lib/chef/exceptions.rb
+++ b/lib/chef/exceptions.rb
@@ -98,7 +98,7 @@ class Chef
class InvalidResourceReference < RuntimeError; end
class ResourceNotFound < RuntimeError; end
class VerificationNotFound < RuntimeError; end
- class UnknownEventType < ArgumentError; end
+ class InvalidEventType < ArgumentError; end
# Can't find a Resource of this type that is valid on this platform.
class NoSuchResourceType < NameError
diff --git a/spec/unit/chef_class_spec.rb b/spec/unit/chef_class_spec.rb
index 65a637dcbb..d6bf74572e 100644
--- a/spec/unit/chef_class_spec.rb
+++ b/spec/unit/chef_class_spec.rb
@@ -108,7 +108,7 @@ describe "Chef class" do
on :yolo do
end
end
- end.to raise_error(Chef::Exceptions::UnknownEventType)
+ end.to raise_error(Chef::Exceptions::InvalidEventType)
end
end
end
diff --git a/spec/unit/event_dispatch/dsl_spec.rb b/spec/unit/event_dispatch/dsl_spec.rb
index ba91dde2e7..e30b1cb40e 100644
--- a/spec/unit/event_dispatch/dsl_spec.rb
+++ b/spec/unit/event_dispatch/dsl_spec.rb
@@ -20,16 +20,55 @@ require 'spec_helper'
require 'chef/event_dispatch/dsl'
describe Chef::EventDispatch::DSL do
- subject{ described_class.new }
+ subject{ described_class.new('test') }
it 'raise error when invalid event type is supplied' do
expect do
subject.on(:foo_bar) {}
- end.to raise_error(Chef::Exceptions::UnknownEventType)
+ end.to raise_error(Chef::Exceptions::InvalidEventType)
end
it 'register user hooks against valid event type' do
subject.on(:run_failed) {'testhook'}
expect(Chef::Config[:event_handlers].first.run_failed).to eq('testhook')
end
+
+ it 'preserve state across event hooks' do
+ Chef::Config.reset!
+ node = Chef::Node.new
+ calls = []
+ Chef.event_handler do
+ on :resource_updated do
+ calls << :updated
+ end
+ on :resource_action_start do
+ calls << :started
+ end
+ end
+ events = Chef::EventDispatch::Dispatcher.new(*Chef::Config[:event_handlers])
+ rc = Chef::RunContext.new(node, nil, events)
+ resource = Chef::Resource::RubyBlock.new('foo', rc)
+ resource.block { }
+ resource.run_action(:run)
+ expect(calls).to eq([:started, :updated])
+ end
+
+ it 'preserve instance variables across handler callbacks' do
+ Chef::Config.reset!
+ node = Chef::Node.new
+ Chef.event_handler do
+ on :resource_action_start do
+ @ivar = [1]
+ end
+ on :resource_updated do
+ @ivar << 2
+ end
+ end
+ events = Chef::EventDispatch::Dispatcher.new(*Chef::Config[:event_handlers])
+ rc = Chef::RunContext.new(node, nil, events)
+ resource = Chef::Resource::RubyBlock.new('foo', rc)
+ resource.block { }
+ resource.run_action(:run)
+ expect(Chef::Config[:event_handlers].first.instance_variable_get(:@ivar)).to eq([1, 2])
+ end
end