diff options
-rw-r--r-- | features/data/cookbooks/run_interval/recipes/default.rb | 11 | ||||
-rw-r--r-- | features/steps/run_client_steps.rb | 72 |
2 files changed, 55 insertions, 28 deletions
diff --git a/features/data/cookbooks/run_interval/recipes/default.rb b/features/data/cookbooks/run_interval/recipes/default.rb index 4b7f432de2..d0e6c30d15 100644 --- a/features/data/cookbooks/run_interval/recipes/default.rb +++ b/features/data/cookbooks/run_interval/recipes/default.rb @@ -2,7 +2,7 @@ # Cookbook Name:: run_interval # Recipe:: default # -# Copyright 2009, Opscode +# Copyright 2009, 2010, Opscode # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -16,3 +16,12 @@ # See the License for the specific language governing permissions and # limitations under the License. # + +# Force chef-client to exit once this cookbook has been applied twice. +# The test depends on chef having run twice, so this number is tied to +# run_interval.feature! + +$run_interval_global ||= 2 + +$run_interval_global -= 1 +exit(2) if $run_interval_global == 0 diff --git a/features/steps/run_client_steps.rb b/features/steps/run_client_steps.rb index 34e6ce2180..0ecf85ec00 100644 --- a/features/steps/run_client_steps.rb +++ b/features/steps/run_client_steps.rb @@ -23,16 +23,19 @@ include Chef::Mixin::ShellOut CHEF_CLIENT = File.join(CHEF_PROJECT_ROOT, "chef", "bin", "chef-client") +def chef_client_command_string + @log_level ||= ENV["LOG_LEVEL"] ? ENV["LOG_LEVEL"] : "error" + @chef_args ||= "" + @config_file ||= File.expand_path(File.join(configdir, 'client.rb')) + + "#{File.join(File.dirname(__FILE__), "..", "..", "chef", "bin", "chef-client")} -l #{@log_level} -c #{@config_file} #{@chef_args}" +end ### # When ### When /^I run the chef\-client$/ do - @log_level ||= ENV["LOG_LEVEL"] ? ENV["LOG_LEVEL"] : "error" - @chef_args ||= "" - @config_file ||= File.expand_path(File.join(configdir, 'client.rb')) - status = Chef::Mixin::Command.popen4( - "#{File.join(File.dirname(__FILE__), "..", "..", "chef", "bin", "chef-client")} -l #{@log_level} -c #{@config_file} #{@chef_args}") do |p, i, o, e| + status = Chef::Mixin::Command.popen4(chef_client_command_string()) do |p, i, o, e| @stdout = o.gets(nil) @stderr = e.gets(nil) end @@ -65,29 +68,44 @@ When /^I run the chef\-client with '(.+)' for '(.+)' seconds$/ do |args, run_for end When /^I run the chef\-client for '(.+)' seconds$/ do |run_for| - cid = Process.fork { - sleep run_for.to_i - - client_pid = `ps ax | grep chef-client | grep -v grep | grep -v rake | grep -v cucumber | awk '{ print $1 }'`.to_i - - # Send a SIGINT to the child process so it has a chance to cleanly exit, - # including flushing its stdout. - Process.kill("INT", client_pid) - - sleep 1 - - # Send KILL to the child chef-client. Due to OHAI-223, where ohai sometimes - # ignores/doesn't exit correctly on receipt of SIGINT, brutally kill the - # subprocess. - begin - Process.kill("KILL", client_pid) - rescue Errno::ESRCH - # SIGINT worked above, so the KILL failed. Ignore it as this means things - # are working the way they're supposed to. + # Normal behavior depends on the run_interval/recipes/default.rb to count down + # and exit subordinate chef-client after two runs. However, we will forcably + # kill the client if that didn't work. + begin + stdout_filename = "/tmp/chef.run_interval.stdout.#{$$}.txt" + stderr_filename = "/tmp/chef.run_interval.stderr.#{$$}.txt" + client_pid = Process.fork do + STDOUT.reopen(File.open(stdout_filename, "w")) + STDERR.reopen(File.open(stderr_filename, "w")) + exec chef_client_command_string() + exit 2 end - } - When 'I run the chef-client' - Process.waitpid2(cid) + + killer_pid = Process.fork { + sleep run_for.to_i + + # Send KILL to the child chef-client. Due to OHAI-223, where ohai sometimes + # ignores/doesn't exit correctly on receipt of SIGINT, brutally kill the + # subprocess. + begin + Process.kill("KILL", client_pid) + rescue Errno::ESRCH + # Kill didn't work; the process exited while we were waiting, like + # it's supposed to. + end + } + + Process.waitpid2(killer_pid) + @status = Process.waitpid2(client_pid).last + + # Read these in so they can be used in later steps. + @stdout = IO.read(stdout_filename) + @stderr = IO.read(stderr_filename) + ensure + # clean up after ourselves. + File.delete(stdout_filename) + File.delete(stderr_filename) + end end When /^I run the chef\-client at log level '(.+)'$/ do |log_level| |