diff options
Diffstat (limited to 'test/unit/test_stream_input.rb')
-rw-r--r-- | test/unit/test_stream_input.rb | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/test/unit/test_stream_input.rb b/test/unit/test_stream_input.rb new file mode 100644 index 0000000..20e048d --- /dev/null +++ b/test/unit/test_stream_input.rb @@ -0,0 +1,143 @@ +# -*- encoding: binary -*- + +require 'test/unit' +require 'digest/sha1' +require 'unicorn' + +class TestStreamInput < Test::Unit::TestCase + def setup + @rs = $/ + @env = {} + @rd, @wr = Kgio::UNIXSocket.pair + @rd.sync = @wr.sync = true + @start_pid = $$ + end + + def teardown + return if $$ != @start_pid + $/ = @rs + @rd.close rescue nil + @wr.close rescue nil + Process.waitall + end + + def test_read_small + r = init_request('hello') + si = Unicorn::StreamInput.new(@rd, r) + assert_equal 'hello', si.read + assert_equal '', si.read + assert_nil si.read(5) + assert_nil si.gets + end + + def test_gets_oneliner + r = init_request('hello') + si = Unicorn::StreamInput.new(@rd, r) + assert_equal 'hello', si.gets + assert_nil si.gets + end + + def test_gets_multiline + r = init_request("a\nb\n\n") + si = Unicorn::StreamInput.new(@rd, r) + assert_equal "a\n", si.gets + assert_equal "b\n", si.gets + assert_equal "\n", si.gets + assert_nil si.gets + end + + def test_gets_empty_rs + $/ = nil + r = init_request("a\nb\n\n") + si = Unicorn::StreamInput.new(@rd, r) + assert_equal "a\nb\n\n", si.gets + assert_nil si.gets + end + + def test_read_with_equal_len + r = init_request("abcde") + si = Unicorn::StreamInput.new(@rd, r) + assert_equal "abcde", si.read(5) + assert_nil si.read(5) + end + + def test_big_body_multi + r = init_request('.', Unicorn::Const::MAX_BODY + 1) + si = Unicorn::StreamInput.new(@rd, r) + assert_equal Unicorn::Const::MAX_BODY, @parser.content_length + assert ! @parser.body_eof? + nr = Unicorn::Const::MAX_BODY / 4 + pid = fork { + @rd.close + nr.times { @wr.write('....') } + @wr.close + } + @wr.close + assert_equal '.', si.read(1) + nr.times { |x| + assert_equal '....', si.read(4), "nr=#{x}" + } + assert_nil si.read(1) + status = nil + assert_nothing_raised { pid, status = Process.waitpid2(pid) } + assert status.success? + end + + def test_gets_long + r = init_request("hello", 5 + (4096 * 4 * 3) + "#$/foo#$/".size) + si = Unicorn::StreamInput.new(@rd, r) + status = line = nil + pid = fork { + @rd.close + 3.times { @wr.write("ffff" * 4096) } + @wr.write "#$/foo#$/" + @wr.close + } + @wr.close + assert_nothing_raised { line = si.gets } + assert_equal(4096 * 4 * 3 + 5 + $/.size, line.size) + assert_equal("hello" << ("ffff" * 4096 * 3) << "#$/", line) + assert_nothing_raised { line = si.gets } + assert_equal "foo#$/", line + assert_nil si.gets + assert_nothing_raised { pid, status = Process.waitpid2(pid) } + assert status.success? + end + + def test_read_with_buffer + r = init_request('hello') + si = Unicorn::StreamInput.new(@rd, r) + buf = '' + rv = si.read(4, buf) + assert_equal 'hell', rv + assert_equal 'hell', buf + assert_equal rv.object_id, buf.object_id + assert_equal 'o', si.read + assert_equal nil, si.read(5, buf) + end + + def test_read_with_buffer_clobbers + r = init_request('hello') + si = Unicorn::StreamInput.new(@rd, r) + buf = 'foo' + assert_equal 'hello', si.read(nil, buf) + assert_equal 'hello', buf + assert_equal '', si.read(nil, buf) + assert_equal '', buf + buf = 'asdf' + assert_nil si.read(5, buf) + assert_equal '', buf + end + + def init_request(body, size = nil) + @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}" + assert_equal @env, @parser.headers(@env, @buf) + assert_equal body, @buf + @parser + end +end |