From 3661dae19c734f8c0c63db08b150c90c04ec338a Mon Sep 17 00:00:00 2001 From: normal Date: Sat, 18 Jul 2015 01:29:25 +0000 Subject: test/ruby/test_process.rb: test thread+sigs work after failed exec Preparation for possible upcoming changes to timer thread. We need to ensure signal handling and thread scheduling works after an exec failure. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51289 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- test/ruby/test_process.rb | 70 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) (limited to 'test') diff --git a/test/ruby/test_process.rb b/test/ruby/test_process.rb index 00bbf9ee0b..80dc3446e5 100644 --- a/test/ruby/test_process.rb +++ b/test/ruby/test_process.rb @@ -2092,4 +2092,74 @@ EOS end } end + + def test_signals_work_after_exec_fail + r, w = IO.pipe + pid = status = nil + Timeout.timeout(30) do + pid = fork do + r.close + begin + trap(:USR1) { w.syswrite("USR1\n"); exit 0 } + exec "/path/to/non/existent/#$$/#{rand}.ex" + rescue SystemCallError + w.syswrite("exec failed\n") + end + sleep + exit 1 + end + w.close + assert_equal "exec failed\n", r.gets + Process.kill(:USR1, pid) + assert_equal "USR1\n", r.gets + assert_nil r.gets + _, status = Process.waitpid2(pid) + end + assert_predicate status, :success? + rescue Timeout::Error + begin + Process.kill(:KILL, pid) + rescue Errno::ESRCH + end + raise + ensure + w.close if w + r.close if r + end if defined?(fork) + + def test_threading_works_after_exec_fail + r, w = IO.pipe + pid = status = nil + Timeout.timeout(30) do + pid = fork do + r.close + begin + exec "/path/to/non/existent/#$$/#{rand}.ex" + rescue SystemCallError + w.syswrite("exec failed\n") + end + run = true + th1 = Thread.new { i = 0; i += 1 while run; i } + th2 = Thread.new { j = 0; j += 1 while run && Thread.pass.nil?; j } + sleep 0.5 + run = false + w.syswrite "#{th1.value} #{th2.value}\n" + end + w.close + assert_equal "exec failed\n", r.gets + vals = r.gets.chomp.split.map!(&:to_i) + assert_operator vals[0], :>, vals[1], vals.inspect + _, status = Process.waitpid2(pid) + end + assert_predicate status, :success? + rescue Timeout::Error + begin + Process.kill(:KILL, pid) + rescue Errno::ESRCH + end + raise + ensure + w.close if w + r.close if r + end if defined?(fork) end -- cgit v1.2.3