rainbows 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/GIT-VERSION-GEN +1 -1
- data/GNUmakefile +12 -6
- data/README +3 -2
- data/Rakefile +3 -3
- data/TODO +2 -9
- data/lib/rainbows.rb +1 -0
- data/lib/rainbows/app_pool.rb +10 -6
- data/lib/rainbows/base.rb +1 -1
- data/lib/rainbows/const.rb +1 -1
- data/lib/rainbows/ev_core.rb +88 -0
- data/lib/rainbows/event_machine.rb +218 -0
- data/lib/rainbows/http_server.rb +4 -1
- data/lib/rainbows/rev.rb +21 -89
- data/lib/rainbows/revactor.rb +4 -10
- data/local.mk.sample +13 -7
- data/rainbows.gemspec +17 -2
- data/t/.gitignore +1 -0
- data/t/GNUmakefile +63 -40
- data/t/README +6 -2
- data/t/async_sinatra.ru +13 -0
- data/t/bin/unused_listen +1 -1
- data/t/large-file-response.ru +1 -0
- data/t/my-tap-lib.sh +200 -0
- data/t/simple-http_Base.ru +3 -0
- data/t/simple-http_EventMachine.ru +9 -0
- data/t/simple-http_Rev.ru +9 -0
- data/t/simple-http_Revactor.ru +10 -0
- data/t/simple-http_ThreadPool.ru +10 -0
- data/t/simple-http_ThreadSpawn.ru +10 -0
- data/t/t0000-simple-http.sh +142 -0
- data/t/t0001-unix-http.sh +103 -0
- data/t/t0002-graceful.sh +32 -0
- data/t/t0002-parser-error.sh +31 -0
- data/t/t0003-reopen-logs.sh +97 -0
- data/t/t0005-large-file-response.sh +83 -0
- data/t/t0100-rack-input-hammer.sh +45 -0
- data/t/t0101-rack-input-trailer.sh +68 -0
- data/t/t0200-async-response.sh +66 -0
- data/t/t0201-async-response-no-autochunk.sh +3 -0
- data/t/t0300-async_sinatra.sh +65 -0
- data/t/t9000-rack-app-pool.sh +45 -33
- data/t/test-lib.sh +67 -56
- metadata +26 -56
- data/t/lib-async-response-no-autochunk.sh +0 -6
- data/t/lib-async-response.sh +0 -45
- data/t/lib-graceful.sh +0 -40
- data/t/lib-input-trailer.sh +0 -63
- data/t/lib-large-file-response.sh +0 -45
- data/t/lib-parser-error.sh +0 -29
- data/t/lib-rack-input-hammer.sh +0 -38
- data/t/lib-reopen-logs.sh +0 -60
- data/t/lib-simple-http.sh +0 -92
- data/t/t0000-basic.sh +0 -2
- data/t/t1000-thread-pool-basic.sh +0 -2
- data/t/t1002-thread-pool-graceful.sh +0 -2
- data/t/t1003-thread-pool-reopen-logs.sh +0 -2
- data/t/t1004-thread-pool-async-response.sh +0 -45
- data/t/t1005-thread-pool-large-file-response.sh +0 -45
- data/t/t1006-thread-pool-async-response-no-autochunk.sh +0 -6
- data/t/t1100-thread-pool-rack-input.sh +0 -2
- data/t/t1101-thread-pool-input-trailer.sh +0 -2
- data/t/t2000-thread-spawn-basic.sh +0 -2
- data/t/t2002-thread-spawn-graceful.sh +0 -2
- data/t/t2003-thread-spawn-reopen-logs.sh +0 -2
- data/t/t2004-thread-spawn-async-response.sh +0 -45
- data/t/t2005-thread-spawn-large-file-response.sh +0 -45
- data/t/t2006-thread-spawn-async-response-no-autochunk.sh +0 -6
- data/t/t2100-thread-spawn-rack-input.sh +0 -2
- data/t/t2101-thread-spawn-input-trailer.sh +0 -2
- data/t/t3000-revactor-basic.sh +0 -2
- data/t/t3002-revactor-graceful.sh +0 -2
- data/t/t3003-revactor-reopen-logs.sh +0 -2
- data/t/t3004-revactor-async-response.sh +0 -45
- data/t/t3005-revactor-large-file-response.sh +0 -2
- data/t/t3006-revactor-async-response-no-autochunk.sh +0 -6
- data/t/t3100-revactor-rack-input.sh +0 -2
- data/t/t3101-revactor-rack-input-trailer.sh +0 -2
- data/t/t4000-rev-basic.sh +0 -2
- data/t/t4002-rev-graceful.sh +0 -2
- data/t/t4003-rev-parser-error.sh +0 -2
- data/t/t4003-rev-reopen-logs.sh +0 -2
- data/t/t4004-rev-async-response.sh +0 -45
- data/t/t4005-rev-large-file-response.sh +0 -2
- data/t/t4006-rev-async-response-no-autochunk.sh +0 -6
- data/t/t4100-rev-rack-input.sh +0 -2
- data/t/t4101-rev-rack-input-trailer.sh +0 -2
data/t/bin/unused_listen
CHANGED
data/t/large-file-response.ru
CHANGED
data/t/my-tap-lib.sh
ADDED
@@ -0,0 +1,200 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
# Copyright (c) 2009 Eric Wong <normalperson@yhbt.net>
|
3
|
+
#
|
4
|
+
# TAP-producing shell library for POSIX-compliant Bourne shells We do
|
5
|
+
# not _rely_ on Bourne Again features, though we will use "set -o
|
6
|
+
# pipefail" from ksh93 or bash 3 if available
|
7
|
+
#
|
8
|
+
# Only generic, non-project/non-language-specific stuff goes here. We
|
9
|
+
# only have POSIX dependencies for the core tests (without --verbose),
|
10
|
+
# though we'll enable useful non-POSIX things if they're available.
|
11
|
+
#
|
12
|
+
# This test library is intentionally unforgiving, it does not support
|
13
|
+
# skipping tests nor continuing after any failure. Any failures
|
14
|
+
# immediately halt execution as do any references to undefined
|
15
|
+
# variables.
|
16
|
+
#
|
17
|
+
# When --verbose is specified, we always prefix stdout/stderr
|
18
|
+
# output with "#" to avoid confusing TAP consumers. Otherwise
|
19
|
+
# the normal stdout/stderr streams are redirected to /dev/null
|
20
|
+
|
21
|
+
# dup normal stdout(fd=1) and stderr (fd=2) to fd=3 and fd=4 respectively
|
22
|
+
# normal TAP output goes to fd=3, nothing should go to fd=4
|
23
|
+
exec 3>&1 4>&2
|
24
|
+
|
25
|
+
# ensure a sane environment
|
26
|
+
TZ=UTC LC_ALL=C LANG=C
|
27
|
+
export LANG LC_ALL TZ
|
28
|
+
unset CDPATH
|
29
|
+
|
30
|
+
# pipefail is non-POSIX, but very useful in ksh93/bash
|
31
|
+
( set -o pipefail 2>/dev/null ) && set -o pipefail
|
32
|
+
|
33
|
+
SED=${SED-sed}
|
34
|
+
|
35
|
+
# Unlike other test frameworks, we are unforgiving and bail immediately
|
36
|
+
# on any failures. We do this because we're lazy about error handling
|
37
|
+
# and also because we believe anything broken should not be allowed to
|
38
|
+
# propagate throughout the rest of the test
|
39
|
+
set -e
|
40
|
+
set -u
|
41
|
+
|
42
|
+
# name of our test
|
43
|
+
T=${0##*/}
|
44
|
+
|
45
|
+
t_expect_nr=-1
|
46
|
+
t_nr=0
|
47
|
+
t_current=
|
48
|
+
t_complete=false
|
49
|
+
|
50
|
+
# list of files to remove unconditionally on exit
|
51
|
+
T_RM_LIST=
|
52
|
+
|
53
|
+
# list of files to remove only on successful exit
|
54
|
+
T_OK_RM_LIST=
|
55
|
+
|
56
|
+
# emit output to stdout, it'll be parsed by the TAP consumer
|
57
|
+
# so it must be TAP-compliant output
|
58
|
+
t_echo () {
|
59
|
+
echo >&3 "$@"
|
60
|
+
}
|
61
|
+
|
62
|
+
# emits non-parsed information to stdout, it will be prefixed with a '#'
|
63
|
+
# to not throw off TAP consumers
|
64
|
+
t_info () {
|
65
|
+
t_echo '#' "$@"
|
66
|
+
}
|
67
|
+
|
68
|
+
# exit with an error and print a diagnostic
|
69
|
+
die () {
|
70
|
+
echo >&2 "$@"
|
71
|
+
exit 1
|
72
|
+
}
|
73
|
+
|
74
|
+
# our at_exit handler, it'll fire for all exits except SIGKILL (unavoidable)
|
75
|
+
t_at_exit () {
|
76
|
+
code=$?
|
77
|
+
set +e
|
78
|
+
if test $code -eq 0
|
79
|
+
then
|
80
|
+
$t_complete || {
|
81
|
+
t_info "t_done not called"
|
82
|
+
code=1
|
83
|
+
}
|
84
|
+
elif test -n "$t_current"
|
85
|
+
then
|
86
|
+
t_echo "not ok $t_nr - $t_current"
|
87
|
+
fi
|
88
|
+
if test $t_expect_nr -ne -1
|
89
|
+
then
|
90
|
+
test $t_expect_nr -eq $t_nr || {
|
91
|
+
t_info "planned $t_expect_nr tests but ran $t_nr"
|
92
|
+
test $code -ne 0 || code=1
|
93
|
+
}
|
94
|
+
fi
|
95
|
+
$t_complete || {
|
96
|
+
t_info "unexpected test failure"
|
97
|
+
test $code -ne 0 || code=1
|
98
|
+
}
|
99
|
+
rm -f $T_RM_LIST
|
100
|
+
test $code -eq 0 && rm -f $T_OK_RM_LIST
|
101
|
+
set +x
|
102
|
+
exec >&3 2>&4
|
103
|
+
t_close_fds
|
104
|
+
exit $code
|
105
|
+
}
|
106
|
+
|
107
|
+
# close test-specific extra file descriptors
|
108
|
+
t_close_fds () {
|
109
|
+
exec 3>&- 4>&-
|
110
|
+
}
|
111
|
+
|
112
|
+
# call this at the start of your test to specify the number of tests
|
113
|
+
# you plan to run
|
114
|
+
t_plan () {
|
115
|
+
test "$1" -ge 1 || die "must plan at least one test"
|
116
|
+
test $t_expect_nr -eq -1 || die "tried to plan twice in one test"
|
117
|
+
t_expect_nr=$1
|
118
|
+
shift
|
119
|
+
t_echo 1..$t_expect_nr "#" "$@"
|
120
|
+
trap t_at_exit EXIT
|
121
|
+
}
|
122
|
+
|
123
|
+
_t_checkup () {
|
124
|
+
test $t_expect_nr -le 0 && die "no tests planned"
|
125
|
+
test -n "$t_current" && t_echo "ok $t_nr - $t_current"
|
126
|
+
true
|
127
|
+
}
|
128
|
+
|
129
|
+
# finalizes any previously test and starts a new one
|
130
|
+
t_begin () {
|
131
|
+
_t_checkup
|
132
|
+
t_nr=$(( $t_nr + 1 ))
|
133
|
+
t_current="$1"
|
134
|
+
|
135
|
+
# just in case somebody wanted to cheat us:
|
136
|
+
set -e
|
137
|
+
}
|
138
|
+
|
139
|
+
# finalizes the current test without starting a new one
|
140
|
+
t_end () {
|
141
|
+
_t_checkup
|
142
|
+
t_current=
|
143
|
+
}
|
144
|
+
|
145
|
+
# run this to signify the end of your test
|
146
|
+
t_done () {
|
147
|
+
_t_checkup
|
148
|
+
t_current=
|
149
|
+
t_complete=true
|
150
|
+
test $t_expect_nr -eq $t_nr || exit 1
|
151
|
+
exit 0
|
152
|
+
}
|
153
|
+
|
154
|
+
# create and assign named-pipes to variable _names_ passed to this function
|
155
|
+
t_fifos () {
|
156
|
+
for _id in "$@"
|
157
|
+
do
|
158
|
+
_name=$_id
|
159
|
+
_tmp=$(mktemp -t $T.$$.$_id.XXXXXXXX)
|
160
|
+
eval "$_id=$_tmp"
|
161
|
+
rm -f $_tmp
|
162
|
+
mkfifo $_tmp
|
163
|
+
T_RM_LIST="$T_RM_LIST $_tmp"
|
164
|
+
done
|
165
|
+
}
|
166
|
+
|
167
|
+
t_verbose=false t_trace=false
|
168
|
+
|
169
|
+
while test "$#" -ne 0
|
170
|
+
do
|
171
|
+
arg="$1"
|
172
|
+
shift
|
173
|
+
case $arg in
|
174
|
+
-v|--verbose) t_verbose=true ;;
|
175
|
+
--trace) t_trace=true t_verbose=true ;;
|
176
|
+
*) die "Unknown option: $arg" ;;
|
177
|
+
esac
|
178
|
+
done
|
179
|
+
|
180
|
+
# we always only setup stdout, nothing should end up in the "real" stderr
|
181
|
+
if $t_verbose
|
182
|
+
then
|
183
|
+
if test x"$(which mktemp 2>/dev/null)" = x
|
184
|
+
then
|
185
|
+
die "mktemp(1) not available for --verbose"
|
186
|
+
fi
|
187
|
+
t_fifos t_stdout t_stderr
|
188
|
+
|
189
|
+
(
|
190
|
+
# use a subshell so seds are not waitable
|
191
|
+
$SED -e 's/^/#: /' $t_stdout &
|
192
|
+
$SED -e 's/^/#! /' $t_stderr &
|
193
|
+
) &
|
194
|
+
exec > $t_stdout 2> $t_stderr
|
195
|
+
else
|
196
|
+
exec > /dev/null 2> /dev/null
|
197
|
+
fi
|
198
|
+
|
199
|
+
$t_trace && set -x
|
200
|
+
true
|
@@ -0,0 +1,10 @@
|
|
1
|
+
use Rack::ContentLength
|
2
|
+
use Rack::ContentType
|
3
|
+
run lambda { |env|
|
4
|
+
Actor.sleep 1
|
5
|
+
if env['rack.multithread'] == false && env['rainbows.model'] == :Revactor
|
6
|
+
[ 200, {}, [ Thread.current.inspect << "\n" ] ]
|
7
|
+
else
|
8
|
+
raise "rack.multithread is true"
|
9
|
+
end
|
10
|
+
}
|
@@ -0,0 +1,142 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
. ./test-lib.sh
|
3
|
+
t_plan 24 "simple HTTP connection keepalive/pipelining tests for $model"
|
4
|
+
|
5
|
+
t_begin "checking for config.ru for $model" && {
|
6
|
+
tbase=simple-http_$model.ru
|
7
|
+
test -f "$tbase"
|
8
|
+
}
|
9
|
+
|
10
|
+
t_begin "setup and start" && {
|
11
|
+
rainbows_setup
|
12
|
+
rainbows -D $tbase -c $unicorn_config
|
13
|
+
rainbows_wait_start
|
14
|
+
}
|
15
|
+
|
16
|
+
t_begin "pid file exists" && {
|
17
|
+
test -f $pid
|
18
|
+
}
|
19
|
+
|
20
|
+
t_begin "single request" && {
|
21
|
+
curl -sSfv http://$listen/
|
22
|
+
}
|
23
|
+
|
24
|
+
dbgcat r_err
|
25
|
+
|
26
|
+
t_begin "two requests with keepalive" && {
|
27
|
+
curl -sSfv http://$listen/a http://$listen/b > $tmp 2>&1
|
28
|
+
}
|
29
|
+
|
30
|
+
dbgcat r_err
|
31
|
+
dbgcat tmp
|
32
|
+
|
33
|
+
t_begin "reused existing connection" && {
|
34
|
+
grep 'Re-using existing connection' < $tmp
|
35
|
+
}
|
36
|
+
|
37
|
+
t_begin "pipelining partial requests" && {
|
38
|
+
req='GET / HTTP/1.1\r\nHost: example.com\r\n'
|
39
|
+
(
|
40
|
+
cat $fifo > $tmp &
|
41
|
+
printf "$req"'\r\n'"$req"
|
42
|
+
sleep 1
|
43
|
+
printf 'Connection: close\r\n\r\n'
|
44
|
+
wait
|
45
|
+
echo ok > $ok
|
46
|
+
) | socat - TCP:$listen > $fifo
|
47
|
+
}
|
48
|
+
dbgcat tmp
|
49
|
+
|
50
|
+
t_begin "two HTTP/1.1 responses" && {
|
51
|
+
test 2 -eq $(grep '^HTTP/1.1' $tmp | wc -l)
|
52
|
+
}
|
53
|
+
|
54
|
+
t_begin "two HTTP/1.1 200 OK responses" && {
|
55
|
+
test 2 -eq $(grep '^HTTP/1.1 200 OK' $tmp | wc -l)
|
56
|
+
}
|
57
|
+
|
58
|
+
t_begin 'one "Connection: keep-alive" response' && {
|
59
|
+
test 1 -eq $(grep '^Connection: keep-alive' $tmp | wc -l)
|
60
|
+
}
|
61
|
+
|
62
|
+
t_begin 'one "Connection: close" response' && {
|
63
|
+
test 1 -eq $(grep '^Connection: close' $tmp | wc -l)
|
64
|
+
}
|
65
|
+
|
66
|
+
t_begin 'check subshell success' && {
|
67
|
+
test x"$(cat $ok)" = xok
|
68
|
+
}
|
69
|
+
|
70
|
+
|
71
|
+
t_begin "check stderr" && {
|
72
|
+
check_stderr
|
73
|
+
}
|
74
|
+
|
75
|
+
t_begin "burst pipelining requests" && {
|
76
|
+
req='GET / HTTP/1.1\r\nHost: example.com\r\n'
|
77
|
+
(
|
78
|
+
cat $fifo > $tmp &
|
79
|
+
printf "$req"'\r\n'"$req"'Connection: close\r\n\r\n'
|
80
|
+
wait
|
81
|
+
echo ok > $ok
|
82
|
+
) | socat - TCP:$listen > $fifo
|
83
|
+
}
|
84
|
+
|
85
|
+
dbgcat tmp
|
86
|
+
dbgcat r_err
|
87
|
+
|
88
|
+
t_begin "got 2 HTTP/1.1 responses from pipelining" && {
|
89
|
+
test 2 -eq $(grep '^HTTP/1.1' $tmp | wc -l)
|
90
|
+
}
|
91
|
+
|
92
|
+
t_begin "got 2 HTTP/1.1 200 OK responses" && {
|
93
|
+
test 2 -eq $(grep '^HTTP/1.1 200 OK' $tmp | wc -l)
|
94
|
+
}
|
95
|
+
|
96
|
+
t_begin "one keepalive connection" && {
|
97
|
+
test 1 -eq $(grep '^Connection: keep-alive' $tmp | wc -l)
|
98
|
+
}
|
99
|
+
|
100
|
+
t_begin "second request closes connection" && {
|
101
|
+
test 1 -eq $(grep '^Connection: close' $tmp | wc -l)
|
102
|
+
}
|
103
|
+
|
104
|
+
t_begin "subshell exited correctly" && {
|
105
|
+
test x"$(cat $ok)" = xok
|
106
|
+
}
|
107
|
+
|
108
|
+
t_begin "stderr log has no errors" && {
|
109
|
+
check_stderr
|
110
|
+
}
|
111
|
+
|
112
|
+
t_begin "HTTP/0.9 request should not return headers" && {
|
113
|
+
(
|
114
|
+
printf 'GET /\r\n'
|
115
|
+
cat $fifo > $tmp &
|
116
|
+
wait
|
117
|
+
echo ok > $ok
|
118
|
+
) | socat - TCP:$listen > $fifo
|
119
|
+
}
|
120
|
+
|
121
|
+
dbgcat tmp
|
122
|
+
dbgcat r_err
|
123
|
+
|
124
|
+
t_begin "env.inspect should've put everything on one line" && {
|
125
|
+
test 1 -eq $(wc -l < $tmp)
|
126
|
+
}
|
127
|
+
|
128
|
+
t_begin "no headers in output" && {
|
129
|
+
if grep ^Connection: $tmp
|
130
|
+
then
|
131
|
+
die "Connection header found in $tmp"
|
132
|
+
elif grep ^HTTP/ $tmp
|
133
|
+
then
|
134
|
+
die "HTTP/ found in $tmp"
|
135
|
+
fi
|
136
|
+
}
|
137
|
+
|
138
|
+
t_begin "killing succeeds" && {
|
139
|
+
kill $rainbows_pid
|
140
|
+
}
|
141
|
+
|
142
|
+
t_done
|
@@ -0,0 +1,103 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
. ./test-lib.sh
|
3
|
+
t_plan 18 "simple HTTP connection keepalive/pipelining tests for $model"
|
4
|
+
|
5
|
+
t_begin "checking for config.ru for $model" && {
|
6
|
+
tbase=simple-http_$model.ru
|
7
|
+
test -f "$tbase"
|
8
|
+
}
|
9
|
+
|
10
|
+
t_begin "setup and start" && {
|
11
|
+
rtmpfiles unix_socket
|
12
|
+
rainbows_setup
|
13
|
+
echo "listen '$unix_socket'" >> $unicorn_config
|
14
|
+
rainbows -D $tbase -c $unicorn_config
|
15
|
+
rainbows_wait_start
|
16
|
+
}
|
17
|
+
|
18
|
+
t_begin "pid file exists" && {
|
19
|
+
test -f $pid
|
20
|
+
}
|
21
|
+
|
22
|
+
t_begin "single TCP request" && {
|
23
|
+
curl -sSfv http://$listen/
|
24
|
+
}
|
25
|
+
|
26
|
+
dbgcat r_err
|
27
|
+
|
28
|
+
t_begin "pipelining partial requests" && {
|
29
|
+
req='GET / HTTP/1.1\r\nHost: example.com\r\n'
|
30
|
+
(
|
31
|
+
cat $fifo > $tmp &
|
32
|
+
printf "$req"'\r\n'"$req"
|
33
|
+
sleep 1
|
34
|
+
printf 'Connection: close\r\n\r\n'
|
35
|
+
wait
|
36
|
+
echo ok > $ok
|
37
|
+
) | socat - UNIX:$unix_socket > $fifo
|
38
|
+
}
|
39
|
+
dbgcat tmp
|
40
|
+
|
41
|
+
t_begin "two HTTP/1.1 responses" && {
|
42
|
+
test 2 -eq $(grep '^HTTP/1.1' $tmp | wc -l)
|
43
|
+
}
|
44
|
+
|
45
|
+
t_begin "two HTTP/1.1 200 OK responses" && {
|
46
|
+
test 2 -eq $(grep '^HTTP/1.1 200 OK' $tmp | wc -l)
|
47
|
+
}
|
48
|
+
|
49
|
+
t_begin 'one "Connection: keep-alive" response' && {
|
50
|
+
test 1 -eq $(grep '^Connection: keep-alive' $tmp | wc -l)
|
51
|
+
}
|
52
|
+
|
53
|
+
t_begin 'one "Connection: close" response' && {
|
54
|
+
test 1 -eq $(grep '^Connection: close' $tmp | wc -l)
|
55
|
+
}
|
56
|
+
|
57
|
+
t_begin 'check subshell success' && {
|
58
|
+
test x"$(cat $ok)" = xok
|
59
|
+
}
|
60
|
+
|
61
|
+
|
62
|
+
t_begin "check stderr" && {
|
63
|
+
check_stderr
|
64
|
+
}
|
65
|
+
|
66
|
+
t_begin "burst pipelining requests" && {
|
67
|
+
req='GET / HTTP/1.1\r\nHost: example.com\r\n'
|
68
|
+
(
|
69
|
+
cat $fifo > $tmp &
|
70
|
+
printf "$req"'\r\n'"$req"'Connection: close\r\n\r\n'
|
71
|
+
wait
|
72
|
+
echo ok > $ok
|
73
|
+
) | socat - UNIX:$unix_socket > $fifo
|
74
|
+
}
|
75
|
+
|
76
|
+
dbgcat tmp
|
77
|
+
dbgcat r_err
|
78
|
+
|
79
|
+
t_begin "two HTTP/1.1 responses" && {
|
80
|
+
test 2 -eq $(grep '^HTTP/1.1' $tmp | wc -l)
|
81
|
+
}
|
82
|
+
|
83
|
+
t_begin "two HTTP/1.1 200 OK responses" && {
|
84
|
+
test 2 -eq $(grep '^HTTP/1.1 200 OK' $tmp | wc -l)
|
85
|
+
}
|
86
|
+
|
87
|
+
t_begin 'one "Connection: keep-alive" response' && {
|
88
|
+
test 1 -eq $(grep '^Connection: keep-alive' $tmp | wc -l)
|
89
|
+
}
|
90
|
+
|
91
|
+
t_begin 'one "Connection: close" response' && {
|
92
|
+
test 1 -eq $(grep '^Connection: close' $tmp | wc -l)
|
93
|
+
}
|
94
|
+
|
95
|
+
t_begin 'check subshell success' && {
|
96
|
+
test x"$(cat $ok)" = xok
|
97
|
+
}
|
98
|
+
|
99
|
+
t_begin "killing succeeds" && {
|
100
|
+
kill $rainbows_pid
|
101
|
+
}
|
102
|
+
|
103
|
+
t_done
|