about summary refs log tree commit homepage
path: root/t
diff options
context:
space:
mode:
Diffstat (limited to 't')
-rw-r--r--t/GNUmakefile8
-rw-r--r--t/preread_input.ru17
-rw-r--r--t/rack-input-tests.ru21
-rwxr-xr-xt/t0002-parser-error.sh31
-rwxr-xr-xt/t0003-working_directory.sh5
-rwxr-xr-xt/t0010-reap-logging.sh55
-rwxr-xr-xt/t0012-reload-empty-config.sh5
-rwxr-xr-xt/t0013-rewindable-input-false.sh24
-rw-r--r--t/t0013.ru12
-rwxr-xr-xt/t0014-rewindable-input-true.sh24
-rw-r--r--t/t0014.ru12
-rwxr-xr-xt/t0015-configurator-internals.sh25
-rwxr-xr-xt/t0016-trust-x-forwarded-false.sh30
-rwxr-xr-xt/t0017-trust-x-forwarded-true.sh30
-rwxr-xr-xt/t0100-rack-input-tests.sh124
-rwxr-xr-xt/t0116-client_body_buffer_size.sh80
-rw-r--r--t/t0116.ru16
-rwxr-xr-xt/t0303-rails3-alt-working_directory_config.ru.sh5
-rwxr-xr-xt/t9000-preread-input.sh48
-rw-r--r--t/test-rails3.sh2
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/*-*