unicorn 0.96.1 → 0.97.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +1 -0
- data/Documentation/unicorn_rails.1.txt +6 -1
- data/FAQ +7 -0
- data/GIT-VERSION-GEN +1 -1
- data/GNUmakefile +6 -8
- data/KNOWN_ISSUES +8 -0
- data/Rakefile +1 -4
- data/TODO +1 -6
- data/bin/unicorn +4 -42
- data/bin/unicorn_rails +65 -68
- data/examples/init.sh +7 -2
- data/examples/logger_mp_safe.rb +25 -0
- data/ext/unicorn_http/CFLAGS +13 -0
- data/ext/unicorn_http/c_util.h +13 -0
- data/ext/unicorn_http/common_field_optimization.h +3 -3
- data/ext/unicorn_http/ext_help.h +2 -2
- data/ext/unicorn_http/global_variables.h +1 -3
- data/ext/unicorn_http/unicorn_http.rl +15 -13
- data/lib/unicorn.rb +64 -12
- data/lib/unicorn/configurator.rb +19 -1
- data/lib/unicorn/const.rb +4 -7
- data/lib/unicorn/http_request.rb +1 -1
- data/lib/unicorn/tee_input.rb +39 -39
- data/lib/unicorn/util.rb +1 -2
- data/t/.gitignore +2 -0
- data/t/GNUmakefile +67 -0
- data/t/README +42 -0
- data/t/bin/content-md5-put +36 -0
- data/t/bin/sha1sum.rb +23 -0
- data/t/bin/unused_listen +40 -0
- data/t/bin/utee +12 -0
- data/t/env.ru +3 -0
- data/t/my-tap-lib.sh +200 -0
- data/t/t0000-http-basic.sh +50 -0
- data/t/t0001-reload-bad-config.sh +52 -0
- data/t/t0002-config-conflict.sh +49 -0
- data/t/test-lib.sh +100 -0
- data/test/rails/test_rails.rb +3 -3
- data/test/test_helper.rb +5 -0
- data/test/unit/test_http_parser_ng.rb +0 -1
- data/test/unit/test_server.rb +1 -0
- data/test/unit/test_signals.rb +5 -1
- data/test/unit/test_tee_input.rb +15 -15
- data/test/unit/test_upload.rb +1 -0
- metadata +17 -2
@@ -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 $(wc -l < $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,52 @@
|
|
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
|
+
}
|
38
|
+
|
39
|
+
t_begin "hit with curl" && {
|
40
|
+
out=$(curl -sSf http://$listen/)
|
41
|
+
test x"$out" = x'{"hello"=>"world"}'
|
42
|
+
}
|
43
|
+
|
44
|
+
t_begin "killing succeeds" && {
|
45
|
+
kill $unicorn_pid
|
46
|
+
}
|
47
|
+
|
48
|
+
t_begin "check stderr" && {
|
49
|
+
check_stderr
|
50
|
+
}
|
51
|
+
|
52
|
+
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
|
data/t/test-lib.sh
ADDED
@@ -0,0 +1,100 @@
|
|
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
|
+
set -e
|
8
|
+
RUBY="${RUBY-ruby}"
|
9
|
+
RUBY_VERSION=${RUBY_VERSION-$($RUBY -e 'puts RUBY_VERSION')}
|
10
|
+
t_pfx=$PWD/trash/$T-$RUBY_VERSION
|
11
|
+
set -u
|
12
|
+
|
13
|
+
PATH=$PWD/bin:$PATH
|
14
|
+
export PATH
|
15
|
+
|
16
|
+
test -x $PWD/bin/unused_listen || die "must be run in 't' directory"
|
17
|
+
|
18
|
+
wait_for_pid () {
|
19
|
+
path="$1"
|
20
|
+
nr=30
|
21
|
+
while ! test -s "$path" && test $nr -gt 0
|
22
|
+
do
|
23
|
+
nr=$(($nr - 1))
|
24
|
+
sleep 1
|
25
|
+
done
|
26
|
+
}
|
27
|
+
|
28
|
+
# given a list of variable names, create temporary files and assign
|
29
|
+
# the pathnames to those variables
|
30
|
+
rtmpfiles () {
|
31
|
+
for id in "$@"
|
32
|
+
do
|
33
|
+
name=$id
|
34
|
+
_tmp=$t_pfx.$id
|
35
|
+
eval "$id=$_tmp"
|
36
|
+
|
37
|
+
case $name in
|
38
|
+
*fifo)
|
39
|
+
rm -f $_tmp
|
40
|
+
mkfifo $_tmp
|
41
|
+
T_RM_LIST="$T_RM_LIST $_tmp"
|
42
|
+
;;
|
43
|
+
*socket)
|
44
|
+
rm -f $_tmp
|
45
|
+
T_RM_LIST="$T_RM_LIST $_tmp"
|
46
|
+
;;
|
47
|
+
*)
|
48
|
+
> $_tmp
|
49
|
+
T_OK_RM_LIST="$T_OK_RM_LIST $_tmp"
|
50
|
+
;;
|
51
|
+
esac
|
52
|
+
done
|
53
|
+
}
|
54
|
+
|
55
|
+
dbgcat () {
|
56
|
+
id=$1
|
57
|
+
eval '_file=$'$id
|
58
|
+
echo "==> $id <=="
|
59
|
+
sed -e "s/^/$id:/" < $_file
|
60
|
+
}
|
61
|
+
|
62
|
+
check_stderr () {
|
63
|
+
set +u
|
64
|
+
_r_err=${1-${r_err}}
|
65
|
+
set -u
|
66
|
+
if grep -v $T $_r_err | grep -i Error
|
67
|
+
then
|
68
|
+
die "Errors found in $_r_err"
|
69
|
+
elif grep SIGKILL $_r_err
|
70
|
+
then
|
71
|
+
die "SIGKILL found in $_r_err"
|
72
|
+
fi
|
73
|
+
}
|
74
|
+
|
75
|
+
# unicorn_setup
|
76
|
+
unicorn_setup () {
|
77
|
+
eval $(unused_listen)
|
78
|
+
rtmpfiles unicorn_config pid r_err r_out fifo tmp ok
|
79
|
+
cat > $unicorn_config <<EOF
|
80
|
+
listen "$listen"
|
81
|
+
pid "$pid"
|
82
|
+
stderr_path "$r_err"
|
83
|
+
stdout_path "$r_out"
|
84
|
+
EOF
|
85
|
+
}
|
86
|
+
|
87
|
+
unicorn_wait_start () {
|
88
|
+
# no need to play tricks with FIFOs since we got "ready_pipe" now
|
89
|
+
unicorn_pid=$(cat $pid)
|
90
|
+
}
|
91
|
+
|
92
|
+
rsha1 () {
|
93
|
+
_cmd="$(which sha1sum 2>/dev/null || :)"
|
94
|
+
test -n "$_cmd" || _cmd="$(which openssl 2>/dev/null || :) sha1"
|
95
|
+
test "$_cmd" != " sha1" || _cmd="$(which gsha1sum 2>/dev/null || :)"
|
96
|
+
|
97
|
+
# last resort, see comments in sha1sum.rb for reasoning
|
98
|
+
test -n "$_cmd" || _cmd=sha1sum.rb
|
99
|
+
expr "$($_cmd < random_blob)" : '\([a-f0-9]\{40\}\)'
|
100
|
+
}
|
data/test/rails/test_rails.rb
CHANGED
@@ -92,9 +92,6 @@ logger Logger.new('#{COMMON_TMP.path}')
|
|
92
92
|
redirect_test_io { @pid = fork { exec 'unicorn_rails', "-l#@addr:#@port" } }
|
93
93
|
wait_master_ready("test_stderr.#$$.log")
|
94
94
|
|
95
|
-
# temp dirs exist
|
96
|
-
tmp_dirs.each { |dir| assert(File.directory?("tmp/#{dir}")) }
|
97
|
-
|
98
95
|
# basic GET
|
99
96
|
res = Net::HTTP.get_response(URI.parse("http://#@addr:#@port/foo"))
|
100
97
|
assert_equal "FOO\n", res.body
|
@@ -102,6 +99,9 @@ logger Logger.new('#{COMMON_TMP.path}')
|
|
102
99
|
assert_equal "4", res['Content-Length']
|
103
100
|
assert_equal "200 OK", res['Status']
|
104
101
|
|
102
|
+
# temp dirs exist
|
103
|
+
tmp_dirs.each { |dir| assert(File.directory?("tmp/#{dir}")) }
|
104
|
+
|
105
105
|
# can we set cookies?
|
106
106
|
res = Net::HTTP.get_response(URI.parse("http://#@addr:#@port/foo/xcookie"))
|
107
107
|
assert_equal "200", res.code
|
data/test/test_helper.rb
CHANGED
data/test/unit/test_server.rb
CHANGED
data/test/unit/test_signals.rb
CHANGED
@@ -40,6 +40,10 @@ class SignalsTest < Test::Unit::TestCase
|
|
40
40
|
@server = nil
|
41
41
|
end
|
42
42
|
|
43
|
+
def teardown
|
44
|
+
reset_sig_handlers
|
45
|
+
end
|
46
|
+
|
43
47
|
def test_worker_dies_on_dead_master
|
44
48
|
pid = fork {
|
45
49
|
app = lambda { |env| [ 200, {'X-Pid' => "#$$" }, [] ] }
|
@@ -190,7 +194,7 @@ class SignalsTest < Test::Unit::TestCase
|
|
190
194
|
killer = fork { loop { Process.kill(:HUP, pid); sleep(0.0001) } }
|
191
195
|
buf = ' ' * @bs
|
192
196
|
@count.times { sock.syswrite(buf) }
|
193
|
-
Process.kill(:
|
197
|
+
Process.kill(:KILL, killer)
|
194
198
|
Process.waitpid2(killer)
|
195
199
|
redirect_test_io { @server.stop(true) }
|
196
200
|
# can't check for == since pending signals get merged
|
data/test/unit/test_tee_input.rb
CHANGED
@@ -71,8 +71,8 @@ class TestTeeInput < Test::Unit::TestCase
|
|
71
71
|
ti = Unicorn::TeeInput.new(@rd, @env, @parser, @buf)
|
72
72
|
assert_equal 0, @parser.content_length
|
73
73
|
assert @parser.body_eof?
|
74
|
-
assert_equal StringIO, ti.
|
75
|
-
assert_equal 0, ti.
|
74
|
+
assert_equal StringIO, ti.tmp.class
|
75
|
+
assert_equal 0, ti.tmp.pos
|
76
76
|
assert_equal 5, ti.size
|
77
77
|
assert_equal 'hello', ti.read
|
78
78
|
assert_equal '', ti.read
|
@@ -99,8 +99,8 @@ class TestTeeInput < Test::Unit::TestCase
|
|
99
99
|
ti = Unicorn::TeeInput.new(@rd, @env, @parser, @buf)
|
100
100
|
assert_equal 0, @parser.content_length
|
101
101
|
assert @parser.body_eof?
|
102
|
-
assert_kind_of File, ti.
|
103
|
-
assert_equal 0, ti.
|
102
|
+
assert_kind_of File, ti.tmp
|
103
|
+
assert_equal 0, ti.tmp.pos
|
104
104
|
assert_equal Unicorn::Const::MAX_BODY + 1, ti.size
|
105
105
|
end
|
106
106
|
|
@@ -125,9 +125,9 @@ class TestTeeInput < Test::Unit::TestCase
|
|
125
125
|
ti = Unicorn::TeeInput.new(@rd, @env, @parser, @buf)
|
126
126
|
assert_equal Unicorn::Const::MAX_BODY, @parser.content_length
|
127
127
|
assert ! @parser.body_eof?
|
128
|
-
assert_kind_of File, ti.
|
129
|
-
assert_equal 0, ti.
|
130
|
-
assert_equal 1, ti.
|
128
|
+
assert_kind_of File, ti.tmp
|
129
|
+
assert_equal 0, ti.tmp.pos
|
130
|
+
assert_equal 1, ti.tmp.size
|
131
131
|
assert_equal Unicorn::Const::MAX_BODY + 1, ti.size
|
132
132
|
nr = Unicorn::Const::MAX_BODY / 4
|
133
133
|
pid = fork {
|
@@ -165,19 +165,19 @@ class TestTeeInput < Test::Unit::TestCase
|
|
165
165
|
@wr.close
|
166
166
|
ti = Unicorn::TeeInput.new(@rd, @env, @parser, @buf)
|
167
167
|
assert_nil @parser.content_length
|
168
|
-
assert_nil ti.
|
168
|
+
assert_nil ti.len
|
169
169
|
assert ! @parser.body_eof?
|
170
170
|
assert_equal 25, ti.size
|
171
171
|
assert @parser.body_eof?
|
172
|
-
assert_equal 25, ti.
|
173
|
-
assert_equal 0, ti.
|
172
|
+
assert_equal 25, ti.len
|
173
|
+
assert_equal 0, ti.tmp.pos
|
174
174
|
assert_nothing_raised { ti.rewind }
|
175
|
-
assert_equal 0, ti.
|
175
|
+
assert_equal 0, ti.tmp.pos
|
176
176
|
assert_equal 'abcdeabcdeabcdeabcde', ti.read(20)
|
177
|
-
assert_equal 20, ti.
|
177
|
+
assert_equal 20, ti.tmp.pos
|
178
178
|
assert_nothing_raised { ti.rewind }
|
179
|
-
assert_equal 0, ti.
|
180
|
-
assert_kind_of File, ti.
|
179
|
+
assert_equal 0, ti.tmp.pos
|
180
|
+
assert_kind_of File, ti.tmp
|
181
181
|
status = nil
|
182
182
|
assert_nothing_raised { pid, status = Process.waitpid2(pid) }
|
183
183
|
assert status.success?
|
@@ -203,7 +203,7 @@ class TestTeeInput < Test::Unit::TestCase
|
|
203
203
|
}
|
204
204
|
ti = Unicorn::TeeInput.new(@rd, @env, @parser, @buf)
|
205
205
|
assert_nil @parser.content_length
|
206
|
-
assert_nil ti.
|
206
|
+
assert_nil ti.len
|
207
207
|
assert ! @parser.body_eof?
|
208
208
|
chunks.each do |chunk|
|
209
209
|
wr.write('.')
|
data/test/unit/test_upload.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: unicorn
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.97.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Unicorn hackers
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-
|
12
|
+
date: 2010-03-01 00:00:00 +00:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -98,8 +98,10 @@ files:
|
|
98
98
|
- examples/echo.ru
|
99
99
|
- examples/git.ru
|
100
100
|
- examples/init.sh
|
101
|
+
- examples/logger_mp_safe.rb
|
101
102
|
- examples/nginx.conf
|
102
103
|
- examples/unicorn.conf.rb
|
104
|
+
- ext/unicorn_http/CFLAGS
|
103
105
|
- ext/unicorn_http/c_util.h
|
104
106
|
- ext/unicorn_http/common_field_optimization.h
|
105
107
|
- ext/unicorn_http/ext_help.h
|
@@ -126,6 +128,19 @@ files:
|
|
126
128
|
- man/man1/unicorn.1
|
127
129
|
- man/man1/unicorn_rails.1
|
128
130
|
- setup.rb
|
131
|
+
- t/.gitignore
|
132
|
+
- t/GNUmakefile
|
133
|
+
- t/README
|
134
|
+
- t/bin/content-md5-put
|
135
|
+
- t/bin/sha1sum.rb
|
136
|
+
- t/bin/unused_listen
|
137
|
+
- t/bin/utee
|
138
|
+
- t/env.ru
|
139
|
+
- t/my-tap-lib.sh
|
140
|
+
- t/t0000-http-basic.sh
|
141
|
+
- t/t0001-reload-bad-config.sh
|
142
|
+
- t/t0002-config-conflict.sh
|
143
|
+
- t/test-lib.sh
|
129
144
|
- test/aggregate.rb
|
130
145
|
- test/benchmark/README
|
131
146
|
- test/benchmark/dd.ru
|