Rakefile: fix RAA license
[kgio.git] / test / lib_read_write.rb
blob20bdd597acaad061a6065ab5d06e28e8806e1036
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 unless @rd.closed?
14       @wr.close unless @wr.closed?
15     end
16   end
18   def test_read_zero
19     assert_equal "", @rd.kgio_read(0)
20     buf = "foo"
21     assert_equal buf.object_id, @rd.kgio_read(0, buf).object_id
22     assert_equal "", buf
23   end
25   def test_tryread_zero
26     assert_equal "", @rd.kgio_tryread(0)
27     buf = "foo"
28     assert_equal buf.object_id, @rd.kgio_tryread(0, buf).object_id
29     assert_equal "", buf
30   end
32   def test_read_eof
33     @wr.close
34     assert_nil @rd.kgio_read(5)
35   end
37   def test_read_bang_eof
38     @wr.close
39     begin
40       @rd.kgio_read!(5)
41       assert false, "should never get here (line:#{__LINE__})"
42     rescue EOFError => e
43       assert_equal [], e.backtrace
44     end
45   end
47   def test_tryread_eof
48     @wr.close
49     assert_nil @rd.kgio_tryread(5)
50   end
52   def test_write_closed
53     @rd.close
54     begin
55       loop { @wr.kgio_write "HI" }
56     rescue Errno::EPIPE, Errno::ECONNRESET => e
57       assert_equal [], e.backtrace
58       return
59     end
60     assert false, "should never get here (line:#{__LINE__})"
61   end
63   def test_trywrite_closed
64     @rd.close
65     begin
66       loop { @wr.kgio_trywrite "HI" }
67     rescue Errno::EPIPE, Errno::ECONNRESET => e
68       assert_equal [], e.backtrace
69       return
70     end
71     assert false, "should never get here (line:#{__LINE__})"
72   end
74   def test_trywrite_full
75     buf = "\302\251" * 1024 * 1024
76     buf2 = ""
77     dig = Digest::SHA1.new
78     t = Thread.new do
79       sleep 1
80       nr = 0
81       begin
82         dig.update(@rd.readpartial(4096, buf2))
83         nr += buf2.size
84       rescue EOFError
85         break
86       rescue => e
87       end while true
88       dig.hexdigest
89     end
90     50.times do
91       wr = buf
92       begin
93         rv = @wr.kgio_trywrite(wr)
94         case rv
95         when String
96           wr = rv
97         when :wait_readable
98           assert false, "should never get here line=#{__LINE__}"
99         when :wait_writable
100           IO.select(nil, [ @wr ])
101         else
102           wr = false
103         end
104       end while wr
105     end
106     @wr.close
107     t.join
108     assert_equal '8ff79d8115f9fe38d18be858c66aa08a1cc27a66', t.value
109   end
111   def test_write_conv
112     assert_equal nil, @wr.kgio_write(10)
113     assert_equal "10", @rd.kgio_read(2)
114   end
116   def test_trywrite_conv
117     assert_equal nil, @wr.kgio_trywrite(10)
118     assert_equal "10", @rd.kgio_tryread(2)
119   end
121   def test_tryread_empty
122     assert_equal :wait_readable, @rd.kgio_tryread(1)
123   end
125   def test_read_too_much
126     assert_equal nil, @wr.kgio_write("hi")
127     assert_equal "hi", @rd.kgio_read(4)
128   end
130   def test_tryread_too_much
131     assert_equal nil, @wr.kgio_trywrite("hi")
132     assert_equal "hi", @rd.kgio_tryread(4)
133   end
135   def test_read_short
136     assert_equal nil, @wr.kgio_write("hi")
137     assert_equal "h", @rd.kgio_read(1)
138     assert_equal "i", @rd.kgio_read(1)
139   end
141   def test_tryread_short
142     assert_equal nil, @wr.kgio_trywrite("hi")
143     assert_equal "h", @rd.kgio_tryread(1)
144     assert_equal "i", @rd.kgio_tryread(1)
145   end
147   def test_read_extra_buf
148     tmp = ""
149     tmp_object_id = tmp.object_id
150     assert_equal nil, @wr.kgio_write("hi")
151     rv = @rd.kgio_read(2, tmp)
152     assert_equal "hi", rv
153     assert_equal rv.object_id, tmp.object_id
154     assert_equal tmp_object_id, rv.object_id
155   end
157   def test_trywrite_return_wait_writable
158     tmp = []
159     tmp << @wr.kgio_trywrite("HI") until tmp[-1] == :wait_writable
160     assert :wait_writable === tmp[-1]
161     assert(!(:wait_readable === tmp[-1]))
162     assert_equal :wait_writable, tmp.pop
163     assert tmp.size > 0
164     penultimate = tmp.pop
165     assert(penultimate == "I" || penultimate == nil)
166     assert tmp.size > 0
167     tmp.each { |count| assert_equal nil, count }
168   end
170   def test_tryread_extra_buf_eagain_clears_buffer
171     tmp = "hello world"
172     rv = @rd.kgio_tryread(2, tmp)
173     assert_equal :wait_readable, rv
174     assert_equal "", tmp
175   end
177   def test_tryread_extra_buf_eof_clears_buffer
178     tmp = "hello world"
179     @wr.close
180     assert_nil @rd.kgio_tryread(2, tmp)
181     assert_equal "", tmp
182   end
184   def test_monster_trywrite
185     buf = RANDOM_BLOB.dup
186     rv = @wr.kgio_trywrite(buf)
187     assert_kind_of String, rv
188     assert rv.size < buf.size
189     @rd.nonblock = false
190     assert_equal(buf, @rd.read(buf.size - rv.size) + rv)
191   end
193   def test_monster_write
194     buf = RANDOM_BLOB.dup
195     thr = Thread.new { @wr.kgio_write(buf) }
196     @rd.nonblock = false
197     readed = @rd.read(buf.size)
198     thr.join
199     assert_nil thr.value
200     assert_equal buf, readed
201   end
203   def test_monster_write_wait_writable
204     @wr.instance_variable_set :@nr, 0
205     def @wr.kgio_wait_writable
206       @nr += 1
207       IO.select(nil, [self])
208     end
209     buf = "." * 1024 * 1024 * 10
210     thr = Thread.new { @wr.kgio_write(buf) }
211     readed = @rd.read(buf.size)
212     thr.join
213     assert_nil thr.value
214     assert_equal buf, readed
215     assert @wr.instance_variable_get(:@nr) > 0
216   end
218   def test_wait_readable_ruby_default
219     elapsed = 0
220     foo = nil
221     t0 = Time.now
222     thr = Thread.new { sleep 1; @wr.write "HELLO" }
223     assert_nothing_raised do
224       foo = @rd.kgio_read(5)
225       elapsed = Time.now - t0
226     end
227     assert elapsed >= 1.0, "elapsed: #{elapsed}"
228     assert_equal "HELLO", foo
229     thr.join
230     assert_equal 5, thr.value
231   end
233   def test_wait_writable_ruby_default
234     buf = "." * 512
235     nr = 0
236     begin
237       nr += @wr.write_nonblock(buf)
238     rescue Errno::EAGAIN
239       break
240     end while true
241     elapsed = 0
242     foo = nil
243     t0 = Time.now
244     thr = Thread.new { sleep 1; @rd.readpartial(nr) }
245     assert_nothing_raised do
246       foo = @wr.kgio_write("HELLO")
247       elapsed = Time.now - t0
248     end
249     assert_nil foo
250     if @wr.stat.pipe?
251       assert elapsed >= 1.0, "elapsed: #{elapsed}"
252     end
253     assert(String === foo || foo == nil)
254     assert_kind_of String, thr.value
255   end
257   def test_wait_readable_method
258     def @rd.kgio_wait_readable
259       defined?(@z) ? raise(RuntimeError, "Hello") : @z = "HI"
260     end
261     foo = nil
262     begin
263       foo = @rd.kgio_read(5)
264       assert false
265     rescue RuntimeError => e
266       assert_equal("Hello", e.message)
267     end
268     assert_equal "HI", @rd.instance_variable_get(:@z)
269     assert_nil foo
270   end
272   def test_tryread_wait_readable_method
273     def @rd.kgio_wait_readable
274       raise "Hello"
275     end
276     assert_equal :wait_readable, @rd.kgio_tryread(5)
277   end
279   def test_trywrite_wait_readable_method
280     def @wr.kgio_wait_writable
281       raise "Hello"
282     end
283     tmp = []
284     buf = "." * 1024
285     10000.times { tmp << @wr.kgio_trywrite(buf) }
286     assert_equal :wait_writable, tmp.pop
287   end
289   def test_wait_writable_method
290     def @wr.kgio_wait_writable
291       defined?(@z) ? raise(RuntimeError, "Hello") : @z = "HI"
292     end
293     n = []
294     begin
295       loop { n << @wr.kgio_write("HIHIHIHIHIHI") }
296       assert false
297     rescue RuntimeError => e
298       assert_equal("Hello", e.message)
299     end
300     assert n.size > 0
301     assert_equal "HI", @wr.instance_variable_get(:@z)
302   end