run_tests: improve spacing
[ctdb.git] / tests / scripts / run_tests
1 #!/bin/bash
2
3 usage() {
4     cat <<EOF
5 Usage: run_tests [OPTIONS] [TESTS]
6
7 Options:
8   -s            Print a summary of tests results after running all tests
9   -l            Use local daemons for integration tests
10   -e            Exit on the first test failure
11   -V <dir>      Use <dir> as $TEST_VAR_DIR
12   -C            Clean up - kill daemons and remove $TEST_VAR_DIR when done
13   -v            Verbose - print test output for non-failures (only some tests)
14   -A            Use "cat -A" to print test output (only some tests)
15   -D            Show diff between failed/expected test output (some tests only)
16   -X            Trace certain scripts run by tests using -x (only some tests)
17   -d            Print descriptions of tests instead of filenames (dodgy!)
18   -H            No headers - for running single test with other wrapper
19   -q            Quiet - don't show tests being run (hint: use with -s)
20   -x            Trace this script with the -x option
21 EOF
22     exit 1
23 }
24
25 # Print a message and exit.
26 die ()
27 {
28     echo "$1" >&2 ; exit ${2:-1}
29 }
30
31 ######################################################################
32
33 with_summary=false
34 with_desc=false
35 quiet=false
36 exit_on_fail=false
37 no_header=false
38
39 export TEST_VERBOSE=false
40 export TEST_COMMAND_TRACE=false
41 export TEST_CAT_RESULTS_OPTS=""
42 export TEST_DIFF_RESULTS=false
43 export TEST_LOCAL_DAEMONS  # No default, developer can "override"!
44 export TEST_VAR_DIR=""
45 export TEST_CLEANUP=false
46
47 temp=$(getopt -n "$prog" -o "xdehlqsvV:XACDH" -l help -- "$@")
48
49 [ $? != 0 ] && usage
50
51 eval set -- "$temp"
52
53 while true ; do
54     case "$1" in
55         -x) set -x; shift ;;
56         -d) with_desc=true ; shift ;;  # 4th line of output is description
57         -e) exit_on_fail=true ; shift ;;
58         -l) TEST_LOCAL_DAEMONS="3" ; shift ;;
59         -q) quiet=true ; shift ;;
60         -s) with_summary=true ; shift ;;
61         -v) TEST_VERBOSE=true ; shift ;;
62         -V) TEST_VAR_DIR="$2" ; shift 2 ;;
63         -X) TEST_COMMAND_TRACE=true ; shift ;;
64         -A) TEST_CAT_RESULTS_OPTS="-A" ; shift ;;
65         -C) TEST_CLEANUP=true ; shift ;;
66         -D) TEST_DIFF_RESULTS=true ; shift ;;
67         -H) no_header=true ; shift ;;
68         --) shift ; break ;;
69         *) usage ;;
70     esac
71 done
72
73 if $quiet ; then
74     show_progress() { cat >/dev/null ; }
75 else
76     show_progress() { cat ; }
77 fi
78
79 ######################################################################
80
81 ctdb_test_begin ()
82 {
83     local name="$1"
84
85     teststarttime=$(date '+%s')
86     testduration=0
87
88     echo "--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--"
89     echo "Running test $name ($(date '+%T'))"
90     echo "--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--"
91 }
92
93 ctdb_test_end ()
94 {
95     local name="$1" ; shift
96     local status="$1" ; shift
97     # "$@" is command-line
98
99     local interp="SKIPPED"
100     local statstr=" (reason $*)"
101     if [ -n "$status" ] ; then
102         if [ $status -eq 0 ] ; then
103             interp="PASSED"
104             statstr=""
105             echo "ALL OK: $*"
106         else
107             interp="FAILED"
108             statstr=" (status $status)"
109         fi
110     fi
111
112     testduration=$(($(date +%s)-$teststarttime))
113
114     echo "=========================================================================="
115     echo "TEST ${interp}: ${name}${statstr} (duration: ${testduration}s)"
116     echo "=========================================================================="
117
118 }
119
120 ctdb_test_run ()
121 {
122     local name="$1" ; shift
123
124     [ -n "$1" ] || set -- "$name"
125
126     $no_header || ctdb_test_begin "$name"
127
128     local status=0
129     "$@" || status=$?
130
131     $no_header || ctdb_test_end "$name" "$status" "$*"
132
133     return $status
134 }
135
136 ######################################################################
137
138 tests_total=0
139 tests_passed=0
140 tests_failed=0
141 summary=""
142
143 rows=$(if tty -s ; then stty size ; else echo x 80 ; fi | sed -e 's@.* @@' -e 's@^0$@80@')
144 ww=$((rows - 7))
145
146 tf=$(mktemp)
147 sf=$(mktemp)
148
149 set -o pipefail
150
151 run_one_test ()
152 {
153     _f="$1"
154
155     [ -x "$_f" ] || die "test \"$_f\" is not executable"
156     tests_total=$(($tests_total + 1))
157
158     ctdb_test_run "$_f" | tee "$tf" | show_progress
159     status=$?
160     if $with_summary ; then
161         if [ $status -eq 0 ] ; then
162             tests_passed=$(($tests_passed + 1))
163             _t=" PASSED "
164         else
165             _t="*FAILED*"
166             tests_failed=$(($tests_failed + 1))
167         fi
168         if $with_desc ; then
169             desc=$(tail -n +4 $tf | head -n 1)
170             _f="$desc"
171         fi
172         echo "$_t $_f" >>"$sf"
173     fi
174 }
175
176 find_and_run_one_test ()
177 {
178     _t="$1"
179     _dir="$2"
180
181     _f="${_dir}${_dir:+/}${_t}"
182
183     if [ -d "$_f" ] ; then
184         for _i in $(ls "${_f%/}/"*".sh" 2>/dev/null) ; do
185             run_one_test "$_i"
186             if $exit_on_fail && [ $status -ne 0 ] ; then
187                 break
188             fi
189         done
190     elif [ -f "$_f" ] ; then
191         run_one_test "$_f"
192     else
193         status=127
194     fi
195 }
196
197 [ -n "$TEST_VAR_DIR" ] || TEST_VAR_DIR=$(mktemp -d)
198 mkdir -p "$TEST_VAR_DIR"
199 # Must be absolute
200 TEST_VAR_DIR=$(cd "$TEST_VAR_DIR"; echo "$PWD")
201 echo "TEST_VAR_DIR=$TEST_VAR_DIR"
202
203 export TEST_SCRIPTS_DIR=$(dirname "$0")
204
205 for f ; do
206     find_and_run_one_test "$f"
207
208     if [ $status -eq 127 ] ; then
209         # Find the the top-level tests directory
210         tests_dir=$(dirname $(cd $TEST_SCRIPTS_DIR; echo $PWD))
211         # Strip off current directory from beginning, if there, just
212         # to make paths more friendly.
213         tests_dir=${tests_dir#$PWD/}
214         find_and_run_one_test "$f" "$tests_dir"
215     fi
216
217     if [ $status -eq 127 ] ; then
218             die "test \"$f\" is not recognised"
219     fi
220
221     if $exit_on_fail && [ $status -ne 0 ] ; then
222             break
223     fi
224 done
225
226 rm -f "$tf"
227
228 if $with_summary ; then
229     echo
230     cat "$sf"
231     echo
232     echo "${tests_passed}/${tests_total} tests passed"
233 fi
234
235 rm -f "$sf"
236
237 echo
238
239 if $TEST_CLEANUP ; then
240     echo "Removing TEST_VAR_DIR=$TEST_VAR_DIR"
241     rm -rf "$TEST_VAR_DIR"
242 else
243     echo "Not cleaning up TEST_VAR_DIR=$TEST_VAR_DIR"
244 fi
245
246 if [ $tests_failed -gt 0 ] ; then
247     if $no_header ; then
248         exit $status
249     else
250         exit 1
251     fi
252 fi