summaryrefslogtreecommitdiff
path: root/test/ruby/test_process.rb
diff options
context:
space:
mode:
authornormal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-07-18 01:29:25 +0000
committernormal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-07-18 01:29:25 +0000
commit3661dae19c734f8c0c63db08b150c90c04ec338a (patch)
treeb149f3c7971ad753be36d4f554a89b82aa71be42 /test/ruby/test_process.rb
parent1d9cf30d39e869e56fc61c32318bd6fc8110d674 (diff)
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
Diffstat (limited to 'test/ruby/test_process.rb')
-rw-r--r--test/ruby/test_process.rb70
1 files changed, 70 insertions, 0 deletions
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