From: Brian Candler Date: 2005-03-19T20:15:09+09:00 Subject: Test::Unit teardown with child process I have a suggestion which might improve the behaviour of the 'teardown' facility in Test::Unit. I had a problem where my tests were being torn down prematurely, which took some hunting around to find. It turned out that it was because my tests were forking a child process using IO.popen, and when the child terminated, the teardown was being called. The test script attached below demonstrates this. I can work around it like this: class MyTest < Test::Unit::TestCase BASEPID = $$ def teardown # If we are a child process exiting, don't do any teardown return unless BASEPID == $$ .. do stuff end end But I think it would be nice if the Test::Unit infrastructure could take care of that, i.e. only call the teardown methods if the current pid is the same as the pid when the 'setup' method was called. However, I have to say I don't understand this entirely. If I fork a child using Process.fork then the child's termination *doesn't* cause the teardown to be called - see method test2 in the attached script. Any ideas why test1 and test2 should be different in this regard? Regards, Brian. ------------------------------------------------------------------------- require 'test/unit' class MyTest < Test::Unit::TestCase def setup $stderr.puts "setup #{$$}" File.open("xxx","w") { |f| f.puts "testdata" } end def teardown $stderr.puts "teardown #{$$}" File.delete("xxx") end # This test fails; teardown is called prematurely def test1 res = nil IO.popen("-") do |pipe| if pipe res = pipe.read else puts "hello" exit 0 end end assert_match(/hello/, res, "child status") data = nil File.open("xxx") { |f| data = f.read } assert_match(/testdata/, data) end # Strangely, this test succeeds def test2 pid = Process.fork do puts "Child OK #{$$}" exit 0 end dummy, status = Process.waitpid2(pid) assert_equal(pid, dummy, "correct pid") assert_equal(0, status.exitstatus, "correct exit status") sleep 1 data = nil File.open("xxx") { |f| data = f.read } assert_match(/testdata/, data) end end