diff options
Diffstat (limited to 't')
-rw-r--r-- | t/close-has-env.ru | 65 | ||||
-rw-r--r-- | t/t0050-response-body-close-has-env.sh | 109 |
2 files changed, 174 insertions, 0 deletions
diff --git a/t/close-has-env.ru b/t/close-has-env.ru new file mode 100644 index 0000000..471f605 --- /dev/null +++ b/t/close-has-env.ru @@ -0,0 +1,65 @@ +#\ -E none +use Rainbows::DevFdResponse +class ClosablePipe < ::IO + attr_accessor :env + + def self.new(env) + rv = popen "echo hello", "rb" + rv.env = env + rv + end + + def close + super + $stdout.syswrite "path_info=#{@env['PATH_INFO']}\n" + end +end + +class ClosableFile < ::File + attr_accessor :env + alias to_path path + def close + super + $stdout.syswrite "path_info=#{@env['PATH_INFO']}\n" + end +end + +class Blob + def initialize(env) + @env = env + end + + def each(&block) + yield "BLOB\n" + end + + def close + $stdout.syswrite "path_info=#{@env['PATH_INFO']}\n" + end +end + +run(lambda { |env| + case env["PATH_INFO"] + when %r{\A/pipe/} + [ 200, + [ %w(Content-Length 6), %w(Content-Type text/plain)], + ClosablePipe.new(env) + ] + when %r{\A/file/} + f = ClosableFile.open("env.ru", "rb") + f.env = env + [ 200, { + 'X-Req-Path' => env["PATH_INFO"], + 'Content-Length' => f.stat.size.to_s, + 'Content-Type' => 'text/plain' }, + f + ] + when %r{\A/blob/} + [ 200, + [%w(Content-Length 5), %w(Content-Type text/plain)], + Blob.new(env) + ] + else + [ 404, [%w(Content-Length 0), %w(Content-Type text/plain)], [] ] + end +}) diff --git a/t/t0050-response-body-close-has-env.sh b/t/t0050-response-body-close-has-env.sh new file mode 100644 index 0000000..4d0cd6f --- /dev/null +++ b/t/t0050-response-body-close-has-env.sh @@ -0,0 +1,109 @@ +#!/bin/sh +. ./test-lib.sh + +t_plan 29 "keepalive does not clear Rack env prematurely for $model" + +t_begin "setup and start" && { + rainbows_setup + rtmpfiles curl_out curl_err + echo "preload_app true" >> $unicorn_config + rainbows -D close-has-env.ru -c $unicorn_config + rainbows_wait_start +} + +req_pipelined () { + pfx=$1 + t_begin "make pipelined requests to trigger $pfx response body" && { + > $r_out + ( + cat $fifo > $tmp & + printf 'GET /%s/1 HTTP/1.1\r\n' $pfx + printf 'Host: example.com\r\n\r\n' + printf 'GET /%s/2 HTTP/1.1\r\n' $pfx + printf 'Host: example.com\r\n\r\n' + printf 'GET /%s/3 HTTP/1.1\r\n' $pfx + printf 'Host: example.com\r\n' + printf 'Connection: close\r\n\r\n' + wait + echo ok > $ok + ) | socat - TCP4:$listen > $fifo + test xok = x$(cat $ok) + } +} + +reload () { + t_begin 'reloading Rainbows! to ensure writeout' && { + # reload to ensure everything is flushed + kill -HUP $rainbows_pid + test xSTART = x"$(cat $fifo)" + } +} + +check_log () { + pfx="$1" + t_begin "check body close messages" && { + < $r_out awk ' +/^path_info=\/'$pfx'\/[1-3]$/ { next } +{ exit(2) } +END { exit(NR == 3 ? 0 : 1) } +' + } +} + +req_keepalive () { + pfx="$1" + t_begin "make keepalive requests to trigger $pfx response body" && { + > $r_out + rm -f $curl_err $curl_out + curl -vsSf http://$listen/$pfx/[1-3] 2> $curl_err > $curl_out + } +} + +req_keepalive file +reload +check_log file + +req_pipelined file +reload +check_log file + +req_keepalive blob +reload +check_log blob + +req_pipelined blob +reload +check_log blob + +req_keepalive pipe +reload +check_log pipe + +req_pipelined pipe +reload +check_log pipe + +t_begin "enable sendfile gem" && { + echo "require 'sendfile'" >> $unicorn_config + curl http://$listen/ >/dev/null # ensure worker is loaded before HUP +} + +reload + +req_keepalive file +reload +check_log file + +req_pipelined file +reload +check_log file + +t_begin "killing succeeds" && { + kill $rainbows_pid +} + +t_begin "check stderr" && { + check_stderr +} + +t_done |