diff options
Diffstat (limited to 't')
-rw-r--r-- | t/GNUmakefile | 8 | ||||
-rw-r--r-- | t/preread_input.ru | 17 | ||||
-rw-r--r-- | t/rack-input-tests.ru | 21 | ||||
-rwxr-xr-x | t/t0002-parser-error.sh | 31 | ||||
-rwxr-xr-x | t/t0003-working_directory.sh | 5 | ||||
-rwxr-xr-x | t/t0010-reap-logging.sh | 55 | ||||
-rwxr-xr-x | t/t0012-reload-empty-config.sh | 5 | ||||
-rwxr-xr-x | t/t0013-rewindable-input-false.sh | 24 | ||||
-rw-r--r-- | t/t0013.ru | 12 | ||||
-rwxr-xr-x | t/t0014-rewindable-input-true.sh | 24 | ||||
-rw-r--r-- | t/t0014.ru | 12 | ||||
-rwxr-xr-x | t/t0015-configurator-internals.sh | 25 | ||||
-rwxr-xr-x | t/t0016-trust-x-forwarded-false.sh | 30 | ||||
-rwxr-xr-x | t/t0017-trust-x-forwarded-true.sh | 30 | ||||
-rwxr-xr-x | t/t0100-rack-input-tests.sh | 124 | ||||
-rwxr-xr-x | t/t0116-client_body_buffer_size.sh | 80 | ||||
-rw-r--r-- | t/t0116.ru | 16 | ||||
-rwxr-xr-x | t/t0303-rails3-alt-working_directory_config.ru.sh | 5 | ||||
-rwxr-xr-x | t/t9000-preread-input.sh | 48 | ||||
-rw-r--r-- | t/test-rails3.sh | 2 |
20 files changed, 561 insertions, 13 deletions
diff --git a/t/GNUmakefile b/t/GNUmakefile index e80c43a..8f2668c 100644 --- a/t/GNUmakefile +++ b/t/GNUmakefile @@ -17,6 +17,12 @@ endif RUBY_ENGINE := $(shell $(RUBY) -e 'puts((RUBY_ENGINE rescue "ruby"))') export RUBY_ENGINE +isolate_libs := ../tmp/isolate/$(RUBY_ENGINE)-$(RUBY_VERSION).mk +$(isolate_libs): ../script/isolate_for_tests + @cd .. && $(RUBY) script/isolate_for_tests +-include $(isolate_libs) +MYLIBS := $(RUBYLIB):$(ISOLATE_LIBS) + T = $(wildcard t[0-9][0-9][0-9][0-9]-*.sh) all:: $(T) @@ -58,7 +64,7 @@ $(test_prefix)/.stamp: $(T): export RUBY := $(RUBY) $(T): export RAKE := $(RAKE) $(T): export PATH := $(test_prefix)/bin:$(PATH) -$(T): export RUBYLIB := $(test_prefix)/lib:$(RUBYLIB) +$(T): export RUBYLIB := $(test_prefix)/lib:$(MYLIBS) $(T): dep $(test_prefix)/.stamp trash/.gitignore $(TRACER) $(SHELL) $(SH_TEST_OPTS) $@ $(TEST_OPTS) diff --git a/t/preread_input.ru b/t/preread_input.ru new file mode 100644 index 0000000..79685c4 --- /dev/null +++ b/t/preread_input.ru @@ -0,0 +1,17 @@ +#\-E none +require 'digest/sha1' +require 'unicorn/preread_input' +use Rack::ContentLength +use Rack::ContentType, "text/plain" +use Unicorn::PrereadInput +nr = 0 +run lambda { |env| + $stderr.write "app dispatch: #{nr += 1}\n" + input = env["rack.input"] + dig = Digest::SHA1.new + while buf = input.read(16384) + dig.update(buf) + end + + [ 200, {}, [ "#{dig.hexdigest}\n" ] ] +} diff --git a/t/rack-input-tests.ru b/t/rack-input-tests.ru new file mode 100644 index 0000000..8c35630 --- /dev/null +++ b/t/rack-input-tests.ru @@ -0,0 +1,21 @@ +# SHA1 checksum generator +require 'digest/sha1' +use Rack::ContentLength +cap = 16384 +app = lambda do |env| + /\A100-continue\z/i =~ env['HTTP_EXPECT'] and + return [ 100, {}, [] ] + digest = Digest::SHA1.new + input = env['rack.input'] + input.size if env["PATH_INFO"] == "/size_first" + input.rewind if env["PATH_INFO"] == "/rewind_first" + if buf = input.read(rand(cap)) + begin + raise "#{buf.size} > #{cap}" if buf.size > cap + digest.update(buf) + end while input.read(rand(cap), buf) + end + + [ 200, {'Content-Type' => 'text/plain'}, [ digest.hexdigest << "\n" ] ] +end +run app diff --git a/t/t0002-parser-error.sh b/t/t0002-parser-error.sh new file mode 100755 index 0000000..9a3e7cf --- /dev/null +++ b/t/t0002-parser-error.sh @@ -0,0 +1,31 @@ +#!/bin/sh +. ./test-lib.sh +t_plan 5 "parser error test" + +t_begin "setup and startup" && { + unicorn_setup + unicorn -D env.ru -c $unicorn_config + unicorn_wait_start +} + +t_begin "send a bad request" && { + ( + printf 'GET / HTTP/1/1\r\nHost: example.com\r\n\r\n' + cat $fifo > $tmp & + wait + echo ok > $ok + ) | socat - TCP:$listen > $fifo + test xok = x$(cat $ok) +} + +dbgcat tmp + +t_begin "response should be a 400" && { + grep -F 'HTTP/1.1 400 Bad Request' $tmp +} + +t_begin "server stderr should be clean" && check_stderr + +t_begin "term signal sent" && kill $unicorn_pid + +t_done diff --git a/t/t0003-working_directory.sh b/t/t0003-working_directory.sh index 53345ae..79988d8 100755 --- a/t/t0003-working_directory.sh +++ b/t/t0003-working_directory.sh @@ -1,9 +1,4 @@ #!/bin/sh -if test -n "$RBX_SKIP" -then - echo "$0 is broken under Rubinius for now" - exit 0 -fi . ./test-lib.sh t_plan 4 "config.ru inside alt working_directory" diff --git a/t/t0010-reap-logging.sh b/t/t0010-reap-logging.sh new file mode 100755 index 0000000..93d8c60 --- /dev/null +++ b/t/t0010-reap-logging.sh @@ -0,0 +1,55 @@ +#!/bin/sh +. ./test-lib.sh +t_plan 9 "reap worker logging messages" + +t_begin "setup and start" && { + unicorn_setup + cat >> $unicorn_config <<EOF +after_fork { |s,w| File.open('$fifo','w') { |f| f.write '.' } } +EOF + unicorn -c $unicorn_config pid.ru & + test '.' = $(cat $fifo) + unicorn_wait_start +} + +t_begin "kill 1st worker=0" && { + pid_1=$(curl http://$listen/) + kill -9 $pid_1 +} + +t_begin "wait for 2nd worker to start" && { + test '.' = $(cat $fifo) +} + +t_begin "ensure log of 1st reap is an ERROR" && { + dbgcat r_err + grep 'ERROR.*reaped.*worker=0' $r_err | grep $pid_1 + dbgcat r_err + > $r_err +} + +t_begin "kill 2nd worker gracefully" && { + pid_2=$(curl http://$listen/) + kill -QUIT $pid_2 +} + +t_begin "wait for 3rd worker=0 to start " && { + test '.' = $(cat $fifo) +} + +t_begin "ensure log of 2nd reap is a INFO" && { + grep 'INFO.*reaped.*worker=0' $r_err | grep $pid_2 + > $r_err +} + +t_begin "killing succeeds" && { + kill $unicorn_pid + wait + kill -0 $unicorn_pid && false +} + +t_begin "check stderr" && { + check_stderr +} + +t_done diff --git a/t/t0012-reload-empty-config.sh b/t/t0012-reload-empty-config.sh index c18c030..81e1fb3 100755 --- a/t/t0012-reload-empty-config.sh +++ b/t/t0012-reload-empty-config.sh @@ -50,7 +50,10 @@ t_begin "reload signal succeeds" && { do sleep 1 done - + while ! grep reaped < $r_err >/dev/null + do + sleep 1 + done grep 'done reloading' $r_err >/dev/null } diff --git a/t/t0013-rewindable-input-false.sh b/t/t0013-rewindable-input-false.sh new file mode 100755 index 0000000..0e89631 --- /dev/null +++ b/t/t0013-rewindable-input-false.sh @@ -0,0 +1,24 @@ +#!/bin/sh +. ./test-lib.sh +t_plan 4 "rewindable_input toggled to false" + +t_begin "setup and start" && { + unicorn_setup + echo rewindable_input false >> $unicorn_config + unicorn -D -c $unicorn_config t0013.ru + unicorn_wait_start +} + +t_begin "ensure worker is started" && { + test xOK = x$(curl -T t0013.ru -H Expect: -vsSf http://$listen/) +} + +t_begin "killing succeeds" && { + kill $unicorn_pid +} + +t_begin "check stderr" && { + check_stderr +} + +t_done diff --git a/t/t0013.ru b/t/t0013.ru new file mode 100644 index 0000000..48a3a34 --- /dev/null +++ b/t/t0013.ru @@ -0,0 +1,12 @@ +#\ -E none +use Rack::ContentLength +use Rack::ContentType, 'text/plain' +app = lambda do |env| + case env['rack.input'] + when Unicorn::StreamInput + [ 200, {}, %w(OK) ] + else + [ 500, {}, %w(NO) ] + end +end +run app diff --git a/t/t0014-rewindable-input-true.sh b/t/t0014-rewindable-input-true.sh new file mode 100755 index 0000000..dd48bc6 --- /dev/null +++ b/t/t0014-rewindable-input-true.sh @@ -0,0 +1,24 @@ +#!/bin/sh +. ./test-lib.sh +t_plan 4 "rewindable_input toggled to true" + +t_begin "setup and start" && { + unicorn_setup + echo rewindable_input true >> $unicorn_config + unicorn -D -c $unicorn_config t0014.ru + unicorn_wait_start +} + +t_begin "ensure worker is started" && { + test xOK = x$(curl -T t0014.ru -sSf http://$listen/) +} + +t_begin "killing succeeds" && { + kill $unicorn_pid +} + +t_begin "check stderr" && { + check_stderr +} + +t_done diff --git a/t/t0014.ru b/t/t0014.ru new file mode 100644 index 0000000..b0bd2b7 --- /dev/null +++ b/t/t0014.ru @@ -0,0 +1,12 @@ +#\ -E none +use Rack::ContentLength +use Rack::ContentType, 'text/plain' +app = lambda do |env| + case env['rack.input'] + when Unicorn::TeeInput + [ 200, {}, %w(OK) ] + else + [ 500, {}, %w(NO) ] + end +end +run app diff --git a/t/t0015-configurator-internals.sh b/t/t0015-configurator-internals.sh new file mode 100755 index 0000000..4e3acbe --- /dev/null +++ b/t/t0015-configurator-internals.sh @@ -0,0 +1,25 @@ +#!/bin/sh +. ./test-lib.sh +t_plan 4 "configurator internals tests (from FAQ)" + +t_begin "setup and start" && { + unicorn_setup + cat >> $unicorn_config <<EOF +HttpRequest::DEFAULTS["rack.url_scheme"] = "https" +Configurator::DEFAULTS[:logger].formatter = Logger::Formatter.new +EOF + unicorn -D -c $unicorn_config env.ru + unicorn_wait_start +} + +t_begin "single request" && { + curl -sSfv http://$listen/ | grep '"rack.url_scheme"=>"https"' +} + +t_begin "killing succeeds" && { + kill $unicorn_pid +} + +t_begin "no errors" && check_stderr + +t_done diff --git a/t/t0016-trust-x-forwarded-false.sh b/t/t0016-trust-x-forwarded-false.sh new file mode 100755 index 0000000..3163690 --- /dev/null +++ b/t/t0016-trust-x-forwarded-false.sh @@ -0,0 +1,30 @@ +#!/bin/sh +. ./test-lib.sh +t_plan 5 "trust_x_forwarded=false configuration test" + +t_begin "setup and start" && { + unicorn_setup + echo "trust_x_forwarded false" >> $unicorn_config + unicorn -D -c $unicorn_config env.ru + unicorn_wait_start +} + +t_begin "spoofed request with X-Forwarded-Proto does not trigger" && { + curl -H 'X-Forwarded-Proto: https' http://$listen/ | \ + grep -F '"rack.url_scheme"=>"http"' +} + +t_begin "spoofed request with X-Forwarded-SSL does not trigger" && { + curl -H 'X-Forwarded-SSL: on' http://$listen/ | \ + grep -F '"rack.url_scheme"=>"http"' +} + +t_begin "killing succeeds" && { + kill $unicorn_pid +} + +t_begin "check stderr has no errors" && { + check_stderr +} + +t_done diff --git a/t/t0017-trust-x-forwarded-true.sh b/t/t0017-trust-x-forwarded-true.sh new file mode 100755 index 0000000..11103c5 --- /dev/null +++ b/t/t0017-trust-x-forwarded-true.sh @@ -0,0 +1,30 @@ +#!/bin/sh +. ./test-lib.sh +t_plan 5 "trust_x_forwarded=true configuration test" + +t_begin "setup and start" && { + unicorn_setup + echo "trust_x_forwarded true " >> $unicorn_config + unicorn -D -c $unicorn_config env.ru + unicorn_wait_start +} + +t_begin "spoofed request with X-Forwarded-Proto sets 'https'" && { + curl -H 'X-Forwarded-Proto: https' http://$listen/ | \ + grep -F '"rack.url_scheme"=>"https"' +} + +t_begin "spoofed request with X-Forwarded-SSL sets 'https'" && { + curl -H 'X-Forwarded-SSL: on' http://$listen/ | \ + grep -F '"rack.url_scheme"=>"https"' +} + +t_begin "killing succeeds" && { + kill $unicorn_pid +} + +t_begin "check stderr has no errors" && { + check_stderr +} + +t_done diff --git a/t/t0100-rack-input-tests.sh b/t/t0100-rack-input-tests.sh new file mode 100755 index 0000000..13d4207 --- /dev/null +++ b/t/t0100-rack-input-tests.sh @@ -0,0 +1,124 @@ +#!/bin/sh +. ./test-lib.sh +test -r random_blob || die "random_blob required, run with 'make $0'" + +t_plan 10 "rack.input read tests" + +t_begin "setup and startup" && { + rtmpfiles curl_out curl_err + unicorn_setup + unicorn -E none -D rack-input-tests.ru -c $unicorn_config + blob_sha1=$(rsha1 < random_blob) + blob_size=$(wc -c < random_blob) + t_info "blob_sha1=$blob_sha1" + unicorn_wait_start +} + +t_begin "corked identity request" && { + rm -f $tmp + ( + cat $fifo > $tmp & + printf 'PUT / HTTP/1.0\r\n' + printf 'Content-Length: %d\r\n\r\n' $blob_size + cat random_blob + wait + echo ok > $ok + ) | ( sleep 1 && socat - TCP4:$listen > $fifo ) + test 1 -eq $(grep $blob_sha1 $tmp |wc -l) + test x"$(cat $ok)" = xok +} + +t_begin "corked chunked request" && { + rm -f $tmp + ( + cat $fifo > $tmp & + content-md5-put < random_blob + wait + echo ok > $ok + ) | ( sleep 1 && socat - TCP4:$listen > $fifo ) + test 1 -eq $(grep $blob_sha1 $tmp |wc -l) + test x"$(cat $ok)" = xok +} + +t_begin "corked identity request (input#size first)" && { + rm -f $tmp + ( + cat $fifo > $tmp & + printf 'PUT /size_first HTTP/1.0\r\n' + printf 'Content-Length: %d\r\n\r\n' $blob_size + cat random_blob + wait + echo ok > $ok + ) | ( sleep 1 && socat - TCP4:$listen > $fifo ) + test 1 -eq $(grep $blob_sha1 $tmp |wc -l) + test x"$(cat $ok)" = xok +} + +t_begin "corked identity request (input#rewind first)" && { + rm -f $tmp + ( + cat $fifo > $tmp & + printf 'PUT /rewind_first HTTP/1.0\r\n' + printf 'Content-Length: %d\r\n\r\n' $blob_size + cat random_blob + wait + echo ok > $ok + ) | ( sleep 1 && socat - TCP4:$listen > $fifo ) + test 1 -eq $(grep $blob_sha1 $tmp |wc -l) + test x"$(cat $ok)" = xok +} + +t_begin "corked chunked request (input#size first)" && { + rm -f $tmp + ( + cat $fifo > $tmp & + printf 'PUT /size_first HTTP/1.1\r\n' + printf 'Host: example.com\r\n' + printf 'Transfer-Encoding: chunked\r\n' + printf 'Trailer: Content-MD5\r\n' + printf '\r\n' + content-md5-put --no-headers < random_blob + wait + echo ok > $ok + ) | ( sleep 1 && socat - TCP4:$listen > $fifo ) + test 1 -eq $(grep $blob_sha1 $tmp |wc -l) + test 1 -eq $(grep $blob_sha1 $tmp |wc -l) + test x"$(cat $ok)" = xok +} + +t_begin "corked chunked request (input#rewind first)" && { + rm -f $tmp + ( + cat $fifo > $tmp & + printf 'PUT /rewind_first HTTP/1.1\r\n' + printf 'Host: example.com\r\n' + printf 'Transfer-Encoding: chunked\r\n' + printf 'Trailer: Content-MD5\r\n' + printf '\r\n' + content-md5-put --no-headers < random_blob + wait + echo ok > $ok + ) | ( sleep 1 && socat - TCP4:$listen > $fifo ) + test 1 -eq $(grep $blob_sha1 $tmp |wc -l) + test x"$(cat $ok)" = xok +} + +t_begin "regular request" && { + curl -sSf -T random_blob http://$listen/ > $curl_out 2> $curl_err + test x$blob_sha1 = x$(cat $curl_out) + test ! -s $curl_err +} + +t_begin "chunked request" && { + curl -sSf -T- < random_blob http://$listen/ > $curl_out 2> $curl_err + test x$blob_sha1 = x$(cat $curl_out) + test ! -s $curl_err +} + +dbgcat r_err + +t_begin "shutdown" && { + kill $unicorn_pid +} + +t_done diff --git a/t/t0116-client_body_buffer_size.sh b/t/t0116-client_body_buffer_size.sh new file mode 100755 index 0000000..c9e17c7 --- /dev/null +++ b/t/t0116-client_body_buffer_size.sh @@ -0,0 +1,80 @@ +#!/bin/sh +. ./test-lib.sh +t_plan 12 "client_body_buffer_size settings" + +t_begin "setup and start" && { + unicorn_setup + rtmpfiles unicorn_config_tmp one_meg + dd if=/dev/zero bs=1M count=1 of=$one_meg + cat >> $unicorn_config <<EOF +after_fork do |server, worker| + File.open("$fifo", "wb") { |fp| fp.syswrite "START" } +end +EOF + cat $unicorn_config > $unicorn_config_tmp + echo client_body_buffer_size 0 >> $unicorn_config + unicorn -D -c $unicorn_config t0116.ru + unicorn_wait_start + fs_class=Unicorn::TmpIO + mem_class=StringIO + + test x"$(cat $fifo)" = xSTART +} + +t_begin "class for a zero-byte file should be StringIO" && { + > $tmp + test xStringIO = x"$(curl -T $tmp -sSf http://$listen/input_class)" +} + +t_begin "class for a 1 byte file should be filesystem-backed" && { + echo > $tmp + test x$fs_class = x"$(curl -T $tmp -sSf http://$listen/tmp_class)" +} + +t_begin "reload with default client_body_buffer_size" && { + mv $unicorn_config_tmp $unicorn_config + kill -HUP $unicorn_pid + test x"$(cat $fifo)" = xSTART +} + +t_begin "class for a 1 byte file should be memory-backed" && { + echo > $tmp + test x$mem_class = x"$(curl -T $tmp -sSf http://$listen/tmp_class)" +} + +t_begin "class for a random blob file should be filesystem-backed" && { + resp="$(curl -T random_blob -sSf http://$listen/tmp_class)" + test x$fs_class = x"$resp" +} + +t_begin "one megabyte file should be filesystem-backed" && { + resp="$(curl -T $one_meg -sSf http://$listen/tmp_class)" + test x$fs_class = x"$resp" +} + +t_begin "reload with a big client_body_buffer_size" && { + echo "client_body_buffer_size(1024 * 1024)" >> $unicorn_config + kill -HUP $unicorn_pid + test x"$(cat $fifo)" = xSTART +} + +t_begin "one megabyte file should be memory-backed" && { + resp="$(curl -T $one_meg -sSf http://$listen/tmp_class)" + test x$mem_class = x"$resp" +} + +t_begin "one megabyte + 1 byte file should be filesystem-backed" && { + echo >> $one_meg + resp="$(curl -T $one_meg -sSf http://$listen/tmp_class)" + test x$fs_class = x"$resp" +} + +t_begin "killing succeeds" && { + kill $unicorn_pid +} + +t_begin "check stderr" && { + check_stderr +} + +t_done diff --git a/t/t0116.ru b/t/t0116.ru new file mode 100644 index 0000000..fab5fce --- /dev/null +++ b/t/t0116.ru @@ -0,0 +1,16 @@ +#\ -E none +use Rack::ContentLength +use Rack::ContentType, 'text/plain' +app = lambda do |env| + input = env['rack.input'] + case env["PATH_INFO"] + when "/tmp_class" + body = input.instance_variable_get(:@tmp).class.name + when "/input_class" + body = input.class.name + else + return [ 500, {}, [] ] + end + [ 200, {}, [ body ] ] +end +run app diff --git a/t/t0303-rails3-alt-working_directory_config.ru.sh b/t/t0303-rails3-alt-working_directory_config.ru.sh index 444f05a..1433f94 100755 --- a/t/t0303-rails3-alt-working_directory_config.ru.sh +++ b/t/t0303-rails3-alt-working_directory_config.ru.sh @@ -1,9 +1,4 @@ #!/bin/sh -if test -n "$RBX_SKIP" -then - echo "$0 is broken under Rubinius for now" - exit 0 -fi . ./test-rails3.sh t_plan 5 "Rails 3 (beta) inside alt working_directory (w/ config.ru)" diff --git a/t/t9000-preread-input.sh b/t/t9000-preread-input.sh new file mode 100755 index 0000000..b9da05e --- /dev/null +++ b/t/t9000-preread-input.sh @@ -0,0 +1,48 @@ +#!/bin/sh +. ./test-lib.sh +t_plan 9 "PrereadInput middleware tests" + +t_begin "setup and start" && { + random_blob_sha1=$(rsha1 < random_blob) + unicorn_setup + unicorn -D -c $unicorn_config preread_input.ru + unicorn_wait_start +} + +t_begin "single identity request" && { + curl -sSf -T random_blob http://$listen/ > $tmp +} + +t_begin "sha1 matches" && { + test x"$(cat $tmp)" = x"$random_blob_sha1" +} + +t_begin "single chunked request" && { + curl -sSf -T- < random_blob http://$listen/ > $tmp +} + +t_begin "sha1 matches" && { + test x"$(cat $tmp)" = x"$random_blob_sha1" +} + +t_begin "app only dispatched twice" && { + test 2 -eq "$(grep 'app dispatch:' < $r_err | wc -l )" +} + +t_begin "aborted chunked request" && { + rm -f $tmp + curl -sSf -T- < $fifo http://$listen/ > $tmp & + curl_pid=$! + kill -9 $curl_pid + wait +} + +t_begin "app only dispatched twice" && { + test 2 -eq "$(grep 'app dispatch:' < $r_err | wc -l )" +} + +t_begin "killing succeeds" && { + kill -QUIT $unicorn_pid +} + +t_done diff --git a/t/test-rails3.sh b/t/test-rails3.sh index b398f03..907ef0d 100644 --- a/t/test-rails3.sh +++ b/t/test-rails3.sh @@ -13,7 +13,7 @@ rails_gems=../tmp/isolate/rails-$RAILS_VERSION/gems rails_bin="$rails_gems/rails-$RAILS_VERSION/bin/rails" if ! test -d "$arch_gems" || ! test -d "$rails_gems" || ! test -x "$rails_bin" then - ( cd ../ && $RAKE isolate ) + ( cd ../ && ./script/isolate_for_tests ) fi for i in $arch_gems/*-* $rails_gems/*-* |