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.
Files changed (158) hide show
  1. checksums.yaml +7 -0
  2. data/.CHANGELOG.old +25 -0
  3. data/.document +28 -0
  4. data/.gitattributes +5 -0
  5. data/.gitignore +25 -0
  6. data/.mailmap +26 -0
  7. data/.manifest +156 -0
  8. data/.olddoc.yml +18 -0
  9. data/Application_Timeouts +77 -0
  10. data/CONTRIBUTORS +35 -0
  11. data/COPYING +674 -0
  12. data/DESIGN +95 -0
  13. data/Documentation/.gitignore +5 -0
  14. data/Documentation/GNUmakefile +30 -0
  15. data/Documentation/unicorn.1.txt +187 -0
  16. data/Documentation/unicorn_rails.1.txt +175 -0
  17. data/FAQ +70 -0
  18. data/GIT-VERSION-FILE +1 -0
  19. data/GIT-VERSION-GEN +39 -0
  20. data/GNUmakefile +253 -0
  21. data/HACKING +120 -0
  22. data/ISSUES +90 -0
  23. data/KNOWN_ISSUES +79 -0
  24. data/LATEST +30 -0
  25. data/LICENSE +67 -0
  26. data/Links +56 -0
  27. data/NEWS +2465 -0
  28. data/PHILOSOPHY +139 -0
  29. data/README +138 -0
  30. data/Rakefile +16 -0
  31. data/SIGNALS +123 -0
  32. data/Sandbox +104 -0
  33. data/TODO +3 -0
  34. data/TUNING +119 -0
  35. data/archive/.gitignore +3 -0
  36. data/archive/slrnpull.conf +4 -0
  37. data/bin/unicorn +126 -0
  38. data/bin/unicorn_rails +209 -0
  39. data/examples/big_app_gc.rb +2 -0
  40. data/examples/echo.ru +27 -0
  41. data/examples/init.sh +102 -0
  42. data/examples/logger_mp_safe.rb +25 -0
  43. data/examples/logrotate.conf +44 -0
  44. data/examples/nginx.conf +155 -0
  45. data/examples/unicorn.conf.minimal.rb +13 -0
  46. data/examples/unicorn.conf.rb +110 -0
  47. data/examples/unicorn.socket +11 -0
  48. data/examples/unicorn@.service +33 -0
  49. data/ext/unicorn_http/CFLAGS +13 -0
  50. data/ext/unicorn_http/c_util.h +124 -0
  51. data/ext/unicorn_http/common_field_optimization.h +111 -0
  52. data/ext/unicorn_http/ext_help.h +62 -0
  53. data/ext/unicorn_http/extconf.rb +11 -0
  54. data/ext/unicorn_http/global_variables.h +97 -0
  55. data/ext/unicorn_http/httpdate.c +78 -0
  56. data/ext/unicorn_http/unicorn_http.c +4274 -0
  57. data/ext/unicorn_http/unicorn_http.rl +980 -0
  58. data/ext/unicorn_http/unicorn_http_common.rl +76 -0
  59. data/lib/unicorn/app/old_rails/static.rb +59 -0
  60. data/lib/unicorn/app/old_rails.rb +35 -0
  61. data/lib/unicorn/cgi_wrapper.rb +147 -0
  62. data/lib/unicorn/configurator.rb +664 -0
  63. data/lib/unicorn/const.rb +21 -0
  64. data/lib/unicorn/http_request.rb +122 -0
  65. data/lib/unicorn/http_response.rb +60 -0
  66. data/lib/unicorn/http_server.rb +824 -0
  67. data/lib/unicorn/launcher.rb +62 -0
  68. data/lib/unicorn/oob_gc.rb +82 -0
  69. data/lib/unicorn/preread_input.rb +33 -0
  70. data/lib/unicorn/socket_helper.rb +195 -0
  71. data/lib/unicorn/stream_input.rb +146 -0
  72. data/lib/unicorn/tee_input.rb +133 -0
  73. data/lib/unicorn/tmpio.rb +27 -0
  74. data/lib/unicorn/util.rb +90 -0
  75. data/lib/unicorn/version.rb +1 -0
  76. data/lib/unicorn/worker.rb +140 -0
  77. data/lib/unicorn.rb +123 -0
  78. data/man/man1/unicorn.1 +221 -0
  79. data/man/man1/unicorn_rails.1 +212 -0
  80. data/setup.rb +1586 -0
  81. data/t/.gitignore +4 -0
  82. data/t/GNUmakefile +74 -0
  83. data/t/README +42 -0
  84. data/t/bin/content-md5-put +36 -0
  85. data/t/bin/sha1sum.rb +17 -0
  86. data/t/bin/unused_listen +40 -0
  87. data/t/broken-app.ru +12 -0
  88. data/t/detach.ru +11 -0
  89. data/t/env.ru +3 -0
  90. data/t/fails-rack-lint.ru +5 -0
  91. data/t/heartbeat-timeout.ru +12 -0
  92. data/t/hijack.ru +43 -0
  93. data/t/listener_names.ru +4 -0
  94. data/t/my-tap-lib.sh +201 -0
  95. data/t/oob_gc.ru +20 -0
  96. data/t/oob_gc_path.ru +20 -0
  97. data/t/pid.ru +3 -0
  98. data/t/preread_input.ru +17 -0
  99. data/t/rack-input-tests.ru +21 -0
  100. data/t/t0000-http-basic.sh +50 -0
  101. data/t/t0001-reload-bad-config.sh +53 -0
  102. data/t/t0002-config-conflict.sh +49 -0
  103. data/t/t0002-parser-error.sh +94 -0
  104. data/t/t0003-working_directory.sh +51 -0
  105. data/t/t0004-heartbeat-timeout.sh +69 -0
  106. data/t/t0004-working_directory_broken.sh +24 -0
  107. data/t/t0005-working_directory_app.rb.sh +40 -0
  108. data/t/t0006-reopen-logs.sh +83 -0
  109. data/t/t0006.ru +13 -0
  110. data/t/t0007-working_directory_no_embed_cli.sh +44 -0
  111. data/t/t0008-back_out_of_upgrade.sh +110 -0
  112. data/t/t0009-broken-app.sh +56 -0
  113. data/t/t0009-winch_ttin.sh +59 -0
  114. data/t/t0010-reap-logging.sh +55 -0
  115. data/t/t0011-active-unix-socket.sh +79 -0
  116. data/t/t0012-reload-empty-config.sh +85 -0
  117. data/t/t0013-rewindable-input-false.sh +24 -0
  118. data/t/t0013.ru +12 -0
  119. data/t/t0014-rewindable-input-true.sh +24 -0
  120. data/t/t0014.ru +12 -0
  121. data/t/t0015-configurator-internals.sh +25 -0
  122. data/t/t0018-write-on-close.sh +23 -0
  123. data/t/t0019-max_header_len.sh +49 -0
  124. data/t/t0020-at_exit-handler.sh +49 -0
  125. data/t/t0021-process_detach.sh +29 -0
  126. data/t/t0022-listener_names-preload_app.sh +32 -0
  127. data/t/t0100-rack-input-tests.sh +124 -0
  128. data/t/t0116-client_body_buffer_size.sh +80 -0
  129. data/t/t0116.ru +16 -0
  130. data/t/t0200-rack-hijack.sh +30 -0
  131. data/t/t0300-no-default-middleware.sh +20 -0
  132. data/t/t9000-preread-input.sh +48 -0
  133. data/t/t9001-oob_gc.sh +47 -0
  134. data/t/t9002-oob_gc-path.sh +75 -0
  135. data/t/test-lib.sh +128 -0
  136. data/t/write-on-close.ru +11 -0
  137. data/test/aggregate.rb +15 -0
  138. data/test/benchmark/README +50 -0
  139. data/test/benchmark/dd.ru +18 -0
  140. data/test/benchmark/stack.ru +8 -0
  141. data/test/exec/README +5 -0
  142. data/test/exec/test_exec.rb +1099 -0
  143. data/test/test_helper.rb +298 -0
  144. data/test/unit/test_configurator.rb +175 -0
  145. data/test/unit/test_droplet.rb +28 -0
  146. data/test/unit/test_http_parser.rb +886 -0
  147. data/test/unit/test_http_parser_ng.rb +633 -0
  148. data/test/unit/test_request.rb +182 -0
  149. data/test/unit/test_response.rb +111 -0
  150. data/test/unit/test_server.rb +268 -0
  151. data/test/unit/test_signals.rb +188 -0
  152. data/test/unit/test_socket_helper.rb +197 -0
  153. data/test/unit/test_stream_input.rb +203 -0
  154. data/test/unit/test_tee_input.rb +304 -0
  155. data/test/unit/test_upload.rb +306 -0
  156. data/test/unit/test_util.rb +105 -0
  157. data/unicorn.gemspec +50 -0
  158. metadata +310 -0
@@ -0,0 +1,59 @@
1
+ #!/bin/sh
2
+ . ./test-lib.sh
3
+ t_plan 8 "SIGTTIN succeeds after SIGWINCH"
4
+
5
+ t_begin "setup and start" && {
6
+ unicorn_setup
7
+ cat >> $unicorn_config <<EOF
8
+ after_fork do |server, worker|
9
+ # test script will block while reading from $fifo,
10
+ File.open("$fifo", "wb") { |fp| fp.syswrite worker.nr.to_s }
11
+ end
12
+ EOF
13
+ unicorn -D -c $unicorn_config pid.ru
14
+ unicorn_wait_start
15
+ test 0 -eq $(cat $fifo) || die "worker.nr != 0"
16
+ }
17
+
18
+ t_begin "read worker pid" && {
19
+ orig_worker_pid=$(curl -sSf http://$listen/)
20
+ test -n "$orig_worker_pid" && kill -0 $orig_worker_pid
21
+ }
22
+
23
+ t_begin "stop all workers" && {
24
+ kill -WINCH $unicorn_pid
25
+ }
26
+
27
+ # we have to do this next step before delivering TTIN
28
+ # signals aren't guaranteed to delivered in order
29
+ t_begin "wait for worker to die" && {
30
+ i=0
31
+ while kill -0 $orig_worker_pid 2>/dev/null
32
+ do
33
+ i=$(( $i + 1 ))
34
+ test $i -lt 600 || die "timed out"
35
+ sleep 1
36
+ done
37
+ }
38
+
39
+ t_begin "start one worker back up" && {
40
+ kill -TTIN $unicorn_pid
41
+ }
42
+
43
+ t_begin "wait for new worker to start" && {
44
+ test 0 -eq $(cat $fifo) || die "worker.nr != 0"
45
+ new_worker_pid=$(curl -sSf http://$listen/)
46
+ test -n "$new_worker_pid" && kill -0 $new_worker_pid
47
+ test $orig_worker_pid -ne $new_worker_pid || \
48
+ die "worker wasn't replaced"
49
+ }
50
+
51
+ t_begin "killing succeeds" && {
52
+ kill $unicorn_pid
53
+ }
54
+
55
+ t_begin "check stderr" && check_stderr
56
+
57
+ dbgcat r_err
58
+
59
+ t_done
@@ -0,0 +1,55 @@
1
+ #!/bin/sh
2
+ . ./test-lib.sh
3
+ t_plan 9 "reap worker logging messages"
4
+
5
+ t_begin "setup and start" && {
6
+ unicorn_setup
7
+ cat >> $unicorn_config <<EOF
8
+ after_fork { |s,w| File.open('$fifo','w') { |f| f.write '.' } }
9
+ EOF
10
+ unicorn -c $unicorn_config pid.ru &
11
+ test '.' = $(cat $fifo)
12
+ unicorn_wait_start
13
+ }
14
+
15
+ t_begin "kill 1st worker=0" && {
16
+ pid_1=$(curl http://$listen/)
17
+ kill -9 $pid_1
18
+ }
19
+
20
+ t_begin "wait for 2nd worker to start" && {
21
+ test '.' = $(cat $fifo)
22
+ }
23
+
24
+ t_begin "ensure log of 1st reap is an ERROR" && {
25
+ dbgcat r_err
26
+ grep 'ERROR.*reaped.*worker=0' $r_err | grep $pid_1
27
+ dbgcat r_err
28
+ > $r_err
29
+ }
30
+
31
+ t_begin "kill 2nd worker gracefully" && {
32
+ pid_2=$(curl http://$listen/)
33
+ kill -QUIT $pid_2
34
+ }
35
+
36
+ t_begin "wait for 3rd worker=0 to start " && {
37
+ test '.' = $(cat $fifo)
38
+ }
39
+
40
+ t_begin "ensure log of 2nd reap is a INFO" && {
41
+ grep 'INFO.*reaped.*worker=0' $r_err | grep $pid_2
42
+ > $r_err
43
+ }
44
+
45
+ t_begin "killing succeeds" && {
46
+ kill $unicorn_pid
47
+ wait
48
+ kill -0 $unicorn_pid && false
49
+ }
50
+
51
+ t_begin "check stderr" && {
52
+ check_stderr
53
+ }
54
+
55
+ t_done
@@ -0,0 +1,79 @@
1
+ #!/bin/sh
2
+ . ./test-lib.sh
3
+ t_plan 11 "existing UNIX domain socket check"
4
+
5
+ read_pid_unix () {
6
+ x=$(printf 'GET / HTTP/1.0\r\n\r\n' | \
7
+ socat - UNIX:$unix_socket | \
8
+ tail -1)
9
+ test -n "$x"
10
+ y="$(expr "$x" : '\([0-9][0-9]*\)')"
11
+ test x"$x" = x"$y"
12
+ test -n "$y"
13
+ echo "$y"
14
+ }
15
+
16
+ t_begin "setup and start" && {
17
+ rtmpfiles unix_socket unix_config
18
+ rm -f $unix_socket
19
+ unicorn_setup
20
+ grep -v ^listen < $unicorn_config > $unix_config
21
+ echo "listen '$unix_socket'" >> $unix_config
22
+ unicorn -D -c $unix_config pid.ru
23
+ unicorn_wait_start
24
+ orig_master_pid=$unicorn_pid
25
+ }
26
+
27
+ t_begin "get pid of worker" && {
28
+ worker_pid=$(read_pid_unix)
29
+ t_info "worker_pid=$worker_pid"
30
+ }
31
+
32
+ t_begin "fails to start with existing pid file" && {
33
+ rm -f $ok
34
+ unicorn -D -c $unix_config pid.ru || echo ok > $ok
35
+ test x"$(cat $ok)" = xok
36
+ }
37
+
38
+ t_begin "worker pid unchanged" && {
39
+ test x"$(read_pid_unix)" = x$worker_pid
40
+ > $r_err
41
+ }
42
+
43
+ t_begin "fails to start with listening UNIX domain socket bound" && {
44
+ rm $ok $pid
45
+ unicorn -D -c $unix_config pid.ru || echo ok > $ok
46
+ test x"$(cat $ok)" = xok
47
+ > $r_err
48
+ }
49
+
50
+ t_begin "worker pid unchanged (again)" && {
51
+ test x"$(read_pid_unix)" = x$worker_pid
52
+ }
53
+
54
+ t_begin "nuking the existing Unicorn succeeds" && {
55
+ kill -9 $unicorn_pid $worker_pid
56
+ while kill -0 $unicorn_pid
57
+ do
58
+ sleep 1
59
+ done
60
+ check_stderr
61
+ }
62
+
63
+ t_begin "succeeds in starting with leftover UNIX domain socket bound" && {
64
+ test -S $unix_socket
65
+ unicorn -D -c $unix_config pid.ru
66
+ unicorn_wait_start
67
+ }
68
+
69
+ t_begin "worker pid changed" && {
70
+ test x"$(read_pid_unix)" != x$worker_pid
71
+ }
72
+
73
+ t_begin "killing succeeds" && {
74
+ kill $unicorn_pid
75
+ }
76
+
77
+ t_begin "no errors" && check_stderr
78
+
79
+ t_done
@@ -0,0 +1,85 @@
1
+ #!/bin/sh
2
+ . ./test-lib.sh
3
+ t_plan 9 "reloading unset config resets defaults"
4
+
5
+ t_begin "setup and start" && {
6
+ unicorn_setup
7
+ rtmpfiles unicorn_config_orig before_reload after_reload
8
+ cat $unicorn_config > $unicorn_config_orig
9
+ cat >> $unicorn_config <<EOF
10
+ logger Logger.new(STDOUT)
11
+ preload_app true
12
+ timeout 0x7fffffff
13
+ worker_processes 2
14
+ after_fork { |s,w| }
15
+ \$dump_cfg = lambda { |fp,srv|
16
+ defaults = Unicorn::Configurator::DEFAULTS
17
+ defaults.keys.map { |x| x.to_s }.sort.each do |key|
18
+ next if key =~ %r{\Astd(?:err|out)_path\z}
19
+ key = key.to_sym
20
+ def_value = defaults[key]
21
+ srv_value = srv.__send__(key)
22
+ fp << "#{key}|#{srv_value}|#{def_value}\\n"
23
+ end
24
+ }
25
+ before_fork { |s,w|
26
+ File.open("$before_reload", "a") { |fp| \$dump_cfg.call(fp, s) }
27
+ }
28
+ before_exec { |s| }
29
+ EOF
30
+ unicorn -D -c $unicorn_config env.ru
31
+ unicorn_wait_start
32
+ }
33
+
34
+ t_begin "ensure worker is started" && {
35
+ curl -sSf http://$listen/ > $tmp
36
+ }
37
+
38
+ t_begin "replace config file with original(-ish)" && {
39
+ grep -v ^pid < $unicorn_config_orig > $unicorn_config
40
+ cat >> $unicorn_config <<EOF
41
+ before_fork { |s,w|
42
+ File.open("$after_reload", "a") { |fp| \$dump_cfg.call(fp, s) }
43
+ }
44
+ EOF
45
+ }
46
+
47
+ t_begin "reload signal succeeds" && {
48
+ kill -HUP $unicorn_pid
49
+ while ! egrep '(done|error) reloading' $r_err >/dev/null
50
+ do
51
+ sleep 1
52
+ done
53
+ while ! grep reaped < $r_err >/dev/null
54
+ do
55
+ sleep 1
56
+ done
57
+ grep 'done reloading' $r_err >/dev/null
58
+ }
59
+
60
+ t_begin "ensure worker is started" && {
61
+ curl -sSf http://$listen/ > $tmp
62
+ }
63
+
64
+ t_begin "pid file no longer exists" && {
65
+ if test -f $pid
66
+ then
67
+ die "pid=$pid should not exist"
68
+ fi
69
+ }
70
+
71
+ t_begin "killing succeeds" && {
72
+ kill $unicorn_pid
73
+ }
74
+
75
+ t_begin "check stderr" && {
76
+ check_stderr
77
+ }
78
+
79
+ t_begin "ensure reloading restored settings" && {
80
+ awk < $after_reload -F'|' '
81
+ $1 != "before_fork" && $2 != $3 { print $0; exit(1) }
82
+ '
83
+ }
84
+
85
+ t_done
@@ -0,0 +1,24 @@
1
+ #!/bin/sh
2
+ . ./test-lib.sh
3
+ t_plan 4 "rewindable_input toggled to false"
4
+
5
+ t_begin "setup and start" && {
6
+ unicorn_setup
7
+ echo rewindable_input false >> $unicorn_config
8
+ unicorn -D -c $unicorn_config t0013.ru
9
+ unicorn_wait_start
10
+ }
11
+
12
+ t_begin "ensure worker is started" && {
13
+ test xOK = x$(curl -T t0013.ru -H Expect: -vsSf http://$listen/)
14
+ }
15
+
16
+ t_begin "killing succeeds" && {
17
+ kill $unicorn_pid
18
+ }
19
+
20
+ t_begin "check stderr" && {
21
+ check_stderr
22
+ }
23
+
24
+ t_done
data/t/t0013.ru ADDED
@@ -0,0 +1,12 @@
1
+ #\ -E none
2
+ use Rack::ContentLength
3
+ use Rack::ContentType, 'text/plain'
4
+ app = lambda do |env|
5
+ case env['rack.input']
6
+ when Unicorn::StreamInput
7
+ [ 200, {}, %w(OK) ]
8
+ else
9
+ [ 500, {}, %w(NO) ]
10
+ end
11
+ end
12
+ run app
@@ -0,0 +1,24 @@
1
+ #!/bin/sh
2
+ . ./test-lib.sh
3
+ t_plan 4 "rewindable_input toggled to true"
4
+
5
+ t_begin "setup and start" && {
6
+ unicorn_setup
7
+ echo rewindable_input true >> $unicorn_config
8
+ unicorn -D -c $unicorn_config t0014.ru
9
+ unicorn_wait_start
10
+ }
11
+
12
+ t_begin "ensure worker is started" && {
13
+ test xOK = x$(curl -T t0014.ru -sSf http://$listen/)
14
+ }
15
+
16
+ t_begin "killing succeeds" && {
17
+ kill $unicorn_pid
18
+ }
19
+
20
+ t_begin "check stderr" && {
21
+ check_stderr
22
+ }
23
+
24
+ t_done
data/t/t0014.ru ADDED
@@ -0,0 +1,12 @@
1
+ #\ -E none
2
+ use Rack::ContentLength
3
+ use Rack::ContentType, 'text/plain'
4
+ app = lambda do |env|
5
+ case env['rack.input']
6
+ when Unicorn::TeeInput
7
+ [ 200, {}, %w(OK) ]
8
+ else
9
+ [ 500, {}, %w(NO) ]
10
+ end
11
+ end
12
+ run app
@@ -0,0 +1,25 @@
1
+ #!/bin/sh
2
+ . ./test-lib.sh
3
+ t_plan 4 "configurator internals tests (from FAQ)"
4
+
5
+ t_begin "setup and start" && {
6
+ unicorn_setup
7
+ cat >> $unicorn_config <<EOF
8
+ HttpRequest::DEFAULTS["rack.url_scheme"] = "https"
9
+ Configurator::DEFAULTS[:logger].formatter = Logger::Formatter.new
10
+ EOF
11
+ unicorn -D -c $unicorn_config env.ru
12
+ unicorn_wait_start
13
+ }
14
+
15
+ t_begin "single request" && {
16
+ curl -sSfv http://$listen/ | grep '"rack.url_scheme"=>"https"'
17
+ }
18
+
19
+ t_begin "killing succeeds" && {
20
+ kill $unicorn_pid
21
+ }
22
+
23
+ t_begin "no errors" && check_stderr
24
+
25
+ t_done
@@ -0,0 +1,23 @@
1
+ #!/bin/sh
2
+ . ./test-lib.sh
3
+ t_plan 4 "write-on-close tests for funky response-bodies"
4
+
5
+ t_begin "setup and start" && {
6
+ unicorn_setup
7
+ unicorn -D -c $unicorn_config write-on-close.ru
8
+ unicorn_wait_start
9
+ }
10
+
11
+ t_begin "write-on-close response body succeeds" && {
12
+ test xGoodbye = x"$(curl -sSf http://$listen/)"
13
+ }
14
+
15
+ t_begin "killing succeeds" && {
16
+ kill $unicorn_pid
17
+ }
18
+
19
+ t_begin "check stderr" && {
20
+ check_stderr
21
+ }
22
+
23
+ t_done
@@ -0,0 +1,49 @@
1
+ #!/bin/sh
2
+ . ./test-lib.sh
3
+ t_plan 5 "max_header_len setting (only intended for Rainbows!)"
4
+
5
+ t_begin "setup and start" && {
6
+ unicorn_setup
7
+ req='GET / HTTP/1.0\r\n\r\n'
8
+ len=$(printf "$req" | count_bytes)
9
+ echo Unicorn::HttpParser.max_header_len = $len >> $unicorn_config
10
+ unicorn -D -c $unicorn_config env.ru
11
+ unicorn_wait_start
12
+ }
13
+
14
+ t_begin "minimal request succeeds" && {
15
+ rm -f $tmp
16
+ (
17
+ cat $fifo > $tmp &
18
+ printf "$req"
19
+ wait
20
+ echo ok > $ok
21
+ ) | socat - TCP:$listen > $fifo
22
+ test xok = x$(cat $ok)
23
+
24
+ fgrep "HTTP/1.1 200 OK" $tmp
25
+ }
26
+
27
+ t_begin "big request fails" && {
28
+ rm -f $tmp
29
+ (
30
+ cat $fifo > $tmp &
31
+ printf 'GET /xxxxxx HTTP/1.0\r\n\r\n'
32
+ wait
33
+ echo ok > $ok
34
+ ) | socat - TCP:$listen > $fifo
35
+ test xok = x$(cat $ok)
36
+ fgrep "HTTP/1.1 413" $tmp
37
+ }
38
+
39
+ dbgcat tmp
40
+
41
+ t_begin "killing succeeds" && {
42
+ kill $unicorn_pid
43
+ }
44
+
45
+ t_begin "check stderr" && {
46
+ check_stderr
47
+ }
48
+
49
+ t_done
@@ -0,0 +1,49 @@
1
+ #!/bin/sh
2
+ . ./test-lib.sh
3
+
4
+ t_plan 5 "at_exit/END handlers work as expected"
5
+
6
+ t_begin "setup and startup" && {
7
+ unicorn_setup
8
+ cat >> $unicorn_config <<EOF
9
+ at_exit { \$stdout.syswrite("#{Process.pid} BOTH\\n") }
10
+ END { \$stdout.syswrite("#{Process.pid} END BOTH\\n") }
11
+ after_fork do |_,_|
12
+ at_exit { \$stdout.syswrite("#{Process.pid} WORKER ONLY\\n") }
13
+ END { \$stdout.syswrite("#{Process.pid} END WORKER ONLY\\n") }
14
+ end
15
+ EOF
16
+
17
+ unicorn -D pid.ru -c $unicorn_config
18
+ unicorn_wait_start
19
+ }
20
+
21
+ t_begin "read worker PID" && {
22
+ worker_pid=$(curl -sSf http://$listen/)
23
+ t_info "worker_pid=$worker_pid"
24
+ }
25
+
26
+ t_begin "issue graceful shutdown (SIGQUIT) and wait for termination" && {
27
+ kill -QUIT $unicorn_pid
28
+
29
+ while kill -0 $unicorn_pid >/dev/null 2>&1
30
+ do
31
+ sleep 1
32
+ done
33
+ }
34
+
35
+ t_begin "check stderr" && check_stderr
36
+
37
+ dbgcat r_err
38
+ dbgcat r_out
39
+
40
+ t_begin "all at_exit handlers ran" && {
41
+ grep "$worker_pid BOTH" $r_out
42
+ grep "$unicorn_pid BOTH" $r_out
43
+ grep "$worker_pid END BOTH" $r_out
44
+ grep "$unicorn_pid END BOTH" $r_out
45
+ grep "$worker_pid WORKER ONLY" $r_out
46
+ grep "$worker_pid END WORKER ONLY" $r_out
47
+ }
48
+
49
+ t_done
@@ -0,0 +1,29 @@
1
+ #!/bin/sh
2
+ . ./test-lib.sh
3
+
4
+ t_plan 5 "Process.detach on forked background process works"
5
+
6
+ t_begin "setup and startup" && {
7
+ t_fifos process_detach
8
+ unicorn_setup
9
+ TEST_FIFO=$process_detach \
10
+ unicorn -E none -D detach.ru -c $unicorn_config
11
+ unicorn_wait_start
12
+ }
13
+
14
+ t_begin "read detached PID with HTTP/1.0" && {
15
+ detached_pid=$(curl -0 -sSf http://$listen/)
16
+ t_info "detached_pid=$detached_pid"
17
+ }
18
+
19
+ t_begin "read background FIFO" && {
20
+ test xHIHI = x"$(cat $process_detach)"
21
+ }
22
+
23
+ t_begin "killing succeeds" && {
24
+ kill $unicorn_pid
25
+ }
26
+
27
+ t_begin "check stderr" && check_stderr
28
+
29
+ t_done
@@ -0,0 +1,32 @@
1
+ #!/bin/sh
2
+ . ./test-lib.sh
3
+
4
+ # Raindrops::Middleware depends on Unicorn.listener_names,
5
+ # ensure we don't break Raindrops::Middleware when preload_app is true
6
+
7
+ t_plan 4 "Unicorn.listener_names available with preload_app=true"
8
+
9
+ t_begin "setup and startup" && {
10
+ unicorn_setup
11
+ echo preload_app true >> $unicorn_config
12
+ unicorn -E none -D listener_names.ru -c $unicorn_config
13
+ unicorn_wait_start
14
+ }
15
+
16
+ t_begin "read listener names includes listener" && {
17
+ resp=$(curl -sSf http://$listen/)
18
+ ok=false
19
+ t_info "resp=$resp"
20
+ case $resp in
21
+ *\"$listen\"*) ok=true ;;
22
+ esac
23
+ $ok
24
+ }
25
+
26
+ t_begin "killing succeeds" && {
27
+ kill $unicorn_pid
28
+ }
29
+
30
+ t_begin "check stderr" && check_stderr
31
+
32
+ t_done
@@ -0,0 +1,124 @@
1
+ #!/bin/sh
2
+ . ./test-lib.sh
3
+ test -r random_blob || die "random_blob required, run with 'make $0'"
4
+
5
+ t_plan 10 "rack.input read tests"
6
+
7
+ t_begin "setup and startup" && {
8
+ rtmpfiles curl_out curl_err
9
+ unicorn_setup
10
+ unicorn -E none -D rack-input-tests.ru -c $unicorn_config
11
+ blob_sha1=$(rsha1 < random_blob)
12
+ blob_size=$(count_bytes < random_blob)
13
+ t_info "blob_sha1=$blob_sha1"
14
+ unicorn_wait_start
15
+ }
16
+
17
+ t_begin "corked identity request" && {
18
+ rm -f $tmp
19
+ (
20
+ cat $fifo > $tmp &
21
+ printf 'PUT / HTTP/1.0\r\n'
22
+ printf 'Content-Length: %d\r\n\r\n' $blob_size
23
+ cat random_blob
24
+ wait
25
+ echo ok > $ok
26
+ ) | ( sleep 1 && socat - TCP4:$listen > $fifo )
27
+ test 1 -eq $(grep $blob_sha1 $tmp |count_lines)
28
+ test x"$(cat $ok)" = xok
29
+ }
30
+
31
+ t_begin "corked chunked request" && {
32
+ rm -f $tmp
33
+ (
34
+ cat $fifo > $tmp &
35
+ content-md5-put < random_blob
36
+ wait
37
+ echo ok > $ok
38
+ ) | ( sleep 1 && socat - TCP4:$listen > $fifo )
39
+ test 1 -eq $(grep $blob_sha1 $tmp |count_lines)
40
+ test x"$(cat $ok)" = xok
41
+ }
42
+
43
+ t_begin "corked identity request (input#size first)" && {
44
+ rm -f $tmp
45
+ (
46
+ cat $fifo > $tmp &
47
+ printf 'PUT /size_first HTTP/1.0\r\n'
48
+ printf 'Content-Length: %d\r\n\r\n' $blob_size
49
+ cat random_blob
50
+ wait
51
+ echo ok > $ok
52
+ ) | ( sleep 1 && socat - TCP4:$listen > $fifo )
53
+ test 1 -eq $(grep $blob_sha1 $tmp |count_lines)
54
+ test x"$(cat $ok)" = xok
55
+ }
56
+
57
+ t_begin "corked identity request (input#rewind first)" && {
58
+ rm -f $tmp
59
+ (
60
+ cat $fifo > $tmp &
61
+ printf 'PUT /rewind_first HTTP/1.0\r\n'
62
+ printf 'Content-Length: %d\r\n\r\n' $blob_size
63
+ cat random_blob
64
+ wait
65
+ echo ok > $ok
66
+ ) | ( sleep 1 && socat - TCP4:$listen > $fifo )
67
+ test 1 -eq $(grep $blob_sha1 $tmp |count_lines)
68
+ test x"$(cat $ok)" = xok
69
+ }
70
+
71
+ t_begin "corked chunked request (input#size first)" && {
72
+ rm -f $tmp
73
+ (
74
+ cat $fifo > $tmp &
75
+ printf 'PUT /size_first HTTP/1.1\r\n'
76
+ printf 'Host: example.com\r\n'
77
+ printf 'Transfer-Encoding: chunked\r\n'
78
+ printf 'Trailer: Content-MD5\r\n'
79
+ printf '\r\n'
80
+ content-md5-put --no-headers < random_blob
81
+ wait
82
+ echo ok > $ok
83
+ ) | ( sleep 1 && socat - TCP4:$listen > $fifo )
84
+ test 1 -eq $(grep $blob_sha1 $tmp |count_lines)
85
+ test 1 -eq $(grep $blob_sha1 $tmp |count_lines)
86
+ test x"$(cat $ok)" = xok
87
+ }
88
+
89
+ t_begin "corked chunked request (input#rewind first)" && {
90
+ rm -f $tmp
91
+ (
92
+ cat $fifo > $tmp &
93
+ printf 'PUT /rewind_first HTTP/1.1\r\n'
94
+ printf 'Host: example.com\r\n'
95
+ printf 'Transfer-Encoding: chunked\r\n'
96
+ printf 'Trailer: Content-MD5\r\n'
97
+ printf '\r\n'
98
+ content-md5-put --no-headers < random_blob
99
+ wait
100
+ echo ok > $ok
101
+ ) | ( sleep 1 && socat - TCP4:$listen > $fifo )
102
+ test 1 -eq $(grep $blob_sha1 $tmp |count_lines)
103
+ test x"$(cat $ok)" = xok
104
+ }
105
+
106
+ t_begin "regular request" && {
107
+ curl -sSf -T random_blob http://$listen/ > $curl_out 2> $curl_err
108
+ test x$blob_sha1 = x$(cat $curl_out)
109
+ test ! -s $curl_err
110
+ }
111
+
112
+ t_begin "chunked request" && {
113
+ curl -sSf -T- < random_blob http://$listen/ > $curl_out 2> $curl_err
114
+ test x$blob_sha1 = x$(cat $curl_out)
115
+ test ! -s $curl_err
116
+ }
117
+
118
+ dbgcat r_err
119
+
120
+ t_begin "shutdown" && {
121
+ kill $unicorn_pid
122
+ }
123
+
124
+ t_done