diff options
author | Thomas Haller <thaller@redhat.com> | 2023-09-06 13:52:17 +0200 |
---|---|---|
committer | Florian Westphal <fw@strlen.de> | 2023-09-07 19:35:20 +0200 |
commit | 8ba377f5d1954bc662ec4bedfb2f3d7c1ae66428 (patch) | |
tree | b1c95a1bbb0df18ac491599610820bf3fcde22ae | |
parent | 63739f4b7f923def1db8e2d988ad18d021a9cf2e (diff) |
tests/shell: support running tests in parallel
Add option to enable running jobs in parallel. The purpose is to speed
up the run time of the tests.
The global cleanup (removal of kernel modules) interferes with parallel
jobs (or even with, unrelated jobs on the system). By setting
NFT_TEST_JOBS= to a positive number, that cleanup is skipped.
This option is too good to miss. Hence parallel execution is enabled by
default, and you have to opt-out from it.
Signed-off-by: Thomas Haller <thaller@redhat.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
-rwxr-xr-x | tests/shell/run-tests.sh | 86 |
1 files changed, 73 insertions, 13 deletions
diff --git a/tests/shell/run-tests.sh b/tests/shell/run-tests.sh index b49877fe..1af1c0f3 100755 --- a/tests/shell/run-tests.sh +++ b/tests/shell/run-tests.sh @@ -52,6 +52,7 @@ usage() { echo " -R|--without-realroot : Sets NFT_TEST_HAS_REALROOT=n." echo " -U|--no-unshare : Sets NFT_TEST_UNSHARE_CMD=\"\"." echo " -k|--keep-logs : Sets NFT_TEST_KEEP_LOGS=y." + echo " -s|--sequential : Sets NFT_TEST_JOBS=0, which also enables global cleanups." echo " -- : Separate options from tests." echo " [TESTS...] : Other options are treated as test names," echo " that is, executables that are run by the runner." @@ -89,6 +90,11 @@ usage() { echo " Test may consider this." echo " This is only honored when \$NFT_TEST_UNSHARE_CMD= is set. Otherwise it's detected." echo " NFT_TEST_KEEP_LOGS=*|y: Keep the temp directory. On success, it will be deleted by default." + echo " NFT_TEST_JOBS=<NUM}>: number of jobs for parallel execution. Defaults to \"12\" for parallel run." + echo " Setting this to \"0\" or \"1\", means to run jobs sequentially." + echo " Setting this to \"0\" means also to perform global cleanups between tests (remove" + echo " kernel modules)." + echo " Parallel jobs requires unshare and are disabled with NFT_TEST_UNSHARE_CMD=\"\"." echo " TMPDIR=<PATH> : select a different base directory for the result data." } @@ -103,6 +109,7 @@ VALGRIND="$(bool_y "$VALGRIND")" KMEMLEAK="$(bool_y "$KMEMLEAK")" NFT_TEST_KEEP_LOGS="$(bool_y "$NFT_TEST_KEEP_LOGS")" NFT_TEST_HAS_REALROOT="$NFT_TEST_HAS_REALROOT" +NFT_TEST_JOBS="${NFT_TEST_JOBS:-12}" DO_LIST_TESTS= TESTS=() @@ -139,6 +146,9 @@ while [ $# -gt 0 ] ; do -U|--no-unshare) NFT_TEST_UNSHARE_CMD= ;; + -s|--sequential) + NFT_TEST_JOBS=0 + ;; --) TESTS+=( "$@" ) shift $# @@ -236,6 +246,14 @@ fi # If tests wish, they can know whether they are unshared via this variable. export NFT_TEST_HAS_UNSHARED +# normalize the jobs number to be an integer. +case "$NFT_TEST_JOBS" in + ''|*[!0-9]*) NFT_TEST_JOBS=12 ;; +esac +if [ -z "$NFT_TEST_UNSHARE_CMD" -a "$NFT_TEST_JOBS" -gt 1 ] ; then + NFT_TEST_JOBS=1 +fi + [ -z "$NFT" ] && NFT="$NFT_TEST_BASEDIR/../../src/nft" ${NFT} > /dev/null 2>&1 ret=$? @@ -243,9 +261,11 @@ if [ ${ret} -eq 126 ] || [ ${ret} -eq 127 ]; then msg_error "cannot execute nft command: $NFT" fi -MODPROBE="$(which modprobe)" -if [ ! -x "$MODPROBE" ] ; then - msg_error "no modprobe binary found" +if [ "$NFT_TEST_JOBS" -eq 0 ] ; then + MODPROBE="$(which modprobe)" + if [ ! -x "$MODPROBE" ] ; then + msg_error "no modprobe binary found" + fi fi DIFF="$(which diff)" @@ -276,6 +296,7 @@ msg_info "conf: NFT_TEST_HAS_REALROOT=$(printf '%q' "$NFT_TEST_HAS_REALROOT")" msg_info "conf: NFT_TEST_UNSHARE_CMD=$(printf '%q' "$NFT_TEST_UNSHARE_CMD")" msg_info "conf: NFT_TEST_HAS_UNSHARED=$(printf '%q' "$NFT_TEST_HAS_UNSHARED")" msg_info "conf: NFT_TEST_KEEP_LOGS=$(printf '%q' "$NFT_TEST_KEEP_LOGS")" +msg_info "conf: NFT_TEST_JOBS=$NFT_TEST_JOBS" msg_info "conf: TMPDIR=$(printf '%q' "$_TMPDIR")" NFT_TEST_LATEST="$_TMPDIR/nft-test.latest.$USER" @@ -291,6 +312,11 @@ msg_info "info: NFT_TEST_BASEDIR=$(printf '%q' "$NFT_TEST_BASEDIR")" msg_info "info: NFT_TEST_TMPDIR=$(printf '%q' "$NFT_TEST_TMPDIR")" kernel_cleanup() { + if [ "$NFT_TEST_JOBS" -ne 0 ] ; then + # When we run jobs in parallel (even with only one "parallel" + # job via `NFT_TEST_JOBS=1`), we skip such global cleanups. + return + fi if [ "$NFT_TEST_HAS_UNSHARED" != y ] ; then $NFT flush ruleset fi @@ -428,28 +454,62 @@ print_test_result() { fi } +declare -A JOBS_TEMPDIR +declare -A JOBS_PIDLIST + +job_start() { + local testfile="$1" + + if [ "$NFT_TEST_JOBS" -le 1 ] ; then + print_test_header I "$testfile" "EXECUTING" "" + fi + + NFT_TEST_TESTTMPDIR="${JOBS_TEMPDIR["$testfile"]}" \ + NFT="$NFT" NFT_REAL="$NFT_REAL" DIFF="$DIFF" DUMPGEN="$DUMPGEN" $NFT_TEST_UNSHARE_CMD "$NFT_TEST_BASEDIR/helpers/test-wrapper.sh" "$testfile" + local rc_got=$? + + if [ "$NFT_TEST_JOBS" -le 1 ] ; then + echo -en "\033[1A\033[K" # clean the [EXECUTING] foobar line + fi + + return "$rc_got" +} + +job_wait() +{ + local num_jobs="$1" + + while [ "$JOBS_N_RUNNING" -gt 0 -a "$JOBS_N_RUNNING" -ge "$num_jobs" ] ; do + wait -n -p JOBCOMPLETED + local rc_got="$?" + testfile2="${JOBS_PIDLIST[$JOBCOMPLETED]}" + print_test_result "${JOBS_TEMPDIR["$testfile2"]}" "$testfile2" "$rc_got" + ((JOBS_N_RUNNING--)) + check_kmemleak + done +} + TESTIDX=0 +JOBS_N_RUNNING=0 for testfile in "${TESTS[@]}" ; do + job_wait "$NFT_TEST_JOBS" + kernel_cleanup ((TESTIDX++)) - # We also create and export a test-specific temporary directory. NFT_TEST_TESTTMPDIR="$NFT_TEST_TMPDIR/test-${testfile//\//-}.$TESTIDX" mkdir "$NFT_TEST_TESTTMPDIR" chmod 755 "$NFT_TEST_TESTTMPDIR" - export NFT_TEST_TESTTMPDIR - - print_test_header I "$testfile" "EXECUTING" "" - NFT="$NFT" NFT_REAL="$NFT_REAL" DIFF="$DIFF" DUMPGEN="$DUMPGEN" $NFT_TEST_UNSHARE_CMD "$NFT_TEST_BASEDIR/helpers/test-wrapper.sh" "$testfile" - rc_got=$? - echo -en "\033[1A\033[K" # clean the [EXECUTING] foobar line - - print_test_result "$NFT_TEST_TESTTMPDIR" "$testfile" "$rc_got" + JOBS_TEMPDIR["$testfile"]="$NFT_TEST_TESTTMPDIR" - check_kmemleak + job_start "$testfile" & + JOBS_PIDLIST[$!]="$testfile" + ((JOBS_N_RUNNING++)) done +job_wait 0 + echo "" # kmemleak may report suspected leaks |