about summary refs log tree commit homepage
path: root/test/unit/test_tee_input.rb
diff options
context:
space:
mode:
Diffstat (limited to 'test/unit/test_tee_input.rb')
-rw-r--r--test/unit/test_tee_input.rb121
1 files changed, 110 insertions, 11 deletions
diff --git a/test/unit/test_tee_input.rb b/test/unit/test_tee_input.rb
index 3a6c998..0594d6d 100644
--- a/test/unit/test_tee_input.rb
+++ b/test/unit/test_tee_input.rb
@@ -27,7 +27,7 @@ class TestTeeInput < Test::Unit::TestCase
 
   def test_gets_long
     init_parser("hello", 5 + (4096 * 4 * 3) + "#$/foo#$/".size)
-    ti = Unicorn::TeeInput.new(@rd)
+    ti = Unicorn::TeeInput.new(@rd, @env, @parser, @buf)
     status = line = nil
     pid = fork {
       @rd.close
@@ -48,7 +48,7 @@ class TestTeeInput < Test::Unit::TestCase
 
   def test_gets_short
     init_parser("hello", 5 + "#$/foo".size)
-    ti = Unicorn::TeeInput.new(@rd)
+    ti = Unicorn::TeeInput.new(@rd, @env, @parser, @buf)
     status = line = nil
     pid = fork {
       @rd.close
@@ -65,19 +65,118 @@ class TestTeeInput < Test::Unit::TestCase
     assert status.success?
   end
 
+  def test_small_body
+    init_parser('hello')
+    ti = Unicorn::TeeInput.new(@rd, @env, @parser, @buf)
+    assert_equal 0, @parser.content_length
+    assert @parser.body_eof?
+    assert_equal StringIO, ti.instance_eval { @tmp.class }
+    assert_equal 0, ti.instance_eval { @tmp.pos }
+    assert_equal 5, ti.size
+    assert_equal 'hello', ti.read
+    assert_equal '', ti.read
+    assert_nil ti.read(4096)
+  end
+
+  def test_read_with_buffer
+    init_parser('hello')
+    ti = Unicorn::TeeInput.new(@rd, @env, @parser, @buf)
+    buf = ''
+    rv = ti.read(4, buf)
+    assert_equal 'hell', rv
+    assert_equal 'hell', buf
+    assert_equal rv.object_id, buf.object_id
+    assert_equal 'o', ti.read
+    assert_equal nil, ti.read(5, buf)
+    assert_equal 0, ti.rewind
+    assert_equal 'hello', ti.read(5, buf)
+    assert_equal 'hello', buf
+  end
+
+  def test_big_body
+    init_parser('.' * Unicorn::Const::MAX_BODY << 'a')
+    ti = Unicorn::TeeInput.new(@rd, @env, @parser, @buf)
+    assert_equal 0, @parser.content_length
+    assert @parser.body_eof?
+    assert_kind_of File, ti.instance_eval { @tmp }
+    assert_equal 0, ti.instance_eval { @tmp.pos }
+    assert_equal Unicorn::Const::MAX_BODY + 1, ti.size
+  end
+
+  def test_big_body_multi
+    init_parser('.', Unicorn::Const::MAX_BODY + 1)
+    ti = Unicorn::TeeInput.new(@rd, @env, @parser, @buf)
+    assert_equal Unicorn::Const::MAX_BODY, @parser.content_length
+    assert ! @parser.body_eof?
+    assert_kind_of File, ti.instance_eval { @tmp }
+    assert_equal 0, ti.instance_eval { @tmp.pos }
+    assert_equal 1, ti.instance_eval { tmp_size }
+    assert_equal Unicorn::Const::MAX_BODY + 1, ti.size
+    nr = Unicorn::Const::MAX_BODY / 4
+    pid = fork {
+      @rd.close
+      nr.times { @wr.write('....') }
+      @wr.close
+    }
+    @wr.close
+    assert_equal '.', ti.read(1)
+    assert_equal Unicorn::Const::MAX_BODY + 1, ti.size
+    nr.times {
+      assert_equal '....', ti.read(4)
+      assert_equal Unicorn::Const::MAX_BODY + 1, ti.size
+    }
+    assert_nil ti.read(1)
+    status = nil
+    assert_nothing_raised { pid, status = Process.waitpid2(pid) }
+    assert status.success?
+  end
+
+  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
+
+    pid = fork {
+      @rd.close
+      5.times { @wr.write("5\r\nabcde\r\n") }
+      @wr.write("0\r\n")
+    }
+    @wr.close
+    ti = Unicorn::TeeInput.new(@rd, @env, @parser, @buf)
+    assert_nil @parser.content_length
+    assert_nil ti.instance_eval { @size }
+    assert ! @parser.body_eof?
+    assert_equal 25, ti.size
+    assert @parser.body_eof?
+    assert_equal 25, ti.instance_eval { @size }
+    assert_equal 0, ti.instance_eval { @tmp.pos }
+    assert_nothing_raised { ti.rewind }
+    assert_equal 0, ti.instance_eval { @tmp.pos }
+    assert_equal 'abcdeabcdeabcdeabcde', ti.read(20)
+    assert_equal 20, ti.instance_eval { @tmp.pos }
+    assert_nothing_raised { ti.rewind }
+    assert_equal 0, ti.instance_eval { @tmp.pos }
+    assert_kind_of File, ti.instance_eval { @tmp }
+    status = nil
+    assert_nothing_raised { pid, status = Process.waitpid2(pid) }
+    assert status.success?
+  end
+
 private
 
   def init_parser(body, size = nil)
-    @parser = Unicorn::TeeInput::PARSER
-    @parser.reset
+    @parser = Unicorn::HttpParser.new
     body = body.to_s.freeze
-    buf = "POST / HTTP/1.1\r\n" \
-          "Host: localhost\r\n" \
-          "Content-Length: #{size || body.size}\r\n" \
-          "\r\n#{body}"
-    buf = Unicorn::TeeInput::RAW.replace(buf)
-    assert_equal @env, @parser.headers(@env, buf)
-    assert_equal body, 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
   end
 
 end