unicorn-shopify 4.8.2.5.23
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.
- checksums.yaml +7 -0
- data/.CHANGELOG.old +25 -0
- data/.document +28 -0
- data/.gitignore +25 -0
- data/.mailmap +26 -0
- data/.olddoc.yml +15 -0
- data/Application_Timeouts +77 -0
- data/CONTRIBUTORS +35 -0
- data/COPYING +674 -0
- data/DESIGN +97 -0
- data/Documentation/.gitignore +5 -0
- data/Documentation/GNUmakefile +30 -0
- data/Documentation/unicorn.1.txt +185 -0
- data/Documentation/unicorn_rails.1.txt +175 -0
- data/FAQ +61 -0
- data/GIT-VERSION-GEN +39 -0
- data/GNUmakefile +252 -0
- data/HACKING +120 -0
- data/ISSUES +100 -0
- data/KNOWN_ISSUES +79 -0
- data/LICENSE +67 -0
- data/Links +59 -0
- data/PHILOSOPHY +145 -0
- data/README +145 -0
- data/Rakefile +16 -0
- data/SIGNALS +123 -0
- data/Sandbox +103 -0
- data/TODO +5 -0
- data/TUNING +101 -0
- data/archive/.gitignore +3 -0
- data/archive/slrnpull.conf +4 -0
- data/bin/unicorn +126 -0
- data/bin/unicorn_rails +209 -0
- data/examples/big_app_gc.rb +2 -0
- data/examples/echo.ru +27 -0
- data/examples/init.sh +74 -0
- data/examples/logger_mp_safe.rb +25 -0
- data/examples/logrotate.conf +29 -0
- data/examples/nginx.conf +156 -0
- data/examples/unicorn.conf.minimal.rb +13 -0
- data/examples/unicorn.conf.rb +113 -0
- data/ext/unicorn_http/CFLAGS +13 -0
- data/ext/unicorn_http/c_util.h +124 -0
- data/ext/unicorn_http/common_field_optimization.h +111 -0
- data/ext/unicorn_http/ext_help.h +82 -0
- data/ext/unicorn_http/extconf.rb +10 -0
- data/ext/unicorn_http/global_variables.h +97 -0
- data/ext/unicorn_http/httpdate.c +78 -0
- data/ext/unicorn_http/unicorn_http.rl +934 -0
- data/ext/unicorn_http/unicorn_http_common.rl +76 -0
- data/lib/unicorn.rb +112 -0
- data/lib/unicorn/app/old_rails.rb +35 -0
- data/lib/unicorn/app/old_rails/static.rb +59 -0
- data/lib/unicorn/cgi_wrapper.rb +147 -0
- data/lib/unicorn/configurator.rb +686 -0
- data/lib/unicorn/const.rb +21 -0
- data/lib/unicorn/http_request.rb +125 -0
- data/lib/unicorn/http_response.rb +73 -0
- data/lib/unicorn/http_server.rb +816 -0
- data/lib/unicorn/launcher.rb +62 -0
- data/lib/unicorn/oob_gc.rb +81 -0
- data/lib/unicorn/preread_input.rb +33 -0
- data/lib/unicorn/socket_helper.rb +197 -0
- data/lib/unicorn/stream_input.rb +146 -0
- data/lib/unicorn/tee_input.rb +133 -0
- data/lib/unicorn/tmpio.rb +27 -0
- data/lib/unicorn/util.rb +90 -0
- data/lib/unicorn/worker.rb +140 -0
- data/setup.rb +1586 -0
- data/t/.gitignore +4 -0
- data/t/GNUmakefile +74 -0
- data/t/README +42 -0
- data/t/before_murder.ru +7 -0
- data/t/bin/content-md5-put +36 -0
- data/t/bin/sha1sum.rb +17 -0
- data/t/bin/unused_listen +40 -0
- data/t/broken-app.ru +12 -0
- data/t/detach.ru +11 -0
- data/t/env.ru +3 -0
- data/t/fails-rack-lint.ru +5 -0
- data/t/heartbeat-timeout.ru +12 -0
- data/t/hijack.ru +42 -0
- data/t/listener_names.ru +4 -0
- data/t/my-tap-lib.sh +201 -0
- data/t/oob_gc.ru +20 -0
- data/t/oob_gc_path.ru +20 -0
- data/t/pid.ru +3 -0
- data/t/preread_input.ru +17 -0
- data/t/rack-input-tests.ru +21 -0
- data/t/t0000-http-basic.sh +50 -0
- data/t/t0001-reload-bad-config.sh +53 -0
- data/t/t0002-config-conflict.sh +49 -0
- data/t/t0002-parser-error.sh +94 -0
- data/t/t0003-working_directory.sh +51 -0
- data/t/t0004-heartbeat-timeout.sh +69 -0
- data/t/t0004-working_directory_broken.sh +24 -0
- data/t/t0005-working_directory_app.rb.sh +40 -0
- data/t/t0006-reopen-logs.sh +83 -0
- data/t/t0006.ru +13 -0
- data/t/t0007-working_directory_no_embed_cli.sh +44 -0
- data/t/t0008-back_out_of_upgrade.sh +110 -0
- data/t/t0009-broken-app.sh +56 -0
- data/t/t0009-winch_ttin.sh +59 -0
- data/t/t0010-reap-logging.sh +55 -0
- data/t/t0011-active-unix-socket.sh +79 -0
- data/t/t0012-reload-empty-config.sh +85 -0
- data/t/t0013-rewindable-input-false.sh +24 -0
- data/t/t0013.ru +12 -0
- data/t/t0014-rewindable-input-true.sh +24 -0
- data/t/t0014.ru +12 -0
- data/t/t0015-configurator-internals.sh +25 -0
- data/t/t0018-write-on-close.sh +23 -0
- data/t/t0019-max_header_len.sh +49 -0
- data/t/t0020-at_exit-handler.sh +49 -0
- data/t/t0021-process_detach.sh +29 -0
- data/t/t0022-listener_names-preload_app.sh +32 -0
- data/t/t0023-before-murder.sh +40 -0
- data/t/t0024-before-murder_once.sh +52 -0
- data/t/t0100-rack-input-tests.sh +124 -0
- data/t/t0116-client_body_buffer_size.sh +80 -0
- data/t/t0116.ru +16 -0
- data/t/t0200-rack-hijack.sh +27 -0
- data/t/t0300-no-default-middleware.sh +20 -0
- data/t/t9000-preread-input.sh +48 -0
- data/t/t9001-oob_gc.sh +47 -0
- data/t/t9002-oob_gc-path.sh +75 -0
- data/t/test-lib.sh +128 -0
- data/t/write-on-close.ru +11 -0
- data/test/aggregate.rb +15 -0
- data/test/benchmark/README +50 -0
- data/test/benchmark/dd.ru +18 -0
- data/test/benchmark/stack.ru +8 -0
- data/test/exec/README +5 -0
- data/test/exec/test_exec.rb +1047 -0
- data/test/test_helper.rb +297 -0
- data/test/unit/test_configurator.rb +175 -0
- data/test/unit/test_droplet.rb +28 -0
- data/test/unit/test_http_parser.rb +854 -0
- data/test/unit/test_http_parser_ng.rb +622 -0
- data/test/unit/test_request.rb +182 -0
- data/test/unit/test_response.rb +93 -0
- data/test/unit/test_server.rb +268 -0
- data/test/unit/test_signals.rb +188 -0
- data/test/unit/test_socket_helper.rb +197 -0
- data/test/unit/test_stream_input.rb +203 -0
- data/test/unit/test_tee_input.rb +304 -0
- data/test/unit/test_upload.rb +306 -0
- data/test/unit/test_util.rb +105 -0
- data/unicorn.gemspec +41 -0
- metadata +311 -0
data/t/oob_gc.ru
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#\-E none
|
|
2
|
+
require 'unicorn/oob_gc'
|
|
3
|
+
use Rack::ContentLength
|
|
4
|
+
use Rack::ContentType, "text/plain"
|
|
5
|
+
use Unicorn::OobGC
|
|
6
|
+
$gc_started = false
|
|
7
|
+
|
|
8
|
+
# Mock GC.start
|
|
9
|
+
def GC.start
|
|
10
|
+
ObjectSpace.each_object(Kgio::Socket) do |x|
|
|
11
|
+
x.closed? or abort "not closed #{x}"
|
|
12
|
+
end
|
|
13
|
+
$gc_started = true
|
|
14
|
+
end
|
|
15
|
+
run lambda { |env|
|
|
16
|
+
if "/gc_reset" == env["PATH_INFO"] && "POST" == env["REQUEST_METHOD"]
|
|
17
|
+
$gc_started = false
|
|
18
|
+
end
|
|
19
|
+
[ 200, {}, [ "#$gc_started\n" ] ]
|
|
20
|
+
}
|
data/t/oob_gc_path.ru
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#\-E none
|
|
2
|
+
require 'unicorn/oob_gc'
|
|
3
|
+
use Rack::ContentLength
|
|
4
|
+
use Rack::ContentType, "text/plain"
|
|
5
|
+
use Unicorn::OobGC, 5, /BAD/
|
|
6
|
+
$gc_started = false
|
|
7
|
+
|
|
8
|
+
# Mock GC.start
|
|
9
|
+
def GC.start
|
|
10
|
+
ObjectSpace.each_object(Kgio::Socket) do |x|
|
|
11
|
+
x.closed? or abort "not closed #{x}"
|
|
12
|
+
end
|
|
13
|
+
$gc_started = true
|
|
14
|
+
end
|
|
15
|
+
run lambda { |env|
|
|
16
|
+
if "/gc_reset" == env["PATH_INFO"] && "POST" == env["REQUEST_METHOD"]
|
|
17
|
+
$gc_started = false
|
|
18
|
+
end
|
|
19
|
+
[ 200, {}, [ "#$gc_started\n" ] ]
|
|
20
|
+
}
|
data/t/pid.ru
ADDED
data/t/preread_input.ru
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#\-E none
|
|
2
|
+
require 'digest/sha1'
|
|
3
|
+
require 'unicorn/preread_input'
|
|
4
|
+
use Rack::ContentLength
|
|
5
|
+
use Rack::ContentType, "text/plain"
|
|
6
|
+
use Unicorn::PrereadInput
|
|
7
|
+
nr = 0
|
|
8
|
+
run lambda { |env|
|
|
9
|
+
$stderr.write "app dispatch: #{nr += 1}\n"
|
|
10
|
+
input = env["rack.input"]
|
|
11
|
+
dig = Digest::SHA1.new
|
|
12
|
+
while buf = input.read(16384)
|
|
13
|
+
dig.update(buf)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
[ 200, {}, [ "#{dig.hexdigest}\n" ] ]
|
|
17
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# SHA1 checksum generator
|
|
2
|
+
require 'digest/sha1'
|
|
3
|
+
use Rack::ContentLength
|
|
4
|
+
cap = 16384
|
|
5
|
+
app = lambda do |env|
|
|
6
|
+
/\A100-continue\z/i =~ env['HTTP_EXPECT'] and
|
|
7
|
+
return [ 100, {}, [] ]
|
|
8
|
+
digest = Digest::SHA1.new
|
|
9
|
+
input = env['rack.input']
|
|
10
|
+
input.size if env["PATH_INFO"] == "/size_first"
|
|
11
|
+
input.rewind if env["PATH_INFO"] == "/rewind_first"
|
|
12
|
+
if buf = input.read(rand(cap))
|
|
13
|
+
begin
|
|
14
|
+
raise "#{buf.size} > #{cap}" if buf.size > cap
|
|
15
|
+
digest.update(buf)
|
|
16
|
+
end while input.read(rand(cap), buf)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
[ 200, {'Content-Type' => 'text/plain'}, [ digest.hexdigest << "\n" ] ]
|
|
20
|
+
end
|
|
21
|
+
run app
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
. ./test-lib.sh
|
|
3
|
+
t_plan 8 "simple HTTP connection tests"
|
|
4
|
+
|
|
5
|
+
t_begin "setup and start" && {
|
|
6
|
+
unicorn_setup
|
|
7
|
+
unicorn -D -c $unicorn_config env.ru
|
|
8
|
+
unicorn_wait_start
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
t_begin "single request" && {
|
|
12
|
+
curl -sSfv http://$listen/
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
t_begin "check stderr has no errors" && {
|
|
16
|
+
check_stderr
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
t_begin "HTTP/0.9 request should not return headers" && {
|
|
20
|
+
(
|
|
21
|
+
printf 'GET /\r\n'
|
|
22
|
+
cat $fifo > $tmp &
|
|
23
|
+
wait
|
|
24
|
+
echo ok > $ok
|
|
25
|
+
) | socat - TCP:$listen > $fifo
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
t_begin "env.inspect should've put everything on one line" && {
|
|
29
|
+
test 1 -eq $(count_lines < $tmp)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
t_begin "no headers in output" && {
|
|
33
|
+
if grep ^Connection: $tmp
|
|
34
|
+
then
|
|
35
|
+
die "Connection header found in $tmp"
|
|
36
|
+
elif grep ^HTTP/ $tmp
|
|
37
|
+
then
|
|
38
|
+
die "HTTP/ found in $tmp"
|
|
39
|
+
fi
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
t_begin "killing succeeds" && {
|
|
43
|
+
kill $unicorn_pid
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
t_begin "check stderr has no errors" && {
|
|
47
|
+
check_stderr
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
t_done
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
. ./test-lib.sh
|
|
3
|
+
t_plan 7 "reload config.ru error with preload_app true"
|
|
4
|
+
|
|
5
|
+
t_begin "setup and start" && {
|
|
6
|
+
unicorn_setup
|
|
7
|
+
rtmpfiles ru
|
|
8
|
+
|
|
9
|
+
cat > $ru <<\EOF
|
|
10
|
+
use Rack::ContentLength
|
|
11
|
+
use Rack::ContentType, "text/plain"
|
|
12
|
+
x = { "hello" => "world" }
|
|
13
|
+
run lambda { |env| [ 200, {}, [ x.inspect << "\n" ] ] }
|
|
14
|
+
EOF
|
|
15
|
+
echo 'preload_app true' >> $unicorn_config
|
|
16
|
+
unicorn -D -c $unicorn_config $ru
|
|
17
|
+
unicorn_wait_start
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
t_begin "hit with curl" && {
|
|
21
|
+
out=$(curl -sSf http://$listen/)
|
|
22
|
+
test x"$out" = x'{"hello"=>"world"}'
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
t_begin "introduce syntax error in rackup file" && {
|
|
26
|
+
echo '...' >> $ru
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
t_begin "reload signal succeeds" && {
|
|
30
|
+
kill -HUP $unicorn_pid
|
|
31
|
+
while ! egrep '(done|error) reloading' $r_err >/dev/null
|
|
32
|
+
do
|
|
33
|
+
sleep 1
|
|
34
|
+
done
|
|
35
|
+
|
|
36
|
+
grep 'error reloading' $r_err >/dev/null
|
|
37
|
+
> $r_err
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
t_begin "hit with curl" && {
|
|
41
|
+
out=$(curl -sSf http://$listen/)
|
|
42
|
+
test x"$out" = x'{"hello"=>"world"}'
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
t_begin "killing succeeds" && {
|
|
46
|
+
kill $unicorn_pid
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
t_begin "check stderr" && {
|
|
50
|
+
check_stderr
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
t_done
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
. ./test-lib.sh
|
|
3
|
+
t_plan 6 "config variables conflict with preload_app"
|
|
4
|
+
|
|
5
|
+
t_begin "setup and start" && {
|
|
6
|
+
unicorn_setup
|
|
7
|
+
rtmpfiles ru rutmp
|
|
8
|
+
|
|
9
|
+
cat > $ru <<\EOF
|
|
10
|
+
use Rack::ContentLength
|
|
11
|
+
use Rack::ContentType, "text/plain"
|
|
12
|
+
config = ru = { "hello" => "world" }
|
|
13
|
+
run lambda { |env| [ 200, {}, [ ru.inspect << "\n" ] ] }
|
|
14
|
+
EOF
|
|
15
|
+
echo 'preload_app true' >> $unicorn_config
|
|
16
|
+
unicorn -D -c $unicorn_config $ru
|
|
17
|
+
unicorn_wait_start
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
t_begin "hit with curl" && {
|
|
21
|
+
out=$(curl -sSf http://$listen/)
|
|
22
|
+
test x"$out" = x'{"hello"=>"world"}'
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
t_begin "modify rackup file" && {
|
|
26
|
+
sed -e 's/world/WORLD/' < $ru > $rutmp
|
|
27
|
+
mv $rutmp $ru
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
t_begin "reload signal succeeds" && {
|
|
31
|
+
kill -HUP $unicorn_pid
|
|
32
|
+
while ! egrep '(done|error) reloading' < $r_err >/dev/null
|
|
33
|
+
do
|
|
34
|
+
sleep 1
|
|
35
|
+
done
|
|
36
|
+
|
|
37
|
+
grep 'done reloading' $r_err >/dev/null
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
t_begin "hit with curl" && {
|
|
41
|
+
out=$(curl -sSf http://$listen/)
|
|
42
|
+
test x"$out" = x'{"hello"=>"WORLD"}'
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
t_begin "killing succeeds" && {
|
|
46
|
+
kill $unicorn_pid
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
t_done
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
. ./test-lib.sh
|
|
3
|
+
t_plan 11 "parser error test"
|
|
4
|
+
|
|
5
|
+
t_begin "setup and startup" && {
|
|
6
|
+
unicorn_setup
|
|
7
|
+
unicorn -D env.ru -c $unicorn_config
|
|
8
|
+
unicorn_wait_start
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
t_begin "send a bad request" && {
|
|
12
|
+
(
|
|
13
|
+
printf 'GET / HTTP/1/1\r\nHost: example.com\r\n\r\n'
|
|
14
|
+
cat $fifo > $tmp &
|
|
15
|
+
wait
|
|
16
|
+
echo ok > $ok
|
|
17
|
+
) | socat - TCP:$listen > $fifo
|
|
18
|
+
test xok = x$(cat $ok)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
dbgcat tmp
|
|
22
|
+
|
|
23
|
+
t_begin "response should be a 400" && {
|
|
24
|
+
grep -F 'HTTP/1.1 400 Bad Request' $tmp
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
t_begin "send a huge Request URI (REQUEST_PATH > (12 * 1024))" && {
|
|
28
|
+
rm -f $tmp
|
|
29
|
+
cat $fifo > $tmp &
|
|
30
|
+
(
|
|
31
|
+
set -e
|
|
32
|
+
trap 'echo ok > $ok' EXIT
|
|
33
|
+
printf 'GET /'
|
|
34
|
+
for i in $(awk </dev/null 'BEGIN{for(i=0;i<1024;i++) print i}')
|
|
35
|
+
do
|
|
36
|
+
printf '0123456789ab'
|
|
37
|
+
done
|
|
38
|
+
printf ' HTTP/1.1\r\nHost: example.com\r\n\r\n'
|
|
39
|
+
) | socat - TCP:$listen > $fifo || :
|
|
40
|
+
test xok = x$(cat $ok)
|
|
41
|
+
wait
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
t_begin "response should be a 414 (REQUEST_PATH)" && {
|
|
45
|
+
grep -F 'HTTP/1.1 414 ' $tmp
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
t_begin "send a huge Request URI (QUERY_STRING > (10 * 1024))" && {
|
|
49
|
+
rm -f $tmp
|
|
50
|
+
cat $fifo > $tmp &
|
|
51
|
+
(
|
|
52
|
+
set -e
|
|
53
|
+
trap 'echo ok > $ok' EXIT
|
|
54
|
+
printf 'GET /hello-world?a'
|
|
55
|
+
for i in $(awk </dev/null 'BEGIN{for(i=0;i<1024;i++) print i}')
|
|
56
|
+
do
|
|
57
|
+
printf '0123456789'
|
|
58
|
+
done
|
|
59
|
+
printf ' HTTP/1.1\r\nHost: example.com\r\n\r\n'
|
|
60
|
+
) | socat - TCP:$listen > $fifo || :
|
|
61
|
+
test xok = x$(cat $ok)
|
|
62
|
+
wait
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
t_begin "response should be a 414 (QUERY_STRING)" && {
|
|
66
|
+
grep -F 'HTTP/1.1 414 ' $tmp
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
t_begin "send a huge Request URI (FRAGMENT > 1024)" && {
|
|
70
|
+
rm -f $tmp
|
|
71
|
+
cat $fifo > $tmp &
|
|
72
|
+
(
|
|
73
|
+
set -e
|
|
74
|
+
trap 'echo ok > $ok' EXIT
|
|
75
|
+
printf 'GET /hello-world#a'
|
|
76
|
+
for i in $(awk </dev/null 'BEGIN{for(i=0;i<64;i++) print i}')
|
|
77
|
+
do
|
|
78
|
+
printf '0123456789abcdef'
|
|
79
|
+
done
|
|
80
|
+
printf ' HTTP/1.1\r\nHost: example.com\r\n\r\n'
|
|
81
|
+
) | socat - TCP:$listen > $fifo || :
|
|
82
|
+
test xok = x$(cat $ok)
|
|
83
|
+
wait
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
t_begin "response should be a 414 (FRAGMENT)" && {
|
|
87
|
+
grep -F 'HTTP/1.1 414 ' $tmp
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
t_begin "server stderr should be clean" && check_stderr
|
|
91
|
+
|
|
92
|
+
t_begin "term signal sent" && kill $unicorn_pid
|
|
93
|
+
|
|
94
|
+
t_done
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
. ./test-lib.sh
|
|
3
|
+
|
|
4
|
+
t_plan 4 "config.ru inside alt working_directory"
|
|
5
|
+
|
|
6
|
+
t_begin "setup and start" && {
|
|
7
|
+
unicorn_setup
|
|
8
|
+
rtmpfiles unicorn_config_tmp
|
|
9
|
+
rm -rf $t_pfx.app
|
|
10
|
+
mkdir $t_pfx.app
|
|
11
|
+
|
|
12
|
+
cat > $t_pfx.app/config.ru <<EOF
|
|
13
|
+
#\--daemonize --host $host --port $port
|
|
14
|
+
use Rack::ContentLength
|
|
15
|
+
use Rack::ContentType, "text/plain"
|
|
16
|
+
run lambda { |env| [ 200, {}, [ "#{\$master_ppid}\\n" ] ] }
|
|
17
|
+
EOF
|
|
18
|
+
# we have --host/--port in config.ru instead
|
|
19
|
+
grep -v ^listen $unicorn_config > $unicorn_config_tmp
|
|
20
|
+
|
|
21
|
+
# the whole point of this exercise
|
|
22
|
+
echo "working_directory '$t_pfx.app'" >> $unicorn_config_tmp
|
|
23
|
+
|
|
24
|
+
# allows ppid to be 1 in before_fork
|
|
25
|
+
echo "preload_app true" >> $unicorn_config_tmp
|
|
26
|
+
cat >> $unicorn_config_tmp <<\EOF
|
|
27
|
+
before_fork do |server,worker|
|
|
28
|
+
$master_ppid = Process.ppid # should be zero to detect daemonization
|
|
29
|
+
end
|
|
30
|
+
EOF
|
|
31
|
+
|
|
32
|
+
mv $unicorn_config_tmp $unicorn_config
|
|
33
|
+
|
|
34
|
+
# rely on --daemonize switch, no & or -D
|
|
35
|
+
unicorn -c $unicorn_config
|
|
36
|
+
unicorn_wait_start
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
t_begin "hit with curl" && {
|
|
40
|
+
body=$(curl -sSf http://$listen/)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
t_begin "killing succeeds" && {
|
|
44
|
+
kill $unicorn_pid
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
t_begin "response body ppid == 1 (daemonized)" && {
|
|
48
|
+
test "$body" -eq 1
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
t_done
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
. ./test-lib.sh
|
|
3
|
+
|
|
4
|
+
t_plan 11 "heartbeat/timeout test"
|
|
5
|
+
|
|
6
|
+
t_begin "setup and startup" && {
|
|
7
|
+
unicorn_setup
|
|
8
|
+
echo timeout 3 >> $unicorn_config
|
|
9
|
+
echo preload_app true >> $unicorn_config
|
|
10
|
+
unicorn -D heartbeat-timeout.ru -c $unicorn_config
|
|
11
|
+
unicorn_wait_start
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
t_begin "read worker PID" && {
|
|
15
|
+
worker_pid=$(curl -sSf http://$listen/)
|
|
16
|
+
t_info "worker_pid=$worker_pid"
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
t_begin "sleep for a bit, ensure worker PID does not change" && {
|
|
20
|
+
sleep 4
|
|
21
|
+
test $(curl -sSf http://$listen/) -eq $worker_pid
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
t_begin "block the worker process to force it to die" && {
|
|
25
|
+
rm $ok
|
|
26
|
+
t0=$(unix_time)
|
|
27
|
+
err="$(curl -sSf http://$listen/block-forever 2>&1 || > $ok)"
|
|
28
|
+
t1=$(unix_time)
|
|
29
|
+
elapsed=$(($t1 - $t0))
|
|
30
|
+
t_info "elapsed=$elapsed err=$err"
|
|
31
|
+
test x"$err" != x"Should never get here"
|
|
32
|
+
test x"$err" != x"$worker_pid"
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
t_begin "ensure worker was killed" && {
|
|
36
|
+
test -e $ok
|
|
37
|
+
test 1 -eq $(grep timeout $r_err | grep killing | count_lines)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
t_begin "ensure timeout took at least 3 seconds" && {
|
|
41
|
+
test $elapsed -ge 3
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
t_begin "we get a fresh new worker process" && {
|
|
45
|
+
new_worker_pid=$(curl -sSf http://$listen/)
|
|
46
|
+
test $new_worker_pid -ne $worker_pid
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
t_begin "truncate the server error log" && {
|
|
50
|
+
> $r_err
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
t_begin "SIGSTOP and SIGCONT on unicorn master does not kill worker" && {
|
|
54
|
+
kill -STOP $unicorn_pid
|
|
55
|
+
sleep 4
|
|
56
|
+
kill -CONT $unicorn_pid
|
|
57
|
+
sleep 2
|
|
58
|
+
test $new_worker_pid -eq $(curl -sSf http://$listen/)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
t_begin "stop server" && {
|
|
62
|
+
kill -QUIT $unicorn_pid
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
t_begin "check stderr" && check_stderr
|
|
66
|
+
|
|
67
|
+
dbgcat r_err
|
|
68
|
+
|
|
69
|
+
t_done
|