1 # -*- encoding: binary -*-
10 class Test_IO_Splice < Test::Unit::TestCase
16 tmp = Tempfile.new('ruby_io_splice')
18 assert_nothing_raised {
23 nr = IO.splice(tmp.fileno, nil, wr.fileno, nil, size, 0)
25 assert_equal str, rd.sysread(size)
32 tmp = Tempfile.new('ruby_io_splice')
34 assert_nothing_raised {
39 nr = IO.splice(tmp, nil, wr, nil, size, 0)
41 assert_equal str, rd.sysread(size)
44 def test_splice_io_ish
48 tmp = Tempfile.new('ruby_io_splice')
54 assert_nothing_raised {
59 nr = IO.splice(io_ish, nil, wr, nil, size, 0)
61 assert_equal str, rd.sysread(size)
64 def test_splice_in_offset
69 tmp = Tempfile.new('ruby_io_splice')
71 assert_nothing_raised {
76 nr = IO.splice(tmp.fileno, off, wr.fileno, nil, len, 0)
78 assert_equal 'de', rd.sysread(len)
81 def test_splice_out_offset
84 tmp = Tempfile.new('ruby_io_splice')
86 assert_nothing_raised { wr.syswrite(str) }
87 nr = IO.splice(rd.fileno, nil, tmp.fileno, 3, str.size, 0)
89 assert_nothing_raised { tmp.sysseek(0) }
90 assert_equal "\0\0\0abcde", tmp.sysread(9)
93 def test_splice_nonblock
95 tmp = Tempfile.new('ruby_io_splice')
97 assert_raises(Errno::EAGAIN) {
98 IO.splice(rd.fileno, nil, tmp.fileno, 0, 5, IO::Splice::F_NONBLOCK)
102 def test_trysplice_nonblock
104 tmp = Tempfile.new('ruby_io_splice')
105 assert_equal :EAGAIN,
106 IO.trysplice(rd, nil, tmp, 0, 5, IO::Splice::F_NONBLOCK)
111 tmp = Tempfile.new('ruby_io_splice')
115 nr = IO.splice(rd.fileno, nil, tmp.fileno, 0, 5, IO::Splice::F_NONBLOCK)
117 assert_raises(EOFError) {
118 IO.splice(rd.fileno, nil, tmp.fileno, 0, 5, IO::Splice::F_NONBLOCK)
122 def test_trysplice_eof
124 tmp = Tempfile.new('ruby_io_splice')
128 nr = IO.trysplice(rd, nil, tmp, 0, 5, IO::Splice::F_NONBLOCK)
130 assert_nil IO.trysplice(rd, nil, tmp, 0, 5, IO::Splice::F_NONBLOCK)
133 def test_splice_nonblock_socket
134 server = TCPServer.new('127.0.0.1', 0)
135 port = server.addr[1]
137 rs = TCPSocket.new('127.0.0.1', port)
139 assert_raises(Errno::EAGAIN) { IO.splice(rs, nil, wp, nil, 1024, 0) }
150 assert_nothing_raised { wra.syswrite(str) }
151 nr = IO.tee(rda.fileno, wrb.fileno, size, 0)
153 assert_equal str, rdb.sysread(5)
154 assert_equal str, rda.sysread(5)
161 assert_raises(EOFError) { IO.tee(rda.fileno, wrb.fileno, 4096, 0) }
164 def test_tee_nonblock
167 assert_raises(Errno::EAGAIN) {
168 IO.tee(rda.fileno, wrb.fileno, 4096, IO::Splice::F_NONBLOCK)
178 assert_nothing_raised { wra.syswrite(str) }
179 nr = IO.tee(rda, wrb, size, 0)
181 assert_equal str, rdb.sysread(5)
182 assert_equal str, rda.sysread(5)
185 def test_vmsplice_array
186 data = %w(hello world how are you today)
188 n = IO.vmsplice(w.fileno, data, 0)
189 assert_equal data.join('').size, n
190 assert_equal data.join(''), r.readpartial(16384)
193 def test_vmsplice_string
195 assert_equal 5, IO.vmsplice(w, 'hello', 0)
196 assert_equal 'hello', r.read(5)
199 def test_vmsplice_array_io
200 data = %w(hello world how are you today)
202 n = IO.vmsplice(w, data, 0)
203 assert_equal data.join('').size, n
204 assert_equal data.join(''), r.readpartial(16384)
207 def test_vmsplice_nonblock
208 data = %w(hello world how are you today)
210 w.syswrite('.' * IO::Splice::PIPE_CAPA)
211 assert_raises(Errno::EAGAIN) {
212 IO.vmsplice(w.fileno, data, IO::Splice::F_NONBLOCK)
216 def test_vmsplice_in_full
219 # bs * count should be > PIPE_BUF
220 [ [ 512, 512 ], [ 131073, 3 ], [ 4098, 64 ] ].each do |(bs,count)|
222 buf = File.open('/dev/urandom', 'rb') { |fp| fp.sysread(bs) }
224 vec = (1..count).map { buf }
230 tmp << rd.readpartial(8192)
234 ok = (vec.join(empty) == tmp.join(empty))
237 assert_nothing_raised { rd.close }
238 assert_equal(bs * count, IO.vmsplice(wr.fileno, vec, 0))
239 assert_nothing_raised { wr.close }
240 _, status = Process.waitpid2(pid)
241 assert status.success?
245 def test_vmsplice_nil
246 data = %w(hello world how are you today)
247 assert_raises(TypeError) { IO.vmsplice(nil, data, 0) }
251 assert IO::Splice::PIPE_BUF > 0
252 %w(move nonblock more gift).each { |x|
253 assert Integer === IO::Splice.const_get("F_#{x.upcase}")
255 assert IO::Splice::PIPE_CAPA >= IO::Splice::PIPE_BUF
258 def test_splice_copy_stream_file_to_file_small
259 a, b = Tempfile.new('a'), Tempfile.new('b')
260 a.syswrite 'hello world'
262 IO::Splice.copy_stream(a, b)
264 assert_equal 'hello world', b.read
267 def test_splice_copy_stream_file_to_file_big
268 buf = ('ab' * IO::Splice::PIPE_CAPA) + 'hi'
269 a, b = Tempfile.new('a'), Tempfile.new('b')
272 IO::Splice.copy_stream(a, b)
274 assert_equal buf, b.read
277 def test_splice_copy_stream_file_to_file_big_partial
278 nr = IO::Splice::PIPE_CAPA
279 buf = ('ab' * nr) + 'hi'
280 a, b = Tempfile.new('a'), Tempfile.new('b')
283 assert_equal nr, IO::Splice.copy_stream(a, b, nr)
285 assert_equal('ab' * (nr/2), b.read)
288 def test_splice_copy_stream_file_to_file_len
289 a, b = Tempfile.new('a'), Tempfile.new('b')
290 a.syswrite 'hello world'
292 IO::Splice.copy_stream(a, b, 5)
294 assert_equal 'hello', b.read
297 def test_splice_copy_stream_pipe_to_file_len
298 a = Tempfile.new('a')
300 w.syswrite 'hello world'
301 IO::Splice.copy_stream(r, a, 5)
303 assert_equal 'hello', a.read
306 def test_splice_copy_stream_paths
307 a = Tempfile.new('a')
308 b = Tempfile.new('a')
309 a.syswrite('hello world')
310 IO::Splice.copy_stream(a.path, b.path, 5)
311 assert_equal 'hello', b.read
314 def test_splice_copy_stream_src_offset
315 a = Tempfile.new('a')
316 b = Tempfile.new('a')
317 a.syswrite('hello world')
318 IO::Splice.copy_stream(a.path, b.path, 5, 6)
319 assert_equal 'world', b.read
322 def test_copy_stream_nonblock_src
323 server = TCPServer.new('127.0.0.1', 0)
324 port = server.addr[1]
326 rs = TCPSocket.new('127.0.0.1', port)
329 assert_raises(Timeout::Error) do
330 timeout(0.05) { nr += IO::Splice.copy_stream(rs, wp, 5) }
337 def test_copy_stream_nonblock_dst
338 server = TCPServer.new('127.0.0.1', 0)
339 port = server.addr[1]
341 rs = TCPSocket.new('127.0.0.1', port)
343 client = server.accept
344 buf = ' ' * IO::Splice::PIPE_CAPA
346 assert_raises(Timeout::Error) do
349 wp.write_nonblock(buf)
353 nr += IO::Splice.copy_stream(rp, rs, IO::Splice::PIPE_CAPA)
357 assert_equal nr, client.read(nr).size
362 def test_copy_stream_eof
364 w.syswrite 'hello world'
366 a = Tempfile.new('a')
367 assert_equal 11, IO::Splice.copy_stream(r, a)
369 assert_equal 'hello world', a.read
374 assert_kind_of Integer, r.pipe_size
375 assert(r.pipe_size >= 512)
376 assert_nothing_raised { w.pipe_size = 8192 }
377 assert_equal 8192, r.pipe_size
380 assert_raises(Errno::EBUSY) { r.pipe_size = 4096 }
382 pipe_max_size = File.read("/proc/sys/fs/pipe-max-size").to_i
383 assert_nothing_raised { r.pipe_size = pipe_max_size }
384 assert_raises(Errno::EPERM) { r.pipe_size = pipe_max_size * 2 }
385 end if IO.method_defined?(:pipe_size)