From: Eric Wong Date: Sun, 9 Feb 2014 07:26:52 +0000 (+0000) Subject: remove copy_stream tests and references X-Git-Tag: v4.3.0~3 X-Git-Url: https://repo.or.cz/w/ruby_io_splice.git/commitdiff_plain/66d8ad006ff1ca1ede0b0e1988d6a25a67321ae4 remove copy_stream tests and references It is deprecated, so stop testing and advertising it. --- diff --git a/README b/README index 6300ac6..5245cb1 100644 --- a/README +++ b/README @@ -14,11 +14,9 @@ buffer. arbitrary file descriptors (assuming kernel support), not just file-to-socket (or file-to-anything in newer Linux). -* Thread-safe blocking operations under Ruby 1.9, releases GVL +* Thread-safe blocking operations under Ruby 1.9+, releases GVL if blocking operations are used. -* Almost drop-in replacement for IO.copy_stream: IO::Splice.copy_stream - * Safely usable with non-blocking I/O frameworks (unlike IO.copy_stream) when combined with the IO::Splice::F_NONBLOCK flag. diff --git a/examples/splice-cp.rb b/examples/splice-cp.rb index bf0d518..8141e51 100755 --- a/examples/splice-cp.rb +++ b/examples/splice-cp.rb @@ -1,13 +1,5 @@ #!/usr/bin/env ruby # -*- encoding: binary -*- - -# Example of using IO.splice to copy a file -# This can be significantly faster than IO.copy_stream as data -# is never copied into userspace. - -require 'io/splice' - -usage = "#$0 SOURCE DEST" -source = ARGV.shift or abort usage -dest = ARGV.shift or abort usage -IO::Splice.copy_stream(source, dest) +# This example is no longer valid, IO.copy_stream is faster in Ruby 2.2+ +# since it uses sendfile directly, which now allows direct file-to-file +# copying (on Linux only) with fewer syscalls than splice. diff --git a/io_splice.gemspec b/io_splice.gemspec index bc3c477..a914029 100644 --- a/io_splice.gemspec +++ b/io_splice.gemspec @@ -21,7 +21,6 @@ Gem::Specification.new do |s| s.rubyforge_project = %q{qrp} s.test_files = Dir['test/test_*.rb'] s.add_development_dependency('wrongdoc', '~> 1.5') - s.add_development_dependency('rack', '~> 1.2') # s.licenses = %w(LGPL) # accessor not compatible with older RubyGems end diff --git a/test/test_copy_stream.rb b/test/test_copy_stream.rb deleted file mode 100644 index 71d7cae..0000000 --- a/test/test_copy_stream.rb +++ /dev/null @@ -1,340 +0,0 @@ -require 'test/unit' -require 'tmpdir' -require "fcntl" -require 'io/nonblock' -require 'socket' -require 'timeout' -require 'tempfile' -require 'io/splice' - -class TestIOCopyStreamCompat < Test::Unit::TestCase - def have_nonblock? - IO.method_defined?("nonblock=") - end - - def pipe(wp, rp) - re, we = nil, nil - r, w = IO.pipe - rt = Thread.new do - begin - rp.call(r) - rescue Exception - r.close - re = $! - end - end - wt = Thread.new do - begin - wp.call(w) - rescue Exception - w.close - we = $! - end - end - flunk("timeout") unless wt.join(10) && rt.join(10) - ensure - w.close unless !w || w.closed? - r.close unless !r || r.closed? - (wt.kill; wt.join) if wt - (rt.kill; rt.join) if rt - raise we if we - raise re if re - end - - def with_pipe - r, w = IO.pipe - begin - yield r, w - ensure - r.close unless r.closed? - w.close unless w.closed? - end - end - - def with_read_pipe(content) - pipe(proc do |w| - w << content - w.close - end, proc do |r| - yield r - end) - end - - def mkcdtmpdir - Dir.mktmpdir {|d| - Dir.chdir(d) { - yield - } - } - end - - def trapping_usr1 - @usr1_rcvd = 0 - trap(:USR1) { @usr1_rcvd += 1 } - yield - ensure - trap(:USR1, "DEFAULT") - end - - def test_copy_stream - mkcdtmpdir { - content = "foobar" - File.open("src", "w") {|f| f << content } - ret = IO::Splice.copy_stream("src", "dst") - assert_equal(content.bytesize, ret) - assert_equal(content, File.read("dst")) - - # overwrite by smaller file. - content = "baz" - File.open("src", "w") {|f| f << content } - ret = IO::Splice.copy_stream("src", "dst") - assert_equal(content.bytesize, ret) - assert_equal(content, File.read("dst")) - - ret = IO::Splice.copy_stream("src", "dst", 2) - assert_equal(2, ret) - assert_equal(content[0,2], File.read("dst")) - - ret = IO::Splice.copy_stream("src", "dst", 0) - assert_equal(0, ret) - assert_equal("", File.read("dst")) - - ret = IO::Splice.copy_stream("src", "dst", nil, 1) - assert_equal(content.bytesize-1, ret) - assert_equal(content[1..-1], File.read("dst")) - - assert_raise(Errno::ENOENT) { - IO::Splice.copy_stream("nodir/foo", "dst") - } - - assert_raise(Errno::ENOENT) { - IO::Splice.copy_stream("src", "nodir/bar") - } - - pipe(proc do |w| - ret = IO::Splice.copy_stream("src", w) - assert_equal(content.bytesize, ret) - w.close - end, proc do |r| - assert_equal(content, r.read) - end) - - with_pipe {|r, w| - w.close - assert_raise(IOError) { IO::Splice.copy_stream("src", w) } - } - - pipe_content = "abc" - with_read_pipe(pipe_content) {|r| - ret = IO::Splice.copy_stream(r, "dst") - assert_equal(pipe_content.bytesize, ret) - assert_equal(pipe_content, File.read("dst")) - } - - pipe(proc do |w| - ret = IO::Splice.copy_stream("src", w, 1, 1) - assert_equal(1, ret) - w.close - end, proc do |r| - assert_equal(content[1,1], r.read) - end) - - bigcontent = "abc" * 123456 - File.open("bigsrc", "w") {|f| f << bigcontent } - ret = IO::Splice.copy_stream("bigsrc", "bigdst") - assert_equal(bigcontent.bytesize, ret) - assert_equal(bigcontent, File.read("bigdst")) - - File.unlink("bigdst") - ret = IO::Splice.copy_stream("bigsrc", "bigdst", nil, 100) - assert_equal(bigcontent.bytesize-100, ret) - assert_equal(bigcontent[100..-1], File.read("bigdst")) - - File.unlink("bigdst") - ret = IO::Splice.copy_stream("bigsrc", "bigdst", 30000, 100) - assert_equal(30000, ret) - assert_equal(bigcontent[100, 30000], File.read("bigdst")) - - File.open("bigsrc") {|f| - begin - assert_equal(0, f.pos) - ret = IO::Splice.copy_stream(f, "bigdst", nil, 10) - assert_equal(bigcontent.bytesize-10, ret) - assert_equal(bigcontent[10..-1], File.read("bigdst")) - assert_equal(0, f.pos) - ret = IO::Splice.copy_stream(f, "bigdst", 40, 30) - assert_equal(40, ret) - assert_equal(bigcontent[30, 40], File.read("bigdst")) - assert_equal(0, f.pos) - rescue NotImplementedError - #skip "pread(2) is not implemtented." - end - } - - with_pipe {|r, w| - w.close - assert_raise(IOError) { IO::Splice.copy_stream("src", w) } - } - - megacontent = "abc" * 1234567 - File.open("megasrc", "w") {|f| f << megacontent } - - if have_nonblock? - with_pipe {|r1, w1| - with_pipe {|r2, w2| - begin - r1.nonblock = true - w2.nonblock = true - rescue Errno::EBADF - skip "nonblocking IO for pipe is not implemented" - end - t1 = Thread.new { w1 << megacontent; w1.close } - t2 = Thread.new { r2.read } - ret = IO::Splice.copy_stream(r1, w2) - assert_equal(megacontent.bytesize, ret) - w2.close - t1.join - assert_equal(megacontent, t2.value) - } - } - end - - with_pipe {|r1, w1| - with_pipe {|r2, w2| - t1 = Thread.new { w1 << megacontent; w1.close } - t2 = Thread.new { r2.read } - ret = IO::Splice.copy_stream(r1, w2) - assert_equal(megacontent.bytesize, ret) - w2.close - t1.join - assert_equal(megacontent, t2.value) - } - } - - with_pipe {|r, w| - t = Thread.new { r.read } - ret = IO::Splice.copy_stream("megasrc", w) - assert_equal(megacontent.bytesize, ret) - w.close - assert_equal(megacontent, t.value) - } - } - end - - def with_socketpair - s1, s2 = UNIXSocket.pair - begin - yield s1, s2 - ensure - s1.close unless s1.closed? - s2.close unless s2.closed? - end - end - - def test_copy_stream_socket - mkcdtmpdir { - - content = "foobar" - File.open("src", "w") {|f| f << content } - - with_socketpair {|s1, s2| - ret = IO::Splice.copy_stream("src", s1) - assert_equal(content.bytesize, ret) - s1.close - assert_equal(content, s2.read) - } - - bigcontent = "abc" * 123456 - File.open("bigsrc", "w") {|f| f << bigcontent } - - with_socketpair {|s1, s2| - t = Thread.new { s2.read } - ret = IO::Splice.copy_stream("bigsrc", s1) - assert_equal(bigcontent.bytesize, ret) - s1.close - result = t.value - assert_equal(bigcontent, result) - } - - with_socketpair {|s1, s2| - t = Thread.new { s2.read } - ret = IO::Splice.copy_stream("bigsrc", s1, 10000) - assert_equal(10000, ret) - s1.close - result = t.value - assert_equal(bigcontent[0,10000], result) - } - - File.open("bigsrc") {|f| - assert_equal(0, f.pos) - with_socketpair {|s1, s2| - t = Thread.new { s2.read } - ret = IO::Splice.copy_stream(f, s1, nil, 100) - assert_equal(bigcontent.bytesize-100, ret) - assert_equal(0, f.pos) - s1.close - result = t.value - assert_equal(bigcontent[100..-1], result) - } - } - - File.open("bigsrc") {|f| - assert_equal(bigcontent[0,100], f.sysread(100)) - assert_equal(100, f.pos) - with_socketpair {|s1, s2| - t = Thread.new { s2.read } - ret = IO::Splice.copy_stream(f, s1) - assert_equal(bigcontent.bytesize-100, ret) - assert_equal(bigcontent.length, f.sysseek(0, IO::SEEK_CUR)) - s1.close - result = t.value - assert_equal(bigcontent[100..-1], result) - } - } - - megacontent = "abc" * 1234567 - File.open("megasrc", "w") {|f| f << megacontent } - - if have_nonblock? - with_socketpair {|s1, s2| - begin - s1.nonblock = true - rescue Errno::EBADF - skip "nonblocking IO for pipe is not implemented" - end - t = Thread.new { s2.read } - ret = IO::Splice.copy_stream("megasrc", s1) - assert_equal(megacontent.bytesize, ret) - s1.close - result = t.value - assert_equal(megacontent, result) - } - with_socketpair {|s1, s2| - begin - s1.nonblock = true - rescue Errno::EBADF - skip "nonblocking IO for pipe is not implemented" - end - trapping_usr1 do - nr = 10 - pid = fork do - s1.close - IO.select([s2]) - Process.kill(:USR1, Process.ppid) - s2.read - end - s2.close - nr.times do - assert_equal megacontent.bytesize, - IO::Splice.copy_stream("megasrc", s1) - end - assert_equal(1, @usr1_rcvd) - s1.close - _, status = Process.waitpid2(pid) - assert status.success?, status.inspect - end - } - end - } - end -end diff --git a/test/test_io_splice.rb b/test/test_io_splice.rb index 26f2e00..ba66a61 100644 --- a/test/test_io_splice.rb +++ b/test/test_io_splice.rb @@ -332,130 +332,6 @@ class Test_IO_Splice < Test::Unit::TestCase assert IO::Splice::PIPE_CAPA >= IO::Splice::PIPE_BUF end - def test_splice_copy_stream_file_to_file_small - a, b = Tempfile.new('a'), Tempfile.new('b') - a.syswrite 'hello world' - a.sysseek(0) - IO::Splice.copy_stream(a, b) - b.rewind - assert_equal 'hello world', b.read - end - - def test_splice_copy_stream_file_to_file_big - buf = ('ab' * IO::Splice::PIPE_CAPA) + 'hi' - a, b = Tempfile.new('a'), Tempfile.new('b') - a.syswrite buf - a.sysseek(0) - IO::Splice.copy_stream(a, b) - b.rewind - assert_equal buf, b.read - end - - def test_splice_copy_stream_file_to_file_big_partial - nr = IO::Splice::PIPE_CAPA - buf = ('ab' * nr) + 'hi' - a, b = Tempfile.new('a'), Tempfile.new('b') - a.syswrite buf - a.sysseek(0) - assert_equal nr, IO::Splice.copy_stream(a, b, nr) - b.rewind - assert_equal('ab' * (nr/2), b.read) - end - - def test_splice_copy_stream_file_to_file_len - a, b = Tempfile.new('a'), Tempfile.new('b') - a.syswrite 'hello world' - a.sysseek(0) - IO::Splice.copy_stream(a, b, 5) - b.rewind - assert_equal 'hello', b.read - end - - def test_splice_copy_stream_pipe_to_file_len - a = Tempfile.new('a') - r, w = IO.pipe - w.syswrite 'hello world' - IO::Splice.copy_stream(r, a, 5) - a.rewind - assert_equal 'hello', a.read - end - - def test_splice_copy_stream_paths - a = Tempfile.new('a') - b = Tempfile.new('a') - a.syswrite('hello world') - IO::Splice.copy_stream(a.path, b.path, 5) - assert_equal 'hello', b.read - end - - def test_splice_copy_stream_src_offset - a = Tempfile.new('a') - b = Tempfile.new('a') - a.syswrite('hello world') - IO::Splice.copy_stream(a.path, b.path, 5, 6) - assert_equal 'world', b.read - end - - def test_splice_copy_stream_src_offset_unchanged - a = Tempfile.new('a') - b = Tempfile.new('a') - a.syswrite('hello world') - assert_equal 0, a.sysseek(0, IO::SEEK_SET) - IO::Splice.copy_stream(a, b.path, 5, 6) - assert_equal 'world', b.read - assert_equal 0, a.sysseek(0, IO::SEEK_CUR) - end - - def test_copy_stream_nonblock_src - server = TCPServer.new('127.0.0.1', 0) - port = server.addr[1] - rp, wp = IO.pipe - rs = TCPSocket.new('127.0.0.1', port) - rs.nonblock = true - nr = 0 - assert_raises(Timeout::Error) do - timeout(0.05) { nr += IO::Splice.copy_stream(rs, wp, 5) } - end - assert_equal 0, nr - rs.close - server.close - end if mri? - - def test_copy_stream_nonblock_dst - server = TCPServer.new('127.0.0.1', 0) - port = server.addr[1] - rp, wp = IO.pipe - rs = TCPSocket.new('127.0.0.1', port) - rs.nonblock = true - client = server.accept - buf = ' ' * IO::Splice::PIPE_CAPA - nr = 0 - assert_raises(Timeout::Error) do - loop do - begin - wp.write_nonblock(buf) - rescue Errno::EAGAIN - end - timeout(0.05) do - nr += IO::Splice.copy_stream(rp, rs, IO::Splice::PIPE_CAPA) - end - end - end - assert_equal nr, client.read(nr).size - rs.close - server.close - end if mri? - - def test_copy_stream_eof - r, w = IO.pipe - w.syswrite 'hello world' - w.close - a = Tempfile.new('a') - assert_equal 11, IO::Splice.copy_stream(r, a) - a.rewind - assert_equal 'hello world', a.read - end - def test_pipe_size r, w = IO.pipe assert_kind_of Integer, r.pipe_size diff --git a/test/test_rack_file_compat.rb b/test/test_rack_file_compat.rb deleted file mode 100644 index 5505262..0000000 --- a/test/test_rack_file_compat.rb +++ /dev/null @@ -1,31 +0,0 @@ -# -*- encoding: binary -*- -require "rack" -require "test/unit" -require "socket" -require "io/splice" - -class TestRackFileCompat < Test::Unit::TestCase - def setup - @app = Rack::File.new(File.dirname(__FILE__)) - @req = Rack::MockRequest.new(@app) - @base_file = File.basename(__FILE__) - @r, @w = UNIXSocket.pair - end - - def teardown - [ @r, @w ].each { |io| io.closed? or io.close } - end - - def test_get_rack_file - env = Rack::MockRequest.env_for "http://example.com/#@base_file" - status, headers, body = @app.call(env) - assert_equal 200, status.to_i - headers.each { |k,v| - assert_instance_of String, k.to_str - assert_instance_of String, v.to_str - } - thr = Thread.new { @r.read(File.size(__FILE__)) } - assert_equal File.size(__FILE__), IO::Splice.copy_stream(body, @w) - assert_equal File.read(__FILE__), thr.value - end -end if IO.respond_to?(:copy_stream) diff --git a/test/test_tcp_splice.rb b/test/test_tcp_splice.rb deleted file mode 100644 index 686333c..0000000 --- a/test/test_tcp_splice.rb +++ /dev/null @@ -1,66 +0,0 @@ -require 'socket' -require 'io/wait' -require 'io/splice' -require 'io/nonblock' -require "test/unit" - -class TestTCPCopyStream < Test::Unit::TestCase - def setup - host = ENV["TEST_HOST"] || "127.0.0.1" - @srv = TCPServer.new(host, 0) - @port = @srv.addr[1] - @client = TCPSocket.new(host, @port) - @client.setsockopt Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1 - @accept = @srv.accept - @accept.setsockopt Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1 - @client.sync = @accept.sync = true - @r, @w = IO.pipe - end - - def teardown - @srv.close - [ @client, @accept, @r, @w ].each { |io| io.close unless io.closed? } - end - - def test_client_to_server_eof - nr = 2000 - buf = '0123456789abcdef' * 1024 - expect = buf.size * nr - thr = Thread.new do - nr.times { @client.write(buf) } - @client.close - end - sleep 1 # wait for rcvbuf to fill up - bytes = IO::Splice.copy_stream(@accept, "/dev/null") - assert_equal expect, bytes - end - - def test_client_to_server_expect - nr = 2000 - buf = '0123456789abcdef' * 1024 - expect = buf.size * nr - thr = Thread.new do - nr.times { @client.write(buf) } - end - sleep 1 # wait for rcvbuf to fill up - bytes = IO::Splice.copy_stream(@accept, "/dev/null", expect) - assert_equal expect, bytes - end - - def test_mega_splice - nr = 2000 - buf = '0123456789abcdef' * 1024 - expect = buf.size * nr - thr = Thread.new do - nr.times { @client.write(buf) } - @client.close - end - size_t_max = if (1 << 30).kind_of?(Bignum) - 0xffffffff - else - 0xffffffffffffffff - end - bytes = IO::Splice.copy_stream(@accept, "/dev/null", size_t_max) - assert_equal expect, bytes - end -end