1 # -*- encoding: binary -*-
9 module LibReadWriteTest
10 RANDOM_BLOB = File.open("/dev/urandom") do |fp|
13 # get roughly a 20MB block of random data
14 (buf * (20 * 1024 * 1024 / nr)) + (buf * rand(123))
18 @rd.close if defined?(@rd) && ! @rd.closed?
19 @wr.close if defined?(@wr) && ! @wr.closed?
20 FileUtils.remove_entry_secure(@tmpdir) if defined?(@tmpdir)
24 assert_nil @wr.kgio_write("")
27 def test_trywrite_empty
28 assert_nil @wr.kgio_trywrite("")
32 assert_nil @wr.kgio_writev([])
35 def test_trywritev_empty
36 assert_nil @wr.kgio_trywritev([])
40 assert_equal "", @rd.kgio_read(0)
42 assert_equal buf.object_id, @rd.kgio_read(0, buf).object_id
50 assert_equal "a", @rd.kgio_read(0x1000, a)
52 assert_equal "." * 0x1000, b
55 def test_read_shared_2
59 assert_equal "a", @rd.kgio_read(0x1000, b)
61 assert_equal "." * 0x1000, a
65 assert_equal "", @rd.kgio_tryread(0)
67 assert_equal buf.object_id, @rd.kgio_tryread(0, buf).object_id
71 def test_tryread_shared
75 IO.select([@rd]) # this seems needed on FreeBSD 9.0
76 assert_equal "a", @rd.kgio_tryread(0x1000, b)
78 assert_equal "." * 0x1000, a
81 def test_tryread_shared_2
85 IO.select([@rd]) # this seems needed on FreeBSD 9.0
86 assert_equal "a", @rd.kgio_tryread(0x1000, a)
88 assert_equal "." * 0x1000, b
93 assert_nil @rd.kgio_read(5)
96 def test_read_bang_eof
100 assert false, "should never get here (line:#{__LINE__})"
102 assert_equal [], e.backtrace
108 IO.select([@rd]) # this seems needed on FreeBSD 9.0
109 assert_nil @rd.kgio_tryread(5)
112 def test_write_closed
115 loop { @wr.kgio_write "HI" }
116 rescue Errno::EPIPE, Errno::ECONNRESET => e
117 assert_equal [], e.backtrace
120 assert false, "should never get here (line:#{__LINE__})"
123 def test_trywrite_closed
126 loop { @wr.kgio_trywrite "HI" }
127 rescue Errno::EPIPE, Errno::ECONNRESET => e
128 assert_equal [], e.backtrace
131 assert false, "should never get here (line:#{__LINE__})"
134 def test_writev_closed
137 loop { @wr.kgio_writev ["HI"] }
138 rescue Errno::EPIPE, Errno::ECONNRESET => e
139 assert_equal [], e.backtrace
142 assert false, "should never get here (line:#{__LINE__})"
145 def test_trywritev_closed
148 loop { @wr.kgio_trywritev ["HI"] }
149 rescue Errno::EPIPE, Errno::ECONNRESET => e
150 assert_equal [], e.backtrace
153 assert false, "should never get here (line:#{__LINE__})"
156 def test_trywrite_full
157 buf = "\302\251" * 1024 * 1024
159 dig = Digest::SHA1.new
164 dig.update(@rd.readpartial(4096, buf2))
175 rv = @wr.kgio_trywrite(wr)
180 assert false, "should never get here line=#{__LINE__}"
182 IO.select(nil, [ @wr ])
190 assert_equal '8ff79d8115f9fe38d18be858c66aa08a1cc27a66', t.value
193 def test_trywritev_full
194 buf = ["\302\251" * 128] * 8 * 1024
196 dig = Digest::SHA1.new
201 dig.update(@rd.readpartial(4096, buf2))
212 rv = @wr.kgio_trywritev(wr)
217 assert false, "should never get here line=#{__LINE__}"
219 IO.select(nil, [ @wr ])
227 assert_equal '8ff79d8115f9fe38d18be858c66aa08a1cc27a66', t.value
231 assert_equal nil, @wr.kgio_write(10)
232 assert_equal "10", @rd.kgio_read(2)
235 def test_trywrite_conv
236 assert_equal nil, @wr.kgio_trywrite(10)
237 IO.select([@rd]) # this seems needed on FreeBSD 9.0
238 assert_equal "10", @rd.kgio_tryread(2)
241 def test_tryread_empty
242 assert_equal :wait_readable, @rd.kgio_tryread(1)
245 def test_read_too_much
246 assert_equal nil, @wr.kgio_write("hi")
247 assert_equal "hi", @rd.kgio_read(4)
250 def test_tryread_too_much
251 assert_equal nil, @wr.kgio_trywrite("hi")
252 assert_equal @rd, @rd.kgio_wait_readable
253 assert_equal "hi", @rd.kgio_tryread(4)
257 assert_equal nil, @wr.kgio_write("hi")
258 assert_equal "h", @rd.kgio_read(1)
259 assert_equal "i", @rd.kgio_read(1)
262 def test_tryread_short
263 assert_equal nil, @wr.kgio_trywrite("hi")
264 IO.select([@rd]) # this seems needed on FreeBSD 9.0
265 assert_equal "h", @rd.kgio_tryread(1)
266 assert_equal "i", @rd.kgio_tryread(1)
269 def test_read_extra_buf
271 tmp_object_id = tmp.object_id
272 assert_equal nil, @wr.kgio_write("hi")
273 rv = @rd.kgio_read(2, tmp)
274 assert_equal "hi", rv
275 assert_equal rv.object_id, tmp.object_id
276 assert_equal tmp_object_id, rv.object_id
279 def test_trywrite_return_wait_writable
281 tmp << @wr.kgio_trywrite("HI") until tmp[-1] == :wait_writable
282 assert :wait_writable === tmp[-1]
283 assert(!(:wait_readable === tmp[-1]))
284 assert_equal :wait_writable, tmp.pop
286 penultimate = tmp.pop
287 assert(penultimate == "I" || penultimate == nil)
289 tmp.each { |count| assert_equal nil, count }
292 def test_trywritev_return_wait_writable
294 tmp << @wr.kgio_trywritev(["HI"]) until tmp[-1] == :wait_writable
295 assert :wait_writable === tmp[-1]
296 assert(!(:wait_readable === tmp[-1]))
297 assert_equal :wait_writable, tmp.pop
299 penultimate = tmp.pop
300 assert(penultimate == ["I"] || penultimate == nil,
301 "penultimate is #{penultimate.inspect}")
303 tmp.each { |count| assert_equal nil, count }
306 def test_tryread_extra_buf_eagain_clears_buffer
308 rv = @rd.kgio_tryread(2, tmp)
309 assert_equal :wait_readable, rv
313 def test_tryread_extra_buf_eof_clears_buffer
316 IO.select([@rd]) # this seems needed on FreeBSD 9.0
317 assert_nil @rd.kgio_tryread(2, tmp)
321 def test_monster_trywrite
322 buf = RANDOM_BLOB.dup
323 rv = @wr.kgio_trywrite(buf)
324 assert_kind_of String, rv
325 assert rv.size < buf.size
327 assert_equal(buf, @rd.read(buf.size - rv.size) + rv)
330 def test_monster_write
331 buf = RANDOM_BLOB.dup
332 thr = Thread.new { @wr.kgio_write(buf) }
334 readed = @rd.read(buf.size)
337 assert_equal buf, readed
340 def test_monster_trywritev
342 while start < RANDOM_BLOB.size
343 s = RANDOM_BLOB[start, 1000]
347 rv = @wr.kgio_trywritev(buf)
348 assert_kind_of Array, rv
350 assert rv.size < RANDOM_BLOB.size
352 assert_equal(RANDOM_BLOB, @rd.read(RANDOM_BLOB.size - rv.size) + rv)
355 def test_monster_writev
357 while start < RANDOM_BLOB.size
358 s = RANDOM_BLOB[start, 10000]
362 thr = Thread.new { @wr.kgio_writev(buf) }
364 readed = @rd.read(RANDOM_BLOB.size)
367 e = (RANDOM_BLOB == readed)
371 def test_monster_write_wait_writable
372 @wr.instance_variable_set :@nr, 0
373 def @wr.kgio_wait_writable
375 IO.select(nil, [self])
378 thr = Thread.new { @wr.kgio_write(buf) }
379 Thread.pass until thr.stop?
380 readed = @rd.read(buf.size)
383 assert_equal buf, readed
384 assert @wr.instance_variable_get(:@nr) > 0
387 def test_monster_writev_wait_writable
388 @wr.instance_variable_set :@nr, 0
389 def @wr.kgio_wait_writable
391 IO.select(nil, [self])
393 buf = [ RANDOM_BLOB, RANDOM_BLOB ]
394 buf_size = buf.inject(0){|c, s| c + s.size}
395 thr = Thread.new { @wr.kgio_writev(buf) }
396 Thread.pass until thr.stop?
397 readed = @rd.read(buf_size)
400 e = (buf.join == readed)
402 assert @wr.instance_variable_get(:@nr) > 0
405 def test_wait_readable_ruby_default
409 thr = Thread.new { sleep 1; @wr.write "HELLO" }
410 foo = @rd.kgio_read(5)
411 elapsed = Time.now - t0
412 assert elapsed >= 1.0, "elapsed: #{elapsed}"
413 assert_equal "HELLO", foo
415 assert_equal 5, thr.value
418 def test_wait_writable_ruby_default
422 nr += @wr.write_nonblock(buf)
429 thr = Thread.new { sleep 1; @rd.read(nr) }
430 foo = @wr.kgio_write("HELLO")
431 elapsed = Time.now - t0
435 assert elapsed >= 1.0, "elapsed: #{elapsed}"
437 assert(String === foo || foo == nil)
438 assert_kind_of String, thr.value
441 def test_wait_readable_method
442 def @rd.kgio_wait_readable
443 defined?(@z) ? raise(RuntimeError, "Hello") : @z = "HI"
447 foo = @rd.kgio_read(5)
449 rescue RuntimeError => e
450 assert_equal("Hello", e.message)
452 assert_equal "HI", @rd.instance_variable_get(:@z)
456 def test_tryread_wait_readable_method
457 def @rd.kgio_wait_readable
460 assert_equal :wait_readable, @rd.kgio_tryread(5)
463 def test_trywrite_wait_readable_method
464 def @wr.kgio_wait_writable
469 until rv == :wait_writable
470 rv = @wr.kgio_trywrite(buf)
472 assert_equal :wait_writable, rv
475 def test_wait_writable_method
476 def @wr.kgio_wait_writable
477 defined?(@z) ? raise(RuntimeError, "Hello") : @z = "HI"
481 loop { n << @wr.kgio_write("HIHIHIHIHIHI") }
483 rescue RuntimeError => e
484 assert_equal("Hello", e.message)
487 assert_equal "HI", @wr.instance_variable_get(:@z)