about summary refs log tree commit homepage
path: root/t
diff options
context:
space:
mode:
Diffstat (limited to 't')
-rw-r--r--t/close-has-env.ru65
-rw-r--r--t/t0050-response-body-close-has-env.sh109
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