diff options
author | normal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2015-07-18 01:29:25 +0000 |
---|---|---|
committer | normal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2015-07-18 01:29:25 +0000 |
commit | 810df4e5163ca4ecf7d5266321aae582961817fe (patch) | |
tree | b149f3c7971ad753be36d4f554a89b82aa71be42 | |
parent | 0e57dbc634ebb0176720c978839add58c2975fd0 (diff) | |
download | ruby-810df4e5163ca4ecf7d5266321aae582961817fe.tar.gz |
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
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | test/ruby/test_process.rb | 70 |
2 files changed, 74 insertions, 0 deletions
@@ -1,3 +1,7 @@ +Sat Jul 18 10:29:03 2015 Eric Wong <e@80x24.org> + + * test/ruby/test_process.rb: test thread+sigs work after failed exec + Sat Jul 18 07:20:18 2015 Jeremy Evans <code@jeremyevans.net> * test/socket/test_nonblock: use smaller buffer for sendmsg 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 |