diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-05 17:47:29 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-05 17:47:29 +0000 |
commit | 4f5791ebd03eaec1c7da0865a383175b05102712 (patch) | |
tree | 8ce7b00f7a76baa386372422adebbe64510812d4 /ctdb/tests/run_tests.sh | |
parent | Initial commit. (diff) | |
download | samba-4f5791ebd03eaec1c7da0865a383175b05102712.tar.xz samba-4f5791ebd03eaec1c7da0865a383175b05102712.zip |
Adding upstream version 2:4.17.12+dfsg.upstream/2%4.17.12+dfsgupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'ctdb/tests/run_tests.sh')
-rwxr-xr-x | ctdb/tests/run_tests.sh | 399 |
1 files changed, 399 insertions, 0 deletions
diff --git a/ctdb/tests/run_tests.sh b/ctdb/tests/run_tests.sh new file mode 100755 index 0000000..ff431f8 --- /dev/null +++ b/ctdb/tests/run_tests.sh @@ -0,0 +1,399 @@ +#!/usr/bin/env bash + +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 + -C Clean up when done by removing test state directory (see -V) + -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 + -I <count> Iterate tests <count> times, exiting on failure (implies -e, -N) + -l <count> Use <count> daemons for local daemon integration tests + -L Print daemon logs on test failure (only some tests) + -N Don't print summary of tests results after running all tests + -q Quiet - don't show tests being run (still displays summary) + -S <lib> Use socket wrapper library <lib> for local integration tests + -v Verbose - print test output for non-failures (only some tests) + -V <dir> Use <dir> as test state directory + -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 () +{ + echo "$1" >&2 ; exit "${2:-1}" +} + +###################################################################### + +with_summary=true +quiet=false +exit_on_fail=false +max_iterations=1 +no_header=false +test_state_dir="" +cleanup=false +test_time_limit=3600 + +export CTDB_TEST_VERBOSE=false +export CTDB_TEST_COMMAND_TRACE=false +export CTDB_TEST_CAT_RESULTS_OPTS="" +export CTDB_TEST_DIFF_RESULTS=false +export CTDB_TEST_PRINT_LOGS_ON_ERROR=false +export CTDB_TEST_LOCAL_DAEMONS=3 +export CTDB_TEST_SWRAP_SO_PATH="" + +while getopts "AcCDehHI:l:LNqS:T:vV:xX?" opt ; do + case "$opt" in + A) CTDB_TEST_CAT_RESULTS_OPTS="-A" ;; + c) CTDB_TEST_LOCAL_DAEMONS="" ;; + C) cleanup=true ;; + D) CTDB_TEST_DIFF_RESULTS=true ;; + e) exit_on_fail=true ;; + H) no_header=true ;; + I) max_iterations="$OPTARG" ; exit_on_fail=true ; with_summary=false ;; + l) CTDB_TEST_LOCAL_DAEMONS="$OPTARG" ;; + L) CTDB_TEST_PRINT_LOGS_ON_ERROR=true ;; + N) with_summary=false ;; + q) quiet=true ;; + S) CTDB_TEST_SWRAP_SO_PATH="$OPTARG" ;; + T) test_time_limit="$OPTARG" ;; + v) CTDB_TEST_VERBOSE=true ;; + V) test_state_dir="$OPTARG" ;; + x) set -x ;; + X) CTDB_TEST_COMMAND_TRACE=true ;; + \?|h) usage ;; + esac +done +shift $((OPTIND - 1)) + +case $(basename "$0") in + *run_cluster_tests*) + # Running on a cluster... same as -c + CTDB_TEST_LOCAL_DAEMONS="" + ;; +esac + +if $quiet ; then + show_progress() { cat >/dev/null ; } +else + show_progress() { cat ; } +fi + +###################################################################### + +test_header () +{ + local name="$1" + + echo "--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--" + echo "Running test $name ($(date '+%T'))" + echo "--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--" +} + +test_footer () +{ + local f="$1" + local status="$2" + local interp="$3" + local duration="$4" + + local statstr="" + if [ "$status" -eq 0 ] ; then + statstr="" + else + statstr=" (status $status)" + fi + + echo "==========================================================================" + echo "TEST ${interp}: ${f}${statstr} (duration: ${duration}s)" + echo "==========================================================================" +} + +ctdb_test_run () +{ + local f="$1" + + $no_header || test_header "$f" + + local status=0 + local start_time + + start_time=$(date '+%s') + + if [ -x "$f" ] ; then + timeout "$test_time_limit" "$f" </dev/null | show_progress + status=$? + else + echo "TEST IS NOT EXECUTABLE" + status=99 + fi + + local duration=$(($(date +%s) - start_time)) + + tests_total=$((tests_total + 1)) + + local interp + case "$status" in + 0) + interp="PASSED" + tests_passed=$((tests_passed + 1)) + ;; + 77) + interp="SKIPPED" + tests_skipped=$((tests_skipped + 1)) + ;; + 99) + interp="ERROR" + tests_failed=$((tests_failed + 1)) + ;; + 124) + interp="TIMEDOUT" + tests_failed=$((tests_failed + 1)) + ;; + *) + interp="FAILED" + tests_failed=$((tests_failed + 1)) + ;; + esac + + $no_header || test_footer "$f" "$status" "$interp" "$duration" + + 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 + + # Skipped tests should not cause failure + case "$status" in + 77) + status=0 + ;; + esac + + return $status +} + +###################################################################### + +tests_total=0 +tests_passed=0 +tests_skipped=0 +tests_failed=0 + +if ! type mktemp >/dev/null 2>&1 ; then + # Not perfect, but it will do... + mktemp () + { + local dir=false + if [ "$1" = "-d" ] ; then + dir=true + fi + local t="${TMPDIR:-/tmp}/tmp.$$.$RANDOM" + ( + umask 077 + if $dir ; then + mkdir "$t" + else + : >"$t" + fi + ) + echo "$t" + } +fi + +set -o pipefail + +run_one_test () +{ + local f="$1" + + 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 + + # 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}"/}" + + export CTDB_TEST_TMP_DIR="${test_state_dir}/${reldir}" + rm -rf "$CTDB_TEST_TMP_DIR" + mkdir -p "$CTDB_TEST_TMP_DIR" + + ctdb_test_run "$f" + status=$? +} + +run_tests () +{ + local f + + for f ; do + case "$f" in + */README|*/README.md) + continue + ;; + esac + + if [ ! -e "$f" ] ; then + # Can't find it? Check relative to CTDB_TEST_DIR. + # Strip off current directory from beginning, + # if there, just to make paths more friendly. + f="${CTDB_TEST_DIR#"${PWD}"/}/${f}" + fi + + if [ -d "$f" ] ; then + 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" + ;; + */*) + # This is a test suite + subtests=$(echo "${f%/}/"*".sh") + if [ "$subtests" = "${f%/}/*.sh" ] ; then + # Probably empty directory + die "test \"$f\" is not recognised" + fi + ;; + CLUSTER|INTEGRATION|UNIT) + # 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 + elif [ -f "$f" ] ; then + run_one_test "$f" + else + # Time to give up + die "test \"$f\" is not recognised" + fi + + if $exit_on_fail && [ $status -ne 0 ] ; then + return $status + fi + done +} + +export CTDB_TEST_MODE="yes" + +# Following 2 lines may be modified by installation script +CTDB_TESTS_ARE_INSTALLED=false +CTDB_TEST_DIR=$(dirname "$0") +export CTDB_TESTS_ARE_INSTALLED CTDB_TEST_DIR + +if [ -z "$test_state_dir" ] ; then + if $CTDB_TESTS_ARE_INSTALLED ; then + test_state_dir=$(mktemp -d) + else + test_state_dir="${CTDB_TEST_DIR}/var" + fi +fi +mkdir -p "$test_state_dir" + +summary_file="${test_state_dir}/.summary" +: >"$summary_file" + +export TEST_SCRIPTS_DIR="${CTDB_TEST_DIR}/scripts" + +# If no tests specified then run some defaults +if [ -z "$1" ] ; then + if [ -n "$CTDB_TEST_LOCAL_DAEMONS" ] ; then + set -- UNIT INTEGRATION + else + set -- INTEGRATION CLUSTER + fi +fi + +do_cleanup () +{ + if $cleanup ; then + echo "Removing test state directory: ${test_state_dir}" + rm -rf "$test_state_dir" + else + echo "Not cleaning up test state directory: ${test_state_dir}" + fi +} + +trap "do_cleanup ; exit 130" SIGINT +trap "do_cleanup ; exit 143" SIGTERM + +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 "$@" + status=$? + + if [ $status -ne 0 ] ; then + break + fi +done + +if $with_summary ; then + if [ $status -eq 0 ] || ! $exit_on_fail ; then + echo + cat "$summary_file" + + echo + 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' + fi +fi +rm -f "$summary_file" + +echo + +do_cleanup + +if $no_header || $exit_on_fail ; then + exit $status +elif [ $tests_failed -gt 0 ] ; then + exit 1 +else + exit 0 +fi |