From: Tomoyuki Chikanaga Date: 2010-05-26T18:28:06+09:00 Subject: [ruby-dev:41422] trunk/1.9.2 で test_io.rb が test_print_separators で固まる 近永と申します。 Bug なのか環境が悪いのか単に test の問題なのか判断がつかないので ML で報告させて頂きます。 ruby_1_9_2 ブランチと trunk で、make test-all が以下のように固まって進まなくなってしまいます。 $ uname -a Linux cluster05 2.4.21-47.ELsmp #1 SMP Wed Jul 5 20:38:41 EDT 2006 i686 i686 i386 GNU/Linux $ ./ruby-trunk -v ruby 1.9.3dev (2010-05-25 trunk 28010) [i686-linux] $ make test-all TESTS=-v (snip) TestIO#test_pipe_block_close: 0.00 s: . TestIO#test_pos: 0.00 s: . TestIO#test_print: 0.05 s: . TestIO#test_print_separators: ↑ここで止まる test_io.rb から抜き出して削っていくと以下の内容で再現できました。 ========= 再現スクリプト ========== begin Thread.new do thr = Thread.start { sleep } $SAFE = 4 thr.kill end.join rescue SecurityError puts "caught SecurityError : #{$!}" end #$, = ':' $\ = "\n" r, w = IO.pipe w.print('a') # <- hangup here w.close r.close =================================== shrink の過程で * $SAFE = 4 とするテストで Timeout.timeout を利用しているために timeout メソッドの ensure 節の Thread#kill が SecurityError 例外を 発生させてしまい、本来テストしたい SecurityError 例外の発生が確認できていない * test_print_separators で pipe の読み書きでブロックしていた ので、それぞれ他のテストを参考に回避するパッチを書きテストは通るようになりました。 末尾にパッチをはりつけています。 気になるのは、test_print_separators の内容はそれだけを実行すれば通るということです。 pipe への書き込みが(読み出されないと)ブロックしてしまうこと自体はありうるとは思いますが その前に SecurityError 例外の発生?があるかどうかでブロックせずに pipe に書き込める サイズが変化してしまうのがどうも関連があるように思えなくてすっきりしません。 これはこういうものでしょうか?あるいは何かバグが潜んでいる予兆でしょうか? 以上、よろしくお願い致します。 Index: test/ruby/test_io.rb =================================================================== --- test/ruby/test_io.rb (revision 28018) +++ test/ruby/test_io.rb (working copy) @@ -740,12 +740,12 @@ end def safe_4 - Thread.new do - Timeout.timeout(10) do - $SAFE = 4 - yield - end - end.join + unless (Thread.new do + $SAFE = 4 + yield + end.join(10)) + flunk("timeout in safe_4") + end end def pipe(wp, rp) @@ -1461,15 +1461,16 @@ def test_print_separators $, = ':' $\ = "\n" - r, w = IO.pipe - w.print('a') - w.print('a','b','c') - w.close - assert_equal("a\n", r.gets) - assert_equal("a:b:c\n", r.gets) - assert_nil r.gets - r.close - + pipe(proc do |w| + w.print('a') + w.print('a','b','c') + w.close + end, proc do |r| + assert_equal("a\n", r.gets) + assert_equal("a:b:c\n", r.gets) + assert_nil r.gets + r.close + end) ensure $, = nil $\ = nil -- Chikanaga Tomoyuki Nippon Control System Corp.