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)
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 = ""
2013-12-02 08:39:48 +04:00
export TEST_VERBOSE = false
export TEST_COMMAND_TRACE = false
export TEST_CAT_RESULTS_OPTS = ""
export TEST_DIFF_RESULTS = false
export TEST_LOCAL_DAEMONS
[ -n " $TEST_LOCAL_DAEMONS " ] || TEST_LOCAL_DAEMONS = 3
export TEST_CLEANUP = false
2018-02-05 07:45:09 +03:00
export TEST_TIMEOUT = 3600
2018-01-22 11:14:48 +03:00
export TEST_SOCKET_WRAPPER_SO_PATH = ""
2013-12-02 08:39:48 +04:00
2019-09-04 07:59:22 +03:00
while getopts "AcCDehHI:NqS:T:vV:xX?" opt ; do
2018-07-08 14:54:40 +03:00
case " $opt " in
A) TEST_CAT_RESULTS_OPTS = "-A" ; ;
c) TEST_LOCAL_DAEMONS = "" ; ;
C) TEST_CLEANUP = true ; ;
D) TEST_DIFF_RESULTS = true ; ;
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 ; ;
2018-07-08 14:54:40 +03:00
N) with_summary = false ; ;
q) quiet = true ; ;
S) TEST_SOCKET_WRAPPER_SO_PATH = " $OPTARG " ; ;
T) TEST_TIMEOUT = " $OPTARG " ; ;
v) 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 ; ;
X) TEST_COMMAND_TRACE = true ; ;
\? | 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
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
######################################################################
ctdb_test_begin ( )
{
local name = " $1 "
teststarttime = $( date '+%s' )
testduration = 0
echo "--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--"
echo " Running test $name ( $( date '+%T' ) ) "
echo "--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--"
}
ctdb_test_end ( )
{
local name = " $1 " ; shift
local status = " $1 " ; shift
# "$@" is command-line
local interp = "SKIPPED"
local statstr = " (reason $* ) "
if [ -n " $status " ] ; then
2019-08-05 03:09:34 +03:00
if [ " $status " -eq 0 ] ; then
2013-12-02 08:39:48 +04:00
interp = "PASSED"
statstr = ""
echo " ALL OK: $* "
2019-08-05 03:09:34 +03:00
elif [ " $status " -eq 124 ] ; then
2018-01-20 09:05:37 +03:00
interp = "TIMEOUT"
statstr = " (status $status ) "
2013-12-02 08:39:48 +04:00
else
interp = "FAILED"
statstr = " (status $status ) "
fi
fi
2019-08-05 03:14:22 +03:00
testduration = $(( $( date +%s) - teststarttime))
2013-12-02 08:39:48 +04:00
echo "=========================================================================="
echo " TEST ${ interp } : ${ name } ${ statstr } (duration: ${ testduration } s) "
echo "=========================================================================="
}
ctdb_test_run ( )
{
local name = " $1 " ; shift
[ -n " $1 " ] || set -- " $name "
$no_header || ctdb_test_begin " $name "
local status = 0
2018-05-18 04:44:11 +03:00
if [ -x " $1 " ] ; then
2019-08-05 03:09:34 +03:00
timeout " $TEST_TIMEOUT " " $@ " || status = $?
2018-05-18 04:44:11 +03:00
else
echo "TEST IS NOT EXECUTABLE"
status = 1
fi
2013-12-02 08:39:48 +04:00
$no_header || ctdb_test_end " $name " " $status " " $* "
return $status
}
######################################################################
tests_total = 0
tests_passed = 0
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 )
reldir = " ${ test_suite_dir # ${ test_dir } / } "
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-08-05 03:14:22 +03:00
tests_total = $(( tests_total + 1 ))
2013-12-02 08:39:48 +04:00
2019-09-04 07:59:22 +03:00
ctdb_test_run " $f " | show_progress
2013-12-02 08:39:48 +04:00
status = $?
if [ $status -eq 0 ] ; then
2019-08-05 03:14:22 +03:00
tests_passed = $(( tests_passed + 1 ))
2013-12-02 08:39:48 +04:00
else
2019-08-05 03:14:22 +03:00
tests_failed = $(( tests_failed + 1 ))
2013-12-02 08:39:48 +04:00
fi
if $with_summary ; then
2016-10-11 05:32:31 +03:00
local t
2013-12-02 08:39:48 +04:00
if [ $status -eq 0 ] ; then
2016-10-11 05:32:31 +03:00
t = " PASSED "
2013-12-02 08:39:48 +04:00
else
2016-10-11 05:32:31 +03:00
t = "*FAILED*"
2013-12-02 08:39:48 +04:00
fi
2019-09-04 08:04:05 +03:00
echo " $t $f " >>" $summary_file "
2013-12-02 08:39:48 +04:00
fi
}
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.
2019-09-09 04:40:21 +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 )
reldir = " ${ dir # ${ test_dir } / } "
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
2018-01-22 11:48:02 +03:00
if [ -n " $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 ( )
{
if $TEST_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-08-05 04:52:16 +03:00
echo
echo " ${ tests_passed } / ${ tests_total } tests passed "
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