-
Notifications
You must be signed in to change notification settings - Fork 4.4k
/
run-tests.sh
executable file
·349 lines (275 loc) · 7.53 KB
/
run-tests.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
#!/bin/bash
set -eEuo pipefail
# DEBUG=1 enables set -x for this script so echos every command run
DEBUG=${DEBUG:-}
# FILTER_TESTS="<pattern>" skips any test whose CASENAME doesn't match the
# pattern. CASENAME is combination of the name from the case-<name> dir and the
# envoy version for example: "http, envoy 1.8.0". The pattern is passed to grep
# over that string.
FILTER_TESTS=${FILTER_TESTS:-}
# STOP_ON_FAIL exits after a case fails so the workdir state can be viewed and
# the components interacted with to debug the failure. This is useful when tests
# only fail when run as part of a whole suite but work in isolation.
STOP_ON_FAIL=${STOP_ON_FAIL:-}
# ENVOY_VERSIONS is the list of envoy versions to run each test against
ENVOY_VERSIONS=${ENVOY_VERSIONS:-"1.10.0 1.11.2 1.12.7 1.13.7"}
if [ ! -z "$DEBUG" ] ; then
set -x
fi
DIR=$(cd -P -- "$(dirname -- "$0")" && pwd -P)
cd $DIR
LEAVE_CONSUL_UP=${LEAVE_CONSUL_UP:-}
PROXY_LOGS_ON_FAIL=${PROXY_LOGS_ON_FAIL:-}
source helpers.bash
RESULT=1
CLEANED_UP=0
function cleanup {
local STATUS="$?"
if [ "$CLEANED_UP" != 0 ] ; then
return
fi
CLEANED_UP=1
if [ "$STATUS" -ne 0 ]
then
capture_logs
fi
docker-compose down -v --remove-orphans
}
trap cleanup EXIT
function command_error {
echo "ERR: command exited with status $1" 1>&2
echo " command: $2" 1>&2
echo " line: $3" 1>&2
echo " function: $4" 1>&2
echo " called at: $5" 1>&2
# printf '%s\n' "${FUNCNAME[@]}"
# printf '%s\n' "${BASH_SOURCE[@]}"
# printf '%s\n' "${BASH_LINENO[@]}"
}
trap 'command_error $? "${BASH_COMMAND}" "${LINENO}" "${FUNCNAME[0]:-main}" "${BASH_SOURCE[0]}:${BASH_LINENO[0]}"' ERR
# Cleanup from any previous unclean runs.
docker-compose down -v --remove-orphans
# Start the volume container
docker-compose up -d workdir
function init_workdir {
local DC="$1"
if test -z "$DC"
then
DC=primary
fi
# Note, we use explicit set of dirs so we don't delete .gitignore. Also,
# don't wipe logs between runs as they are already split and we need them to
# upload as artifacts later.
rm -rf workdir/${DC}
mkdir -p workdir/${DC}/{consul,envoy,bats,statsd,data}
# Reload consul config from defaults
cp consul-base-cfg/* workdir/${DC}/consul/
# Add any overrides if there are any (no op if not)
find ${CASE_DIR} -maxdepth 1 -name '*.hcl' -type f -exec cp -f {} workdir/${DC}/consul \;
# Copy all the test files
find ${CASE_DIR} -maxdepth 1 -name '*.bats' -type f -exec cp -f {} workdir/${DC}/bats \;
# Copy DC specific bats
cp helpers.bash workdir/${DC}/bats
# Add any DC overrides
if test -d "${CASE_DIR}/${DC}"
then
find ${CASE_DIR}/${DC} -type f -name '*.hcl' -exec cp -f {} workdir/${DC}/consul \;
find ${CASE_DIR}/${DC} -type f -name '*.bats' -exec cp -f {} workdir/${DC}/bats \;
fi
if test -d "${CASE_DIR}/data"
then
cp -r ${CASE_DIR}/data/* workdir/${DC}/data
fi
return 0
}
function start_consul {
local DC=${1:-primary}
# Start consul now as setup script needs it up
docker-compose rm -s -v -f consul-${DC} || true
docker-compose up -d consul-${DC}
}
function pre_service_setup {
local DC=${1:-primary}
# Run test case setup (e.g. generating Envoy bootstrap, starting containers)
if [ -f "${CASE_DIR}${DC}/setup.sh" ]
then
source ${CASE_DIR}${DC}/setup.sh
else
source ${CASE_DIR}setup.sh
fi
}
function start_services {
# Push the state to the shared docker volume (note this is because CircleCI
# can't use shared volumes)
docker cp workdir/. envoy_workdir_1:/workdir
# Start containers required
if [ ! -z "$REQUIRED_SERVICES" ] ; then
docker-compose rm -s -v -f $REQUIRED_SERVICES || true
docker-compose up --build -d $REQUIRED_SERVICES
fi
return 0
}
function verify {
local DC=$1
if test -z "$DC"
then
DC=primary
fi
# Execute tests
res=0
echo "- - - - - - - - - - - - - - - - - - - - - - - -"
echoblue -n "CASE $CASE_STR"
echo -n ": "
# Nuke any previous case's verify container.
docker-compose rm -s -v -f verify-${DC} || true
if docker-compose up --abort-on-container-exit --exit-code-from verify-${DC} verify-${DC} ; then
echogreen "✓ PASS"
else
echored "⨯ FAIL"
res=1
fi
echo "================================================"
return $res
}
function capture_logs {
echo "Capturing Logs for $CASE_STR"
mkdir -p "$LOG_DIR"
services="$REQUIRED_SERVICES consul-primary"
if is_set $REQUIRE_SECONDARY
then
services="$services consul-secondary"
fi
if [ -f "${CASE_DIR}capture.sh" ]
then
echo "Executing ${CASE_DIR}capture.sh"
source ${CASE_DIR}capture.sh || true
fi
for cont in $services
do
echo "Capturing log for $cont"
docker-compose logs --no-color "$cont" 2>&1 > "${LOG_DIR}/${cont}.log"
done
}
function stop_services {
# Teardown
if [ -f "${CASE_DIR}teardown.sh" ] ; then
source "${CASE_DIR}teardown.sh"
fi
docker-compose rm -s -v -f $REQUIRED_SERVICES || true
}
function initVars {
source "defaults.sh"
if [ -f "${CASE_DIR}vars.sh" ] ; then
source "${CASE_DIR}vars.sh"
fi
}
function runTest {
initVars
# Initialize the workdir
init_workdir primary
if is_set $REQUIRE_SECONDARY
then
init_workdir secondary
fi
# Wipe state
docker-compose up wipe-volumes
# Push the state to the shared docker volume (note this is because CircleCI
# can't use shared volumes)
docker cp workdir/. envoy_workdir_1:/workdir
start_consul primary
if [ $? -ne 0 ]
then
capture_logs
return 1
fi
if is_set $REQUIRE_SECONDARY
then
start_consul secondary
if [ $? -ne 0 ]
then
capture_logs
return 1
fi
fi
echo "Setting up the primary datacenter"
pre_service_setup primary
if [ $? -ne 0 ]
then
echo "Setting up the primary datacenter failed"
capture_logs
return 1
fi
if is_set $REQUIRE_SECONDARY
then
echo "Setting up the secondary datacenter"
pre_service_setup secondary
if [ $? -ne 0 ]
then
echo "Setting up the secondary datacenter failed"
capture_logs
return 1
fi
fi
echo "Starting services"
start_services
if [ $? -ne 0 ]
then
capture_logs
return 1
fi
# Run the verify container and report on the output
verify primary
TESTRESULT=$?
if is_set $REQUIRE_SECONDARY && test "$TESTRESULT" -eq 0
then
verify secondary
SECONDARYRESULT=$?
if [ "$SECONDARYRESULT" -ne 0 ]
then
TESTRESULT=$SECONDARYRESULT
fi
fi
if [ "$TESTRESULT" -ne 0 ]
then
capture_logs
fi
stop_services primary
if is_set $REQUIRE_SECONDARY
then
stop_services secondary
fi
return $TESTRESULT
}
RESULT=0
for c in ./case-*/ ; do
for ev in $ENVOY_VERSIONS ; do
export CASE_DIR="${c}"
export CASE_NAME=$( basename $c | cut -c6- )
export CASE_ENVOY_VERSION="envoy $ev"
export CASE_STR="$CASE_NAME, $CASE_ENVOY_VERSION"
export ENVOY_VERSION="${ev}"
export LOG_DIR="workdir/logs/${CASE_DIR}/${ENVOY_VERSION}"
echo "================================================"
echoblue "CASE $CASE_STR"
echo "- - - - - - - - - - - - - - - - - - - - - - - -"
if [ ! -z "$FILTER_TESTS" ] && echo "$CASE_STR" | grep -v "$FILTER_TESTS" > /dev/null ; then
echo " SKIPPED: doesn't match FILTER_TESTS=$FILTER_TESTS"
continue 1
fi
if ! runTest
then
RESULT=1
fi
if [ $RESULT -ne 0 ] && [ ! -z "$STOP_ON_FAIL" ] ; then
echo " => STOPPING because STOP_ON_FAIL set"
break 2
fi
done
done
cleanup
if [ $RESULT -eq 0 ] ; then
echogreen "✓ PASS"
else
echored "⨯ FAIL"
exit 1
fi