Skip to content

Commit d80096b

Browse files
committed
Fixes CHEF-162. Delayed notifications now properly collapse
1 parent ca6b085 commit d80096b

7 files changed

Lines changed: 82 additions & 9 deletions

File tree

chef/lib/chef/runner.rb

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ def build_provider(resource)
5858

5959
def converge
6060

61-
delayed_actions = Array.new
61+
delayed_actions = Hash.new
6262

6363
@collection.each do |resource|
6464
begin
@@ -95,10 +95,11 @@ def converge
9595
end
9696
if resource.actions[action].has_key?(:delayed)
9797
resource.actions[action][:delayed].each do |r|
98-
delayed_actions << lambda {
98+
delayed_actions[r] = Hash.new unless delayed_actions.has_key?(r)
99+
delayed_actions[r][action] = Array.new unless delayed_actions[r].has_key?(action)
100+
delayed_actions[r][action] << lambda {
99101
Chef::Log.info("#{resource} sending #{action} action to #{r} (delayed)")
100-
build_provider(r).send("action_#{action}")
101-
}
102+
}
102103
end
103104
end
104105
end
@@ -111,7 +112,12 @@ def converge
111112
end
112113

113114
# Run all our :delayed actions
114-
delayed_actions.each { |da| da.call }
115+
delayed_actions.each do |resource, action_hash|
116+
action_hash.each do |action, log_array|
117+
log_array.each { |l| l.call } # Call each log message
118+
build_provider(resource).send("action_#{action}")
119+
end
120+
end
115121

116122
true
117123
end

chef/spec/unit/runner_spec.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,5 +140,17 @@ def new_runner
140140
@runner.converge
141141
end
142142

143+
it "should collapse delayed actions on changed resources" do
144+
Chef::Platform.stub!(:find_provider_for_node).and_return(Chef::Provider::SnakeOil)
145+
provider = Chef::Provider::SnakeOil.new(@node, @collection[0])
146+
Chef::Provider::SnakeOil.stub!(:new).and_return(provider)
147+
cat = Chef::Resource::Cat.new("peanut", @collection)
148+
cat.notifies :buy, @collection[0], :delayed
149+
cat.updated = true
150+
@collection << cat
151+
@collection << cat
152+
provider.should_receive(:action_buy).once.and_return(true)
153+
@runner.converge
154+
end
143155

144156
end

features/data/cookbooks/delayed_notifications/recipes/notify_a_resource_from_a_single_source.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,6 @@
2121
action :nothing
2222
end
2323

24-
exec "echo foo" do
24+
execute "echo foo" do
2525
notifies :create, resources("file[#{node[:tmpdir]}/notified_file.txt]"), :delayed
2626
end
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#
2+
# Cookbook Name:: delayed_notifications
3+
# Recipe:: notify_a_resource_from_multiple_sources
4+
#
5+
# Copyright 2009, Opscode
6+
#
7+
# Licensed under the Apache License, Version 2.0 (the "License");
8+
# you may not use this file except in compliance with the License.
9+
# You may obtain a copy of the License at
10+
#
11+
# http://www.apache.org/licenses/LICENSE-2.0
12+
#
13+
# Unless required by applicable law or agreed to in writing, software
14+
# distributed under the License is distributed on an "AS IS" BASIS,
15+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
# See the License for the specific language governing permissions and
17+
# limitations under the License.
18+
#
19+
20+
execute "bob dylan" do
21+
command "echo 'bob dylan' >> #{node[:tmpdir]}/notified_file.txt"
22+
action :nothing
23+
end
24+
25+
execute "echo foo" do
26+
notifies :run, resources("execute[bob dylan]"), :delayed
27+
end
28+
29+
execute "echo bar" do
30+
notifies :run, resources("execute[bob dylan]"), :delayed
31+
end

features/delayed_notifications.feature

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,13 @@ Feature: Delayed Notifications
99
When I run the chef-client
1010
Then the run should exit '0'
1111
And a file named 'notified_file.txt' should exist
12+
13+
Scenario: Notify a resource from multiple sources
14+
Given a validated node
15+
And it includes the recipe 'delayed_notifications::notify_a_resource_from_multiple_sources'
16+
When I run the chef-client
17+
Then the run should exit '0'
18+
And a file named 'notified_file.txt' should contain 'bob dylan' only '1' time
1219

1320

1421

features/steps/files.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,14 @@
6363
file.should == "#{specificity}\n"
6464
end
6565

66+
Then /^a file named '(.+)' should contain '(.+)' only '(.+)' time$/ do |filename, string, count|
67+
seen_count = 0
68+
IO.foreach(File.join(tmpdir, filename)) do |line|
69+
if line =~ /#{string}/
70+
seen_count += 1
71+
end
72+
end
73+
seen_count.should == count.to_i
74+
end
75+
76+

features/steps/run_client.rb

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,17 @@
3737
begin
3838
@status.exitstatus.should eql(exit_code.to_i)
3939
rescue
40-
puts "--- run stdout: #{@stdout}"
41-
puts @stdout
42-
puts "--- run stderr: #{@stderr}"
40+
print_output
4341
raise
4442
end
43+
print_output if ENV["LOG_LEVEL"] == "debug"
44+
end
45+
46+
def print_output
47+
puts "--- run stdout:"
48+
puts @stdout
49+
puts "--- run stderr"
50+
puts @stderr
4551
end
4652

4753
Then /^stdout should have '(.+)'$/ do |to_match|

0 commit comments

Comments
 (0)