preliminary implementation of "smart_nopush"
[kgio.git] / test / test_nopush_smart.rb
blob6d4a6983aec7116f4c1c9092e4376a493864593d
1 require 'tempfile'
2 require 'test/unit'
3 RUBY_PLATFORM =~ /linux/ and require 'strace'
4 $-w = true
5 require 'kgio'
7 class TestNoPushSmart < Test::Unit::TestCase
8   TCP_CORK = 3
10   def setup
11     Kgio.nopush_smart = false
12     assert_equal false, Kgio.nopush_smart?
14     @host = ENV["TEST_HOST"] || '127.0.0.1'
15     @srv = Kgio::TCPServer.new(@host, 0)
16     assert_nothing_raised {
17       @srv.setsockopt(Socket::SOL_TCP, TCP_CORK, 1)
18     } if RUBY_PLATFORM =~ /linux/
19     @port = @srv.addr[1]
20   end
22   def test_nopush_smart_true_unix
23     Kgio.nopush_smart = true
24     tmp = Tempfile.new('kgio_unix')
25     @path = tmp.path
26     File.unlink(@path)
27     tmp.close rescue nil
28     @srv = Kgio::UNIXServer.new(@path)
29     @rd = Kgio::UNIXSocket.new(@path)
30     io, err = Strace.me { @wr = @srv.kgio_accept }
31     assert_nil err
32     rc = nil
33     io, err = Strace.me {
34       @wr.kgio_write "HI\n"
35       rc = @wr.kgio_tryread 666
36     }
37     assert_nil err
38     lines = io.readlines
39     assert lines.grep(/TCP_CORK/).empty?, lines.inspect
40     assert_equal :wait_readable, rc
41   ensure
42     File.unlink(@path) rescue nil
43   end
45   def test_nopush_smart_false
46     Kgio.nopush_smart = nil
47     assert_equal false, Kgio.nopush_smart?
49     @wr = Kgio::TCPSocket.new(@host, @port)
50     io, err = Strace.me { @rd = @srv.kgio_accept }
51     assert_nil err
52     lines = io.readlines
53     assert lines.grep(/TCP_CORK/).empty?, lines.inspect
54     assert_equal 1, @rd.getsockopt(Socket::SOL_TCP, TCP_CORK).unpack("i")[0]
56     rbuf = "..."
57     t0 = Time.now
58     @rd.kgio_write "HI\n"
59     @wr.kgio_read(3, rbuf)
60     diff = Time.now - t0
61     assert(diff >= 0.200, "TCP_CORK broken? diff=#{diff} > 200ms")
62     assert_equal "HI\n", rbuf
63   end if RUBY_PLATFORM =~ /linux/
65   def test_nopush_smart_true
66     Kgio.nopush_smart = true
67     assert_equal true, Kgio.nopush_smart?
68     @wr = Kgio::TCPSocket.new(@host, @port)
69     io, err = Strace.me { @rd = @srv.kgio_accept }
70     assert_nil err
71     lines = io.readlines
72     assert_equal 1, lines.grep(/TCP_CORK/).size, lines.inspect
73     assert_equal 1, @rd.getsockopt(Socket::SOL_TCP, TCP_CORK).unpack("i")[0]
75     @wr.write "HI\n"
76     rbuf = ""
77     io, err = Strace.me { @rd.kgio_read(3, rbuf) }
78     assert_nil err
79     lines = io.readlines
80     assert lines.grep(/TCP_CORK/).empty?, lines.inspect
81     assert_equal "HI\n", rbuf
83     t0 = Time.now
84     @rd.kgio_write "HI2U2\n"
85     @rd.kgio_write "HOW\n"
86     rc = false
87     io, err = Strace.me { rc = @rd.kgio_tryread(666) }
88     @wr.readpartial(666, rbuf)
89     rbuf == "HI2U2\nHOW\n" or warn "rbuf=#{rbuf.inspect} looking bad?"
90     diff = Time.now - t0
91     assert(diff < 0.200, "time diff=#{diff} >= 200ms")
92     assert_equal :wait_readable, rc
93     assert_nil err
94     lines = io.readlines
95     assert_equal 2, lines.grep(/TCP_CORK/).size, lines.inspect
96     assert_nothing_raised { @wr.close }
97     assert_nothing_raised { @rd.close }
99     @wr = Kgio::TCPSocket.new(@host, @port)
100     io, err = Strace.me { @rd = @srv.kgio_accept }
101     assert_nil err
102     lines = io.readlines
103     assert lines.grep(/TCP_CORK/).empty?, "optimization fail: #{lines.inspect}"
104     assert_equal 1, @rd.getsockopt(Socket::SOL_TCP, TCP_CORK).unpack("i")[0]
105   end if RUBY_PLATFORM =~ /linux/
107   def teardown
108     Kgio.nopush_smart = false
109   end