[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Test::Unit teardown with child process

Brian Candler

3/19/2005 11:15:00 AM

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


1 Answer

Ryan Davis

3/19/2005 6:56:00 PM

0


On Mar 19, 2005, at 3:15 AM, Brian Candler wrote:

> 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

I've been tearing up rubicon in the past couple of days and noticed
something similar that might help you:

def teardown
if $os != MsWin32 && $os != JRuby
begin
loop { Process.wait; $stderr.puts "\n\nCHILD REAPED\n\n" }
rescue Errno::ECHILD
end
end
super
end


--
ryand-ruby@zenspider.com - Seattle.rb -
http://www.zenspider.com/...
http://blog.zens... - http://rubyforge.org/proje...