Switch to Ragel/C-based chunk/trailer parser
[unicorn.git] / test / unit / test_tee_input.rb
blob3a6c9987472108afa3a2b9ad679026db9a9a2cd3
1 # encoding: binary
2 require 'test/unit'
3 require 'digest/sha1'
4 require 'unicorn'
6 class TestTeeInput < Test::Unit::TestCase
8   def setup
9     @rs = $/
10     @env = {}
11     @rd, @wr = IO.pipe
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     begin
22       Process.wait
23     rescue Errno::ECHILD
24       break
25     end while true
26   end
28   def test_gets_long
29     init_parser("hello", 5 + (4096 * 4 * 3) + "#$/foo#$/".size)
30     ti = Unicorn::TeeInput.new(@rd)
31     status = line = nil
32     pid = fork {
33       @rd.close
34       3.times { @wr.write("ffff" * 4096) }
35       @wr.write "#$/foo#$/"
36       @wr.close
37     }
38     @wr.close
39     assert_nothing_raised { line = ti.gets }
40     assert_equal(4096 * 4 * 3 + 5 + $/.size, line.size)
41     assert_equal("hello" << ("ffff" * 4096 * 3) << "#$/", line)
42     assert_nothing_raised { line = ti.gets }
43     assert_equal "foo#$/", line
44     assert_nil ti.gets
45     assert_nothing_raised { pid, status = Process.waitpid2(pid) }
46     assert status.success?
47   end
49   def test_gets_short
50     init_parser("hello", 5 + "#$/foo".size)
51     ti = Unicorn::TeeInput.new(@rd)
52     status = line = nil
53     pid = fork {
54       @rd.close
55       @wr.write "#$/foo"
56       @wr.close
57     }
58     @wr.close
59     assert_nothing_raised { line = ti.gets }
60     assert_equal("hello#$/", line)
61     assert_nothing_raised { line = ti.gets }
62     assert_equal "foo", line
63     assert_nil ti.gets
64     assert_nothing_raised { pid, status = Process.waitpid2(pid) }
65     assert status.success?
66   end
68 private
70   def init_parser(body, size = nil)
71     @parser = Unicorn::TeeInput::PARSER
72     @parser.reset
73     body = body.to_s.freeze
74     buf = "POST / HTTP/1.1\r\n" \
75           "Host: localhost\r\n" \
76           "Content-Length: #{size || body.size}\r\n" \
77           "\r\n#{body}"
78     buf = Unicorn::TeeInput::RAW.replace(buf)
79     assert_equal @env, @parser.headers(@env, buf)
80     assert_equal body, buf
81   end
83 end