From: Mat Schaffer Date: 2007-01-04T01:33:05+09:00 Subject: Re: Problem in Unit Testing Methods that start new threads On Jan 3, 2007, at 8:30 AM, Hemant Kumar wrote: > I have a bit of doubt, in Unit Testing Programs that start new > threads. > Please have a look at the code below: > > > class Foobar > > def hello_world > p "Hello World" > @thread_status = false > end > > def new_thread_start > Thread.new do > sleep(100) > @thread_status = true > end > end > > end > > # here goes the lame test case > require "test/unit" > > module Test::Unit::Assertions > def assert_false(t_object,message=nil) > boolean = !t_object > full_message = build_message(message,' Object is not > false',boolean) > assert_block(full_message) { boolean} > end > end > > class TestFoobar < Test::Unit::TestCase > def setup > @foo = Foobar.new > class << @foo > def ivar var > instance_variable_get(:"@#{var}") > end > end > end > > def test_hello_world > @foo.hello_world > assert_false @foo.ivar(:thread_status) > end > > > def test_new_thread > # sorry for a bit of not so DRY thingy > @foo.hello_world > assert_false @foo.ivar(:thread_status) > @foo.new_thread_start > > # next assert is true because method was started in a new thread > # and control came back immediately, what i would probably want is > # to wait here so that i can have proper check on the method and > # state of the program, but i am not sure, if that's exactly > # approach i should take. > > assert_false @foo.ivar(:thread_status) > end > end > > > Now, as someone suggested on IRC, I can do a join and wait for the > thread to finish. But the problem is, I don't exactly have an instance > to the thread, because its managed by a plugin and i am just using the > plugin to do stuff. > > Any ideas/suggestions are more than welcome. Ara's right on this one. It's a race condition. But it looks like you're interested in checking that the thread has indeed started. If I were to write something like this I would probably have the unit test run @foo.new_thread_start and immediately sleep waiting for a signal from the child thread. The child thread would then signal back to the any waiting threads that it had set it's thread status to true. Altough the more I ponder it, the more I feel like I've just moved the race condition to the sleep call. I'll have to review my concurrent programming texts a bit. Seems like you should do the same. Either way, check out Monitor for some insight: http://www.ruby-doc.org/stdlib/libdoc/monitor/rdoc/index.html -Mat