summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2023-09-06 13:52:17 +0200
committerFlorian Westphal <fw@strlen.de>2023-09-07 19:35:20 +0200
commit8ba377f5d1954bc662ec4bedfb2f3d7c1ae66428 (patch)
treeb1c95a1bbb0df18ac491599610820bf3fcde22ae
parent63739f4b7f923def1db8e2d988ad18d021a9cf2e (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-xtests/shell/run-tests.sh86
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