From: "shinichiro.h" Date: 2008-11-19T02:15:39+09:00 Subject: [ruby-dev:37119] test/rinda/test_rinda.rb fails occasionally 浜地です。 なんか体感で 1/5 くらいの確率で test_rinda.rb が 1) Failure: test_core_03_notify(Rinda::TupleSpaceTest) [/home/i/src/ruby_orig/test/rinda/test_rinda.rb:396]: <[0, 3]> expected but was <[0, 1]>. などと言ってコケるので、少し眺めてみました。 よくわかってませんが MockClock が mock しきれてなくて ちょっとずれてるんじゃないかと思います。 expire する timeout をちょっとゆとりを加えてやると 100回やって100回通ったのでまぁマシになってはいるのでないかと。 さらにレアな 1) Failure: test_core_03_notify(Rinda::TupleSpaceTest) [/home/i/src/ruby/test/rinda/test_rin da.rb:408]: <["delete", {"message"=>"second", "name"=>"1"}]> expected but was <["close"]>. の方ですが(数十回に1回出る程度?)、これも notify3 の timeout にゆとりを持たせたら出なくなったように思います。 ついでに sleep の意図がよくわからなかったので コメントを足しておいたのと、 listener1 と listener2 で スタイルが違うことに意味を見出せなかったのでいじっておきました。 マジメに修正するならおそらく MockClock を deterministic な形に書き直すべきなのかな、 と思いますが確信はありません。 Index: test/rinda/test_rinda.rb =================================================================== --- test/rinda/test_rinda.rb (revision 20267) +++ test/rinda/test_rinda.rb (working copy) @@ -317,8 +317,8 @@ def test_core_03_notify notify1 = @ts.notify(nil, [:req, Integer]) - notify2 = @ts.notify(nil, [:ans, Integer], 5) - notify3 = @ts.notify(nil, {"message"=>String, "name"=>String}, 5) + notify2 = @ts.notify(nil, [:ans, Integer], 8) + notify3 = @ts.notify(nil, {"message"=>String, "name"=>String}, 8) @ts.write({"message"=>"first", "name"=>"3"}, 3) @ts.write({"message"=>"second", "name"=>"1"}, 1) @@ -347,18 +347,18 @@ result = nil lv = 0 n = 0 - notify2.each do |ev| + notify2.each do |ev, tuple| n += 1 - if ev[0] == 'write' + if ev == 'write' lv = lv + 1 - elsif ev[0] == 'take' + elsif ev == 'take' lv = lv - 1 - elsif ev[0] == 'close' + elsif ev == 'close' result = [lv, n] break end assert(lv >= 0) - assert_equal([:ans, 10], ev[1]) + assert_equal([:ans, 10], tuple) end result end @@ -385,13 +385,15 @@ sleep(4) assert_equal(10, thread_join(taker)) + # notify2 must not expire until this @ts.take. + # sleep(4) might be short enough for the timeout of notify2 (8 secs) tuple = @ts.take([:ans, nil]) assert_equal(10, tuple[1]) assert_equal([], @ts.read_all([nil, nil])) - + notify1.cancel - sleep(3) # notify2 expired - + sleep(7) # notify2 expired (sleep(4)+sleep(7) > 8) + assert_equal([0, 11], thread_join(listener1)) assert_equal([0, 3], thread_join(listener2))