generate empty backtraces for EPIPE and ECONNRESET
[kgio.git] / test / lib_read_write.rb
blob146c222f201d3da7bc08ba2e6103920c3e3ba76e
1 require 'test/unit'
2 require 'io/nonblock'
3 $-w = true
4 require 'kgio'
6 module LibReadWriteTest
7   RANDOM_BLOB = File.open("/dev/urandom") { |fp| fp.read(10 * 1024 * 1024) }
9   def teardown
10     assert_nothing_raised do
11       @rd.close unless @rd.closed?
12       @wr.close unless @wr.closed?
13     end
14     assert_nothing_raised do
15       Kgio.wait_readable = Kgio.wait_writable = nil
16     end
17   end
19   def test_read_eof
20     @wr.close
21     assert_nil @rd.kgio_read(5)
22   end
24   def test_read_bang_eof
25     @wr.close
26     begin
27       @rd.kgio_read!(5)
28       assert false, "should never get here (line:#{__LINE__})"
29     rescue EOFError => e
30       assert_equal [], e.backtrace
31     end
32   end
34   def test_tryread_eof
35     @wr.close
36     assert_nil @rd.kgio_tryread(5)
37   end
39   def test_write_closed
40     @rd.close
41     begin
42       loop { @wr.kgio_write "HI" }
43     rescue Errno::EPIPE, Errno::ECONNRESET => e
44       assert_equal [], e.backtrace
45       return
46     end
47     assert false, "should never get here (line:#{__LINE__})"
48   end
50   def test_trywrite_closed
51     @rd.close
52     begin
53       loop { @wr.kgio_trywrite "HI" }
54     rescue Errno::EPIPE, Errno::ECONNRESET => e
55       assert_equal [], e.backtrace
56       return
57     end
58     assert false, "should never get here (line:#{__LINE__})"
59   end
61   def test_write_conv
62     assert_equal nil, @wr.kgio_write(10)
63     assert_equal "10", @rd.kgio_read(2)
64   end
66   def test_trywrite_conv
67     assert_equal nil, @wr.kgio_trywrite(10)
68     assert_equal "10", @rd.kgio_tryread(2)
69   end
71   def test_tryread_empty
72     assert_equal Kgio::WaitReadable, @rd.kgio_tryread(1)
73   end
75   def test_read_too_much
76     assert_equal nil, @wr.kgio_write("hi")
77     assert_equal "hi", @rd.kgio_read(4)
78   end
80   def test_tryread_too_much
81     assert_equal nil, @wr.kgio_trywrite("hi")
82     assert_equal "hi", @rd.kgio_tryread(4)
83   end
85   def test_read_short
86     assert_equal nil, @wr.kgio_write("hi")
87     assert_equal "h", @rd.kgio_read(1)
88     assert_equal "i", @rd.kgio_read(1)
89   end
91   def test_tryread_short
92     assert_equal nil, @wr.kgio_trywrite("hi")
93     assert_equal "h", @rd.kgio_tryread(1)
94     assert_equal "i", @rd.kgio_tryread(1)
95   end
97   def test_read_extra_buf
98     tmp = ""
99     tmp_object_id = tmp.object_id
100     assert_equal nil, @wr.kgio_write("hi")
101     rv = @rd.kgio_read(2, tmp)
102     assert_equal "hi", rv
103     assert_equal rv.object_id, tmp.object_id
104     assert_equal tmp_object_id, rv.object_id
105   end
107   def test_trywrite_return_wait_writable
108     tmp = []
109     tmp << @wr.kgio_trywrite("HI") until tmp[-1] == Kgio::WaitWritable
110     assert_equal Kgio::WaitWritable, tmp.pop
111     assert tmp.size > 0
112     penultimate = tmp.pop
113     assert(penultimate == "I" || penultimate == nil)
114     assert tmp.size > 0
115     tmp.each { |count| assert_equal nil, count }
116   end
118   def test_tryread_extra_buf_eagain_clears_buffer
119     tmp = "hello world"
120     rv = @rd.kgio_tryread(2, tmp)
121     assert_equal Kgio::WaitReadable, rv
122     assert_equal "", tmp
123   end
125   def test_tryread_extra_buf_eof_clears_buffer
126     tmp = "hello world"
127     @wr.close
128     assert_nil @rd.kgio_tryread(2, tmp)
129     assert_equal "", tmp
130   end
132   def test_monster_trywrite
133     buf = RANDOM_BLOB.dup
134     rv = @wr.kgio_trywrite(buf)
135     assert_kind_of String, rv
136     assert rv.size < buf.size
137     @rd.nonblock = false
138     assert_equal(buf, @rd.read(buf.size - rv.size) + rv)
139   end
141   def test_monster_write
142     buf = RANDOM_BLOB.dup
143     thr = Thread.new { @wr.kgio_write(buf) }
144     @rd.nonblock = false
145     readed = @rd.read(buf.size)
146     thr.join
147     assert_nil thr.value
148     assert_equal buf, readed
149   end
151   def test_monster_write_wait_writable
152     @wr.instance_variable_set :@nr, 0
153     def @wr.wait_writable
154       @nr += 1
155       IO.select(nil, [self])
156     end
157     Kgio.wait_writable = :wait_writable
158     buf = "." * 1024 * 1024 * 10
159     thr = Thread.new { @wr.kgio_write(buf) }
160     readed = @rd.read(buf.size)
161     thr.join
162     assert_nil thr.value
163     assert_equal buf, readed
164     assert @wr.instance_variable_get(:@nr) > 0
165   end
167   def test_wait_readable_ruby_default
168     assert_nothing_raised { Kgio.wait_readable = nil }
169     elapsed = 0
170     foo = nil
171     t0 = Time.now
172     thr = Thread.new { sleep 1; @wr.write "HELLO" }
173     assert_nothing_raised do
174       foo = @rd.kgio_read(5)
175       elapsed = Time.now - t0
176     end
177     assert elapsed >= 1.0, "elapsed: #{elapsed}"
178     assert_equal "HELLO", foo
179     thr.join
180     assert_equal 5, thr.value
181   end
183   def test_wait_writable_ruby_default
184     buf = "." * 512
185     nr = 0
186     begin
187       nr += @wr.write_nonblock(buf)
188     rescue Errno::EAGAIN
189       break
190     end while true
191     assert_nothing_raised { Kgio.wait_writable = nil }
192     elapsed = 0
193     foo = nil
194     t0 = Time.now
195     thr = Thread.new { sleep 1; @rd.readpartial(nr) }
196     assert_nothing_raised do
197       foo = @wr.kgio_write("HELLO")
198       elapsed = Time.now - t0
199     end
200     assert_nil foo
201     if @wr.stat.pipe?
202       assert elapsed >= 1.0, "elapsed: #{elapsed}"
203     end
204     assert(String === foo || foo == nil)
205     assert_kind_of String, thr.value
206   end
208   def test_wait_readable_method
209     def @rd.moo
210       defined?(@z) ? raise(RuntimeError, "Hello") : @z = "HI"
211     end
212     assert_nothing_raised { Kgio.wait_readable = :moo }
213     foo = nil
214     begin
215       foo = @rd.kgio_read(5)
216       assert false
217     rescue RuntimeError => e
218       assert_equal("Hello", e.message)
219     end
220     assert_equal "HI", @rd.instance_variable_get(:@z)
221     assert_nil foo
222   end
224   def test_tryread_wait_readable_method
225     def @rd.moo
226       raise "Hello"
227     end
228     assert_nothing_raised { Kgio.wait_readable = :moo }
229     assert_equal Kgio::WaitReadable, @rd.kgio_tryread(5)
230   end
232   def test_trywrite_wait_readable_method
233     def @wr.moo
234       raise "Hello"
235     end
236     assert_nothing_raised { Kgio.wait_writable = :moo }
237     tmp = []
238     buf = "." * 1024
239     10000.times { tmp << @wr.kgio_trywrite(buf) }
240     assert_equal Kgio::WaitWritable, tmp.pop
241   end
243   def test_wait_writable_method
244     def @wr.moo
245       defined?(@z) ? raise(RuntimeError, "Hello") : @z = "HI"
246     end
247     assert_nothing_raised { Kgio.wait_writable = :moo }
248     n = []
249     begin
250       loop { n << @wr.kgio_write("HIHIHIHIHIHI") }
251       assert false
252     rescue RuntimeError => e
253       assert_equal("Hello", e.message)
254     end
255     assert n.size > 0
256     assert_equal "HI", @wr.instance_variable_get(:@z)
257   end