2018-07-01 06:30:06 +03:00
#!/usr/bin/env bash
2007-04-28 12:57:58 +04:00
2013-12-02 08:39:48 +04:00
usage( ) {
cat <<EOF
Usage: $0 [ OPTIONS] [ TESTS]
Options:
-A Use "cat -A" to print test output ( only some tests)
-c Run integration tests on a cluster
2019-09-09 10:59:15 +03:00
-C Clean up when done by removing test state directory ( see -V)
2013-12-02 08:39:48 +04:00
-D Show diff between failed/expected test output ( some tests only)
-e Exit on the first test failure
-H No headers - for running single test with other wrapper
2019-08-05 04:48:13 +03:00
-I <count> Iterate tests <count> times, exiting on failure ( implies -e, -N)
2019-10-17 08:42:36 +03:00
-l <count> Use <count> daemons for local daemon integration tests
2019-10-17 07:53:09 +03:00
-L Print daemon logs on test failure ( only some tests)
2013-12-02 08:39:48 +04:00
-N Don' t print summary of tests results after running all tests
2019-08-05 04:50:21 +03:00
-q Quiet - don' t show tests being run ( still displays summary)
2018-01-22 11:14:48 +03:00
-S <lib> Use socket wrapper library <lib> for local integration tests
2013-12-02 08:39:48 +04:00
-v Verbose - print test output for non-failures ( only some tests)
2019-09-09 10:59:15 +03:00
-V <dir> Use <dir> as test state directory
2013-12-02 08:39:48 +04:00
-x Trace this script with the -x option
-X Trace certain scripts run by tests using -x ( only some tests)
EOF
exit 1
}
# Print a message and exit.
die ( )
{
2019-08-05 03:09:34 +03:00
echo " $1 " >& 2 ; exit " ${ 2 :- 1 } "
2013-12-02 08:39:48 +04:00
}
######################################################################
with_summary = true
quiet = false
exit_on_fail = false
2019-08-05 04:48:13 +03:00
max_iterations = 1
2013-12-02 08:39:48 +04:00
no_header = false
2019-09-09 10:59:15 +03:00
test_state_dir = ""
2019-09-09 09:08:41 +03:00
cleanup = false
test_time_limit = 3600
2013-12-02 08:39:48 +04:00
2019-10-17 08:33:48 +03:00
export CTDB_TEST_VERBOSE = false
export CTDB_TEST_COMMAND_TRACE = false
export CTDB_TEST_CAT_RESULTS_OPTS = ""
export CTDB_TEST_DIFF_RESULTS = false
2019-10-17 07:53:09 +03:00
export CTDB_TEST_PRINT_LOGS_ON_ERROR = false
2019-10-17 08:42:36 +03:00
export CTDB_TEST_LOCAL_DAEMONS = 3
2019-10-17 08:33:48 +03:00
export CTDB_TEST_SWRAP_SO_PATH = ""
2013-12-02 08:39:48 +04:00
2019-10-17 08:42:36 +03:00
while getopts "AcCDehHI:l:LNqS:T:vV:xX?" opt ; do
2018-07-08 14:54:40 +03:00
case " $opt " in
2019-10-17 08:33:48 +03:00
A) CTDB_TEST_CAT_RESULTS_OPTS = "-A" ; ;
c) CTDB_TEST_LOCAL_DAEMONS = "" ; ;
2019-09-09 09:08:41 +03:00
C) cleanup = true ; ;
2019-10-17 08:33:48 +03:00
D) CTDB_TEST_DIFF_RESULTS = true ; ;
2018-07-08 14:54:40 +03:00
e) exit_on_fail = true ; ;
H) no_header = true ; ;
2019-08-05 04:48:13 +03:00
I) max_iterations = " $OPTARG " ; exit_on_fail = true ; with_summary = false ; ;
2019-10-17 08:42:36 +03:00
l) CTDB_TEST_LOCAL_DAEMONS = " $OPTARG " ; ;
2019-10-17 07:53:09 +03:00
L) CTDB_TEST_PRINT_LOGS_ON_ERROR = true ; ;
2018-07-08 14:54:40 +03:00
N) with_summary = false ; ;
q) quiet = true ; ;
2019-10-17 08:33:48 +03:00
S) CTDB_TEST_SWRAP_SO_PATH = " $OPTARG " ; ;
2019-09-09 09:08:41 +03:00
T) test_time_limit = " $OPTARG " ; ;
2019-10-17 08:33:48 +03:00
v) CTDB_TEST_VERBOSE = true ; ;
2019-09-09 10:59:15 +03:00
V) test_state_dir = " $OPTARG " ; ;
2018-07-08 14:54:40 +03:00
x) set -x ; ;
2019-10-17 08:33:48 +03:00
X) CTDB_TEST_COMMAND_TRACE = true ; ;
2018-07-08 14:54:40 +03:00
\? | h) usage ; ;
esac
2013-12-02 08:39:48 +04:00
done
2018-07-08 14:54:40 +03:00
shift $(( OPTIND - 1 ))
2012-04-20 08:10:34 +04:00
2012-05-14 05:57:20 +04:00
case $( basename " $0 " ) in
*run_cluster_tests*)
2013-12-02 08:39:48 +04:00
# Running on a cluster... same as -c
2019-10-17 08:33:48 +03:00
CTDB_TEST_LOCAL_DAEMONS = ""
2012-05-14 05:57:20 +04:00
; ;
esac
2013-12-02 08:39:48 +04:00
if $quiet ; then
show_progress( ) { cat >/dev/null ; }
else
show_progress( ) { cat ; }
fi
######################################################################
2019-10-03 10:25:10 +03:00
test_header ( )
2013-12-02 08:39:48 +04:00
{
2019-09-10 03:51:31 +03:00
local name = " $1 "
2013-12-02 08:39:48 +04:00
2019-09-10 03:51:31 +03:00
echo "--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--"
echo " Running test $name ( $( date '+%T' ) ) "
echo "--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--"
2013-12-02 08:39:48 +04:00
}
2019-10-03 10:25:10 +03:00
test_footer ( )
2013-12-02 08:39:48 +04:00
{
2019-09-09 13:57:42 +03:00
local f = " $1 "
local status = " $2 "
local interp = " $3 "
2019-09-10 03:51:31 +03:00
local duration = " $4 "
2013-12-02 08:39:48 +04:00
2019-09-09 13:57:42 +03:00
local statstr = ""
2019-08-05 03:09:34 +03:00
if [ " $status " -eq 0 ] ; then
2019-09-09 13:57:42 +03:00
statstr = ""
2013-12-02 08:39:48 +04:00
else
2019-09-09 13:57:42 +03:00
statstr = " (status $status ) "
2013-12-02 08:39:48 +04:00
fi
2019-09-09 13:57:42 +03:00
echo "=========================================================================="
2019-09-10 03:51:31 +03:00
echo " TEST ${ interp } : ${ f } ${ statstr } (duration: ${ duration } s) "
2019-09-09 13:57:42 +03:00
echo "=========================================================================="
2013-12-02 08:39:48 +04:00
}
ctdb_test_run ( )
{
2019-09-09 13:51:51 +03:00
local f = " $1 "
2013-12-02 08:39:48 +04:00
2019-10-03 10:25:10 +03:00
$no_header || test_header " $f "
2013-12-02 08:39:48 +04:00
2019-09-09 13:51:51 +03:00
local status = 0
2019-09-10 03:51:31 +03:00
local start_time
start_time = $( date '+%s' )
2019-09-09 13:51:51 +03:00
if [ -x " $f " ] ; then
2020-01-30 05:37:00 +03:00
timeout " $test_time_limit " " $f " </dev/null | show_progress
2019-09-18 05:25:06 +03:00
status = $?
2019-09-09 13:51:51 +03:00
else
echo "TEST IS NOT EXECUTABLE"
2019-09-18 05:31:10 +03:00
status = 99
2019-09-09 13:51:51 +03:00
fi
2013-12-02 08:39:48 +04:00
2019-09-10 03:51:31 +03:00
local duration = $(( $( date +%s) - start_time))
2019-09-09 13:57:42 +03:00
tests_total = $(( tests_total + 1 ))
local interp
case " $status " in
0)
interp = "PASSED"
tests_passed = $(( tests_passed + 1 ))
; ;
2019-09-18 05:36:05 +03:00
77)
interp = "SKIPPED"
tests_skipped = $(( tests_skipped + 1 ))
; ;
2019-09-18 05:31:10 +03:00
99)
interp = "ERROR"
tests_failed = $(( tests_failed + 1 ))
; ;
2019-09-09 13:57:42 +03:00
124)
interp = "TIMEDOUT"
tests_failed = $(( tests_failed + 1 ))
; ;
*)
interp = "FAILED"
tests_failed = $(( tests_failed + 1 ))
; ;
esac
2019-10-03 10:25:10 +03:00
$no_header || test_footer " $f " " $status " " $interp " " $duration "
2019-09-09 13:57:42 +03:00
if $with_summary ; then
local t
if [ $status -eq 0 ] ; then
t = " ${ interp } "
else
t = " * ${ interp } * "
fi
printf '%-10s %s\n' " $t " " $f " >>" $summary_file "
fi
2013-12-02 08:39:48 +04:00
2020-03-05 03:40:56 +03:00
# Skipped tests should not cause failure
case " $status " in
77)
status = 0
; ;
esac
2019-09-09 13:51:51 +03:00
return $status
2013-12-02 08:39:48 +04:00
}
######################################################################
tests_total = 0
tests_passed = 0
2019-09-18 05:36:05 +03:00
tests_skipped = 0
2013-12-02 08:39:48 +04:00
tests_failed = 0
2019-08-05 03:21:16 +03:00
if ! type mktemp >/dev/null 2>& 1 ; then
2013-12-02 08:39:48 +04:00
# Not perfect, but it will do...
mktemp ( )
{
2016-10-11 05:32:31 +03:00
local dir = false
2013-12-02 08:39:48 +04:00
if [ " $1 " = "-d" ] ; then
2016-10-11 05:32:31 +03:00
dir = true
2013-12-02 08:39:48 +04:00
fi
2016-10-11 05:32:31 +03:00
local t = " ${ TMPDIR :- /tmp } /tmp. $$ . $RANDOM "
2013-12-02 08:39:48 +04:00
(
umask 077
2016-10-11 05:32:31 +03:00
if $dir ; then
mkdir " $t "
2013-12-02 08:39:48 +04:00
else
2019-08-05 03:19:13 +03:00
: >" $t "
2013-12-02 08:39:48 +04:00
fi
)
2016-10-11 05:32:31 +03:00
echo " $t "
2013-12-02 08:39:48 +04:00
}
fi
set -o pipefail
run_one_test ( )
{
2016-10-11 05:32:31 +03:00
local f = " $1 "
2013-12-02 08:39:48 +04:00
2019-09-09 09:19:52 +03:00
CTDB_TEST_SUITE_DIR = $( dirname " $f " )
export CTDB_TEST_SUITE_DIR
# This expands the most probable problem cases like "." and "..".
if [ " $( dirname " $CTDB_TEST_SUITE_DIR " ) " = "." ] ; then
CTDB_TEST_SUITE_DIR = $( cd " $CTDB_TEST_SUITE_DIR " && pwd )
fi
2019-09-05 06:42:26 +03:00
# Set CTDB_TEST_TMP_DIR
#
# Determine the relative test suite subdirectory. The top-level
# test directory needs to be a prefix of the test suite directory,
# so make absolute versions of both.
local test_dir test_suite_dir reldir
test_dir = $( cd " $CTDB_TEST_DIR " && pwd )
test_suite_dir = $( cd " $CTDB_TEST_SUITE_DIR " && pwd )
2022-05-27 16:23:48 +03:00
reldir = " ${ test_suite_dir # " ${ test_dir } " / } "
2019-09-05 06:42:26 +03:00
2019-09-09 10:59:15 +03:00
export CTDB_TEST_TMP_DIR = " ${ test_state_dir } / ${ reldir } "
2019-09-05 06:42:26 +03:00
rm -rf " $CTDB_TEST_TMP_DIR "
mkdir -p " $CTDB_TEST_TMP_DIR "
2019-09-18 05:25:06 +03:00
ctdb_test_run " $f "
2013-12-02 08:39:48 +04:00
status = $?
}
2019-08-05 04:19:30 +03:00
run_tests ( )
{
2019-09-09 04:40:21 +03:00
local f
2019-09-09 08:01:49 +03:00
for f ; do
2019-09-25 09:37:46 +03:00
case " $f " in
*/README| */README.md)
continue
; ;
esac
2019-09-09 04:40:21 +03:00
if [ ! -e " $f " ] ; then
# Can't find it? Check relative to CTDB_TEST_DIR.
2019-08-05 04:19:30 +03:00
# Strip off current directory from beginning,
# if there, just to make paths more friendly.
2022-05-27 16:23:48 +03:00
f = " ${ CTDB_TEST_DIR # " ${ PWD } " / } / ${ f } "
2019-08-05 04:19:30 +03:00
fi
2019-09-09 04:40:21 +03:00
if [ -d " $f " ] ; then
2019-09-09 07:47:26 +03:00
local test_dir dir reldir subtests
test_dir = $( cd " $CTDB_TEST_DIR " && pwd )
dir = $( cd " $f " && pwd )
2022-05-27 16:23:48 +03:00
reldir = " ${ dir # " ${ test_dir } " / } "
2019-09-09 07:47:26 +03:00
case " $reldir " in
*/*/*)
die " test \" $f \" is not recognised "
; ;
2019-09-09 09:00:52 +03:00
*/*)
2019-09-09 08:59:31 +03:00
# This is a test suite
2019-09-09 07:47:26 +03:00
subtests = $( echo " ${ f %/ } / " *".sh" )
if [ " $subtests " = " ${ f %/ } /*.sh " ] ; then
# Probably empty directory
die " test \" $f \" is not recognised "
2019-09-09 04:40:21 +03:00
fi
2019-09-09 07:47:26 +03:00
; ;
2019-09-09 09:00:52 +03:00
CLUSTER| INTEGRATION| UNIT)
2019-09-09 07:47:26 +03:00
# A collection of test suites
subtests = $( echo " ${ f %/ } / " *)
; ;
*)
die " test \" $f \" is not recognised "
esac
# Recurse - word-splitting wanted
# shellcheck disable=SC2086
run_tests $subtests
2019-09-09 04:40:21 +03:00
elif [ -f " $f " ] ; then
run_one_test " $f "
else
# Time to give up
2019-08-05 04:19:30 +03:00
die " test \" $f \" is not recognised "
fi
if $exit_on_fail && [ $status -ne 0 ] ; then
return $status
fi
done
}
2018-04-05 08:37:42 +03:00
export CTDB_TEST_MODE = "yes"
2013-12-02 08:39:48 +04:00
# Following 2 lines may be modified by installation script
2019-08-05 03:18:08 +03:00
CTDB_TESTS_ARE_INSTALLED = false
CTDB_TEST_DIR = $( dirname " $0 " )
export CTDB_TESTS_ARE_INSTALLED CTDB_TEST_DIR
2013-12-02 08:39:48 +04:00
2019-09-09 10:59:15 +03:00
if [ -z " $test_state_dir " ] ; then
2013-12-02 08:39:48 +04:00
if $CTDB_TESTS_ARE_INSTALLED ; then
2019-09-09 10:59:15 +03:00
test_state_dir = $( mktemp -d)
2013-12-02 08:39:48 +04:00
else
2019-09-09 10:59:15 +03:00
test_state_dir = " ${ CTDB_TEST_DIR } /var "
2013-12-02 08:39:48 +04:00
fi
fi
2019-09-09 10:59:15 +03:00
mkdir -p " $test_state_dir "
2013-12-02 08:39:48 +04:00
2019-09-09 10:59:15 +03:00
summary_file = " ${ test_state_dir } /.summary "
2019-09-04 08:04:05 +03:00
: >" $summary_file "
2017-08-03 13:36:57 +03:00
export TEST_SCRIPTS_DIR = " ${ CTDB_TEST_DIR } /scripts "
2013-12-02 08:39:48 +04:00
# If no tests specified then run some defaults
if [ -z " $1 " ] ; then
2019-10-17 08:33:48 +03:00
if [ -n " $CTDB_TEST_LOCAL_DAEMONS " ] ; then
2019-09-09 09:00:52 +03:00
set -- UNIT INTEGRATION
2018-01-22 11:48:02 +03:00
else
2019-09-09 09:00:52 +03:00
set -- INTEGRATION CLUSTER
2013-12-02 08:39:48 +04:00
fi
fi
2014-07-04 11:04:10 +04:00
do_cleanup ( )
{
2019-09-09 09:08:41 +03:00
if $cleanup ; then
2019-09-09 10:59:15 +03:00
echo " Removing test state directory: ${ test_state_dir } "
rm -rf " $test_state_dir "
2014-07-04 11:04:10 +04:00
else
2019-09-09 10:59:15 +03:00
echo " Not cleaning up test state directory: ${ test_state_dir } "
2014-07-04 11:04:10 +04:00
fi
}
2018-10-08 05:39:30 +03:00
trap "do_cleanup ; exit 130" SIGINT
trap "do_cleanup ; exit 143" SIGTERM
2014-07-04 11:04:10 +04:00
2019-08-05 04:48:13 +03:00
iterations = 0
# Special case: -I 0 means iterate forever (until failure)
while [ " $max_iterations " -eq 0 ] || [ $iterations -lt " $max_iterations " ] ; do
iterations = $(( iterations + 1 ))
if [ " $max_iterations " -ne 1 ] ; then
echo
echo "##################################################"
echo " ITERATION ${ iterations } "
echo "##################################################"
echo
fi
2019-09-09 07:59:38 +03:00
run_tests " $@ "
2019-08-05 04:48:13 +03:00
status = $?
if [ $status -ne 0 ] ; then
break
fi
done
2013-12-02 08:39:48 +04:00
if $with_summary ; then
2019-08-05 04:52:16 +03:00
if [ $status -eq 0 ] || ! $exit_on_fail ; then
echo
2019-09-04 08:04:05 +03:00
cat " $summary_file "
2019-09-18 05:36:05 +03:00
2019-08-05 04:52:16 +03:00
echo
2019-09-18 05:36:05 +03:00
tests_run = $(( tests_total - tests_skipped))
printf '%d/%d tests passed' $tests_passed $tests_run
if [ $tests_skipped -gt 0 ] ; then
printf ' (%d skipped)' $tests_skipped
fi
printf '\n'
2019-08-05 04:52:16 +03:00
fi
2013-12-02 08:39:48 +04:00
fi
2019-09-04 08:04:05 +03:00
rm -f " $summary_file "
2013-12-02 08:39:48 +04:00
echo
2014-07-04 11:04:10 +04:00
do_cleanup
2013-12-02 08:39:48 +04:00
if $no_header || $exit_on_fail ; then
exit $status
elif [ $tests_failed -gt 0 ] ; then
exit 1
else
exit 0
fi