diff options
Diffstat (limited to 'test/unit/test_tee_input.rb')
-rw-r--r-- | test/unit/test_tee_input.rb | 117 |
1 files changed, 78 insertions, 39 deletions
diff --git a/test/unit/test_tee_input.rb b/test/unit/test_tee_input.rb index a127882..96eb268 100644 --- a/test/unit/test_tee_input.rb +++ b/test/unit/test_tee_input.rb @@ -4,12 +4,15 @@ require 'test/unit' require 'digest/sha1' require 'unicorn' +class TeeInput < Unicorn::TeeInput + attr_accessor :tmp, :len +end + class TestTeeInput < Test::Unit::TestCase def setup @rs = $/ - @env = {} - @rd, @wr = IO.pipe + @rd, @wr = Kgio::UNIXSocket.pair @rd.sync = @wr.sync = true @start_pid = $$ end @@ -27,8 +30,8 @@ class TestTeeInput < Test::Unit::TestCase end def test_gets_long - init_parser("hello", 5 + (4096 * 4 * 3) + "#$/foo#$/".size) - ti = Unicorn::TeeInput.new(@rd, @env, @parser, @buf) + r = init_request("hello", 5 + (4096 * 4 * 3) + "#$/foo#$/".size) + ti = TeeInput.new(@rd, r) status = line = nil pid = fork { @rd.close @@ -48,8 +51,8 @@ class TestTeeInput < Test::Unit::TestCase end def test_gets_short - init_parser("hello", 5 + "#$/foo".size) - ti = Unicorn::TeeInput.new(@rd, @env, @parser, @buf) + r = init_request("hello", 5 + "#$/foo".size) + ti = TeeInput.new(@rd, r) status = line = nil pid = fork { @rd.close @@ -67,8 +70,8 @@ class TestTeeInput < Test::Unit::TestCase end def test_small_body - init_parser('hello') - ti = Unicorn::TeeInput.new(@rd, @env, @parser, @buf) + r = init_request('hello') + ti = TeeInput.new(@rd, r) assert_equal 0, @parser.content_length assert @parser.body_eof? assert_equal StringIO, ti.tmp.class @@ -77,11 +80,12 @@ class TestTeeInput < Test::Unit::TestCase assert_equal 'hello', ti.read assert_equal '', ti.read assert_nil ti.read(4096) + assert_equal 5, ti.size end def test_read_with_buffer - init_parser('hello') - ti = Unicorn::TeeInput.new(@rd, @env, @parser, @buf) + r = init_request('hello') + ti = TeeInput.new(@rd, r) buf = '' rv = ti.read(4, buf) assert_equal 'hell', rv @@ -95,8 +99,8 @@ class TestTeeInput < Test::Unit::TestCase end def test_big_body - init_parser('.' * Unicorn::Const::MAX_BODY << 'a') - ti = Unicorn::TeeInput.new(@rd, @env, @parser, @buf) + r = init_request('.' * Unicorn::Const::MAX_BODY << 'a') + ti = TeeInput.new(@rd, r) assert_equal 0, @parser.content_length assert @parser.body_eof? assert_kind_of File, ti.tmp @@ -106,9 +110,9 @@ class TestTeeInput < Test::Unit::TestCase def test_read_in_full_if_content_length a, b = 300, 3 - init_parser('.' * b, 300) + r = init_request('.' * b, 300) assert_equal 300, @parser.content_length - ti = Unicorn::TeeInput.new(@rd, @env, @parser, @buf) + ti = TeeInput.new(@rd, r) pid = fork { @wr.write('.' * 197) sleep 1 # still a *potential* race here that would make the test moot... @@ -121,13 +125,12 @@ class TestTeeInput < Test::Unit::TestCase end def test_big_body_multi - init_parser('.', Unicorn::Const::MAX_BODY + 1) - ti = Unicorn::TeeInput.new(@rd, @env, @parser, @buf) + r = init_request('.', Unicorn::Const::MAX_BODY + 1) + ti = TeeInput.new(@rd, r) assert_equal Unicorn::Const::MAX_BODY, @parser.content_length assert ! @parser.body_eof? assert_kind_of File, ti.tmp assert_equal 0, ti.tmp.pos - assert_equal 1, ti.tmp.size assert_equal Unicorn::Const::MAX_BODY + 1, ti.size nr = Unicorn::Const::MAX_BODY / 4 pid = fork { @@ -138,8 +141,8 @@ class TestTeeInput < Test::Unit::TestCase @wr.close assert_equal '.', ti.read(1) assert_equal Unicorn::Const::MAX_BODY + 1, ti.size - nr.times { - assert_equal '....', ti.read(4) + nr.times { |x| + assert_equal '....', ti.read(4), "nr=#{x}" assert_equal Unicorn::Const::MAX_BODY + 1, ti.size } assert_nil ti.read(1) @@ -150,12 +153,12 @@ class TestTeeInput < Test::Unit::TestCase def test_chunked @parser = Unicorn::HttpParser.new - @buf = "POST / HTTP/1.1\r\n" \ - "Host: localhost\r\n" \ - "Transfer-Encoding: chunked\r\n" \ - "\r\n" - assert_equal @env, @parser.headers(@env, @buf) - assert_equal "", @buf + @parser.buf << "POST / HTTP/1.1\r\n" \ + "Host: localhost\r\n" \ + "Transfer-Encoding: chunked\r\n" \ + "\r\n" + assert @parser.parse + assert_equal "", @parser.buf pid = fork { @rd.close @@ -163,7 +166,7 @@ class TestTeeInput < Test::Unit::TestCase @wr.write("0\r\n\r\n") } @wr.close - ti = Unicorn::TeeInput.new(@rd, @env, @parser, @buf) + ti = TeeInput.new(@rd, @parser) assert_nil @parser.content_length assert_nil ti.len assert ! @parser.body_eof? @@ -185,12 +188,13 @@ class TestTeeInput < Test::Unit::TestCase def test_chunked_ping_pong @parser = Unicorn::HttpParser.new - @buf = "POST / HTTP/1.1\r\n" \ + buf = @parser.buf + buf << "POST / HTTP/1.1\r\n" \ "Host: localhost\r\n" \ "Transfer-Encoding: chunked\r\n" \ "\r\n" - assert_equal @env, @parser.headers(@env, @buf) - assert_equal "", @buf + assert @parser.parse + assert_equal "", buf chunks = %w(aa bbb cccc dddd eeee) rd, wr = IO.pipe @@ -201,7 +205,7 @@ class TestTeeInput < Test::Unit::TestCase end @wr.write("0\r\n\r\n") } - ti = Unicorn::TeeInput.new(@rd, @env, @parser, @buf) + ti = TeeInput.new(@rd, @parser) assert_nil @parser.content_length assert_nil ti.len assert ! @parser.body_eof? @@ -215,13 +219,14 @@ class TestTeeInput < Test::Unit::TestCase def test_chunked_with_trailer @parser = Unicorn::HttpParser.new - @buf = "POST / HTTP/1.1\r\n" \ + buf = @parser.buf + buf << "POST / HTTP/1.1\r\n" \ "Host: localhost\r\n" \ "Trailer: Hello\r\n" \ "Transfer-Encoding: chunked\r\n" \ "\r\n" - assert_equal @env, @parser.headers(@env, @buf) - assert_equal "", @buf + assert @parser.parse + assert_equal "", buf pid = fork { @rd.close @@ -230,28 +235,62 @@ class TestTeeInput < Test::Unit::TestCase @wr.write("Hello: World\r\n\r\n") } @wr.close - ti = Unicorn::TeeInput.new(@rd, @env, @parser, @buf) + ti = TeeInput.new(@rd, @parser) assert_nil @parser.content_length assert_nil ti.len assert ! @parser.body_eof? assert_equal 25, ti.size - assert_equal "World", @env['HTTP_HELLO'] + assert_equal "World", @parser.env['HTTP_HELLO'] status = nil assert_nothing_raised { pid, status = Process.waitpid2(pid) } assert status.success? end + def test_chunked_and_size_slow + @parser = Unicorn::HttpParser.new + buf = @parser.buf + buf << "POST / HTTP/1.1\r\n" \ + "Host: localhost\r\n" \ + "Trailer: Hello\r\n" \ + "Transfer-Encoding: chunked\r\n" \ + "\r\n" + assert @parser.parse + assert_equal "", buf + + @wr.write("9\r\nabcde") + ti = TeeInput.new(@rd, @parser) + assert_nil @parser.content_length + assert_equal "abcde", ti.read(9) + assert ! @parser.body_eof? + @wr.write("fghi\r\n0\r\nHello: World\r\n\r\n") + assert_equal 9, ti.size + assert_equal "fghi", ti.read(9) + assert_equal nil, ti.read(9) + assert_equal "World", @parser.env['HTTP_HELLO'] + end + + def test_gets_read_mix + r = init_request("hello\nasdfasdf") + ti = Unicorn::TeeInput.new(@rd, r) + assert_equal "hello\n", ti.gets + assert_equal "asdfasdf", ti.read(9) + assert_nil ti.read(9) + end + private - def init_parser(body, size = nil) + def init_request(body, size = nil) @parser = Unicorn::HttpParser.new body = body.to_s.freeze - @buf = "POST / HTTP/1.1\r\n" \ + buf = @parser.buf + buf << "POST / HTTP/1.1\r\n" \ "Host: localhost\r\n" \ "Content-Length: #{size || body.size}\r\n" \ "\r\n#{body}" - assert_equal @env, @parser.headers(@env, @buf) - assert_equal body, @buf + assert @parser.parse + assert_equal body, buf + @buf = buf + @parser end end |