Bug #13405
closedIO#close raises "stream closed"
Description
IO#close is supposed to ignore an IOError indicating the stream is already closed.
Since #10153, however, it can raise the ruby_error_closed_stream
special exception, because that exception's message is "stream closed" instead of "closed stream".
The fix seems easy -- the mismatched string should be updated to use the more common spelling, with something like:
diff --git a/test/lib/test/unit.rb b/test/lib/test/unit.rb
index 6cb22e725a..d1efa5dcfd 100644
--- a/test/lib/test/unit.rb
+++ b/test/lib/test/unit.rb
@@ -228,7 +228,7 @@ def run(task,type)
rescue Errno::EPIPE
died
rescue IOError
- raise unless ["stream closed","closed stream"].include? $!.message
+ raise unless $!.message == "closed stream"
died
end
end
diff --git a/test/lib/test/unit/parallel.rb b/test/lib/test/unit/parallel.rb
index 50d4427189..09a5530b04 100644
--- a/test/lib/test/unit/parallel.rb
+++ b/test/lib/test/unit/parallel.rb
@@ -61,7 +61,7 @@ def _run_suite(suite, type) # :nodoc:
begin
th.join
rescue IOError
- raise unless ["stream closed","closed stream"].include? $!.message
+ raise unless $!.message == "closed stream"
end
i.close
diff --git a/test/ruby/test_io.rb b/test/ruby/test_io.rb
index ca3f1e2d3b..5775e31dde 100644
--- a/test/ruby/test_io.rb
+++ b/test/ruby/test_io.rb
@@ -3411,7 +3411,7 @@ def test_race_closed_stream
end
sleep 0.01
r.close
- assert_raise_with_message(IOError, /stream closed/) do
+ assert_raise_with_message(IOError, /closed stream/) do
thread.join
end
assert_equal(true, closed, "#{bug13158}: stream should be closed")
diff --git a/thread.c b/thread.c
index 5d27681b40..4e6faf6dc8 100644
--- a/thread.c
+++ b/thread.c
@@ -4883,7 +4883,7 @@ Init_Thread(void)
rb_define_method(rb_cThread, "name=", rb_thread_setname, 1);
rb_define_method(rb_cThread, "inspect", rb_thread_inspect, 0);
- rb_vm_register_special_exception(ruby_error_closed_stream, rb_eIOError, "stream closed");
+ rb_vm_register_special_exception(ruby_error_closed_stream, rb_eIOError, "closed stream");
cThGroup = rb_define_class("ThreadGroup", rb_cObject);
rb_define_alloc_func(cThGroup, thgroup_s_alloc);
I can't work out how to prove this fixes the problem, however. :(
The existing test in test_io.rb
shows how to cause the special exception to be raised from gets
, but I haven't managed to synthetically force close
to raise it.
I know it's possible, though: we're seeing this problem semi-frequently in the Rails test suite (e.g. https://travis-ci.org/rails/rails/jobs/218895049#L499) -- though it's partly hidden by #13239 when it occurs on 2.2 and 2.3.