ctdb-tests: Assign known and available arrays via pointers.
[vlendec/samba-autobuild/.git] / ctdb / tests / run_tests.sh
1 #!/bin/bash
2
3 usage() {
4     cat <<EOF
5 Usage: $0 [OPTIONS] [TESTS]
6
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 - kill daemons and remove TEST_VAR_DIR when done
11   -d            Print descriptions of tests instead of filenames (dodgy!)
12   -D            Show diff between failed/expected test output (some tests only)
13   -e            Exit on the first test failure
14   -H            No headers - for running single test with other wrapper
15   -N            Don't print summary of tests results after running all tests
16   -q            Quiet - don't show tests being run (hint: use with -s)
17   -S            Enable socket wrapper
18   -v            Verbose - print test output for non-failures (only some tests)
19   -V <dir>      Use <dir> as TEST_VAR_DIR
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
24 }
25
26 # Print a message and exit.
27 die ()
28 {
29     echo "$1" >&2 ; exit ${2:-1}
30 }
31
32 ######################################################################
33
34 with_summary=true
35 with_desc=false
36 quiet=false
37 exit_on_fail=false
38 no_header=false
39 socket_wrapper=false
40
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_VAR_DIR=""
48 export TEST_CLEANUP=false
49
50 temp=$(getopt -n "$prog" -o "AcCdDehHNqSvV:xX" -l help -- "$@")
51
52 [ $? != 0 ] && usage
53
54 eval set -- "$temp"
55
56 while true ; do
57     case "$1" in
58         -A) TEST_CAT_RESULTS_OPTS="-A" ; shift ;;
59         -c) TEST_LOCAL_DAEMONS="" ; shift ;;
60         -C) TEST_CLEANUP=true ; shift ;;
61         -d) with_desc=true ; shift ;;  # 4th line of output is description
62         -D) TEST_DIFF_RESULTS=true ; shift ;;
63         -e) exit_on_fail=true ; shift ;;
64         -H) no_header=true ; shift ;;
65         -N) with_summary=false ; shift ;;
66         -q) quiet=true ; shift ;;
67         -S) socket_wrapper=true ; shift ;;
68         -v) TEST_VERBOSE=true ; shift ;;
69         -V) TEST_VAR_DIR="$2" ; shift 2 ;;
70         -x) set -x; shift ;;
71         -X) TEST_COMMAND_TRACE=true ; shift ;;
72         --) shift ; break ;;
73         *) usage ;;
74     esac
75 done
76
77 case $(basename "$0") in
78     *run_cluster_tests*)
79         # Running on a cluster...  same as -c
80         TEST_LOCAL_DAEMONS=""
81         ;;
82 esac
83
84 if $quiet ; then
85     show_progress() { cat >/dev/null ; }
86 else
87     show_progress() { cat ; }
88 fi
89
90 ######################################################################
91
92 ctdb_test_begin ()
93 {
94     local name="$1"
95
96     teststarttime=$(date '+%s')
97     testduration=0
98
99     echo "--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--"
100     echo "Running test $name ($(date '+%T'))"
101     echo "--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--"
102 }
103
104 ctdb_test_end ()
105 {
106     local name="$1" ; shift
107     local status="$1" ; shift
108     # "$@" is command-line
109
110     local interp="SKIPPED"
111     local statstr=" (reason $*)"
112     if [ -n "$status" ] ; then
113         if [ $status -eq 0 ] ; then
114             interp="PASSED"
115             statstr=""
116             echo "ALL OK: $*"
117         else
118             interp="FAILED"
119             statstr=" (status $status)"
120         fi
121     fi
122
123     testduration=$(($(date +%s)-$teststarttime))
124
125     echo "=========================================================================="
126     echo "TEST ${interp}: ${name}${statstr} (duration: ${testduration}s)"
127     echo "=========================================================================="
128
129 }
130
131 ctdb_test_run ()
132 {
133     local name="$1" ; shift
134
135     [ -n "$1" ] || set -- "$name"
136
137     $no_header || ctdb_test_begin "$name"
138
139     local status=0
140     "$@" || status=$?
141
142     $no_header || ctdb_test_end "$name" "$status" "$*"
143
144     return $status
145 }
146
147 ######################################################################
148
149 tests_total=0
150 tests_passed=0
151 tests_failed=0
152 summary=""
153
154 if ! which mktemp >/dev/null 2>&1 ; then
155     # Not perfect, but it will do...
156     mktemp ()
157     {
158         _dir=false
159         if [ "$1" = "-d" ] ; then
160             _dir=true
161         fi
162         _t="${TMPDIR:-/tmp}/tmp.$$.$RANDOM"
163         (
164             umask 077
165             if $_dir ; then
166                 mkdir "$_t"
167             else
168                 >"$_t"
169             fi
170         )
171         echo "$_t"
172     }
173 fi
174
175 tf=$(mktemp)
176 sf=$(mktemp)
177
178 set -o pipefail
179
180 run_one_test ()
181 {
182     _f="$1"
183
184     [ -x "$_f" ] || die "test \"$_f\" is not executable"
185     tests_total=$(($tests_total + 1))
186
187     ctdb_test_run "$_f" | tee "$tf" | show_progress
188     status=$?
189     if [ $status -eq 0 ] ; then
190         tests_passed=$(($tests_passed + 1))
191     else
192         tests_failed=$(($tests_failed + 1))
193     fi
194     if $with_summary ; then
195         if [ $status -eq 0 ] ; then
196             _t=" PASSED "
197         else
198             _t="*FAILED*"
199         fi
200         if $with_desc ; then
201             desc=$(tail -n +4 $tf | head -n 1)
202             _f="$desc"
203         fi
204         echo "$_t $_f" >>"$sf"
205     fi
206 }
207
208 find_and_run_one_test ()
209 {
210     _t="$1"
211     _dir="$2"
212
213     _f="${_dir}${_dir:+/}${_t}"
214
215     if [ -d "$_f" ] ; then
216         for _i in $(ls "${_f%/}/"*".sh" 2>/dev/null) ; do
217             run_one_test "$_i"
218             if $exit_on_fail && [ $status -ne 0 ] ; then
219                 break
220             fi
221         done
222         # No tests found?  Not a tests directory!  Not found...
223         [ -n "$status" ] || status=127
224     elif [ -f "$_f" ] ; then
225         run_one_test "$_f"
226     else
227         status=127
228     fi
229 }
230
231 # Following 2 lines may be modified by installation script
232 export CTDB_TESTS_ARE_INSTALLED=false
233 test_dir=$(dirname "$0")
234
235 if [ -z "$TEST_VAR_DIR" ] ; then
236     if $CTDB_TESTS_ARE_INSTALLED ; then
237         TEST_VAR_DIR=$(mktemp -d)
238     else
239         TEST_VAR_DIR="${test_dir}/var"
240     fi
241 fi
242 mkdir -p "$TEST_VAR_DIR"
243
244 # Must be absolute
245 TEST_VAR_DIR=$(cd "$TEST_VAR_DIR"; echo "$PWD")
246 echo "TEST_VAR_DIR=$TEST_VAR_DIR"
247
248 if $socket_wrapper ; then
249     export SOCKET_WRAPPER_DIR="${TEST_VAR_DIR}/sw"
250     mkdir -p "$SOCKET_WRAPPER_DIR"
251 fi
252
253 export TEST_SCRIPTS_DIR="${test_dir}/scripts"
254
255 # If no tests specified then run some defaults
256 if [ -z "$1" ] ; then
257     if [ -n "$TEST_LOCAL_DAEMONS" ] ; then
258         set -- onnode takeover tool eventscripts cunit simple
259     else
260         set -- simple complex
261     fi
262 fi
263
264 do_cleanup ()
265 {
266     if $TEST_CLEANUP ; then
267         echo "Removing TEST_VAR_DIR=$TEST_VAR_DIR"
268         rm -rf "$TEST_VAR_DIR"
269     else
270         echo "Not cleaning up TEST_VAR_DIR=$TEST_VAR_DIR"
271     fi
272 }
273
274 cleanup_handler ()
275 {
276     if $TEST_CLEANUP ; then
277         if [ -n "$TEST_LOCAL_DAEMONS" -a "$f" = "simple" ] ; then
278             echo "***** shutting down daemons *****"
279             find_and_run_one_test simple/99_daemons_shutdown.sh "$tests_dir"
280         fi
281     fi
282     do_cleanup
283 }
284
285 trap cleanup_handler SIGINT SIGTERM
286
287 for f ; do
288     find_and_run_one_test "$f"
289
290     if [ $status -eq 127 ] ; then
291         # Find the the top-level tests directory
292         tests_dir=$(dirname $(cd $TEST_SCRIPTS_DIR; echo $PWD))
293         # Strip off current directory from beginning, if there, just
294         # to make paths more friendly.
295         tests_dir=${tests_dir#$PWD/}
296         find_and_run_one_test "$f" "$tests_dir"
297     fi
298
299     if [ $status -eq 127 ] ; then
300             die "test \"$f\" is not recognised"
301     fi
302
303     if $exit_on_fail && [ $status -ne 0 ] ; then
304             break
305     fi
306 done
307
308 rm -f "$tf"
309
310 if $with_summary ; then
311     echo
312     cat "$sf"
313     echo
314     echo "${tests_passed}/${tests_total} tests passed"
315 fi
316
317 rm -f "$sf"
318
319 echo
320
321 do_cleanup
322
323 if $no_header || $exit_on_fail ; then
324     exit $status
325 elif [ $tests_failed -gt 0 ] ; then
326     exit 1
327 else
328     exit 0
329 fi