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