third_party: Link uid_wrapper against pthread
[Samba.git] / ctdb / tests / run_tests.sh
blob48a272664c0a1f54480b75e3f7fc4615c470f0fa
1 #!/usr/bin/env bash
3 usage() {
4 cat <<EOF
5 Usage: $0 [OPTIONS] [TESTS]
7 Options:
8 -A Use "cat -A" to print test output (only some tests)
9 -c Run integration tests on a cluster
10 -C Clean up when done by removing test state directory (see -V)
11 -D Show diff between failed/expected test output (some tests only)
12 -e Exit on the first test failure
13 -H No headers - for running single test with other wrapper
14 -I <count> Iterate tests <count> times, exiting on failure (implies -e, -N)
15 -N Don't print summary of tests results after running all tests
16 -q Quiet - don't show tests being run (still displays summary)
17 -S <lib> Use socket wrapper library <lib> for local integration tests
18 -v Verbose - print test output for non-failures (only some tests)
19 -V <dir> Use <dir> as test state directory
20 -x Trace this script with the -x option
21 -X Trace certain scripts run by tests using -x (only some tests)
22 EOF
23 exit 1
26 # Print a message and exit.
27 die ()
29 echo "$1" >&2 ; exit "${2:-1}"
32 ######################################################################
34 with_summary=true
35 quiet=false
36 exit_on_fail=false
37 max_iterations=1
38 no_header=false
39 test_state_dir=""
41 export TEST_VERBOSE=false
42 export TEST_COMMAND_TRACE=false
43 export TEST_CAT_RESULTS_OPTS=""
44 export TEST_DIFF_RESULTS=false
45 export TEST_LOCAL_DAEMONS
46 [ -n "$TEST_LOCAL_DAEMONS" ] || TEST_LOCAL_DAEMONS=3
47 export TEST_CLEANUP=false
48 export TEST_TIMEOUT=3600
49 export TEST_SOCKET_WRAPPER_SO_PATH=""
51 while getopts "AcCDehHI:NqS:T:vV:xX?" opt ; do
52 case "$opt" in
53 A) TEST_CAT_RESULTS_OPTS="-A" ;;
54 c) TEST_LOCAL_DAEMONS="" ;;
55 C) TEST_CLEANUP=true ;;
56 D) TEST_DIFF_RESULTS=true ;;
57 e) exit_on_fail=true ;;
58 H) no_header=true ;;
59 I) max_iterations="$OPTARG" ; exit_on_fail=true ; with_summary=false ;;
60 N) with_summary=false ;;
61 q) quiet=true ;;
62 S) TEST_SOCKET_WRAPPER_SO_PATH="$OPTARG" ;;
63 T) TEST_TIMEOUT="$OPTARG" ;;
64 v) TEST_VERBOSE=true ;;
65 V) test_state_dir="$OPTARG" ;;
66 x) set -x ;;
67 X) TEST_COMMAND_TRACE=true ;;
68 \?|h) usage ;;
69 esac
70 done
71 shift $((OPTIND - 1))
73 case $(basename "$0") in
74 *run_cluster_tests*)
75 # Running on a cluster... same as -c
76 TEST_LOCAL_DAEMONS=""
78 esac
80 if $quiet ; then
81 show_progress() { cat >/dev/null ; }
82 else
83 show_progress() { cat ; }
86 ######################################################################
88 ctdb_test_begin ()
90 local name="$1"
92 teststarttime=$(date '+%s')
93 testduration=0
95 echo "--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--"
96 echo "Running test $name ($(date '+%T'))"
97 echo "--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--"
100 ctdb_test_end ()
102 local name="$1" ; shift
103 local status="$1" ; shift
104 # "$@" is command-line
106 local interp="SKIPPED"
107 local statstr=" (reason $*)"
108 if [ -n "$status" ] ; then
109 if [ "$status" -eq 0 ] ; then
110 interp="PASSED"
111 statstr=""
112 echo "ALL OK: $*"
113 elif [ "$status" -eq 124 ] ; then
114 interp="TIMEOUT"
115 statstr=" (status $status)"
116 else
117 interp="FAILED"
118 statstr=" (status $status)"
122 testduration=$(($(date +%s) - teststarttime))
124 echo "=========================================================================="
125 echo "TEST ${interp}: ${name}${statstr} (duration: ${testduration}s)"
126 echo "=========================================================================="
130 ctdb_test_run ()
132 local name="$1" ; shift
134 [ -n "$1" ] || set -- "$name"
136 $no_header || ctdb_test_begin "$name"
138 local status=0
139 if [ -x "$1" ] ; then
140 timeout "$TEST_TIMEOUT" "$@" || status=$?
141 else
142 echo "TEST IS NOT EXECUTABLE"
143 status=1
146 $no_header || ctdb_test_end "$name" "$status" "$*"
148 return $status
151 ######################################################################
153 tests_total=0
154 tests_passed=0
155 tests_failed=0
157 if ! type mktemp >/dev/null 2>&1 ; then
158 # Not perfect, but it will do...
159 mktemp ()
161 local dir=false
162 if [ "$1" = "-d" ] ; then
163 dir=true
165 local t="${TMPDIR:-/tmp}/tmp.$$.$RANDOM"
167 umask 077
168 if $dir ; then
169 mkdir "$t"
170 else
171 : >"$t"
174 echo "$t"
178 set -o pipefail
180 run_one_test ()
182 local f="$1"
184 CTDB_TEST_SUITE_DIR=$(dirname "$f")
185 export CTDB_TEST_SUITE_DIR
186 # This expands the most probable problem cases like "." and "..".
187 if [ "$(dirname "$CTDB_TEST_SUITE_DIR")" = "." ] ; then
188 CTDB_TEST_SUITE_DIR=$(cd "$CTDB_TEST_SUITE_DIR" && pwd)
191 # Set CTDB_TEST_TMP_DIR
193 # Determine the relative test suite subdirectory. The top-level
194 # test directory needs to be a prefix of the test suite directory,
195 # so make absolute versions of both.
196 local test_dir test_suite_dir reldir
197 test_dir=$(cd "$CTDB_TEST_DIR" && pwd)
198 test_suite_dir=$(cd "$CTDB_TEST_SUITE_DIR" && pwd)
199 reldir="${test_suite_dir#${test_dir}/}"
201 export CTDB_TEST_TMP_DIR="${test_state_dir}/${reldir}"
202 rm -rf "$CTDB_TEST_TMP_DIR"
203 mkdir -p "$CTDB_TEST_TMP_DIR"
205 tests_total=$((tests_total + 1))
207 ctdb_test_run "$f" | show_progress
208 status=$?
209 if [ $status -eq 0 ] ; then
210 tests_passed=$((tests_passed + 1))
211 else
212 tests_failed=$((tests_failed + 1))
214 if $with_summary ; then
215 local t
216 if [ $status -eq 0 ] ; then
217 t=" PASSED "
218 else
219 t="*FAILED*"
221 echo "$t $f" >>"$summary_file"
225 find_and_run_one_test ()
227 local t="$1"
228 local dir="$2"
230 local f="${dir}${dir:+/}${t}"
232 if [ -d "$f" ] ; then
233 local i
234 for i in "${f%/}/"*".sh" ; do
235 # Only happens if test removed (unlikely) or empty directory
236 if [ ! -f "$i" ] ; then
237 break
239 run_one_test "$i"
240 if $exit_on_fail && [ $status -ne 0 ] ; then
241 break
243 done
244 # No tests found? Not a tests directory! Not found...
245 [ -n "$status" ] || status=127
246 elif [ -f "$f" ] ; then
247 run_one_test "$f"
248 else
249 status=127
253 run_tests ()
255 local tests=("$@")
257 for f in "${tests[@]}" ; do
258 find_and_run_one_test "$f"
260 if [ $status -eq 127 ] ; then
261 # Find the the top-level tests directory
262 d=$(cd "$TEST_SCRIPTS_DIR" && echo "$PWD")
263 if [ -z "$d" ] ; then
264 local t="$TEST_SCRIPTS_DIR"
265 die "Unable to find TEST_SCRIPTS_DIR=\"${t}\""
267 tests_dir=$(dirname "$d")
268 # Strip off current directory from beginning,
269 # if there, just to make paths more friendly.
270 tests_dir="${tests_dir#${PWD}/}"
271 find_and_run_one_test "$f" "$tests_dir"
274 if [ $status -eq 127 ] ; then
275 die "test \"$f\" is not recognised"
278 if $exit_on_fail && [ $status -ne 0 ] ; then
279 return $status
281 done
284 export CTDB_TEST_MODE="yes"
286 # Following 2 lines may be modified by installation script
287 CTDB_TESTS_ARE_INSTALLED=false
288 CTDB_TEST_DIR=$(dirname "$0")
289 export CTDB_TESTS_ARE_INSTALLED CTDB_TEST_DIR
291 if [ -z "$test_state_dir" ] ; then
292 if $CTDB_TESTS_ARE_INSTALLED ; then
293 test_state_dir=$(mktemp -d)
294 else
295 test_state_dir="${CTDB_TEST_DIR}/var"
298 mkdir -p "$test_state_dir"
300 summary_file="${test_state_dir}/.summary"
301 : >"$summary_file"
303 export TEST_SCRIPTS_DIR="${CTDB_TEST_DIR}/scripts"
305 unit_tests="
306 cunit
307 eventd
308 eventscripts
309 onnode
310 shellcheck
311 takeover
312 takeover_helper
313 tool
316 # If no tests specified then run some defaults
317 if [ -z "$1" ] ; then
318 if [ -n "$TEST_LOCAL_DAEMONS" ] ; then
319 set -- UNIT simple
320 else
321 set -- simple complex
325 do_cleanup ()
327 if $TEST_CLEANUP ; then
328 echo "Removing test state directory: ${test_state_dir}"
329 rm -rf "$test_state_dir"
330 else
331 echo "Not cleaning up test state directory: ${test_state_dir}"
335 trap "do_cleanup ; exit 130" SIGINT
336 trap "do_cleanup ; exit 143" SIGTERM
338 declare -a tests
340 for f ; do
341 if [ "$f" = "UNIT" ] ; then
342 for t in $unit_tests ; do
343 tests[i++]="$t"
344 done
345 else
346 tests[i++]="$f"
348 done
350 iterations=0
351 # Special case: -I 0 means iterate forever (until failure)
352 while [ "$max_iterations" -eq 0 ] || [ $iterations -lt "$max_iterations" ] ; do
353 iterations=$((iterations + 1))
355 if [ "$max_iterations" -ne 1 ] ; then
356 echo
357 echo "##################################################"
358 echo "ITERATION ${iterations}"
359 echo "##################################################"
360 echo
363 run_tests "${tests[@]}"
364 status=$?
366 if [ $status -ne 0 ] ; then
367 break
369 done
371 if $with_summary ; then
372 if [ $status -eq 0 ] || ! $exit_on_fail ; then
373 echo
374 cat "$summary_file"
375 echo
376 echo "${tests_passed}/${tests_total} tests passed"
379 rm -f "$summary_file"
381 echo
383 do_cleanup
385 if $no_header || $exit_on_fail ; then
386 exit $status
387 elif [ $tests_failed -gt 0 ] ; then
388 exit 1
389 else
390 exit 0