GIT-VERSION-GEN: bump version for new API
[kgio.git] / test / test_autopush.rb
blobf5d4e4e3b68d414f01130e96ad2917c2f7e74efb
1 require 'tempfile'
2 require 'test/unit'
3 RUBY_PLATFORM =~ /linux/ and require 'strace'
4 $-w = true
5 require 'kgio'
7 class TestAutopush < Test::Unit::TestCase
8   TCP_CORK = 3
9   TCP_NOPUSH = 4
11   def setup
12     Kgio.autopush = false
13     assert_equal false, Kgio.autopush?
15     @host = ENV["TEST_HOST"] || '127.0.0.1'
16     @srv = Kgio::TCPServer.new(@host, 0)
17     assert_nothing_raised {
18       @srv.setsockopt(Socket::IPPROTO_TCP, TCP_CORK, 1)
19     } if RUBY_PLATFORM =~ /linux/
20     assert_nothing_raised {
21       @srv.setsockopt(Socket::IPPROTO_TCP, TCP_NOPUSH, 1)
22     } if RUBY_PLATFORM =~ /freebsd/
23     @port = @srv.addr[1]
24   end
26   def test_autopush_accessors
27     Kgio.autopush = true
28     opt = RUBY_PLATFORM =~ /freebsd/ ? TCP_NOPUSH : TCP_CORK
29     s = Kgio::TCPSocket.new(@host, @port)
30     assert_equal 0, s.getsockopt(Socket::IPPROTO_TCP, opt).unpack('i')[0]
31     assert ! s.kgio_autopush?
32     s.kgio_autopush = true
33     assert s.kgio_autopush?
34     assert_nothing_raised { s.kgio_write 'asdf' }
35     assert_equal :wait_readable, s.kgio_tryread(1)
36     assert s.kgio_autopush?
37     assert_equal 1, s.getsockopt(Socket::IPPROTO_TCP, opt).unpack('i')[0]
38   end
40   def test_autopush_true_unix
41     Kgio.autopush = true
42     tmp = Tempfile.new('kgio_unix')
43     @path = tmp.path
44     File.unlink(@path)
45     tmp.close rescue nil
46     @srv = Kgio::UNIXServer.new(@path)
47     @rd = Kgio::UNIXSocket.new(@path)
48     t0 = nil
49     if defined?(Strace)
50       io, err = Strace.me { @wr = @srv.kgio_accept }
51       assert_nil err
52       rc = nil
53       io, err = Strace.me {
54         t0 = Time.now
55         @wr.kgio_write "HI\n"
56         rc = @wr.kgio_tryread 666
57       }
58       assert_nil err
59       lines = io.readlines
60       assert lines.grep(/TCP_CORK/).empty?, lines.inspect
61     else
62       assert_nothing_raised do
63         @wr = @srv.kgio_accept
64         t0 = Time.now
65         @wr.kgio_write "HI\n"
66         rc = @wr.kgio_tryread 666
67       end
68     end
69     assert_equal "HI\n", @rd.kgio_read(3)
70     diff = Time.now - t0
71     assert(diff < 0.200, "nopush on UNIX sockets? diff=#{diff} > 200ms")
72     assert_equal :wait_readable, rc
73   ensure
74     File.unlink(@path) rescue nil
75   end
77   def test_autopush_false
78     Kgio.autopush = nil
79     assert_equal false, Kgio.autopush?
81     @wr = Kgio::TCPSocket.new(@host, @port)
82     if defined?(Strace)
83       io, err = Strace.me { @rd = @srv.kgio_accept }
84       assert_nil err
85       lines = io.readlines
86       assert lines.grep(/TCP_CORK/).empty?, lines.inspect
87       assert_equal 1, @rd.getsockopt(Socket::SOL_TCP, TCP_CORK).unpack("i")[0]
88     else
89       @rd = @srv.kgio_accept
90     end
92     rbuf = "..."
93     t0 = Time.now
94     @rd.kgio_write "HI\n"
95     @wr.kgio_read(3, rbuf)
96     diff = Time.now - t0
97     assert(diff >= 0.190, "nopush broken? diff=#{diff} > 200ms")
98     assert_equal "HI\n", rbuf
99   end
101   def test_autopush_true
102     Kgio.autopush = true
103     assert_equal true, Kgio.autopush?
104     @wr = Kgio::TCPSocket.new(@host, @port)
106     if defined?(Strace)
107       io, err = Strace.me { @rd = @srv.kgio_accept }
108       assert_nil err
109       lines = io.readlines
110       assert_equal 1, lines.grep(/TCP_CORK/).size, lines.inspect
111       assert_equal 1, @rd.getsockopt(Socket::SOL_TCP, TCP_CORK).unpack("i")[0]
112     else
113       @rd = @srv.kgio_accept
114     end
116     @wr.write "HI\n"
117     rbuf = ""
118     if defined?(Strace)
119       io, err = Strace.me { @rd.kgio_read(3, rbuf) }
120       assert_nil err
121       lines = io.readlines
122       assert lines.grep(/TCP_CORK/).empty?, lines.inspect
123       assert_equal "HI\n", rbuf
124     else
125       assert_equal "HI\n", @rd.kgio_read(3, rbuf)
126     end
128     t0 = Time.now
129     @rd.kgio_write "HI2U2\n"
130     @rd.kgio_write "HOW\n"
131     rc = false
133     if defined?(Strace)
134       io, err = Strace.me { rc = @rd.kgio_tryread(666) }
135     else
136       rc = @rd.kgio_tryread(666)
137     end
139     @wr.readpartial(666, rbuf)
140     rbuf == "HI2U2\nHOW\n" or warn "rbuf=#{rbuf.inspect} looking bad?"
141     diff = Time.now - t0
142     assert(diff < 0.200, "time diff=#{diff} >= 200ms")
143     assert_equal :wait_readable, rc
144     if defined?(Strace)
145       assert_nil err
146       lines = io.readlines
147       assert_equal 2, lines.grep(/TCP_CORK/).size, lines.inspect
148     end
149     assert_nothing_raised { @wr.close }
150     assert_nothing_raised { @rd.close }
152     @wr = Kgio::TCPSocket.new(@host, @port)
153     if defined?(Strace)
154       io, err = Strace.me { @rd = @srv.kgio_accept }
155       assert_nil err
156       lines = io.readlines
157       assert lines.grep(/TCP_CORK/).empty?,"optimization fail: #{lines.inspect}"
158       assert_equal 1, @rd.getsockopt(Socket::SOL_TCP, TCP_CORK).unpack("i")[0]
159     end
160   end
162   def teardown
163     Kgio.autopush = false
164   end
165 end if RUBY_PLATFORM =~ /linux|freebsd/