unicorn-simon 0.0.1
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/.gitattributes +5 -0
- data/.gitignore +25 -0
- data/.mailmap +26 -0
- data/.manifest +156 -0
- data/.olddoc.yml +18 -0
- data/Application_Timeouts +77 -0
- data/CONTRIBUTORS +35 -0
- data/COPYING +674 -0
- data/DESIGN +95 -0
- data/Documentation/.gitignore +5 -0
- data/Documentation/GNUmakefile +30 -0
- data/Documentation/unicorn.1.txt +187 -0
- data/Documentation/unicorn_rails.1.txt +175 -0
- data/FAQ +70 -0
- data/GIT-VERSION-FILE +1 -0
- data/GIT-VERSION-GEN +39 -0
- data/GNUmakefile +253 -0
- data/HACKING +120 -0
- data/ISSUES +90 -0
- data/KNOWN_ISSUES +79 -0
- data/LATEST +30 -0
- data/LICENSE +67 -0
- data/Links +56 -0
- data/NEWS +2465 -0
- data/PHILOSOPHY +139 -0
- data/README +138 -0
- data/Rakefile +16 -0
- data/SIGNALS +123 -0
- data/Sandbox +104 -0
- data/TODO +3 -0
- data/TUNING +119 -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 +102 -0
- data/examples/logger_mp_safe.rb +25 -0
- data/examples/logrotate.conf +44 -0
- data/examples/nginx.conf +155 -0
- data/examples/unicorn.conf.minimal.rb +13 -0
- data/examples/unicorn.conf.rb +110 -0
- data/examples/unicorn.socket +11 -0
- data/examples/unicorn@.service +33 -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 +62 -0
- data/ext/unicorn_http/extconf.rb +11 -0
- data/ext/unicorn_http/global_variables.h +97 -0
- data/ext/unicorn_http/httpdate.c +78 -0
- data/ext/unicorn_http/unicorn_http.c +4274 -0
- data/ext/unicorn_http/unicorn_http.rl +980 -0
- data/ext/unicorn_http/unicorn_http_common.rl +76 -0
- data/lib/unicorn/app/old_rails/static.rb +59 -0
- data/lib/unicorn/app/old_rails.rb +35 -0
- data/lib/unicorn/cgi_wrapper.rb +147 -0
- data/lib/unicorn/configurator.rb +664 -0
- data/lib/unicorn/const.rb +21 -0
- data/lib/unicorn/http_request.rb +122 -0
- data/lib/unicorn/http_response.rb +60 -0
- data/lib/unicorn/http_server.rb +824 -0
- data/lib/unicorn/launcher.rb +62 -0
- data/lib/unicorn/oob_gc.rb +82 -0
- data/lib/unicorn/preread_input.rb +33 -0
- data/lib/unicorn/socket_helper.rb +195 -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/version.rb +1 -0
- data/lib/unicorn/worker.rb +140 -0
- data/lib/unicorn.rb +123 -0
- data/man/man1/unicorn.1 +221 -0
- data/man/man1/unicorn_rails.1 +212 -0
- data/setup.rb +1586 -0
- data/t/.gitignore +4 -0
- data/t/GNUmakefile +74 -0
- data/t/README +42 -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 +43 -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/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 +30 -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 +1099 -0
- data/test/test_helper.rb +298 -0
- data/test/unit/test_configurator.rb +175 -0
- data/test/unit/test_droplet.rb +28 -0
- data/test/unit/test_http_parser.rb +886 -0
- data/test/unit/test_http_parser_ng.rb +633 -0
- data/test/unit/test_request.rb +182 -0
- data/test/unit/test_response.rb +111 -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 +50 -0
- metadata +310 -0
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
. ./test-lib.sh
|
|
3
|
+
t_plan 12 "client_body_buffer_size settings"
|
|
4
|
+
|
|
5
|
+
t_begin "setup and start" && {
|
|
6
|
+
unicorn_setup
|
|
7
|
+
rtmpfiles unicorn_config_tmp one_meg
|
|
8
|
+
dd if=/dev/zero bs=1M count=1 of=$one_meg
|
|
9
|
+
cat >> $unicorn_config <<EOF
|
|
10
|
+
after_fork do |server, worker|
|
|
11
|
+
File.open("$fifo", "wb") { |fp| fp.syswrite "START" }
|
|
12
|
+
end
|
|
13
|
+
EOF
|
|
14
|
+
cat $unicorn_config > $unicorn_config_tmp
|
|
15
|
+
echo client_body_buffer_size 0 >> $unicorn_config
|
|
16
|
+
unicorn -D -c $unicorn_config t0116.ru
|
|
17
|
+
unicorn_wait_start
|
|
18
|
+
fs_class=Unicorn::TmpIO
|
|
19
|
+
mem_class=StringIO
|
|
20
|
+
|
|
21
|
+
test x"$(cat $fifo)" = xSTART
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
t_begin "class for a zero-byte file should be StringIO" && {
|
|
25
|
+
> $tmp
|
|
26
|
+
test xStringIO = x"$(curl -T $tmp -sSf http://$listen/input_class)"
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
t_begin "class for a 1 byte file should be filesystem-backed" && {
|
|
30
|
+
echo > $tmp
|
|
31
|
+
test x$fs_class = x"$(curl -T $tmp -sSf http://$listen/tmp_class)"
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
t_begin "reload with default client_body_buffer_size" && {
|
|
35
|
+
mv $unicorn_config_tmp $unicorn_config
|
|
36
|
+
kill -HUP $unicorn_pid
|
|
37
|
+
test x"$(cat $fifo)" = xSTART
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
t_begin "class for a 1 byte file should be memory-backed" && {
|
|
41
|
+
echo > $tmp
|
|
42
|
+
test x$mem_class = x"$(curl -T $tmp -sSf http://$listen/tmp_class)"
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
t_begin "class for a random blob file should be filesystem-backed" && {
|
|
46
|
+
resp="$(curl -T random_blob -sSf http://$listen/tmp_class)"
|
|
47
|
+
test x$fs_class = x"$resp"
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
t_begin "one megabyte file should be filesystem-backed" && {
|
|
51
|
+
resp="$(curl -T $one_meg -sSf http://$listen/tmp_class)"
|
|
52
|
+
test x$fs_class = x"$resp"
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
t_begin "reload with a big client_body_buffer_size" && {
|
|
56
|
+
echo "client_body_buffer_size(1024 * 1024)" >> $unicorn_config
|
|
57
|
+
kill -HUP $unicorn_pid
|
|
58
|
+
test x"$(cat $fifo)" = xSTART
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
t_begin "one megabyte file should be memory-backed" && {
|
|
62
|
+
resp="$(curl -T $one_meg -sSf http://$listen/tmp_class)"
|
|
63
|
+
test x$mem_class = x"$resp"
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
t_begin "one megabyte + 1 byte file should be filesystem-backed" && {
|
|
67
|
+
echo >> $one_meg
|
|
68
|
+
resp="$(curl -T $one_meg -sSf http://$listen/tmp_class)"
|
|
69
|
+
test x$fs_class = x"$resp"
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
t_begin "killing succeeds" && {
|
|
73
|
+
kill $unicorn_pid
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
t_begin "check stderr" && {
|
|
77
|
+
check_stderr
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
t_done
|
data/t/t0116.ru
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#\ -E none
|
|
2
|
+
use Rack::ContentLength
|
|
3
|
+
use Rack::ContentType, 'text/plain'
|
|
4
|
+
app = lambda do |env|
|
|
5
|
+
input = env['rack.input']
|
|
6
|
+
case env["PATH_INFO"]
|
|
7
|
+
when "/tmp_class"
|
|
8
|
+
body = input.instance_variable_get(:@tmp).class.name
|
|
9
|
+
when "/input_class"
|
|
10
|
+
body = input.class.name
|
|
11
|
+
else
|
|
12
|
+
return [ 500, {}, [] ]
|
|
13
|
+
end
|
|
14
|
+
[ 200, {}, [ body ] ]
|
|
15
|
+
end
|
|
16
|
+
run app
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
. ./test-lib.sh
|
|
3
|
+
t_plan 5 "rack.hijack tests (Rack 1.5+ (Rack::VERSION >= [ 1,2]))"
|
|
4
|
+
|
|
5
|
+
t_begin "setup and start" && {
|
|
6
|
+
unicorn_setup
|
|
7
|
+
unicorn -D -c $unicorn_config hijack.ru
|
|
8
|
+
unicorn_wait_start
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
t_begin "check request hijack" && {
|
|
12
|
+
test "xrequest.hijacked" = x"$(curl -sSfv http://$listen/hijack_req)"
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
t_begin "check response hijack" && {
|
|
16
|
+
test "xresponse.hijacked" = x"$(curl -sSfv http://$listen/hijack_res)"
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
t_begin "killing succeeds after hijack" && {
|
|
20
|
+
kill $unicorn_pid
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
t_begin "check stderr for hijacked body close" && {
|
|
24
|
+
check_stderr
|
|
25
|
+
grep 'closed DieIfUsed 1\>' $r_err
|
|
26
|
+
grep 'closed DieIfUsed 2\>' $r_err
|
|
27
|
+
! grep 'closed DieIfUsed 3\>' $r_err
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
t_done
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
. ./test-lib.sh
|
|
3
|
+
t_plan 3 "test the -N / --no-default-middleware option"
|
|
4
|
+
|
|
5
|
+
t_begin "setup and start" && {
|
|
6
|
+
unicorn_setup
|
|
7
|
+
unicorn -N -D -c $unicorn_config fails-rack-lint.ru
|
|
8
|
+
unicorn_wait_start
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
t_begin "check exit status with Rack::Lint not present" && {
|
|
12
|
+
test 42 -eq "$(curl -sf -o/dev/null -w'%{http_code}' http://$listen/)"
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
t_begin "killing succeeds" && {
|
|
16
|
+
kill $unicorn_pid
|
|
17
|
+
check_stderr
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
t_done
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
. ./test-lib.sh
|
|
3
|
+
t_plan 9 "PrereadInput middleware tests"
|
|
4
|
+
|
|
5
|
+
t_begin "setup and start" && {
|
|
6
|
+
random_blob_sha1=$(rsha1 < random_blob)
|
|
7
|
+
unicorn_setup
|
|
8
|
+
unicorn -D -c $unicorn_config preread_input.ru
|
|
9
|
+
unicorn_wait_start
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
t_begin "single identity request" && {
|
|
13
|
+
curl -sSf -T random_blob http://$listen/ > $tmp
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
t_begin "sha1 matches" && {
|
|
17
|
+
test x"$(cat $tmp)" = x"$random_blob_sha1"
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
t_begin "single chunked request" && {
|
|
21
|
+
curl -sSf -T- < random_blob http://$listen/ > $tmp
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
t_begin "sha1 matches" && {
|
|
25
|
+
test x"$(cat $tmp)" = x"$random_blob_sha1"
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
t_begin "app only dispatched twice" && {
|
|
29
|
+
test 2 -eq "$(grep 'app dispatch:' < $r_err | count_lines )"
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
t_begin "aborted chunked request" && {
|
|
33
|
+
rm -f $tmp
|
|
34
|
+
curl -sSf -T- < $fifo http://$listen/ > $tmp &
|
|
35
|
+
curl_pid=$!
|
|
36
|
+
kill -9 $curl_pid
|
|
37
|
+
wait
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
t_begin "app only dispatched twice" && {
|
|
41
|
+
test 2 -eq "$(grep 'app dispatch:' < $r_err | count_lines )"
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
t_begin "killing succeeds" && {
|
|
45
|
+
kill -QUIT $unicorn_pid
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
t_done
|
data/t/t9001-oob_gc.sh
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
. ./test-lib.sh
|
|
3
|
+
t_plan 9 "OobGC test"
|
|
4
|
+
|
|
5
|
+
t_begin "setup and start" && {
|
|
6
|
+
unicorn_setup
|
|
7
|
+
unicorn -D -c $unicorn_config oob_gc.ru
|
|
8
|
+
unicorn_wait_start
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
t_begin "test default interval (4 requests)" && {
|
|
12
|
+
test xfalse = x$(curl -vsSf http://$listen/ 2>> $tmp)
|
|
13
|
+
test xfalse = x$(curl -vsSf http://$listen/ 2>> $tmp)
|
|
14
|
+
test xfalse = x$(curl -vsSf http://$listen/ 2>> $tmp)
|
|
15
|
+
test xfalse = x$(curl -vsSf http://$listen/ 2>> $tmp)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
t_begin "GC starting-request returns immediately" && {
|
|
19
|
+
test xfalse = x$(curl -vsSf http://$listen/ 2>> $tmp)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
t_begin "GC is started after 5 requests" && {
|
|
23
|
+
test xtrue = x$(curl -vsSf http://$listen/ 2>> $tmp)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
t_begin "reset GC" && {
|
|
27
|
+
test xfalse = x$(curl -vsSf -X POST http://$listen/gc_reset 2>> $tmp)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
t_begin "test default interval again (3 requests)" && {
|
|
31
|
+
test xfalse = x$(curl -vsSf http://$listen/ 2>> $tmp)
|
|
32
|
+
test xfalse = x$(curl -vsSf http://$listen/ 2>> $tmp)
|
|
33
|
+
test xfalse = x$(curl -vsSf http://$listen/ 2>> $tmp)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
t_begin "GC is started after 5 requests" && {
|
|
37
|
+
test xtrue = x$(curl -vsSf http://$listen/ 2>> $tmp)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
t_begin "killing succeeds" && {
|
|
41
|
+
kill -QUIT $unicorn_pid
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
t_begin "check_stderr" && check_stderr
|
|
45
|
+
dbgcat r_err
|
|
46
|
+
|
|
47
|
+
t_done
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
. ./test-lib.sh
|
|
3
|
+
t_plan 12 "OobGC test with limited path"
|
|
4
|
+
|
|
5
|
+
t_begin "setup and start" && {
|
|
6
|
+
unicorn_setup
|
|
7
|
+
unicorn -D -c $unicorn_config oob_gc_path.ru
|
|
8
|
+
unicorn_wait_start
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
t_begin "test default is noop" && {
|
|
12
|
+
test xfalse = x$(curl -vsSf http://$listen/ 2>> $tmp)
|
|
13
|
+
test xfalse = x$(curl -vsSf http://$listen/ 2>> $tmp)
|
|
14
|
+
test xfalse = x$(curl -vsSf http://$listen/ 2>> $tmp)
|
|
15
|
+
test xfalse = x$(curl -vsSf http://$listen/ 2>> $tmp)
|
|
16
|
+
test xfalse = x$(curl -vsSf http://$listen/ 2>> $tmp)
|
|
17
|
+
test xfalse = x$(curl -vsSf http://$listen/ 2>> $tmp)
|
|
18
|
+
test xfalse = x$(curl -vsSf http://$listen/ 2>> $tmp)
|
|
19
|
+
test xfalse = x$(curl -vsSf http://$listen/ 2>> $tmp)
|
|
20
|
+
test xfalse = x$(curl -vsSf http://$listen/ 2>> $tmp)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
t_begin "4 bad requests to bump counter" && {
|
|
24
|
+
test xfalse = x$(curl -vsSf http://$listen/BAD 2>> $tmp)
|
|
25
|
+
test xfalse = x$(curl -vsSf http://$listen/BAD 2>> $tmp)
|
|
26
|
+
test xfalse = x$(curl -vsSf http://$listen/BAD 2>> $tmp)
|
|
27
|
+
test xfalse = x$(curl -vsSf http://$listen/BAD 2>> $tmp)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
t_begin "GC-starting request returns immediately" && {
|
|
31
|
+
test xfalse = x$(curl -vsSf http://$listen/BAD 2>> $tmp)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
t_begin "GC was started after 5 requests" && {
|
|
35
|
+
test xtrue = x$(curl -vsSf http://$listen/ 2>> $tmp)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
t_begin "reset GC" && {
|
|
39
|
+
test xfalse = x$(curl -vsSf -X POST http://$listen/gc_reset 2>> $tmp)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
t_begin "test default is noop" && {
|
|
43
|
+
test xfalse = x$(curl -vsSf http://$listen/ 2>> $tmp)
|
|
44
|
+
test xfalse = x$(curl -vsSf http://$listen/ 2>> $tmp)
|
|
45
|
+
test xfalse = x$(curl -vsSf http://$listen/ 2>> $tmp)
|
|
46
|
+
test xfalse = x$(curl -vsSf http://$listen/ 2>> $tmp)
|
|
47
|
+
test xfalse = x$(curl -vsSf http://$listen/ 2>> $tmp)
|
|
48
|
+
test xfalse = x$(curl -vsSf http://$listen/ 2>> $tmp)
|
|
49
|
+
test xfalse = x$(curl -vsSf http://$listen/ 2>> $tmp)
|
|
50
|
+
test xfalse = x$(curl -vsSf http://$listen/ 2>> $tmp)
|
|
51
|
+
test xfalse = x$(curl -vsSf http://$listen/ 2>> $tmp)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
t_begin "4 bad requests to bump counter" && {
|
|
55
|
+
test xfalse = x$(curl -vsSf http://$listen/BAD 2>> $tmp)
|
|
56
|
+
test xfalse = x$(curl -vsSf http://$listen/BAD 2>> $tmp)
|
|
57
|
+
test xfalse = x$(curl -vsSf http://$listen/BAD 2>> $tmp)
|
|
58
|
+
test xfalse = x$(curl -vsSf http://$listen/BAD 2>> $tmp)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
t_begin "GC-starting request returns immediately" && {
|
|
62
|
+
test xfalse = x$(curl -vsSf http://$listen/BAD 2>> $tmp)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
t_begin "GC was started after 5 requests" && {
|
|
66
|
+
test xtrue = x$(curl -vsSf http://$listen/ 2>> $tmp)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
t_begin "killing succeeds" && {
|
|
70
|
+
kill -QUIT $unicorn_pid
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
t_begin "check_stderr" && check_stderr
|
|
74
|
+
|
|
75
|
+
t_done
|
data/t/test-lib.sh
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
# Copyright (c) 2009 Rainbows! hackers
|
|
3
|
+
# Copyright (c) 2010 Unicorn hackers
|
|
4
|
+
. ./my-tap-lib.sh
|
|
5
|
+
|
|
6
|
+
set +u
|
|
7
|
+
|
|
8
|
+
# sometimes we rely on http_proxy to avoid wasting bandwidth with Isolate
|
|
9
|
+
# and multiple Ruby versions
|
|
10
|
+
NO_PROXY=${UNICORN_TEST_ADDR-127.0.0.1}
|
|
11
|
+
export NO_PROXY
|
|
12
|
+
|
|
13
|
+
set -e
|
|
14
|
+
RUBY="${RUBY-ruby}"
|
|
15
|
+
RUBY_VERSION=${RUBY_VERSION-$($RUBY -e 'puts RUBY_VERSION')}
|
|
16
|
+
RUBY_ENGINE=${RUBY_ENGINE-$($RUBY -e 'puts((RUBY_ENGINE rescue "ruby"))')}
|
|
17
|
+
t_pfx=$PWD/trash/$T-$RUBY_ENGINE-$RUBY_VERSION
|
|
18
|
+
set -u
|
|
19
|
+
|
|
20
|
+
PATH=$PWD/bin:$PATH
|
|
21
|
+
export PATH
|
|
22
|
+
|
|
23
|
+
test -x $PWD/bin/unused_listen || die "must be run in 't' directory"
|
|
24
|
+
|
|
25
|
+
wait_for_pid () {
|
|
26
|
+
path="$1"
|
|
27
|
+
nr=30
|
|
28
|
+
while ! test -s "$path" && test $nr -gt 0
|
|
29
|
+
do
|
|
30
|
+
nr=$(($nr - 1))
|
|
31
|
+
sleep 1
|
|
32
|
+
done
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
# "unix_time" is not in POSIX, but in GNU, and FreeBSD 9.0 (possibly earlier)
|
|
36
|
+
unix_time () {
|
|
37
|
+
$RUBY -e 'puts Time.now.to_i'
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
# "wc -l" outputs leading whitespace on *BSDs, filter it out for portability
|
|
41
|
+
count_lines () {
|
|
42
|
+
wc -l | tr -d '[:space:]'
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
# "wc -c" outputs leading whitespace on *BSDs, filter it out for portability
|
|
46
|
+
count_bytes () {
|
|
47
|
+
wc -c | tr -d '[:space:]'
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
# given a list of variable names, create temporary files and assign
|
|
51
|
+
# the pathnames to those variables
|
|
52
|
+
rtmpfiles () {
|
|
53
|
+
for id in "$@"
|
|
54
|
+
do
|
|
55
|
+
name=$id
|
|
56
|
+
|
|
57
|
+
case $name in
|
|
58
|
+
*fifo)
|
|
59
|
+
_tmp=$t_pfx.$id
|
|
60
|
+
eval "$id=$_tmp"
|
|
61
|
+
rm -f $_tmp
|
|
62
|
+
mkfifo $_tmp
|
|
63
|
+
T_RM_LIST="$T_RM_LIST $_tmp"
|
|
64
|
+
;;
|
|
65
|
+
*socket)
|
|
66
|
+
_tmp="$(mktemp -t $id.$$.XXXXXXXX)"
|
|
67
|
+
if test $(printf "$_tmp" |count_bytes) -gt 108
|
|
68
|
+
then
|
|
69
|
+
echo >&2 "$_tmp too long, tests may fail"
|
|
70
|
+
echo >&2 "Try to set TMPDIR to a shorter path"
|
|
71
|
+
fi
|
|
72
|
+
eval "$id=$_tmp"
|
|
73
|
+
rm -f $_tmp
|
|
74
|
+
T_RM_LIST="$T_RM_LIST $_tmp"
|
|
75
|
+
;;
|
|
76
|
+
*)
|
|
77
|
+
_tmp=$t_pfx.$id
|
|
78
|
+
eval "$id=$_tmp"
|
|
79
|
+
> $_tmp
|
|
80
|
+
T_OK_RM_LIST="$T_OK_RM_LIST $_tmp"
|
|
81
|
+
;;
|
|
82
|
+
esac
|
|
83
|
+
done
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
dbgcat () {
|
|
87
|
+
id=$1
|
|
88
|
+
eval '_file=$'$id
|
|
89
|
+
echo "==> $id <=="
|
|
90
|
+
sed -e "s/^/$id:/" < $_file
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
check_stderr () {
|
|
94
|
+
set +u
|
|
95
|
+
_r_err=${1-${r_err}}
|
|
96
|
+
set -u
|
|
97
|
+
if grep -v $T $_r_err | grep -i Error
|
|
98
|
+
then
|
|
99
|
+
die "Errors found in $_r_err"
|
|
100
|
+
elif grep SIGKILL $_r_err
|
|
101
|
+
then
|
|
102
|
+
die "SIGKILL found in $_r_err"
|
|
103
|
+
fi
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
# unicorn_setup
|
|
107
|
+
unicorn_setup () {
|
|
108
|
+
eval $(unused_listen)
|
|
109
|
+
port=$(expr $listen : '[^:]*:\([0-9]\+\)')
|
|
110
|
+
host=$(expr $listen : '\([^:]*\):[0-9]\+')
|
|
111
|
+
|
|
112
|
+
rtmpfiles unicorn_config pid r_err r_out fifo tmp ok
|
|
113
|
+
cat > $unicorn_config <<EOF
|
|
114
|
+
listen "$listen"
|
|
115
|
+
pid "$pid"
|
|
116
|
+
stderr_path "$r_err"
|
|
117
|
+
stdout_path "$r_out"
|
|
118
|
+
EOF
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
unicorn_wait_start () {
|
|
122
|
+
# no need to play tricks with FIFOs since we got "ready_pipe" now
|
|
123
|
+
unicorn_pid=$(cat $pid)
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
rsha1 () {
|
|
127
|
+
sha1sum.rb
|
|
128
|
+
}
|
data/t/write-on-close.ru
ADDED
data/test/aggregate.rb
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/usr/bin/ruby -n
|
|
2
|
+
# -*- encoding: binary -*-
|
|
3
|
+
|
|
4
|
+
BEGIN { $tests = $assertions = $failures = $errors = 0 }
|
|
5
|
+
|
|
6
|
+
$_ =~ /(\d+) tests, (\d+) assertions, (\d+) failures, (\d+) errors/ or next
|
|
7
|
+
$tests += $1.to_i
|
|
8
|
+
$assertions += $2.to_i
|
|
9
|
+
$failures += $3.to_i
|
|
10
|
+
$errors += $4.to_i
|
|
11
|
+
|
|
12
|
+
END {
|
|
13
|
+
printf("\n%d tests, %d assertions, %d failures, %d errors\n",
|
|
14
|
+
$tests, $assertions, $failures, $errors)
|
|
15
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
= Performance
|
|
2
|
+
|
|
3
|
+
Unicorn is pretty fast, and we want it to get faster. Unicorn strives
|
|
4
|
+
to get HTTP requests to your application and write HTTP responses back
|
|
5
|
+
as quickly as possible. Unicorn does not do any background processing
|
|
6
|
+
while your app runs, so your app will get all the CPU time provided to
|
|
7
|
+
it by your OS kernel.
|
|
8
|
+
|
|
9
|
+
A gentle reminder: Unicorn is NOT for serving clients over slow network
|
|
10
|
+
connections. Use nginx (or something similar) to complement Unicorn if
|
|
11
|
+
you have slow clients.
|
|
12
|
+
|
|
13
|
+
== dd.ru
|
|
14
|
+
|
|
15
|
+
This is a pure I/O benchmark. In the context of Unicorn, this is the
|
|
16
|
+
only one that matters. It is a standard rackup-compatible .ru file and
|
|
17
|
+
may be used with other Rack-compatible servers.
|
|
18
|
+
|
|
19
|
+
unicorn -E none dd.ru
|
|
20
|
+
|
|
21
|
+
You can change the size and number of chunks in the response with
|
|
22
|
+
the "bs" and "count" environment variables. The following command
|
|
23
|
+
will cause dd.ru to return 4 chunks of 16384 bytes each, leading to
|
|
24
|
+
65536 byte response:
|
|
25
|
+
|
|
26
|
+
bs=16384 count=4 unicorn -E none dd.ru
|
|
27
|
+
|
|
28
|
+
Or if you want to add logging (small performance impact):
|
|
29
|
+
|
|
30
|
+
unicorn -E deployment dd.ru
|
|
31
|
+
|
|
32
|
+
Eric runs then runs clients on a LAN it in several different ways:
|
|
33
|
+
|
|
34
|
+
client@host1 -> unicorn@host1(tcp)
|
|
35
|
+
client@host2 -> unicorn@host1(tcp)
|
|
36
|
+
client@host3 -> nginx@host1 -> unicorn@host1(tcp)
|
|
37
|
+
client@host3 -> nginx@host1 -> unicorn@host1(unix)
|
|
38
|
+
client@host3 -> nginx@host2 -> unicorn@host1(tcp)
|
|
39
|
+
|
|
40
|
+
The benchmark client is usually httperf.
|
|
41
|
+
|
|
42
|
+
Another gentle reminder: performance with slow networks/clients
|
|
43
|
+
is NOT our problem. That is the job of nginx (or similar).
|
|
44
|
+
|
|
45
|
+
== Contributors
|
|
46
|
+
|
|
47
|
+
This directory is maintained independently in the "benchmark" branch
|
|
48
|
+
based against v0.1.0. Only changes to this directory (test/benchmarks)
|
|
49
|
+
are committed to this branch although the master branch may merge this
|
|
50
|
+
branch occassionaly.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# This benchmark is the simplest test of the I/O facilities in
|
|
2
|
+
# unicorn. It is meant to return a fixed-sized blob to test
|
|
3
|
+
# the performance of things in Unicorn, _NOT_ the app.
|
|
4
|
+
#
|
|
5
|
+
# Adjusting this benchmark is done via the "bs" (byte size) and "count"
|
|
6
|
+
# environment variables. "count" designates the count of elements of
|
|
7
|
+
# "bs" length in the Rack response body. The defaults are bs=4096, count=1
|
|
8
|
+
# to return one 4096-byte chunk.
|
|
9
|
+
bs = ENV['bs'] ? ENV['bs'].to_i : 4096
|
|
10
|
+
count = ENV['count'] ? ENV['count'].to_i : 1
|
|
11
|
+
slice = (' ' * bs).freeze
|
|
12
|
+
body = (1..count).map { slice }.freeze
|
|
13
|
+
hdr = {
|
|
14
|
+
'Content-Length' => (bs * count).to_s.freeze,
|
|
15
|
+
'Content-Type' => 'text/plain'.freeze
|
|
16
|
+
}.freeze
|
|
17
|
+
response = [ 200, hdr, body ].freeze
|
|
18
|
+
run(lambda { |env| response })
|
data/test/exec/README
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
These tests require the "unicorn" executable script to be installed in
|
|
2
|
+
PATH and rack being directly "require"-able ("rubygems" will not be
|
|
3
|
+
loaded for you). The tester is responsible for setting up RUBYLIB and
|
|
4
|
+
PATH environment variables (or running tests via GNU Make instead of
|
|
5
|
+
Rake).
|