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
}
find_and_run_one_test ( )
{
2016-10-11 05:32:31 +03:00
local t = " $1 "
local dir = " $2 "
2013-12-02 08:39:48 +04:00
2016-10-11 05:32:31 +03:00
local f = " ${ dir } ${ dir : +/ } ${ t } "
2013-12-02 08:39:48 +04:00
2016-10-11 05:32:31 +03:00
if [ -d " $f " ] ; then
local i
2019-08-05 03:28:52 +03:00
for i in " ${ f %/ } / " *".sh" ; do
# Only happens if test removed (unlikely) or empty directory
if [ ! -f " $i " ] ; then
break
fi
2016-10-11 05:32:31 +03:00
run_one_test " $i "
2013-12-02 08:39:48 +04:00
if $exit_on_fail && [ $status -ne 0 ] ; then
break
fi
done
# No tests found? Not a tests directory! Not found...
[ -n " $status " ] || status = 127
2016-10-11 05:32:31 +03:00
elif [ -f " $f " ] ; then
run_one_test " $f "
2013-12-02 08:39:48 +04:00
else
status = 127
fi
}
2019-08-05 04:19:30 +03:00
run_tests ( )
{
local tests = ( " $@ " )
for f in " ${ tests [@] } " ; do
find_and_run_one_test " $f "
if [ $status -eq 127 ] ; then
# Find the the top-level tests directory
d = $( cd " $TEST_SCRIPTS_DIR " && echo " $PWD " )
if [ -z " $d " ] ; then
local t = " $TEST_SCRIPTS_DIR "
die " Unable to find TEST_SCRIPTS_DIR=\" ${ t } \" "
fi
tests_dir = $( dirname " $d " )
# Strip off current directory from beginning,
# if there, just to make paths more friendly.
tests_dir = " ${ tests_dir # ${ PWD } / } "
find_and_run_one_test " $f " " $tests_dir "
fi
if [ $status -eq 127 ] ; then
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
2018-01-22 11:48:02 +03:00
unit_tests = "
2019-09-09 03:42:11 +03:00
UNIT/cunit
2019-09-09 03:43:38 +03:00
UNIT/eventd
2019-09-09 03:44:45 +03:00
UNIT/eventscripts
2019-09-09 03:47:21 +03:00
UNIT/onnode
2019-09-09 03:48:05 +03:00
UNIT/shellcheck
2019-09-09 03:49:17 +03:00
UNIT/takeover
2019-09-09 03:49:53 +03:00
UNIT/takeover_helper
2018-01-22 11:48:02 +03:00
tool
"
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
set -- UNIT simple
else
set -- simple complex
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
2018-01-22 11:48:02 +03:00
declare -a tests
i = 0
2013-12-02 08:39:48 +04:00
for f ; do
2018-01-22 11:48:02 +03:00
if [ " $f " = "UNIT" ] ; then
for t in $unit_tests ; do
tests[ i++] = " $t "
done
else
tests[ i++] = " $f "
fi
done
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
run_tests " ${ tests [@] } "
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