kgio.git  about / heads / tags
kinder, gentler I/O for Ruby
blob 5ab208dd1790c305ff9c0ccdf5e959706011f42e 1837 bytes (raw)
$ git show rbx-wip:test/test_tfo.rb	# shows this blob on the CLI

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
 
require 'test/unit'
require 'kgio'

class TestTFO < Test::Unit::TestCase
  def test_constants
    if `uname -s`.chomp == "Linux" && `uname -r`.to_f >= 3.7
      assert_equal 23, Kgio::TCP_FASTOPEN
      assert_equal 0x20000000, Kgio::MSG_FASTOPEN
    end
  end

  def fastopen_ok?
    if RUBY_PLATFORM =~ /linux/
      tfo = File.read("/proc/sys/net/ipv4/tcp_fastopen").to_i
      client_enable = 1
      server_enable = 2
      enable = client_enable | server_enable
      (tfo & enable) == enable
    else
      false
    end
  end

  def test_tfo_client_server
    unless fastopen_ok?
      warn "TCP Fast Open not enabled on this system (check kernel docs)"
      return
    end
    addr = '127.0.0.1'
    qlen = 1024
    s = Kgio::TCPServer.new(addr, 0)
    s.setsockopt(:TCP, Kgio::TCP_FASTOPEN, qlen)
    port = s.local_address.ip_port
    addr = Socket.pack_sockaddr_in(port, addr)
    c = Kgio::Socket.new(:INET, :STREAM)
    assert_nil c.kgio_fastopen("HELLO", addr)
    a = s.accept
    assert_equal "HELLO", a.read(5)
    c.close
    a.close

    # ensure empty sends work
    c = Kgio::Socket.new(:INET, :STREAM)
    assert_nil c.kgio_fastopen("", addr)
    a = s.accept
    Thread.new { c.close }
    assert_nil a.read(1)
    a.close

    # try a monster packet
    buf = 'x' * (1024 * 1024 * 320)

    c = Kgio::Socket.new(:INET, :STREAM)
    thr = Thread.new do
      a = s.accept
      assert_equal buf.size, a.read(buf.size).size
      a.close
    end
    assert_nil c.kgio_fastopen(buf, addr)
    thr.join
    c.close

    # allow timeouts
    c = Kgio::Socket.new(:INET, :STREAM)
    c.setsockopt(:SOCKET, :SNDTIMEO, [ 0, 10 ].pack("l_l_"))
    unsent = c.kgio_fastopen(buf, addr)
    c.close
    assert_equal s.accept.read.size + unsent.size, buf.size
  end if defined?(Addrinfo) && defined?(Kgio::TCP_FASTOPEN)
end

git clone git://yhbt.net/kgio.git
git clone https://yhbt.net/kgio.git