regurgitator 0.0.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/.document +5 -0
- data/.gitignore +14 -0
- data/.manifest +46 -0
- data/.wrongdoc.yml +4 -0
- data/COPYING +674 -0
- data/ChangeLog +499 -0
- data/GIT-VERSION-FILE +1 -0
- data/GIT-VERSION-GEN +40 -0
- data/GNUmakefile +8 -0
- data/LATEST +1 -0
- data/LICENSE +18 -0
- data/NEWS +1 -0
- data/README +49 -0
- data/examples/domain_host.ru +6 -0
- data/examples/domain_path.ru +5 -0
- data/examples/one_domain.ru +6 -0
- data/lib/regurgitator.rb +43 -0
- data/lib/regurgitator/device.rb +79 -0
- data/lib/regurgitator/domain.rb +37 -0
- data/lib/regurgitator/domain_host.rb +43 -0
- data/lib/regurgitator/domain_path.rb +33 -0
- data/lib/regurgitator/endpoint.rb +97 -0
- data/lib/regurgitator/file_info.rb +53 -0
- data/lib/regurgitator/file_request.rb +48 -0
- data/lib/regurgitator/local.rb +89 -0
- data/lib/regurgitator/local_file.rb +61 -0
- data/lib/regurgitator/one_domain.rb +33 -0
- data/lib/regurgitator/server_settings.rb +55 -0
- data/pkg.mk +175 -0
- data/regurgitator.gemspec +30 -0
- data/setup.rb +1586 -0
- data/t/.gitignore +7 -0
- data/t/GNUmakefile +65 -0
- data/t/bin/unused_listen +40 -0
- data/t/domain_host.ru +8 -0
- data/t/domain_path.ru +5 -0
- data/t/file.ru +2 -0
- data/t/fixtures.sql +59 -0
- data/t/my-tap-lib.sh +200 -0
- data/t/one_domain.ru +8 -0
- data/t/t0001-domain_path.sh +67 -0
- data/t/t0002-domain_host.sh +71 -0
- data/t/t0003-one_domain.sh +52 -0
- data/t/test-lib.sh +119 -0
- data/test/test_local.rb +78 -0
- data/test/test_server_settings.rb +37 -0
- metadata +191 -0
data/t/.gitignore
ADDED
data/t/GNUmakefile
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
# we can run tests in parallel with GNU make
|
2
|
+
|
3
|
+
all::
|
4
|
+
|
5
|
+
pid := $(shell echo $$PPID)
|
6
|
+
|
7
|
+
RUBY = ruby
|
8
|
+
my_lib := $(shell cd ../lib && pwd)
|
9
|
+
-include ../local.mk
|
10
|
+
ifeq ($(RUBY_VERSION),)
|
11
|
+
RUBY_VERSION := $(shell $(RUBY) -e 'puts RUBY_VERSION')
|
12
|
+
endif
|
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_VERSION RUBY_ENGINE
|
19
|
+
ifeq ($(RUBYLIB),)
|
20
|
+
RUBYLIB := $(my_lib)
|
21
|
+
else
|
22
|
+
RUBYLIB := $(my_lib):$(RUBYLIB)
|
23
|
+
endif
|
24
|
+
export RUBYLIB
|
25
|
+
|
26
|
+
T = $(wildcard t[0-9][0-9][0-9][0-9]-*.sh)
|
27
|
+
|
28
|
+
all:: $(T)
|
29
|
+
|
30
|
+
# can't rely on "set -o pipefail" since we don't require bash or ksh93 :<
|
31
|
+
t_pfx = trash/$@-$(RUBY_ENGINE)-$(RUBY_VERSION)
|
32
|
+
TEST_OPTS =
|
33
|
+
# TRACER = strace -f -o $(t_pfx).strace -s 100000
|
34
|
+
# TRACER = /usr/bin/time -o $(t_pfx).time
|
35
|
+
|
36
|
+
ifdef V
|
37
|
+
ifeq ($(V),2)
|
38
|
+
TEST_OPTS += --trace
|
39
|
+
else
|
40
|
+
TEST_OPTS += --verbose
|
41
|
+
endif
|
42
|
+
endif
|
43
|
+
|
44
|
+
random_blob:
|
45
|
+
dd if=/dev/urandom bs=1M count=1 of=$@.$(pid)
|
46
|
+
mv $@.$(pid) $@
|
47
|
+
|
48
|
+
$(T): random_blob
|
49
|
+
|
50
|
+
dependencies := curl sqlite3
|
51
|
+
deps := $(addprefix .dep+,$(dependencies))
|
52
|
+
$(deps): dep_bin = $(lastword $(subst +, ,$@))
|
53
|
+
$(deps):
|
54
|
+
@which $(dep_bin) > $@.$(pid) 2>/dev/null || :
|
55
|
+
@test -s $@.$(pid) || \
|
56
|
+
{ echo >&2 "E '$(dep_bin)' not found in PATH=$(PATH)"; exit 1; }
|
57
|
+
@mv $@.$(pid) $@
|
58
|
+
|
59
|
+
$(T): $(deps)
|
60
|
+
$(TRACER) $(SHELL) $(SH_TEST_OPTS) $@ $(TEST_OPTS)
|
61
|
+
|
62
|
+
clean:
|
63
|
+
$(RM) -r trash/*.log trash/*.code test-bin-$(RUBY_VERSION)
|
64
|
+
|
65
|
+
.PHONY: $(T) clean
|
data/t/bin/unused_listen
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# -*- encoding: binary -*-
|
3
|
+
# this is to remain compatible with the unused_port function in the
|
4
|
+
# Unicorn test/test_helper.rb file
|
5
|
+
require 'socket'
|
6
|
+
require 'tmpdir'
|
7
|
+
|
8
|
+
default_port = 8080
|
9
|
+
addr = ENV['UNICORN_TEST_ADDR'] || '127.0.0.1'
|
10
|
+
retries = 100
|
11
|
+
base = 5000
|
12
|
+
port = sock = lock_path = nil
|
13
|
+
|
14
|
+
begin
|
15
|
+
begin
|
16
|
+
port = base + rand(32768 - base)
|
17
|
+
while port == default_port
|
18
|
+
port = base + rand(32768 - base)
|
19
|
+
end
|
20
|
+
|
21
|
+
sock = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
|
22
|
+
sock.bind(Socket.pack_sockaddr_in(port, addr))
|
23
|
+
sock.listen(5)
|
24
|
+
rescue Errno::EADDRINUSE, Errno::EACCES
|
25
|
+
sock.close rescue nil
|
26
|
+
retry if (retries -= 1) >= 0
|
27
|
+
end
|
28
|
+
|
29
|
+
# since we'll end up closing the random port we just got, there's a race
|
30
|
+
# condition could allow the random port we just chose to reselect itself
|
31
|
+
# when running tests in parallel with gmake. Create a lock file while
|
32
|
+
# we have the port here to ensure that does not happen.
|
33
|
+
lock_path = "#{Dir::tmpdir}/unicorn_test.#{addr}:#{port}.lock"
|
34
|
+
lock = File.open(lock_path, File::WRONLY|File::CREAT|File::EXCL, 0600)
|
35
|
+
rescue Errno::EEXIST
|
36
|
+
sock.close rescue nil
|
37
|
+
retry
|
38
|
+
end
|
39
|
+
sock.close rescue nil
|
40
|
+
puts %Q(listen=#{addr}:#{port} T_RM_LIST="$T_RM_LIST #{lock_path}")
|
data/t/domain_host.ru
ADDED
data/t/domain_path.ru
ADDED
data/t/file.ru
ADDED
data/t/fixtures.sql
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
CREATE TABLE domain (
|
2
|
+
dmid SMALLINT NOT NULL,
|
3
|
+
namespace VARCHAR(255),
|
4
|
+
PRIMARY KEY (dmid),
|
5
|
+
UNIQUE (namespace)
|
6
|
+
);
|
7
|
+
|
8
|
+
CREATE TABLE file (
|
9
|
+
fid INTEGER NOT NULL,
|
10
|
+
dmid SMALLINT NOT NULL,
|
11
|
+
dkey VARCHAR(255),
|
12
|
+
length INTEGER,
|
13
|
+
classid TINYINT NOT NULL,
|
14
|
+
devcount TINYINT NOT NULL,
|
15
|
+
UNIQUE (dmid, dkey),
|
16
|
+
PRIMARY KEY (fid)
|
17
|
+
);
|
18
|
+
|
19
|
+
CREATE TABLE host (
|
20
|
+
hostid MEDIUMINT NOT NULL PRIMARY KEY,
|
21
|
+
status VARCHAR(5),
|
22
|
+
http_port MEDIUMINT DEFAULT 7500,
|
23
|
+
http_get_port MEDIUMINT,
|
24
|
+
hostname VARCHAR(40),
|
25
|
+
hostip VARCHAR(15),
|
26
|
+
altip VARCHAR(15),
|
27
|
+
altmask VARCHAR(18),
|
28
|
+
UNIQUE (hostname),
|
29
|
+
UNIQUE (hostip),
|
30
|
+
UNIQUE (altip)
|
31
|
+
);
|
32
|
+
|
33
|
+
CREATE TABLE server_settings (
|
34
|
+
field VARCHAR(50) PRIMARY KEY,
|
35
|
+
value VARCHAR(255)
|
36
|
+
);
|
37
|
+
|
38
|
+
CREATE TABLE device (
|
39
|
+
devid MEDIUMINT NOT NULL,
|
40
|
+
hostid MEDIUMINT NOT NULL,
|
41
|
+
status VARCHAR(8),
|
42
|
+
weight MEDIUMINT DEFAULT 100,
|
43
|
+
mb_total MEDIUMINT,
|
44
|
+
mb_used MEDIUMINT,
|
45
|
+
mb_asof INTEGER,
|
46
|
+
PRIMARY KEY (devid)
|
47
|
+
);
|
48
|
+
|
49
|
+
CREATE TABLE file_on (
|
50
|
+
fid INTEGER NOT NULL,
|
51
|
+
devid MEDIUMINT NOT NULL,
|
52
|
+
PRIMARY KEY (fid, devid)
|
53
|
+
);
|
54
|
+
|
55
|
+
INSERT INTO host VALUES(1,'alive',7500,NULL,'localhost','127.0.0.1',NULL,NULL);
|
56
|
+
INSERT INTO device VALUES(1,1,'alive',100,99999,0,1234567890);
|
57
|
+
INSERT INTO domain VALUES(1,'d');
|
58
|
+
INSERT INTO file VALUES(1,1,'blah',0,0,1);
|
59
|
+
INSERT INTO file_on VALUES(1,1);
|
data/t/my-tap-lib.sh
ADDED
@@ -0,0 +1,200 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
# Copyright (c) 2009 Eric Wong <normalperson@yhbt.net>
|
3
|
+
#
|
4
|
+
# TAP-producing shell library for POSIX-compliant Bourne shells We do
|
5
|
+
# not _rely_ on Bourne Again features, though we will use "set -o
|
6
|
+
# pipefail" from ksh93 or bash 3 if available
|
7
|
+
#
|
8
|
+
# Only generic, non-project/non-language-specific stuff goes here. We
|
9
|
+
# only have POSIX dependencies for the core tests (without --verbose),
|
10
|
+
# though we'll enable useful non-POSIX things if they're available.
|
11
|
+
#
|
12
|
+
# This test library is intentionally unforgiving, it does not support
|
13
|
+
# skipping tests nor continuing after any failure. Any failures
|
14
|
+
# immediately halt execution as do any references to undefined
|
15
|
+
# variables.
|
16
|
+
#
|
17
|
+
# When --verbose is specified, we always prefix stdout/stderr
|
18
|
+
# output with "#" to avoid confusing TAP consumers. Otherwise
|
19
|
+
# the normal stdout/stderr streams are redirected to /dev/null
|
20
|
+
|
21
|
+
# dup normal stdout(fd=1) and stderr (fd=2) to fd=3 and fd=4 respectively
|
22
|
+
# normal TAP output goes to fd=3, nothing should go to fd=4
|
23
|
+
exec 3>&1 4>&2
|
24
|
+
|
25
|
+
# ensure a sane environment
|
26
|
+
TZ=UTC LC_ALL=C LANG=C
|
27
|
+
export LANG LC_ALL TZ
|
28
|
+
unset CDPATH
|
29
|
+
|
30
|
+
# pipefail is non-POSIX, but very useful in ksh93/bash
|
31
|
+
( set -o pipefail 2>/dev/null ) && set -o pipefail
|
32
|
+
|
33
|
+
SED=${SED-sed}
|
34
|
+
|
35
|
+
# Unlike other test frameworks, we are unforgiving and bail immediately
|
36
|
+
# on any failures. We do this because we're lazy about error handling
|
37
|
+
# and also because we believe anything broken should not be allowed to
|
38
|
+
# propagate throughout the rest of the test
|
39
|
+
set -e
|
40
|
+
set -u
|
41
|
+
|
42
|
+
# name of our test
|
43
|
+
T=${0##*/}
|
44
|
+
|
45
|
+
t_expect_nr=-1
|
46
|
+
t_nr=0
|
47
|
+
t_current=
|
48
|
+
t_complete=false
|
49
|
+
|
50
|
+
# list of files to remove unconditionally on exit
|
51
|
+
T_RM_LIST=
|
52
|
+
|
53
|
+
# list of files to remove only on successful exit
|
54
|
+
T_OK_RM_LIST=
|
55
|
+
|
56
|
+
# emit output to stdout, it'll be parsed by the TAP consumer
|
57
|
+
# so it must be TAP-compliant output
|
58
|
+
t_echo () {
|
59
|
+
echo >&3 "$@"
|
60
|
+
}
|
61
|
+
|
62
|
+
# emits non-parsed information to stdout, it will be prefixed with a '#'
|
63
|
+
# to not throw off TAP consumers
|
64
|
+
t_info () {
|
65
|
+
t_echo '#' "$@"
|
66
|
+
}
|
67
|
+
|
68
|
+
# exit with an error and print a diagnostic
|
69
|
+
die () {
|
70
|
+
echo >&2 "$@"
|
71
|
+
exit 1
|
72
|
+
}
|
73
|
+
|
74
|
+
# our at_exit handler, it'll fire for all exits except SIGKILL (unavoidable)
|
75
|
+
t_at_exit () {
|
76
|
+
code=$?
|
77
|
+
set +e
|
78
|
+
if test $code -eq 0
|
79
|
+
then
|
80
|
+
$t_complete || {
|
81
|
+
t_info "t_done not called"
|
82
|
+
code=1
|
83
|
+
}
|
84
|
+
elif test -n "$t_current"
|
85
|
+
then
|
86
|
+
t_echo "not ok $t_nr - $t_current"
|
87
|
+
fi
|
88
|
+
if test $t_expect_nr -ne -1
|
89
|
+
then
|
90
|
+
test $t_expect_nr -eq $t_nr || {
|
91
|
+
t_info "planned $t_expect_nr tests but ran $t_nr"
|
92
|
+
test $code -ne 0 || code=1
|
93
|
+
}
|
94
|
+
fi
|
95
|
+
$t_complete || {
|
96
|
+
t_info "unexpected test failure"
|
97
|
+
test $code -ne 0 || code=1
|
98
|
+
}
|
99
|
+
rm -f $T_RM_LIST
|
100
|
+
test $code -eq 0 && rm -f $T_OK_RM_LIST
|
101
|
+
set +x
|
102
|
+
exec >&3 2>&4
|
103
|
+
t_close_fds
|
104
|
+
exit $code
|
105
|
+
}
|
106
|
+
|
107
|
+
# close test-specific extra file descriptors
|
108
|
+
t_close_fds () {
|
109
|
+
exec 3>&- 4>&-
|
110
|
+
}
|
111
|
+
|
112
|
+
# call this at the start of your test to specify the number of tests
|
113
|
+
# you plan to run
|
114
|
+
t_plan () {
|
115
|
+
test "$1" -ge 1 || die "must plan at least one test"
|
116
|
+
test $t_expect_nr -eq -1 || die "tried to plan twice in one test"
|
117
|
+
t_expect_nr=$1
|
118
|
+
shift
|
119
|
+
t_echo 1..$t_expect_nr "#" "$@"
|
120
|
+
trap t_at_exit EXIT
|
121
|
+
}
|
122
|
+
|
123
|
+
_t_checkup () {
|
124
|
+
test $t_expect_nr -le 0 && die "no tests planned"
|
125
|
+
test -n "$t_current" && t_echo "ok $t_nr - $t_current"
|
126
|
+
true
|
127
|
+
}
|
128
|
+
|
129
|
+
# finalizes any previously test and starts a new one
|
130
|
+
t_begin () {
|
131
|
+
_t_checkup
|
132
|
+
t_nr=$(( $t_nr + 1 ))
|
133
|
+
t_current="$1"
|
134
|
+
|
135
|
+
# just in case somebody wanted to cheat us:
|
136
|
+
set -e
|
137
|
+
}
|
138
|
+
|
139
|
+
# finalizes the current test without starting a new one
|
140
|
+
t_end () {
|
141
|
+
_t_checkup
|
142
|
+
t_current=
|
143
|
+
}
|
144
|
+
|
145
|
+
# run this to signify the end of your test
|
146
|
+
t_done () {
|
147
|
+
_t_checkup
|
148
|
+
t_current=
|
149
|
+
t_complete=true
|
150
|
+
test $t_expect_nr -eq $t_nr || exit 1
|
151
|
+
exit 0
|
152
|
+
}
|
153
|
+
|
154
|
+
# create and assign named-pipes to variable _names_ passed to this function
|
155
|
+
t_fifos () {
|
156
|
+
for _id in "$@"
|
157
|
+
do
|
158
|
+
_name=$_id
|
159
|
+
_tmp=$(mktemp -t $T.$$.$_id.XXXXXXXX)
|
160
|
+
eval "$_id=$_tmp"
|
161
|
+
rm -f $_tmp
|
162
|
+
mkfifo $_tmp
|
163
|
+
T_RM_LIST="$T_RM_LIST $_tmp"
|
164
|
+
done
|
165
|
+
}
|
166
|
+
|
167
|
+
t_verbose=false t_trace=false
|
168
|
+
|
169
|
+
while test "$#" -ne 0
|
170
|
+
do
|
171
|
+
arg="$1"
|
172
|
+
shift
|
173
|
+
case $arg in
|
174
|
+
-v|--verbose) t_verbose=true ;;
|
175
|
+
--trace) t_trace=true t_verbose=true ;;
|
176
|
+
*) die "Unknown option: $arg" ;;
|
177
|
+
esac
|
178
|
+
done
|
179
|
+
|
180
|
+
# we always only setup stdout, nothing should end up in the "real" stderr
|
181
|
+
if $t_verbose
|
182
|
+
then
|
183
|
+
if test x"$(which mktemp 2>/dev/null)" = x
|
184
|
+
then
|
185
|
+
die "mktemp(1) not available for --verbose"
|
186
|
+
fi
|
187
|
+
t_fifos t_stdout t_stderr
|
188
|
+
|
189
|
+
(
|
190
|
+
# use a subshell so seds are not waitable
|
191
|
+
$SED -e 's/^/#: /' $t_stdout &
|
192
|
+
$SED -e 's/^/#! /' $t_stderr &
|
193
|
+
) &
|
194
|
+
exec > $t_stdout 2> $t_stderr
|
195
|
+
else
|
196
|
+
exec > /dev/null 2> /dev/null
|
197
|
+
fi
|
198
|
+
|
199
|
+
$t_trace && set -x
|
200
|
+
true
|
data/t/one_domain.ru
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
. ./test-lib.sh
|
3
|
+
t_plan 8 "DomainPath tests"
|
4
|
+
|
5
|
+
t_begin "setup" && {
|
6
|
+
setup domain_path.ru
|
7
|
+
}
|
8
|
+
|
9
|
+
t_begin "retrieve empty file" && {
|
10
|
+
test 0 -eq $(curl -sSvf 2> $curl_err http://$listen/d/blah | wc -c)
|
11
|
+
grep 'E[tT]ag: ' $curl_err && die "ETag not expected"
|
12
|
+
grep 'Last-Modified: ' $curl_err && die "Last-Modified not expected"
|
13
|
+
}
|
14
|
+
|
15
|
+
t_begin "retrieve missing file" && {
|
16
|
+
sqlite3 $db <<EOF
|
17
|
+
UPDATE file SET length = $random_blob_size;
|
18
|
+
EOF
|
19
|
+
ok=$(curl -sSvf 2> $curl_err http://$listen/d/blah || echo ok)
|
20
|
+
test ok = "$ok"
|
21
|
+
grep '\<404\>' $curl_err
|
22
|
+
}
|
23
|
+
|
24
|
+
t_begin "retrieve existing file" && {
|
25
|
+
dir=$TMPDIR/dev1/0/000/000
|
26
|
+
mkdir -p $dir
|
27
|
+
ln random_blob $dir/0000000001.fid
|
28
|
+
cksum="$(curl -sSvf 2> $curl_err http://$listen/d/blah | cksum)"
|
29
|
+
test "$cksum" = "$random_blob_cksum"
|
30
|
+
dbgcat curl_err
|
31
|
+
grep 'E[tT]ag: "1"' $curl_err
|
32
|
+
}
|
33
|
+
|
34
|
+
t_begin "reproxy existing file" && {
|
35
|
+
curl -sSvf -H 'X-Reproxy-Path: /reproxy' 2> $curl_err \
|
36
|
+
http://$listen/d/blah >/dev/null
|
37
|
+
dbgcat curl_err
|
38
|
+
uri=http://$rack_file_listen/dev1/0/000/000/0000000001.fid
|
39
|
+
grep '^< X-Accel-Redirect: /reproxy' $curl_err
|
40
|
+
grep '^< X-Reproxy-Content-Type: application/octet-stream' $curl_err
|
41
|
+
grep "^< Location: $uri" $curl_err
|
42
|
+
grep '^< X-Reproxy-Last-Modified: ' $curl_err
|
43
|
+
grep '^< Content-Length: 0' $curl_err
|
44
|
+
grep '^< Etag: "1"' $curl_err
|
45
|
+
}
|
46
|
+
|
47
|
+
t_begin "HEAD requests work" && {
|
48
|
+
curl -vsSfI > $curl_err http://$listen/d/blah
|
49
|
+
grep '^E[Tt]ag: "1"' $curl_err
|
50
|
+
grep "^Content-Length: $random_blob_size" $curl_err
|
51
|
+
}
|
52
|
+
|
53
|
+
t_begin "HEAD requests work with reproxy" && {
|
54
|
+
curl -vsSfI -H X-Reproxy-Path:/z > $curl_err http://$listen/d/blah
|
55
|
+
grep '^E[Tt]ag: "1"' $curl_err
|
56
|
+
grep "^Content-Length: $random_blob_size" $curl_err
|
57
|
+
grep '^X-Accel-Redirect:' $curl_err && die "unexpected reproxy header"
|
58
|
+
grep '^X-Reproxy' $curl_err && die "unexpected reproxy header"
|
59
|
+
grep '^Location:' $curl_err && die "unexpected reproxy header"
|
60
|
+
}
|
61
|
+
|
62
|
+
t_begin "kill servers" && {
|
63
|
+
kill -INT $rack_file_pid
|
64
|
+
kill -INT $rack_server_pid
|
65
|
+
}
|
66
|
+
|
67
|
+
t_done
|