From 7cbdf6ba4c3463dfc1cac5cb01d4241c02be7fde Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Sat, 27 Jun 2009 16:00:02 -0700 Subject: test_upload: add tests for chunked encoding Additionally, provide verifications for sizes after-the-fact to avoid slamming all of our input into the server. --- test/unit/test_upload.rb | 87 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 86 insertions(+), 1 deletion(-) diff --git a/test/unit/test_upload.rb b/test/unit/test_upload.rb index adc036d..8bb83c5 100644 --- a/test/unit/test_upload.rb +++ b/test/unit/test_upload.rb @@ -18,7 +18,7 @@ class UploadTest < Test::Unit::TestCase @sha1 = Digest::SHA1.new @sha1_app = lambda do |env| input = env['rack.input'] - resp = { :size => input.size } + resp = {} @sha1.reset while buf = input.read(@bs) @@ -37,6 +37,13 @@ class UploadTest < Test::Unit::TestCase resp[:sysread_read_byte_match] = true end + if expect_size = env['HTTP_X_EXPECT_SIZE'] + if expect_size.to_i == input.size + resp[:expect_size_match] = true + end + end + resp[:size] = input.size + [ 200, @hdr.merge({'X-Resp' => resp.inspect}), [] ] end end @@ -158,6 +165,84 @@ class UploadTest < Test::Unit::TestCase assert_match(/sysread_read_byte_match/, resp) end + def test_chunked_upload_via_curl + # POSIX doesn't require all of these to be present on a system + which('curl') or return + which('sha1sum') or return + which('dd') or return + + start_server(@sha1_app) + + tmp = Tempfile.new('dd_dest') + assert(system("dd", "if=#{@random.path}", "of=#{tmp.path}", + "bs=#{@bs}", "count=#{@count}"), + "dd #@random to #{tmp}") + sha1_re = %r!\b([a-f0-9]{40})\b! + sha1_out = `sha1sum #{tmp.path}` + assert $?.success?, 'sha1sum ran OK' + + assert_match(sha1_re, sha1_out) + sha1 = sha1_re.match(sha1_out)[1] + cmd = "curl -H 'X-Expect-Size: #{tmp.size}' --tcp-nodelay \ + -isSf --no-buffer -T- " \ + "http://#@addr:#@port/" + resp = Tempfile.new('resp') + resp.sync = true + + rd, wr = IO.pipe + wr.sync = rd.sync = true + pid = fork { + STDIN.reopen(rd) + rd.close + wr.close + STDOUT.reopen(resp) + exec cmd + } + rd.close + + tmp.rewind + @count.times { |i| + wr.write(tmp.read(@bs)) + sleep(rand / 10) if 0 == i % 8 + } + wr.close + pid, status = Process.waitpid2(pid) + + resp.rewind + resp = resp.read + assert status.success?, 'curl ran OK' + assert_match(%r!\b#{sha1}\b!, resp) + assert_match(/sysread_read_byte_match/, resp) + assert_match(/expect_size_match/, resp) + end + + def test_curl_chunked_small + # POSIX doesn't require all of these to be present on a system + which('curl') or return + which('sha1sum') or return + which('dd') or return + + start_server(@sha1_app) + + tmp = Tempfile.new('dd_dest') + # small StringIO path + assert(system("dd", "if=#{@random.path}", "of=#{tmp.path}", + "bs=1024", "count=1"), + "dd #@random to #{tmp}") + sha1_re = %r!\b([a-f0-9]{40})\b! + sha1_out = `sha1sum #{tmp.path}` + assert $?.success?, 'sha1sum ran OK' + + assert_match(sha1_re, sha1_out) + sha1 = sha1_re.match(sha1_out)[1] + resp = `curl -H 'X-Expect-Size: #{tmp.size}' --tcp-nodelay \ + -isSf --no-buffer -T- http://#@addr:#@port/ < #{tmp.path}` + assert $?.success?, 'curl ran OK' + assert_match(%r!\b#{sha1}\b!, resp) + assert_match(/sysread_read_byte_match/, resp) + assert_match(/expect_size_match/, resp) + end + private def length -- cgit v1.2.3-24-ge0c7