HACKING: updates for wrongdoc vs rdoc
[kgio.git] / test / lib_read_write.rb
blob593a9e902e38c116007240db26bf4eabf8b9b06b
1 # -*- encoding: binary -*-
2 require 'test/unit'
3 require 'io/nonblock'
4 require 'digest/sha1'
5 $-w = true
6 require 'kgio'
8 module LibReadWriteTest
9   RANDOM_BLOB = File.open("/dev/urandom") { |fp| fp.read(10 * 1024 * 1024) }
11   def teardown
12     assert_nothing_raised do
13       @rd.close if defined?(@rd) && ! @rd.closed?
14       @wr.close if defined?(@wr) && ! @wr.closed?
15     end
16   end
18   def test_write_empty
19     assert_nil @wr.kgio_write("")
20   end
22   def test_trywrite_empty
23     assert_nil @wr.kgio_trywrite("")
24   end
26   def test_read_zero
27     assert_equal "", @rd.kgio_read(0)
28     buf = "foo"
29     assert_equal buf.object_id, @rd.kgio_read(0, buf).object_id
30     assert_equal "", buf
31   end
33   def test_tryread_zero
34     assert_equal "", @rd.kgio_tryread(0)
35     buf = "foo"
36     assert_equal buf.object_id, @rd.kgio_tryread(0, buf).object_id
37     assert_equal "", buf
38   end
40   def test_read_eof
41     @wr.close
42     assert_nil @rd.kgio_read(5)
43   end
45   def test_read_bang_eof
46     @wr.close
47     begin
48       @rd.kgio_read!(5)
49       assert false, "should never get here (line:#{__LINE__})"
50     rescue EOFError => e
51       assert_equal [], e.backtrace
52     end
53   end
55   def test_tryread_eof
56     @wr.close
57     assert_nil @rd.kgio_tryread(5)
58   end
60   def test_write_closed
61     @rd.close
62     begin
63       loop { @wr.kgio_write "HI" }
64     rescue Errno::EPIPE, Errno::ECONNRESET => e
65       assert_equal [], e.backtrace
66       return
67     end
68     assert false, "should never get here (line:#{__LINE__})"
69   end
71   def test_trywrite_closed
72     @rd.close
73     begin
74       loop { @wr.kgio_trywrite "HI" }
75     rescue Errno::EPIPE, Errno::ECONNRESET => e
76       assert_equal [], e.backtrace
77       return
78     end
79     assert false, "should never get here (line:#{__LINE__})"
80   end
82   def test_trywrite_full
83     buf = "\302\251" * 1024 * 1024
84     buf2 = ""
85     dig = Digest::SHA1.new
86     t = Thread.new do
87       sleep 1
88       nr = 0
89       begin
90         dig.update(@rd.readpartial(4096, buf2))
91         nr += buf2.size
92       rescue EOFError
93         break
94       rescue => e
95       end while true
96       dig.hexdigest
97     end
98     50.times do
99       wr = buf
100       begin
101         rv = @wr.kgio_trywrite(wr)
102         case rv
103         when String
104           wr = rv
105         when :wait_readable
106           assert false, "should never get here line=#{__LINE__}"
107         when :wait_writable
108           IO.select(nil, [ @wr ])
109         else
110           wr = false
111         end
112       end while wr
113     end
114     @wr.close
115     t.join
116     assert_equal '8ff79d8115f9fe38d18be858c66aa08a1cc27a66', t.value
117   end
119   def test_write_conv
120     assert_equal nil, @wr.kgio_write(10)
121     assert_equal "10", @rd.kgio_read(2)
122   end
124   def test_trywrite_conv
125     assert_equal nil, @wr.kgio_trywrite(10)
126     assert_equal "10", @rd.kgio_tryread(2)
127   end
129   def test_tryread_empty
130     assert_equal :wait_readable, @rd.kgio_tryread(1)
131   end
133   def test_read_too_much
134     assert_equal nil, @wr.kgio_write("hi")
135     assert_equal "hi", @rd.kgio_read(4)
136   end
138   def test_tryread_too_much
139     assert_equal nil, @wr.kgio_trywrite("hi")
140     assert_equal "hi", @rd.kgio_tryread(4)
141   end
143   def test_read_short
144     assert_equal nil, @wr.kgio_write("hi")
145     assert_equal "h", @rd.kgio_read(1)
146     assert_equal "i", @rd.kgio_read(1)
147   end
149   def test_tryread_short
150     assert_equal nil, @wr.kgio_trywrite("hi")
151     assert_equal "h", @rd.kgio_tryread(1)
152     assert_equal "i", @rd.kgio_tryread(1)
153   end
155   def test_read_extra_buf
156     tmp = ""
157     tmp_object_id = tmp.object_id
158     assert_equal nil, @wr.kgio_write("hi")
159     rv = @rd.kgio_read(2, tmp)
160     assert_equal "hi", rv
161     assert_equal rv.object_id, tmp.object_id
162     assert_equal tmp_object_id, rv.object_id
163   end
165   def test_trywrite_return_wait_writable
166     tmp = []
167     tmp << @wr.kgio_trywrite("HI") until tmp[-1] == :wait_writable
168     assert :wait_writable === tmp[-1]
169     assert(!(:wait_readable === tmp[-1]))
170     assert_equal :wait_writable, tmp.pop
171     assert tmp.size > 0
172     penultimate = tmp.pop
173     assert(penultimate == "I" || penultimate == nil)
174     assert tmp.size > 0
175     tmp.each { |count| assert_equal nil, count }
176   end
178   def test_tryread_extra_buf_eagain_clears_buffer
179     tmp = "hello world"
180     rv = @rd.kgio_tryread(2, tmp)
181     assert_equal :wait_readable, rv
182     assert_equal "", tmp
183   end
185   def test_tryread_extra_buf_eof_clears_buffer
186     tmp = "hello world"
187     @wr.close
188     assert_nil @rd.kgio_tryread(2, tmp)
189     assert_equal "", tmp
190   end
192   def test_monster_trywrite
193     buf = RANDOM_BLOB.dup
194     rv = @wr.kgio_trywrite(buf)
195     assert_kind_of String, rv
196     assert rv.size < buf.size
197     @rd.nonblock = false
198     assert_equal(buf, @rd.read(buf.size - rv.size) + rv)
199   end
201   def test_monster_write
202     buf = RANDOM_BLOB.dup
203     thr = Thread.new { @wr.kgio_write(buf) }
204     @rd.nonblock = false
205     readed = @rd.read(buf.size)
206     thr.join
207     assert_nil thr.value
208     assert_equal buf, readed
209   end
211   def test_monster_write_wait_writable
212     @wr.instance_variable_set :@nr, 0
213     def @wr.kgio_wait_writable
214       @nr += 1
215       IO.select(nil, [self])
216     end
217     buf = "." * 1024 * 1024 * 10
218     thr = Thread.new { @wr.kgio_write(buf) }
219     readed = @rd.read(buf.size)
220     thr.join
221     assert_nil thr.value
222     assert_equal buf, readed
223     assert @wr.instance_variable_get(:@nr) > 0
224   end
226   def test_wait_readable_ruby_default
227     elapsed = 0
228     foo = nil
229     t0 = Time.now
230     thr = Thread.new { sleep 1; @wr.write "HELLO" }
231     assert_nothing_raised do
232       foo = @rd.kgio_read(5)
233       elapsed = Time.now - t0
234     end
235     assert elapsed >= 1.0, "elapsed: #{elapsed}"
236     assert_equal "HELLO", foo
237     thr.join
238     assert_equal 5, thr.value
239   end
241   def test_wait_writable_ruby_default
242     buf = "." * 512
243     nr = 0
244     begin
245       nr += @wr.write_nonblock(buf)
246     rescue Errno::EAGAIN
247       break
248     end while true
249     elapsed = 0
250     foo = nil
251     t0 = Time.now
252     thr = Thread.new { sleep 1; @rd.readpartial(nr) }
253     assert_nothing_raised do
254       foo = @wr.kgio_write("HELLO")
255       elapsed = Time.now - t0
256     end
257     assert_nil foo
258     if @wr.stat.pipe?
259       assert elapsed >= 1.0, "elapsed: #{elapsed}"
260     end
261     assert(String === foo || foo == nil)
262     assert_kind_of String, thr.value
263   end
265   def test_wait_readable_method
266     def @rd.kgio_wait_readable
267       defined?(@z) ? raise(RuntimeError, "Hello") : @z = "HI"
268     end
269     foo = nil
270     begin
271       foo = @rd.kgio_read(5)
272       assert false
273     rescue RuntimeError => e
274       assert_equal("Hello", e.message)
275     end
276     assert_equal "HI", @rd.instance_variable_get(:@z)
277     assert_nil foo
278   end
280   def test_tryread_wait_readable_method
281     def @rd.kgio_wait_readable
282       raise "Hello"
283     end
284     assert_equal :wait_readable, @rd.kgio_tryread(5)
285   end
287   def test_trywrite_wait_readable_method
288     def @wr.kgio_wait_writable
289       raise "Hello"
290     end
291     tmp = []
292     buf = "." * 1024
293     10000.times { tmp << @wr.kgio_trywrite(buf) }
294     assert_equal :wait_writable, tmp.pop
295   end
297   def test_wait_writable_method
298     def @wr.kgio_wait_writable
299       defined?(@z) ? raise(RuntimeError, "Hello") : @z = "HI"
300     end
301     n = []
302     begin
303       loop { n << @wr.kgio_write("HIHIHIHIHIHI") }
304       assert false
305     rescue RuntimeError => e
306       assert_equal("Hello", e.message)
307     end
308     assert n.size > 0
309     assert_equal "HI", @wr.instance_variable_get(:@z)
310   end