summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
Diffstat (limited to 'spec')
-rw-r--r--spec/mixlib/shellout_spec.rb53
1 files changed, 52 insertions, 1 deletions
diff --git a/spec/mixlib/shellout_spec.rb b/spec/mixlib/shellout_spec.rb
index 5e92a54..582aef4 100644
--- a/spec/mixlib/shellout_spec.rb
+++ b/spec/mixlib/shellout_spec.rb
@@ -825,7 +825,7 @@ describe Mixlib::ShellOut do
end
end
- context 'with subprocess that takes longer than timeout', :focus do
+ context 'with subprocess that takes longer than timeout' do
def ruby_wo_shell(code)
parts = %w[ruby]
parts << "--disable-gems" if ruby_19?
@@ -889,6 +889,57 @@ describe Mixlib::ShellOut do
end
end
+
+ context "and the child process forks grandchildren" do
+ let(:cmd) do
+ ruby_wo_shell(<<-CODE)
+ STDOUT.sync = true
+ trap(:TERM) { print "got term in child\n"; exit!(123) }
+ fork do
+ trap(:TERM) { print "got term in grandchild\n"; exit!(142) }
+ sleep 10
+ end
+ sleep 10
+ CODE
+ end
+
+ it "should TERM the wayward child and grandchild" do
+ # note: let blocks don't correctly memoize if an exception is raised,
+ # so can't use executed_cmd
+ lambda { shell_cmd.run_command}.should raise_error(Mixlib::ShellOut::CommandTimeout)
+ shell_cmd.stdout.should include("got term in child")
+ shell_cmd.stdout.should include("got term in grandchild")
+ end
+
+ end
+ context "and the child process forks grandchildren that don't respond to TERM" do
+ let(:cmd) do
+ ruby_wo_shell(<<-CODE)
+ STDOUT.sync = true
+ trap(:TERM) { print "got term in child\n" }
+ fork do
+ trap(:TERM) { print "got term in grandchild\n" }
+ sleep 10
+ end
+ sleep 10
+ CODE
+ end
+
+ it "should TERM the wayward child and grandchild, then KILL whoever is left" do
+ # note: let blocks don't correctly memoize if an exception is raised,
+ # so can't use executed_cmd
+ lambda { shell_cmd.run_command}.should raise_error(Mixlib::ShellOut::CommandTimeout)
+ shell_cmd.stdout.should include("got term in child")
+ shell_cmd.stdout.should include("got term in grandchild")
+
+ # A little janky. We get the process group id out of the command
+ # object, then try to kill a process in it to make sure none
+ # exists. Trusting the system under test like this isn't great but
+ # it's difficult to test otherwise.
+ lambda { Process.kill(:INT, shell_cmd.send(:child_pgid)) }.should raise_error(Errno::ESRCH)
+ end
+
+ end
end
context 'with subprocess that exceeds buffersize' do