rainbows 0.2.0 → 0.3.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.
Files changed (71) hide show
  1. data/GIT-VERSION-GEN +1 -1
  2. data/TODO +15 -0
  3. data/TUNING +14 -0
  4. data/lib/rainbows.rb +7 -0
  5. data/lib/rainbows/app_pool.rb +4 -3
  6. data/lib/rainbows/base.rb +17 -11
  7. data/lib/rainbows/const.rb +5 -1
  8. data/lib/rainbows/dev_fd_response.rb +69 -0
  9. data/lib/rainbows/http_response.rb +1 -0
  10. data/lib/rainbows/http_server.rb +2 -0
  11. data/lib/rainbows/rev.rb +136 -43
  12. data/lib/rainbows/revactor.rb +6 -14
  13. data/lib/rainbows/thread_pool.rb +11 -13
  14. data/lib/rainbows/thread_spawn.rb +4 -4
  15. data/local.mk.sample +9 -1
  16. data/t/GNUmakefile +4 -4
  17. data/t/README +1 -1
  18. data/t/async-response-no-autochunk.ru +24 -0
  19. data/t/async-response.ru +13 -0
  20. data/t/bin/content-md5-put +1 -1
  21. data/t/bin/utee +12 -0
  22. data/t/env.ru +3 -0
  23. data/t/large-file-response.ru +13 -0
  24. data/t/lib-async-response-no-autochunk.sh +6 -0
  25. data/t/lib-async-response.sh +45 -0
  26. data/t/lib-graceful.sh +40 -0
  27. data/t/lib-input-trailer.sh +63 -0
  28. data/t/lib-large-file-response.sh +45 -0
  29. data/t/lib-parser-error.sh +29 -0
  30. data/t/{t3100-revactor-tee-input.sh → lib-rack-input-hammer.sh} +3 -9
  31. data/t/lib-reopen-logs.sh +60 -0
  32. data/t/lib-simple-http.sh +92 -0
  33. data/t/sleep.ru +13 -6
  34. data/t/t0000-basic.sh +1 -36
  35. data/t/t1000-thread-pool-basic.sh +1 -41
  36. data/t/t1002-thread-pool-graceful.sh +1 -36
  37. data/t/t1003-thread-pool-reopen-logs.sh +2 -0
  38. data/t/t1004-thread-pool-async-response.sh +45 -0
  39. data/t/t1005-thread-pool-large-file-response.sh +45 -0
  40. data/t/t1006-thread-pool-async-response-no-autochunk.sh +6 -0
  41. data/t/t1100-thread-pool-rack-input.sh +2 -0
  42. data/t/t1101-thread-pool-input-trailer.sh +2 -0
  43. data/t/t2000-thread-spawn-basic.sh +1 -37
  44. data/t/t2002-thread-spawn-graceful.sh +1 -36
  45. data/t/t2003-thread-spawn-reopen-logs.sh +2 -0
  46. data/t/t2004-thread-spawn-async-response.sh +45 -0
  47. data/t/t2005-thread-spawn-large-file-response.sh +45 -0
  48. data/t/t2006-thread-spawn-async-response-no-autochunk.sh +6 -0
  49. data/t/t2100-thread-spawn-rack-input.sh +2 -0
  50. data/t/t2101-thread-spawn-input-trailer.sh +2 -0
  51. data/t/t3000-revactor-basic.sh +1 -39
  52. data/t/t3002-revactor-graceful.sh +1 -37
  53. data/t/t3003-revactor-reopen-logs.sh +1 -53
  54. data/t/t3004-revactor-async-response.sh +45 -0
  55. data/t/t3005-revactor-large-file-response.sh +2 -0
  56. data/t/t3006-revactor-async-response-no-autochunk.sh +6 -0
  57. data/t/t3100-revactor-rack-input.sh +2 -0
  58. data/t/t3101-revactor-rack-input-trailer.sh +2 -0
  59. data/t/t4000-rev-basic.sh +1 -50
  60. data/t/t4002-rev-graceful.sh +1 -51
  61. data/t/t4003-rev-parser-error.sh +1 -33
  62. data/t/t4003-rev-reopen-logs.sh +2 -0
  63. data/t/t4004-rev-async-response.sh +45 -0
  64. data/t/t4005-rev-large-file-response.sh +2 -0
  65. data/t/t4006-rev-async-response-no-autochunk.sh +6 -0
  66. data/t/t4100-rev-rack-input.sh +1 -43
  67. data/t/t4101-rev-rack-input-trailer.sh +1 -50
  68. data/t/t9000-rack-app-pool.sh +2 -3
  69. data/t/test-lib.sh +80 -18
  70. metadata +39 -4
  71. data/t/t3001-revactor-pipeline.sh +0 -46
@@ -0,0 +1,6 @@
1
+ #!/bin/sh
2
+ CONFIG_RU=async-response-no-autochunk.ru
3
+ . ./lib-async-response.sh
4
+ test x"$(cat $a)" = x0123456789
5
+ test x"$(cat $b)" = x0123456789
6
+ test x"$(cat $c)" = x0123456789
@@ -0,0 +1,2 @@
1
+ #!/bin/sh
2
+ . ./lib-rack-input-hammer.sh
@@ -0,0 +1,2 @@
1
+ #!/bin/sh
2
+ . ./lib-input-trailer.sh
data/t/t4000-rev-basic.sh CHANGED
@@ -1,51 +1,2 @@
1
1
  #!/bin/sh
2
- . ./test-lib.sh
3
- require_rev
4
-
5
- eval $(unused_listen)
6
- rtmpfiles unicorn_config pid r_err r_out tmp fifo ok
7
- rm -f $fifo
8
- mkfifo $fifo
9
-
10
- nr_client=30
11
-
12
- cat > $unicorn_config <<EOF
13
- listen "$listen"
14
- pid "$pid"
15
- stderr_path "$r_err"
16
- stdout_path "$r_out"
17
- Rainbows! do
18
- use :Rev
19
- worker_connections 50
20
- end
21
- EOF
22
-
23
- rainbows -D t4000.ru -c $unicorn_config
24
- wait_for_pid $pid
25
-
26
- echo "single request"
27
- curl -sSfv http://$listen/
28
-
29
- echo "two requests with keepalive"
30
- curl -sSfv http://$listen/a http://$listen/b > $tmp 2>&1
31
- grep 'Re-using existing connection' < $tmp
32
-
33
- echo "pipelining partial requests"
34
- req='GET / HTTP/1.1\r\nHost: example.com\r\n'
35
- (
36
- printf "$req"'\r\n'"$req"
37
- cat $fifo > $tmp &
38
- sleep 1
39
- printf 'Connection: close\r\n\r\n'
40
- wait
41
- echo ok > $ok
42
- ) | socat - TCP:$listen > $fifo
43
-
44
- kill $(cat $pid)
45
-
46
- test 2 -eq $(grep '^HTTP/1.1' $tmp | wc -l)
47
- test 2 -eq $(grep '^HTTP/1.1 200 OK' $tmp | wc -l)
48
- test 1 -eq $(grep '^Connection: keep-alive' $tmp | wc -l)
49
- test 1 -eq $(grep '^Connection: close' $tmp | wc -l)
50
- test x"$(cat $ok)" = xok
51
- ! grep Error $r_err
2
+ . ./lib-simple-http.sh
@@ -1,52 +1,2 @@
1
1
  #!/bin/sh
2
- . ./test-lib.sh
3
- require_rev
4
-
5
- eval $(unused_listen)
6
- rtmpfiles unicorn_config tmp pid r_err r_out out
7
- nr_client=10
8
- cat > $unicorn_config <<EOF
9
- listen "$listen"
10
- stderr_path "$r_err"
11
- stdout_path "$r_out"
12
- pid "$pid"
13
- Rainbows! do
14
- use :Rev
15
- end
16
- EOF
17
-
18
- rainbows -D sleep.ru -c $unicorn_config
19
- wait_for_pid $pid
20
-
21
- for i in $(awk "BEGIN{for(i=0;i<$nr_client;++i) print i}" </dev/null)
22
- do
23
- (
24
- rtmpfiles fifo tmp
25
- rm -f $fifo
26
- mkfifo $fifo
27
- (
28
- printf 'GET /0 HTTP/1.1\r\n'
29
- cat $fifo > $tmp &
30
- sleep 1
31
- printf 'Host: example.com\r\n'
32
- sleep 1
33
- printf 'Connection: close\r\n'
34
- sleep 1
35
- printf '\r\n'
36
- wait
37
- ) | socat - TCP:$listen > $fifo
38
- fgrep 'Hello' $tmp >> $out || :
39
- rm -f $fifo $tmp
40
- ) &
41
- done
42
-
43
- sleep 2 # potentially racy :<
44
- kill -QUIT $(cat $pid)
45
- wait
46
-
47
- test x"$(wc -l < $out)" = x$nr_client
48
- nr=$(sort < $out | uniq | wc -l)
49
- test "$nr" -eq 1
50
-
51
- test x$(sort < $out | uniq) = xHello
52
- ! grep Error $r_err
2
+ . ./lib-graceful.sh
@@ -1,34 +1,2 @@
1
1
  #!/bin/sh
2
- . ./test-lib.sh
3
- require_rev
4
-
5
- eval $(unused_listen)
6
- rtmpfiles unicorn_config pid r_err r_out tmp fifo ok
7
- rm -f $fifo
8
- mkfifo $fifo
9
-
10
- cat > $unicorn_config <<EOF
11
- listen "$listen"
12
- pid "$pid"
13
- stderr_path "$r_err"
14
- stdout_path "$r_out"
15
- Rainbows! do
16
- use :Rev
17
- end
18
- EOF
19
-
20
- rainbows -D t4000.ru -c $unicorn_config
21
- wait_for_pid $pid
22
-
23
- (
24
- printf 'GET / HTTP/1/1\r\nHost: example.com\r\n\r\n'
25
- cat $fifo > $tmp &
26
- wait
27
- echo ok > $ok
28
- ) | socat - TCP:$listen > $fifo
29
-
30
- kill $(cat $pid)
31
-
32
- dbgcat tmp
33
- grep -F 'HTTP/1.1 400 Bad Request' $tmp
34
- ! grep Error $r_err
2
+ . ./lib-parser-error.sh
@@ -0,0 +1,2 @@
1
+ #!/bin/sh
2
+ . ./lib-reopen-logs.sh
@@ -0,0 +1,45 @@
1
+ CONFIG_RU=${CONFIG_RU-'async-response.ru'}
2
+ . ./test-lib.sh
3
+ echo "async response for model=$model"
4
+ eval $(unused_listen)
5
+ rtmpfiles unicorn_config a b c r_err r_out pid curl_err
6
+
7
+ cat > $unicorn_config <<EOF
8
+ listen "$listen"
9
+ stderr_path "$r_err"
10
+ stdout_path "$r_out"
11
+ pid "$pid"
12
+ Rainbows! { use :$model }
13
+ EOF
14
+
15
+ # can't load Rack::Lint here since it'll cause Rev to slurp
16
+ rainbows -E none -D $CONFIG_RU -c $unicorn_config
17
+ wait_for_pid $pid
18
+
19
+ t0=$(date +%s)
20
+ ( curl --no-buffer -sSf http://$listen/ 2>> $curl_err | utee $a) &
21
+ ( curl --no-buffer -sSf http://$listen/ 2>> $curl_err | utee $b) &
22
+ ( curl --no-buffer -sSf http://$listen/ 2>> $curl_err | utee $c) &
23
+ wait
24
+ t1=$(date +%s)
25
+
26
+ rainbows_pid=$(cat $pid)
27
+ kill -QUIT $rainbows_pid
28
+ elapsed=$(( $t1 - $t0 ))
29
+ echo "elapsed=$elapsed < 30"
30
+ test $elapsed -lt 30
31
+
32
+ dbgcat a
33
+ dbgcat b
34
+ dbgcat c
35
+ dbgcat r_err
36
+ dbgcat curl_err
37
+ test ! -s $curl_err
38
+ check_stderr
39
+
40
+ while kill -0 $rainbows_pid >/dev/null 2>&1
41
+ do
42
+ sleep 1
43
+ done
44
+
45
+ dbgcat r_err
@@ -0,0 +1,2 @@
1
+ #!/bin/sh
2
+ . ./lib-large-file-response.sh
@@ -0,0 +1,6 @@
1
+ #!/bin/sh
2
+ CONFIG_RU=async-response-no-autochunk.ru
3
+ . ./lib-async-response.sh
4
+ test x"$(cat $a)" = x0123456789
5
+ test x"$(cat $b)" = x0123456789
6
+ test x"$(cat $c)" = x0123456789
@@ -1,44 +1,2 @@
1
1
  #!/bin/sh
2
- nr_client=${nr_client-25}
3
- nr=${nr-50}
4
-
5
- . ./test-lib.sh
6
- require_rev
7
- test -r random_blob || die "random_blob required, run with 'make $0'"
8
-
9
- eval $(unused_listen)
10
- rtmpfiles unicorn_config curl_out curl_err r_err r_out pid
11
-
12
- cat > $unicorn_config <<EOF
13
- listen "$listen"
14
- pid "$pid"
15
- stderr_path "$r_err"
16
- stdout_path "$r_out"
17
- Rainbows! do
18
- use :Rev
19
- worker_connections $nr
20
- end
21
- EOF
22
-
23
- echo pid=$pid
24
- rainbows -D sha1.ru -c $unicorn_config
25
- wait_for_pid $pid
26
-
27
- start=$(date +%s)
28
- for i in $(awk "BEGIN{for(i=0;i<$nr_client;++i) print i}" </dev/null)
29
- do
30
- (
31
- curl -sSf -T- http://$listen/$i \
32
- < random_blob >> $curl_out 2>> $curl_err
33
- ) &
34
- done
35
- wait
36
- echo elapsed=$(( $(date +%s) - $start ))
37
-
38
- kill $(cat $pid)
39
- test $nr_client -eq $(wc -l < $curl_out)
40
- test 1 -eq $(sort < $curl_out | uniq | wc -l)
41
- blob_sha1=$( expr "$(sha1sum < random_blob)" : '\([a-f0-9]\+\)')
42
- echo blob_sha1=$blob_sha1
43
- test x"$blob_sha1" = x"$(sort < $curl_out | uniq)"
44
- ! grep Error $r_err
2
+ . ./lib-rack-input-hammer.sh
@@ -1,51 +1,2 @@
1
1
  #!/bin/sh
2
- nr_client=${nr_client-25}
3
- nr=${nr-50}
4
-
5
- . ./test-lib.sh
6
- require_rev
7
- test -r random_blob || die "random_blob required, run with 'make $0'"
8
-
9
- eval $(unused_listen)
10
- rtmpfiles unicorn_config tmp r_err r_out pid fifo ok
11
- rm -f $fifo
12
- mkfifo $fifo
13
-
14
- cat > $unicorn_config <<EOF
15
- listen "$listen"
16
- pid "$pid"
17
- stderr_path "$r_err"
18
- stdout_path "$r_out"
19
- Rainbows! do
20
- use :Rev
21
- end
22
- EOF
23
-
24
- rainbows -D content-md5.ru -c $unicorn_config
25
- wait_for_pid $pid
26
-
27
- echo "small blob"
28
- (
29
- echo hello world | content-md5-put
30
- cat $fifo > $tmp &
31
- wait
32
- echo ok > $ok
33
- ) | socat - TCP:$listen | tee $fifo
34
-
35
- fgrep 'HTTP/1.1 200 OK' $tmp
36
- test xok = x"$(cat $ok)"
37
- ! grep Error $r_err
38
-
39
-
40
- echo "big blob"
41
- (
42
- content-md5-put < random_blob
43
- cat $fifo > $tmp &
44
- wait
45
- echo ok > $ok
46
- ) | socat - TCP:$listen | tee $fifo
47
-
48
- fgrep 'HTTP/1.1 200 OK' $tmp
49
- test xok = x"$(cat $ok)"
50
- ! grep Error $r_err
51
- kill $(cat $pid)
2
+ . ./lib-input-trailer.sh
@@ -31,7 +31,6 @@ echo elapsed=$(( $(date +%s) - $start ))
31
31
  kill $(cat $pid)
32
32
 
33
33
  test $APP_POOL_SIZE -eq $(sort < $curl_out | uniq | wc -l)
34
- ! test -s $curl_err
34
+ test ! -s $curl_err
35
35
 
36
- ! grep Error $r_err
37
- #
36
+ check_stderr
data/t/test-lib.sh CHANGED
@@ -1,11 +1,36 @@
1
1
  #!/bin/sh
2
2
  # Copyright (c) 2009 Rainbows! developers
3
3
 
4
- set -o pipefail >/dev/null 2>&1 || : # non-POSIX, but useful in ksh/bash
4
+ # pipefail is non-POSIX, but useful in ksh/bash
5
+ (
6
+ set +e
7
+ set -o pipefail 2>/dev/null
8
+ )
9
+ if test $? -eq 0
10
+ then
11
+ set -o pipefail
12
+ else
13
+ echo >&2 "WARNING: your shell does not understand pipefail"
14
+ fi
15
+
5
16
  set -e
6
- set -u
17
+
7
18
  T=$(basename $0)
8
- ruby="${ruby-ruby}"
19
+ if test -z "$model"
20
+ then
21
+ case $T in
22
+ t1???-thread-pool-*.sh) model=ThreadPool ;;
23
+ t2???-thread-spawn-*.sh) model=ThreadSpawn ;;
24
+ t3???-revactor-*.sh) model=Revactor ;;
25
+ t4???-rev-*.sh) model=Rev ;;
26
+ *) model=any ;;
27
+ esac
28
+ fi
29
+
30
+ ruby="${ruby-'ruby'}"
31
+ RUBY_VERSION=${RUBY_VERSION-$($ruby -e 'puts RUBY_VERSION')}
32
+ t_pfx=$PWD/trash/$T-$RUBY_VERSION
33
+ set -u
9
34
 
10
35
  # ensure a sane environment
11
36
  TZ=UTC LC_ALL=C LANG=C
@@ -17,8 +42,22 @@ die () {
17
42
  exit 1
18
43
  }
19
44
 
20
- _TEST_RM_LIST=""
21
- trap 'rm -f $_TEST_RM_LIST' 0
45
+ _test_on_exit () {
46
+ code=$?
47
+ case $code in
48
+ 0)
49
+ echo "ok $T"
50
+ rm -f $_TEST_OK_RM_LIST
51
+ ;;
52
+ *) echo "not ok $T" ;;
53
+ esac
54
+ rm -f $_TEST_RM_LIST
55
+ exit $code
56
+ }
57
+
58
+ _TEST_RM_LIST=
59
+ _TEST_OK_RM_LIST=
60
+ trap _test_on_exit EXIT
22
61
  PATH=$PWD/bin:$PATH
23
62
  export PATH
24
63
 
@@ -34,18 +73,12 @@ wait_for_pid () {
34
73
  done
35
74
  }
36
75
 
37
- require_revactor () {
38
- if ! $ruby -rrevactor -e "puts Revactor::VERSION" >/dev/null 2>&1
76
+ require_check () {
77
+ lib=$1
78
+ const=$2
79
+ if ! $ruby -r$lib -e "puts $const" >/dev/null 2>&1
39
80
  then
40
- echo >&2 "skipping $T since we don't have Revactor"
41
- exit 0
42
- fi
43
- }
44
-
45
- require_rev() {
46
- if ! $ruby -rrev -e "puts Rev::VERSION" >/dev/null 2>&1
47
- then
48
- echo >&2 "skipping $T since we don't have Rev"
81
+ echo >&2 "skipping $T since we don't have $lib"
49
82
  exit 0
50
83
  fi
51
84
  }
@@ -55,14 +88,43 @@ require_rev() {
55
88
  rtmpfiles () {
56
89
  for id in "$@"
57
90
  do
58
- _tmp=$(mktemp -t rainbows.$$.$id.XXXXXXXX)
91
+ name=$id
92
+ _tmp=$t_pfx.$id
93
+ > $_tmp
59
94
  eval "$id=$_tmp"
60
- _TEST_RM_LIST="$_TEST_RM_LIST $_tmp"
95
+ _TEST_OK_RM_LIST="$_TEST_OK_RM_LIST $_tmp"
96
+
97
+ case $name in
98
+ *fifo)
99
+ rm -f $_tmp
100
+ mkfifo $_tmp
101
+ _TEST_RM_LIST="$_TEST_RM_LIST $_tmp"
102
+ ;;
103
+ esac
61
104
  done
62
105
  }
63
106
 
64
107
  dbgcat () {
65
108
  id=$1
66
109
  eval '_file=$'$id
110
+ echo "==> $id <=="
67
111
  sed -e "s/^/$id:/" < $_file
68
112
  }
113
+
114
+ check_stderr () {
115
+ set +u
116
+ _r_err=${1-${r_err}}
117
+ set -u
118
+ if grep Error $_r_err
119
+ then
120
+ die "Errors found in $_r_err"
121
+ elif grep SIGKILL $_r_err
122
+ then
123
+ die "SIGKILL found in $_r_err"
124
+ fi
125
+ }
126
+
127
+ case $model in
128
+ Rev) require_check rev Rev::VERSION ;;
129
+ Revactor) require_check revactor Revactor::VERSION ;;
130
+ esac