listen backlog, sndbuf, rcvbuf are always changeable
[unicorn.git] / test / unit / test_socket_helper.rb
blob0608e242b0334fd6294d1e4ca514c254b493fba4
1 require 'test/test_helper'
2 require 'tempfile'
4 class TestSocketHelper < Test::Unit::TestCase
5   include Unicorn::SocketHelper
6   attr_reader :logger
7   GET_SLASH = "GET / HTTP/1.0\r\n\r\n".freeze
9   def setup
10     @log_tmp = Tempfile.new 'logger'
11     @logger = Logger.new(@log_tmp.path)
12     @test_addr = ENV['UNICORN_TEST_ADDR'] || '127.0.0.1'
13   end
15   def test_bind_listen_tcp
16     port = unused_port @test_addr
17     @tcp_listener_name = "#@test_addr:#{port}"
18     @tcp_listener = bind_listen(@tcp_listener_name)
19     assert TCPServer === @tcp_listener
20     assert_equal @tcp_listener_name, sock_name(@tcp_listener)
21   end
23   def test_bind_listen_options
24     port = unused_port @test_addr
25     tcp_listener_name = "#@test_addr:#{port}"
26     tmp = Tempfile.new 'unix.sock'
27     unix_listener_name = tmp.path
28     File.unlink(tmp.path)
29     [ { :backlog => 5 }, { :sndbuf => 4096 }, { :rcvbuf => 4096 },
30       { :backlog => 16, :rcvbuf => 4096, :sndbuf => 4096 }
31     ].each do |opts|
32       assert_nothing_raised do
33         tcp_listener = bind_listen(tcp_listener_name, opts)
34         assert TCPServer === tcp_listener
35         tcp_listener.close
36         unix_listener = bind_listen(unix_listener_name, opts)
37         assert UNIXServer === unix_listener
38         unix_listener.close
39       end
40     end
41     #system('cat', @log_tmp.path)
42   end
44   def test_bind_listen_unix
45     old_umask = File.umask(0777)
46     tmp = Tempfile.new 'unix.sock'
47     @unix_listener_path = tmp.path
48     File.unlink(@unix_listener_path)
49     @unix_listener = bind_listen(@unix_listener_path)
50     assert UNIXServer === @unix_listener
51     assert_equal @unix_listener_path, sock_name(@unix_listener)
52     assert File.readable?(@unix_listener_path), "not readable"
53     assert File.writable?(@unix_listener_path), "not writable"
54     assert_equal 0777, File.umask
55     ensure
56       File.umask(old_umask)
57   end
59   def test_bind_listen_unix_idempotent
60     test_bind_listen_unix
61     a = bind_listen(@unix_listener)
62     assert_equal a.fileno, @unix_listener.fileno
63     unix_server = server_cast(@unix_listener)
64     assert UNIXServer === unix_server
65     a = bind_listen(unix_server)
66     assert_equal a.fileno, unix_server.fileno
67     assert_equal a.fileno, @unix_listener.fileno
68   end
70   def test_bind_listen_tcp_idempotent
71     test_bind_listen_tcp
72     a = bind_listen(@tcp_listener)
73     assert_equal a.fileno, @tcp_listener.fileno
74     tcp_server = server_cast(@tcp_listener)
75     assert TCPServer === tcp_server
76     a = bind_listen(tcp_server)
77     assert_equal a.fileno, tcp_server.fileno
78     assert_equal a.fileno, @tcp_listener.fileno
79   end
81   def test_bind_listen_unix_rebind
82     test_bind_listen_unix
83     new_listener = bind_listen(@unix_listener_path)
84     assert UNIXServer === new_listener
85     assert new_listener.fileno != @unix_listener.fileno
86     assert_equal sock_name(new_listener), sock_name(@unix_listener)
87     assert_equal @unix_listener_path, sock_name(new_listener)
88     pid = fork do
89       client = server_cast(new_listener).accept
90       client.syswrite('abcde')
91       exit 0
92     end
93     s = UNIXSocket.new(@unix_listener_path)
94     IO.select([s])
95     assert_equal 'abcde', s.sysread(5)
96     pid, status = Process.waitpid2(pid)
97     assert status.success?
98   end
100   def test_server_cast
101     assert_nothing_raised do
102       test_bind_listen_unix
103       test_bind_listen_tcp
104     end
105     unix_listener_socket = Socket.for_fd(@unix_listener.fileno)
106     assert Socket === unix_listener_socket
107     @unix_server = server_cast(unix_listener_socket)
108     assert_equal @unix_listener.fileno, @unix_server.fileno
109     assert UNIXServer === @unix_server
110     assert File.socket?(@unix_server.path)
111     assert_equal @unix_listener_path, sock_name(@unix_server)
113     tcp_listener_socket = Socket.for_fd(@tcp_listener.fileno)
114     assert Socket === tcp_listener_socket
115     @tcp_server = server_cast(tcp_listener_socket)
116     assert_equal @tcp_listener.fileno, @tcp_server.fileno
117     assert TCPServer === @tcp_server
118     assert_equal @tcp_listener_name, sock_name(@tcp_server)
119   end
121   def test_sock_name
122     test_server_cast
123     sock_name(@unix_server)
124   end
126   def test_tcp_unicorn_peeraddr
127     test_bind_listen_tcp
128     @tcp_server = server_cast(@tcp_listener)
129     tmp = Tempfile.new 'shared'
130     pid = fork do
131       client = @tcp_server.accept
132       IO.select([client])
133       assert_equal GET_SLASH, client.sysread(GET_SLASH.size)
134       tmp.syswrite "#{client.unicorn_peeraddr}"
135       exit 0
136     end
137     host, port = sock_name(@tcp_server).split(/:/)
138     client = TCPSocket.new(host, port.to_i)
139     client.syswrite(GET_SLASH)
141     pid, status = Process.waitpid2(pid)
142     assert_nothing_raised { client.close }
143     assert status.success?
144     tmp.sysseek 0
145     assert_equal @test_addr, tmp.sysread(4096)
146     tmp.sysseek 0
147   end
149   def test_unix_unicorn_peeraddr
150     test_bind_listen_unix
151     @unix_server = server_cast(@unix_listener)
152     tmp = Tempfile.new 'shared'
153     pid = fork do
154       client = @unix_server.accept
155       IO.select([client])
156       assert_equal GET_SLASH, client.sysread(4096)
157       tmp.syswrite "#{client.unicorn_peeraddr}"
158       exit 0
159     end
160     client = UNIXSocket.new(@unix_listener_path)
161     client.syswrite(GET_SLASH)
163     pid, status = Process.waitpid2(pid)
164     assert_nothing_raised { client.close }
165     assert status.success?
166     tmp.sysseek 0
167     assert_equal '127.0.0.1', tmp.sysread(4096)
168     tmp.sysseek 0
169   end