unicorn 4.9.0 → 6.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. checksums.yaml +5 -5
  2. data/.gitattributes +5 -0
  3. data/.olddoc.yml +13 -6
  4. data/Application_Timeouts +7 -7
  5. data/DESIGN +2 -4
  6. data/Documentation/.gitignore +1 -3
  7. data/Documentation/unicorn.1 +222 -0
  8. data/Documentation/unicorn_rails.1 +207 -0
  9. data/FAQ +17 -8
  10. data/GIT-VERSION-GEN +1 -1
  11. data/GNUmakefile +121 -56
  12. data/HACKING +1 -2
  13. data/ISSUES +40 -41
  14. data/KNOWN_ISSUES +11 -11
  15. data/LICENSE +2 -2
  16. data/Links +24 -25
  17. data/PHILOSOPHY +0 -6
  18. data/README +46 -39
  19. data/SIGNALS +2 -2
  20. data/Sandbox +10 -9
  21. data/TODO +0 -2
  22. data/TUNING +30 -9
  23. data/archive/slrnpull.conf +1 -1
  24. data/bin/unicorn +4 -2
  25. data/bin/unicorn_rails +3 -3
  26. data/examples/big_app_gc.rb +1 -1
  27. data/examples/init.sh +36 -8
  28. data/examples/logrotate.conf +17 -2
  29. data/examples/nginx.conf +14 -14
  30. data/examples/unicorn.conf.minimal.rb +2 -2
  31. data/examples/unicorn.conf.rb +3 -6
  32. data/examples/unicorn.socket +11 -0
  33. data/examples/unicorn@.service +40 -0
  34. data/ext/unicorn_http/common_field_optimization.h +23 -5
  35. data/ext/unicorn_http/ext_help.h +0 -20
  36. data/ext/unicorn_http/extconf.rb +37 -1
  37. data/ext/unicorn_http/global_variables.h +1 -1
  38. data/ext/unicorn_http/httpdate.c +2 -2
  39. data/ext/unicorn_http/unicorn_http.rl +167 -170
  40. data/ext/unicorn_http/unicorn_http_common.rl +1 -1
  41. data/lib/unicorn.rb +66 -46
  42. data/lib/unicorn/configurator.rb +110 -44
  43. data/lib/unicorn/const.rb +2 -25
  44. data/lib/unicorn/http_request.rb +110 -31
  45. data/lib/unicorn/http_response.rb +17 -31
  46. data/lib/unicorn/http_server.rb +238 -157
  47. data/lib/unicorn/launcher.rb +1 -1
  48. data/lib/unicorn/oob_gc.rb +6 -6
  49. data/lib/unicorn/socket_helper.rb +58 -78
  50. data/lib/unicorn/stream_input.rb +8 -7
  51. data/lib/unicorn/tee_input.rb +8 -10
  52. data/lib/unicorn/tmpio.rb +8 -7
  53. data/lib/unicorn/util.rb +5 -4
  54. data/lib/unicorn/worker.rb +36 -23
  55. data/t/GNUmakefile +3 -72
  56. data/t/README +4 -4
  57. data/t/t0011-active-unix-socket.sh +1 -1
  58. data/t/t0012-reload-empty-config.sh +2 -1
  59. data/t/t0301-no-default-middleware-ignored-in-config.sh +25 -0
  60. data/t/t0301.ru +13 -0
  61. data/t/test-lib.sh +2 -2
  62. data/test/benchmark/README +14 -4
  63. data/test/benchmark/ddstream.ru +50 -0
  64. data/test/benchmark/readinput.ru +40 -0
  65. data/test/benchmark/uconnect.perl +66 -0
  66. data/test/exec/test_exec.rb +73 -19
  67. data/test/test_helper.rb +40 -31
  68. data/test/unit/test_ccc.rb +91 -0
  69. data/test/unit/test_droplet.rb +1 -1
  70. data/test/unit/test_http_parser.rb +46 -16
  71. data/test/unit/test_http_parser_ng.rb +97 -114
  72. data/test/unit/test_request.rb +10 -10
  73. data/test/unit/test_response.rb +28 -16
  74. data/test/unit/test_server.rb +86 -12
  75. data/test/unit/test_signals.rb +8 -8
  76. data/test/unit/test_socket_helper.rb +14 -10
  77. data/test/unit/test_upload.rb +9 -14
  78. data/test/unit/test_util.rb +27 -2
  79. data/unicorn.gemspec +27 -19
  80. metadata +24 -45
  81. data/Documentation/GNUmakefile +0 -30
  82. data/Documentation/unicorn.1.txt +0 -185
  83. data/Documentation/unicorn_rails.1.txt +0 -175
  84. data/examples/git.ru +0 -13
  85. data/lib/unicorn/app/exec_cgi.rb +0 -154
  86. data/lib/unicorn/app/inetd.rb +0 -109
  87. data/lib/unicorn/ssl_client.rb +0 -11
  88. data/lib/unicorn/ssl_configurator.rb +0 -104
  89. data/lib/unicorn/ssl_server.rb +0 -42
  90. data/t/hijack.ru +0 -42
  91. data/t/t0016-trust-x-forwarded-false.sh +0 -30
  92. data/t/t0017-trust-x-forwarded-true.sh +0 -30
  93. data/t/t0200-rack-hijack.sh +0 -27
  94. data/test/unit/test_http_parser_xftrust.rb +0 -38
  95. data/test/unit/test_sni_hostnames.rb +0 -47
data/t/GNUmakefile CHANGED
@@ -1,74 +1,5 @@
1
- # we can run tests in parallel with GNU make
1
+ # there used to be more, here, but we stopped relying on recursive make
2
2
  all::
3
+ $(MAKE) -C .. test-integration
3
4
 
4
- pid := $(shell echo $$PPID)
5
-
6
- RUBY = ruby
7
- RAKE = rake
8
- -include ../local.mk
9
- ifeq ($(RUBY_VERSION),)
10
- RUBY_VERSION := $(shell $(RUBY) -e 'puts RUBY_VERSION')
11
- endif
12
-
13
- ifeq ($(RUBY_VERSION),)
14
- $(error unable to detect RUBY_VERSION)
15
- endif
16
-
17
- RUBY_ENGINE := $(shell $(RUBY) -e 'puts((RUBY_ENGINE rescue "ruby"))')
18
- export RUBY_ENGINE
19
-
20
- MYLIBS := $(RUBYLIB)
21
-
22
- T = $(wildcard t[0-9][0-9][0-9][0-9]-*.sh)
23
-
24
- all:: $(T)
25
-
26
- # can't rely on "set -o pipefail" since we don't require bash or ksh93 :<
27
- t_pfx = trash/$@-$(RUBY_ENGINE)-$(RUBY_VERSION)
28
- TEST_OPTS =
29
- # TRACER = strace -f -o $(t_pfx).strace -s 100000
30
- # TRACER = /usr/bin/time -o $(t_pfx).time
31
-
32
- ifdef V
33
- ifeq ($(V),2)
34
- TEST_OPTS += --trace
35
- else
36
- TEST_OPTS += --verbose
37
- endif
38
- endif
39
-
40
- random_blob:
41
- dd if=/dev/urandom bs=1M count=30 of=$@.$(pid)
42
- mv $@.$(pid) $@
43
-
44
- $(T): random_blob
45
-
46
- dependencies := socat curl
47
- deps := $(addprefix .dep+,$(dependencies))
48
- $(deps): dep_bin = $(lastword $(subst +, ,$@))
49
- $(deps):
50
- @which $(dep_bin) > $@.$(pid) 2>/dev/null || :
51
- @test -s $@.$(pid) || \
52
- { echo >&2 "E '$(dep_bin)' not found in PATH=$(PATH)"; exit 1; }
53
- @mv $@.$(pid) $@
54
- dep: $(deps)
55
-
56
- test_prefix := $(CURDIR)/../test/$(RUBY_ENGINE)-$(RUBY_VERSION)
57
- $(test_prefix)/.stamp:
58
- $(MAKE) -C .. test-install
59
-
60
- $(T): export RUBY := $(RUBY)
61
- $(T): export RAKE := $(RAKE)
62
- $(T): export PATH := $(test_prefix)/bin:$(PATH)
63
- $(T): export RUBYLIB := $(test_prefix)/lib:$(MYLIBS)
64
- $(T): dep $(test_prefix)/.stamp trash/.gitignore
65
- $(TRACER) $(SHELL) $(SH_TEST_OPTS) $@ $(TEST_OPTS)
66
-
67
- trash/.gitignore:
68
- mkdir -p $(@D)
69
- echo '*' > $@
70
-
71
- clean:
72
- $(RM) -r trash/*
73
-
74
- .PHONY: $(T) clean
5
+ .PHONY: all
data/t/README CHANGED
@@ -10,17 +10,17 @@ comfortable writing integration tests with.
10
10
 
11
11
  == Requirements
12
12
 
13
- * {Ruby 1.9.3+}[https://www.ruby-lang.org/] (duh!)
14
- * {GNU make}[http://www.gnu.org/software/make/]
13
+ * {Ruby 1.9.3+}[https://www.ruby-lang.org/en/] (duh!)
14
+ * {GNU make}[https://www.gnu.org/software/make/]
15
15
  * {socat}[http://www.dest-unreach.org/socat/]
16
- * {curl}[http://curl.haxx.se/]
16
+ * {curl}[https://curl.haxx.se/]
17
17
  * standard UNIX shell utilities (Bourne sh, awk, sed, grep, ...)
18
18
 
19
19
  We do not use bashisms or any non-portable, non-POSIX constructs
20
20
  in our shell code. We use the "pipefail" option if available and
21
21
  mainly test with {ksh}[http://kornshell.com/], but occasionally
22
22
  with {dash}[http://gondor.apana.org.au/~herbert/dash/] and
23
- {bash}[http://www.gnu.org/software/bash/], too.
23
+ {bash}[https://www.gnu.org/software/bash/], too.
24
24
 
25
25
  == Running Tests
26
26
 
@@ -52,7 +52,7 @@ t_begin "worker pid unchanged (again)" && {
52
52
  }
53
53
 
54
54
  t_begin "nuking the existing Unicorn succeeds" && {
55
- kill -9 $unicorn_pid $worker_pid
55
+ kill -9 $unicorn_pid
56
56
  while kill -0 $unicorn_pid
57
57
  do
58
58
  sleep 1
@@ -18,7 +18,8 @@ after_fork { |s,w| }
18
18
  next if key =~ %r{\Astd(?:err|out)_path\z}
19
19
  key = key.to_sym
20
20
  def_value = defaults[key]
21
- srv_value = srv.__send__(key)
21
+ srv_value = srv.respond_to?(key) ? srv.__send__(key)
22
+ : srv.instance_variable_get("@#{key}")
22
23
  fp << "#{key}|#{srv_value}|#{def_value}\\n"
23
24
  end
24
25
  }
@@ -0,0 +1,25 @@
1
+ #!/bin/sh
2
+ . ./test-lib.sh
3
+ t_plan 3 "-N / --no-default-middleware option not supported in config.ru"
4
+
5
+ t_begin "setup and start" && {
6
+ unicorn_setup
7
+ RACK_ENV=development unicorn -D -c $unicorn_config t0301.ru
8
+ unicorn_wait_start
9
+ }
10
+
11
+ t_begin "check switches parsed as expected and -N ignored for Rack::Lint" && {
12
+ debug=false
13
+ lint=
14
+ eval "$(curl -sf http://$listen/vars)"
15
+ test x"$debug" = xtrue
16
+ test x"$lint" != x
17
+ test -f "$lint"
18
+ }
19
+
20
+ t_begin "killing succeeds" && {
21
+ kill $unicorn_pid
22
+ check_stderr
23
+ }
24
+
25
+ t_done
data/t/t0301.ru ADDED
@@ -0,0 +1,13 @@
1
+ #\-N --debug
2
+ run(lambda do |env|
3
+ case env['PATH_INFO']
4
+ when '/vars'
5
+ b = "debug=#{$DEBUG.inspect}\n" \
6
+ "lint=#{caller.grep(%r{rack/lint\.rb})[0].split(':')[0]}\n"
7
+ end
8
+ h = {
9
+ 'Content-Length' => b.size.to_s,
10
+ 'Content-Type' => 'text/plain',
11
+ }
12
+ [ 200, h, [ b ] ]
13
+ end)
data/t/test-lib.sh CHANGED
@@ -106,8 +106,8 @@ check_stderr () {
106
106
  # unicorn_setup
107
107
  unicorn_setup () {
108
108
  eval $(unused_listen)
109
- port=$(expr $listen : '[^:]*:\([0-9]\+\)')
110
- host=$(expr $listen : '\([^:]*\):[0-9]\+')
109
+ port=$(expr $listen : '[^:]*:\([0-9]*\)')
110
+ host=$(expr $listen : '\([^:][^:]*\):[0-9][0-9]*')
111
111
 
112
112
  rtmpfiles unicorn_config pid r_err r_out fifo tmp ok
113
113
  cat > $unicorn_config <<EOF
@@ -42,9 +42,19 @@ The benchmark client is usually httperf.
42
42
  Another gentle reminder: performance with slow networks/clients
43
43
  is NOT our problem. That is the job of nginx (or similar).
44
44
 
45
+ == ddstream.ru
46
+
47
+ Standalone Rack app intended to show how BAD we are at slow clients.
48
+ See usage in comments.
49
+
50
+ == readinput.ru
51
+
52
+ Standalone Rack app intended to show how bad we are with slow uploaders.
53
+ See usage in comments.
54
+
45
55
  == Contributors
46
56
 
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.
57
+ This directory is intended to remain stable. Do not make changes
58
+ to benchmarking code which can change performance and invalidate
59
+ results across revisions. Instead, write new benchmarks and update
60
+ coments/documentation as necessary.
@@ -0,0 +1,50 @@
1
+ # This app is intended to test large HTTP responses with or without
2
+ # a fully-buffering reverse proxy such as nginx. Without a fully-buffering
3
+ # reverse proxy, unicorn will be unresponsive when client count exceeds
4
+ # worker_processes.
5
+ #
6
+ # To demonstrate how bad unicorn is at slowly reading clients:
7
+ #
8
+ # # in one terminal, start unicorn with one worker:
9
+ # unicorn -E none -l 127.0.0.1:8080 test/benchmark/ddstream.ru
10
+ #
11
+ # # in a different terminal, start more slow curl processes than
12
+ # # unicorn workers and watch time outputs
13
+ # curl --limit-rate 8K --trace-time -vsN http://127.0.0.1:8080/ >/dev/null &
14
+ # curl --limit-rate 8K --trace-time -vsN http://127.0.0.1:8080/ >/dev/null &
15
+ # wait
16
+ #
17
+ # The last client won't see a response until the first one is done reading
18
+ #
19
+ # nginx note: do not change the default "proxy_buffering" behavior.
20
+ # Setting "proxy_buffering off" prevents nginx from protecting unicorn.
21
+
22
+ # totally standalone rack app to stream a giant response
23
+ class BigResponse
24
+ def initialize(bs, count)
25
+ @buf = "#{bs.to_s(16)}\r\n#{' ' * bs}\r\n"
26
+ @count = count
27
+ @res = [ 200,
28
+ { 'Transfer-Encoding' => -'chunked', 'Content-Type' => 'text/plain' },
29
+ self
30
+ ]
31
+ end
32
+
33
+ # rack response body iterator
34
+ def each
35
+ (1..@count).each { yield @buf }
36
+ yield -"0\r\n\r\n"
37
+ end
38
+
39
+ # rack app entry endpoint
40
+ def call(_env)
41
+ @res
42
+ end
43
+ end
44
+
45
+ # default to a giant (128M) response because kernel socket buffers
46
+ # can be ridiculously large on some systems
47
+ bs = ENV['bs'] ? ENV['bs'].to_i : 65536
48
+ count = ENV['count'] ? ENV['count'].to_i : 2048
49
+ warn "serving response with bs=#{bs} count=#{count} (#{bs*count} bytes)"
50
+ run BigResponse.new(bs, count)
@@ -0,0 +1,40 @@
1
+ # This app is intended to test large HTTP requests with or without
2
+ # a fully-buffering reverse proxy such as nginx. Without a fully-buffering
3
+ # reverse proxy, unicorn will be unresponsive when client count exceeds
4
+ # worker_processes.
5
+
6
+ DOC = <<DOC
7
+ To demonstrate how bad unicorn is at slowly uploading clients:
8
+
9
+ # in one terminal, start unicorn with one worker:
10
+ unicorn -E none -l 127.0.0.1:8080 test/benchmark/readinput.ru
11
+
12
+ # in a different terminal, upload 45M from multiple curl processes:
13
+ dd if=/dev/zero bs=45M count=1 | curl -T- -HExpect: --limit-rate 1M \
14
+ --trace-time -v http://127.0.0.1:8080/ &
15
+ dd if=/dev/zero bs=45M count=1 | curl -T- -HExpect: --limit-rate 1M \
16
+ --trace-time -v http://127.0.0.1:8080/ &
17
+ wait
18
+
19
+ # The last client won't see a response until the first one is done uploading
20
+ # You also won't be able to make GET requests to view this documentation
21
+ # while clients are uploading. You can also view the stderr debug output
22
+ # of unicorn (see logging code in #{__FILE__}).
23
+ DOC
24
+
25
+ run(lambda do |env|
26
+ input = env['rack.input']
27
+ buf = ''.b
28
+
29
+ # default logger contains timestamps, rely on that so users can
30
+ # see what the server is doing
31
+ l = env['rack.logger']
32
+
33
+ l.debug('BEGIN reading input ...') if l
34
+ :nop while input.read(16384, buf)
35
+ l.debug('DONE reading input ...') if l
36
+
37
+ buf.clear
38
+ [ 200, [ %W(Content-Length #{DOC.size}), %w(Content-Type text/plain) ],
39
+ [ DOC ] ]
40
+ end)
@@ -0,0 +1,66 @@
1
+ #!/usr/bin/perl -w
2
+ # Benchmark script to spawn some processes and hammer a local unicorn
3
+ # to test accept loop performance. This only does Unix sockets.
4
+ # There's plenty of TCP benchmarking tools out there, and TCP port reuse
5
+ # has predictability problems since unicorn can't do persistent connections.
6
+ # Written in Perl for the same reason: predictability.
7
+ # Ruby GC is not as predictable as Perl refcounting.
8
+ use strict;
9
+ use Socket qw(AF_UNIX SOCK_STREAM sockaddr_un);
10
+ use POSIX qw(:sys_wait_h);
11
+ use Getopt::Std;
12
+ # -c / -n switches stolen from ab(1)
13
+ my $usage = "$0 [-c CONCURRENCY] [-n NUM_REQUESTS] SOCKET_PATH\n";
14
+ our $opt_c = 2;
15
+ our $opt_n = 1000;
16
+ getopts('c:n:') or die $usage;
17
+ my $unix_path = shift or die $usage;
18
+ use constant REQ => "GET / HTTP/1.1\r\nHost: example.com\r\n\r\n";
19
+ use constant REQ_LEN => length(REQ);
20
+ use constant BUFSIZ => 8192;
21
+ $^F = 99; # don't waste syscall time with FD_CLOEXEC
22
+
23
+ my %workers; # pid => worker num
24
+ die "-n $opt_n not evenly divisible by -c $opt_c\n" if $opt_n % $opt_c;
25
+ my $n_per_worker = $opt_n / $opt_c;
26
+ my $addr = sockaddr_un($unix_path);
27
+
28
+ for my $num (1..$opt_c) {
29
+ defined(my $pid = fork) or die "fork failed: $!\n";
30
+ if ($pid) {
31
+ $workers{$pid} = $num;
32
+ } else {
33
+ work($n_per_worker);
34
+ }
35
+ }
36
+
37
+ reap_worker(0) while scalar keys %workers;
38
+ exit;
39
+
40
+ sub work {
41
+ my ($n) = @_;
42
+ my ($buf, $x);
43
+ for (1..$n) {
44
+ socket(S, AF_UNIX, SOCK_STREAM, 0) or die "socket: $!";
45
+ connect(S, $addr) or die "connect: $!";
46
+ defined($x = syswrite(S, REQ)) or die "write: $!";
47
+ $x == REQ_LEN or die "short write: $x != ".REQ_LEN."\n";
48
+ do {
49
+ $x = sysread(S, $buf, BUFSIZ);
50
+ unless (defined $x) {
51
+ next if $!{EINTR};
52
+ die "sysread: $!\n";
53
+ }
54
+ } until ($x == 0);
55
+ }
56
+ exit 0;
57
+ }
58
+
59
+ sub reap_worker {
60
+ my ($flags) = @_;
61
+ my $pid = waitpid(-1, $flags);
62
+ return if !defined $pid || $pid <= 0;
63
+ my $p = delete $workers{$pid} || '(unknown)';
64
+ warn("$pid [$p] exited with $?\n") if $?;
65
+ $p;
66
+ }
@@ -45,8 +45,9 @@ def call(env)
45
45
 
46
46
  COMMON_TMP = Tempfile.new('unicorn_tmp') unless defined?(COMMON_TMP)
47
47
 
48
+ HEAVY_WORKERS = 2
48
49
  HEAVY_CFG = <<-EOS
49
- worker_processes 4
50
+ worker_processes #{HEAVY_WORKERS}
50
51
  timeout 30
51
52
  logger Logger.new('#{COMMON_TMP.path}')
52
53
  before_fork do |server, worker|
@@ -96,6 +97,59 @@ def teardown
96
97
  end
97
98
  end
98
99
 
100
+ def test_sd_listen_fds_emulation
101
+ # [ruby-core:69895] [Bug #11336] fixed by r51576
102
+ return if RUBY_VERSION.to_f < 2.3
103
+
104
+ File.open("config.ru", "wb") { |fp| fp.write(HI) }
105
+ sock = TCPServer.new(@addr, @port)
106
+
107
+ [ %W(-l #@addr:#@port), nil ].each do |l|
108
+ sock.setsockopt(:SOL_SOCKET, :SO_KEEPALIVE, 0)
109
+
110
+ pid = xfork do
111
+ redirect_test_io do
112
+ # pretend to be systemd
113
+ ENV['LISTEN_PID'] = "#$$"
114
+ ENV['LISTEN_FDS'] = '1'
115
+
116
+ # 3 = SD_LISTEN_FDS_START
117
+ args = [ $unicorn_bin ]
118
+ args.concat(l) if l
119
+ args << { 3 => sock }
120
+ exec(*args)
121
+ end
122
+ end
123
+ res = hit(["http://#@addr:#@port/"])
124
+ assert_equal [ "HI\n" ], res
125
+ assert_shutdown(pid)
126
+ assert sock.getsockopt(:SOL_SOCKET, :SO_KEEPALIVE).bool,
127
+ 'unicorn should always set SO_KEEPALIVE on inherited sockets'
128
+ end
129
+ ensure
130
+ sock.close if sock
131
+ end
132
+
133
+ def test_inherit_listener_unspecified
134
+ File.open("config.ru", "wb") { |fp| fp.write(HI) }
135
+ sock = TCPServer.new(@addr, @port)
136
+ sock.setsockopt(:SOL_SOCKET, :SO_KEEPALIVE, 0)
137
+
138
+ pid = xfork do
139
+ redirect_test_io do
140
+ ENV['UNICORN_FD'] = sock.fileno.to_s
141
+ exec($unicorn_bin, sock.fileno => sock.fileno)
142
+ end
143
+ end
144
+ res = hit(["http://#@addr:#@port/"])
145
+ assert_equal [ "HI\n" ], res
146
+ assert_shutdown(pid)
147
+ assert sock.getsockopt(:SOL_SOCKET, :SO_KEEPALIVE).bool,
148
+ 'unicorn should always set SO_KEEPALIVE on inherited sockets'
149
+ ensure
150
+ sock.close if sock
151
+ end
152
+
99
153
  def test_working_directory_rel_path_config_file
100
154
  other = Tempfile.new('unicorn.wd')
101
155
  File.unlink(other.path)
@@ -140,8 +194,8 @@ def test_working_directory_rel_path_config_file
140
194
  assert_equal other.path, results.first
141
195
 
142
196
  Process.kill(:QUIT, pid)
143
- ensure
144
- FileUtils.rmtree(other.path)
197
+ ensure
198
+ FileUtils.rmtree(other.path)
145
199
  end
146
200
 
147
201
  def test_working_directory
@@ -176,8 +230,8 @@ def test_working_directory
176
230
  assert_equal other.path, results.first
177
231
 
178
232
  Process.kill(:QUIT, pid)
179
- ensure
180
- FileUtils.rmtree(other.path)
233
+ ensure
234
+ FileUtils.rmtree(other.path)
181
235
  end
182
236
 
183
237
  def test_working_directory_controls_relative_paths
@@ -218,11 +272,10 @@ def test_working_directory_controls_relative_paths
218
272
  wait_master_ready("#{other.path}/stderr_log_here")
219
273
 
220
274
  Process.kill(:QUIT, pid)
221
- ensure
222
- FileUtils.rmtree(other.path)
275
+ ensure
276
+ FileUtils.rmtree(other.path)
223
277
  end
224
278
 
225
-
226
279
  def test_exit_signals
227
280
  %w(INT TERM QUIT).each do |sig|
228
281
  File.open("config.ru", "wb") { |fp| fp.syswrite(HI) }
@@ -521,7 +574,7 @@ def test_unicorn_config_per_worker_listen
521
574
  assert_equal String, results[0].class
522
575
  worker_pid = results[0].to_i
523
576
  assert_not_equal pid, worker_pid
524
- s = UNIXSocket.new(tmp.path)
577
+ s = unix_socket(tmp.path)
525
578
  s.syswrite("GET / HTTP/1.0\r\n\r\n")
526
579
  results = ''
527
580
  loop { results << s.sysread(4096) } rescue nil
@@ -554,6 +607,7 @@ def test_unicorn_config_listen_augments_cli
554
607
  def test_weird_config_settings
555
608
  File.open("config.ru", "wb") { |fp| fp.syswrite(HI) }
556
609
  ucfg = Tempfile.new('unicorn_test_config')
610
+ proc_total = HEAVY_WORKERS + 1 # + 1 for master
557
611
  ucfg.syswrite(HEAVY_CFG)
558
612
  pid = xfork do
559
613
  redirect_test_io do
@@ -564,9 +618,9 @@ def test_weird_config_settings
564
618
  results = retry_hit(["http://#{@addr}:#{@port}/"])
565
619
  assert_equal String, results[0].class
566
620
  wait_master_ready(COMMON_TMP.path)
567
- wait_workers_ready(COMMON_TMP.path, 4)
621
+ wait_workers_ready(COMMON_TMP.path, HEAVY_WORKERS)
568
622
  bf = File.readlines(COMMON_TMP.path).grep(/\bbefore_fork: worker=/)
569
- assert_equal 4, bf.size
623
+ assert_equal HEAVY_WORKERS, bf.size
570
624
  rotate = Tempfile.new('unicorn_rotate')
571
625
 
572
626
  File.rename(COMMON_TMP.path, rotate.path)
@@ -578,20 +632,20 @@ def test_weird_config_settings
578
632
  tries = DEFAULT_TRIES
579
633
  log = File.readlines(rotate.path)
580
634
  while (tries -= 1) > 0 &&
581
- log.grep(/reopening logs\.\.\./).size < 5
635
+ log.grep(/reopening logs\.\.\./).size < proc_total
582
636
  sleep DEFAULT_RES
583
637
  log = File.readlines(rotate.path)
584
638
  end
585
- assert_equal 5, log.grep(/reopening logs\.\.\./).size
639
+ assert_equal proc_total, log.grep(/reopening logs\.\.\./).size
586
640
  assert_equal 0, log.grep(/done reopening logs/).size
587
641
 
588
642
  tries = DEFAULT_TRIES
589
643
  log = File.readlines(COMMON_TMP.path)
590
- while (tries -= 1) > 0 && log.grep(/done reopening logs/).size < 5
644
+ while (tries -= 1) > 0 && log.grep(/done reopening logs/).size < proc_total
591
645
  sleep DEFAULT_RES
592
646
  log = File.readlines(COMMON_TMP.path)
593
647
  end
594
- assert_equal 5, log.grep(/done reopening logs/).size
648
+ assert_equal proc_total, log.grep(/done reopening logs/).size
595
649
  assert_equal 0, log.grep(/reopening logs\.\.\./).size
596
650
 
597
651
  Process.kill(:QUIT, pid)
@@ -678,7 +732,7 @@ def test_socket_unlinked_restore
678
732
  wait_for_file(sock_path)
679
733
  assert File.socket?(sock_path)
680
734
 
681
- sock = UNIXSocket.new(sock_path)
735
+ sock = unix_socket(sock_path)
682
736
  sock.syswrite("GET / HTTP/1.0\r\n\r\n")
683
737
  results = sock.sysread(4096)
684
738
 
@@ -688,7 +742,7 @@ def test_socket_unlinked_restore
688
742
  wait_for_file(sock_path)
689
743
  assert File.socket?(sock_path)
690
744
 
691
- sock = UNIXSocket.new(sock_path)
745
+ sock = unix_socket(sock_path)
692
746
  sock.syswrite("GET / HTTP/1.0\r\n\r\n")
693
747
  results = sock.sysread(4096)
694
748
 
@@ -723,7 +777,7 @@ def test_unicorn_config_file
723
777
  assert_equal pid, File.read(pid_file).to_i
724
778
  assert File.socket?(sock_path), "socket created"
725
779
 
726
- sock = UNIXSocket.new(sock_path)
780
+ sock = unix_socket(sock_path)
727
781
  sock.syswrite("GET / HTTP/1.0\r\n\r\n")
728
782
  results = sock.sysread(4096)
729
783
 
@@ -749,7 +803,7 @@ def test_unicorn_config_file
749
803
  wait_for_file(new_sock_path)
750
804
  assert File.socket?(new_sock_path), "socket exists"
751
805
  @sockets.each do |path|
752
- sock = UNIXSocket.new(path)
806
+ sock = unix_socket(path)
753
807
  sock.syswrite("GET / HTTP/1.0\r\n\r\n")
754
808
  results = sock.sysread(4096)
755
809
  assert_equal String, results.class