f59157a8b02a1ba01bce93ac49d2980ddcbc6784
[unicorn.git] / test / unit / test_stream_input.rb
blobf59157a8b02a1ba01bce93ac49d2980ddcbc6784
1 # -*- encoding: binary -*-
3 require 'test/unit'
4 require 'digest/sha1'
5 require 'unicorn'
7 class TestStreamInput < Test::Unit::TestCase
8   def setup
9     @rs = $/
10     @env = {}
11     @rd, @wr = Kgio::UNIXSocket.pair
12     @rd.sync = @wr.sync = true
13     @start_pid = $$
14   end
16   def teardown
17     return if $$ != @start_pid
18     $/ = @rs
19     @rd.close rescue nil
20     @wr.close rescue nil
21     Process.waitall
22   end
24   def test_read_negative
25     r = init_request('hello')
26     si = Unicorn::StreamInput.new(@rd, r)
27     assert_raises(ArgumentError) { si.read(-1) }
28     assert_equal 'hello', si.read
29   end
31   def test_read_small
32     r = init_request('hello')
33     si = Unicorn::StreamInput.new(@rd, r)
34     assert_equal 'hello', si.read
35     assert_equal '', si.read
36     assert_nil si.read(5)
37     assert_nil si.gets
38   end
40   def test_gets_oneliner
41     r = init_request('hello')
42     si = Unicorn::StreamInput.new(@rd, r)
43     assert_equal 'hello', si.gets
44     assert_nil si.gets
45   end
47   def test_gets_multiline
48     r = init_request("a\nb\n\n")
49     si = Unicorn::StreamInput.new(@rd, r)
50     assert_equal "a\n", si.gets
51     assert_equal "b\n", si.gets
52     assert_equal "\n", si.gets
53     assert_nil si.gets
54   end
56   def test_gets_empty_rs
57     $/ = nil
58     r = init_request("a\nb\n\n")
59     si = Unicorn::StreamInput.new(@rd, r)
60     assert_equal "a\nb\n\n", si.gets
61     assert_nil si.gets
62   end
64   def test_read_with_equal_len
65     r = init_request("abcde")
66     si = Unicorn::StreamInput.new(@rd, r)
67     assert_equal "abcde", si.read(5)
68     assert_nil si.read(5)
69   end
71   def test_big_body_multi
72     r = init_request('.', Unicorn::Const::MAX_BODY + 1)
73     si = Unicorn::StreamInput.new(@rd, r)
74     assert_equal Unicorn::Const::MAX_BODY, @parser.content_length
75     assert ! @parser.body_eof?
76     nr = Unicorn::Const::MAX_BODY / 4
77     pid = fork {
78       @rd.close
79       nr.times { @wr.write('....') }
80       @wr.close
81     }
82     @wr.close
83     assert_equal '.', si.read(1)
84     nr.times { |x|
85       assert_equal '....', si.read(4), "nr=#{x}"
86     }
87     assert_nil si.read(1)
88     status = nil
89     assert_nothing_raised { pid, status = Process.waitpid2(pid) }
90     assert status.success?
91   end
93   def test_gets_long
94     r = init_request("hello", 5 + (4096 * 4 * 3) + "#$/foo#$/".size)
95     si = Unicorn::StreamInput.new(@rd, r)
96     status = line = nil
97     pid = fork {
98       @rd.close
99       3.times { @wr.write("ffff" * 4096) }
100       @wr.write "#$/foo#$/"
101       @wr.close
102     }
103     @wr.close
104     assert_nothing_raised { line = si.gets }
105     assert_equal(4096 * 4 * 3 + 5 + $/.size, line.size)
106     assert_equal("hello" << ("ffff" * 4096 * 3) << "#$/", line)
107     assert_nothing_raised { line = si.gets }
108     assert_equal "foo#$/", line
109     assert_nil si.gets
110     assert_nothing_raised { pid, status = Process.waitpid2(pid) }
111     assert status.success?
112   end
114   def test_read_with_buffer
115     r = init_request('hello')
116     si = Unicorn::StreamInput.new(@rd, r)
117     buf = ''
118     rv = si.read(4, buf)
119     assert_equal 'hell', rv
120     assert_equal 'hell', buf
121     assert_equal rv.object_id, buf.object_id
122     assert_equal 'o', si.read
123     assert_equal nil, si.read(5, buf)
124   end
126   def test_read_with_buffer_clobbers
127     r = init_request('hello')
128     si = Unicorn::StreamInput.new(@rd, r)
129     buf = 'foo'
130     assert_equal 'hello', si.read(nil, buf)
131     assert_equal 'hello', buf
132     assert_equal '', si.read(nil, buf)
133     assert_equal '', buf
134     buf = 'asdf'
135     assert_nil si.read(5, buf)
136     assert_equal '', buf
137   end
139   def test_read_zero
140     r = init_request('hello')
141     si = Unicorn::StreamInput.new(@rd, r)
142     assert_equal '', si.read(0)
143     buf = 'asdf'
144     rv = si.read(0, buf)
145     assert_equal rv.object_id, buf.object_id
146     assert_equal '', buf
147     assert_equal 'hello', si.read
148     assert_nil si.read(5)
149     assert_equal '', si.read(0)
150     buf = 'hello'
151     rv = si.read(0, buf)
152     assert_equal rv.object_id, buf.object_id
153     assert_equal '', rv
154   end
156   def test_gets_read_mix
157     r = init_request("hello\nasdfasdf")
158     si = Unicorn::StreamInput.new(@rd, r)
159     assert_equal "hello\n", si.gets
160     assert_equal "asdfasdf", si.read(9)
161     assert_nil si.read(9)
162   end
164   def test_gets_read_mix_chunked
165     r = @parser = Unicorn::HttpParser.new
166     body = "6\r\nhello"
167     @buf = "POST / HTTP/1.1\r\n" \
168            "Host: localhost\r\n" \
169            "Transfer-Encoding: chunked\r\n" \
170            "\r\n#{body}"
171     assert_equal @env, @parser.headers(@env, @buf)
172     assert_equal body, @buf
173     si = Unicorn::StreamInput.new(@rd, r)
174     @wr.syswrite "\n\r\n"
175     assert_equal "hello\n", si.gets
176     @wr.syswrite "8\r\nasdfasdf\r\n"
177     assert_equal"asdfasdf", si.read(9) + si.read(9)
178     @wr.syswrite "0\r\n\r\n"
179     assert_nil si.read(9)
180   end
182   def test_gets_read_mix_big
183     r = init_request("hello\n#{'.' * 65536}")
184     si = Unicorn::StreamInput.new(@rd, r)
185     assert_equal "hello\n", si.gets
186     assert_equal '.' * 16384, si.read(16384)
187     assert_equal '.' * 16383, si.read(16383)
188     assert_equal '.' * 16384, si.read(16384)
189     assert_equal '.' * 16385, si.read(16385)
190     assert_nil si.gets
191   end
193   def init_request(body, size = nil)
194     @parser = Unicorn::HttpParser.new
195     body = body.to_s.freeze
196     @buf = "POST / HTTP/1.1\r\n" \
197            "Host: localhost\r\n" \
198            "Content-Length: #{size || body.size}\r\n" \
199            "\r\n#{body}"
200     assert_equal @env, @parser.headers(@env, @buf)
201     assert_equal body, @buf
202     @parser
203   end