313 lines
8.3 KiB
Diff
313 lines
8.3 KiB
Diff
From 47664038ed253f30518f434fb2967286c9382e7f Mon Sep 17 00:00:00 2001
|
|
From: Frantisek Sumsal <frantisek@sumsal.cz>
|
|
Date: Wed, 10 May 2023 21:12:01 +0200
|
|
Subject: [PATCH] test: abstract the common test parts into a utility script
|
|
|
|
Also, instead of bailing out on the first failed subtest, always run all
|
|
subtests and print a summary at the end (with an appropriate exit code).
|
|
|
|
(cherry picked from commit 15bbc0c1071c439d83e711ef7786d401b6c0a0d4)
|
|
|
|
Related: #2213521
|
|
---
|
|
test/units/test-control.sh | 126 +++++++++++++++++++++++++++++++++++++
|
|
test/units/testsuite-07.sh | 8 +--
|
|
test/units/testsuite-17.sh | 7 ++-
|
|
test/units/testsuite-22.sh | 7 ++-
|
|
test/units/testsuite-23.sh | 59 ++---------------
|
|
test/units/testsuite-74.sh | 8 +--
|
|
6 files changed, 146 insertions(+), 69 deletions(-)
|
|
create mode 100644 test/units/test-control.sh
|
|
|
|
diff --git a/test/units/test-control.sh b/test/units/test-control.sh
|
|
new file mode 100644
|
|
index 0000000000..dd28939cbf
|
|
--- /dev/null
|
|
+++ b/test/units/test-control.sh
|
|
@@ -0,0 +1,126 @@
|
|
+# SPDX-License-Identifier: LGPL-2.1-or-later
|
|
+# shellcheck shell=bash
|
|
+
|
|
+if [[ "${BASH_SOURCE[0]}" -ef "$0" ]]; then
|
|
+ echo >&2 "This file should not be executed directly"
|
|
+ exit 1
|
|
+fi
|
|
+
|
|
+declare -i CHILD_PID=0
|
|
+PASSED_TESTS=()
|
|
+FAILED_TESTS=()
|
|
+
|
|
+# Like trap, but passes the signal name as the first argument
|
|
+trap_with_sig() {
|
|
+ local fun="${1:?}"
|
|
+ local sig
|
|
+ shift
|
|
+
|
|
+ for sig in "$@"; do
|
|
+ # shellcheck disable=SC2064
|
|
+ trap "$fun $sig" "$sig"
|
|
+ done
|
|
+}
|
|
+
|
|
+# Propagate the caught signal to the current child process
|
|
+handle_signal() {
|
|
+ local sig="${1:?}"
|
|
+
|
|
+ if [[ $CHILD_PID -gt 0 ]]; then
|
|
+ echo "Propagating signal $sig to child process $CHILD_PID"
|
|
+ kill -s "$sig" "$CHILD_PID"
|
|
+ fi
|
|
+}
|
|
+
|
|
+# In order to make the handle_signal() stuff above work, we have to execute
|
|
+# each script asynchronously, since bash won't execute traps until the currently
|
|
+# executed command finishes. This, however, introduces another issue regarding
|
|
+# how bash's wait works. Quoting:
|
|
+#
|
|
+# When bash is waiting for an asynchronous command via the wait builtin,
|
|
+# the reception of a signal for which a trap has been set will cause the wait
|
|
+# builtin to return immediately with an exit status greater than 128,
|
|
+# immediately after which the trap is executed.
|
|
+#
|
|
+# In other words - every time we propagate a signal, wait returns with
|
|
+# 128+signal, so we have to wait again - repeat until the process dies.
|
|
+wait_harder() {
|
|
+ local pid="${1:?}"
|
|
+
|
|
+ while kill -0 "$pid" &>/dev/null; do
|
|
+ wait "$pid" || :
|
|
+ done
|
|
+
|
|
+ wait "$pid"
|
|
+}
|
|
+
|
|
+# Like run_subtests, but propagate specified signals to the subtest script
|
|
+run_subtests_with_signals() {
|
|
+ local subtests=("${0%.sh}".*.sh)
|
|
+ local subtest
|
|
+
|
|
+ if [[ "${#subtests[@]}" -eq 0 ]]; then
|
|
+ echo >&2 "No subtests found for file $0"
|
|
+ exit 1
|
|
+ fi
|
|
+
|
|
+ if [[ "$#" -eq 0 ]]; then
|
|
+ echo >&2 "No signals to propagate were specified"
|
|
+ exit 1
|
|
+ fi
|
|
+
|
|
+ trap_with_sig handle_signal "$@"
|
|
+
|
|
+ for subtest in "${subtests[@]}"; do
|
|
+ : "--- $subtest BEGIN ---"
|
|
+ "./$subtest" &
|
|
+ CHILD_PID=$!
|
|
+ wait_harder "$CHILD_PID" && PASSED_TESTS+=("$subtest") || FAILED_TESTS+=("$subtest")
|
|
+ : "--- $subtest END ---"
|
|
+ done
|
|
+
|
|
+ show_summary
|
|
+}
|
|
+
|
|
+run_subtests() {
|
|
+ local subtests=("${0%.sh}".*.sh)
|
|
+ local subtest
|
|
+
|
|
+ if [[ "${#subtests[@]}" -eq 0 ]]; then
|
|
+ echo >&2 "No subtests found for file $0"
|
|
+ exit 1
|
|
+ fi
|
|
+
|
|
+ for subtest in "${subtests[@]}"; do
|
|
+ : "--- $subtest BEGIN ---"
|
|
+ "./$subtest" && PASSED_TESTS+=("$subtest") || FAILED_TESTS+=("$subtest")
|
|
+ : "--- $subtest END ---"
|
|
+ done
|
|
+
|
|
+ show_summary
|
|
+}
|
|
+
|
|
+show_summary() {(
|
|
+ set +x
|
|
+
|
|
+ if [[ ${#PASSED_TESTS[@]} -eq 0 && ${#FAILED_TESTS[@]} -eq 0 ]]; then
|
|
+ echo >&2 "No tests were executed, this is most likely an error"
|
|
+ exit 1
|
|
+ fi
|
|
+
|
|
+ printf "PASSED TESTS: %3d:\n" "${#PASSED_TESTS[@]}"
|
|
+ echo "------------------"
|
|
+ for t in "${PASSED_TESTS[@]}"; do
|
|
+ echo "$t"
|
|
+ done
|
|
+
|
|
+ if [[ "${#FAILED_TESTS[@]}" -ne 0 ]]; then
|
|
+ printf "FAILED TESTS: %3d:\n" "${#FAILED_TESTS[@]}"
|
|
+ echo "------------------"
|
|
+ for t in "${FAILED_TESTS[@]}"; do
|
|
+ echo "$t"
|
|
+ done
|
|
+ fi
|
|
+
|
|
+ [[ "${#FAILED_TESTS[@]}" -eq 0 ]]
|
|
+)}
|
|
diff --git a/test/units/testsuite-07.sh b/test/units/testsuite-07.sh
|
|
index 8c004a72e5..58d278e1f1 100755
|
|
--- a/test/units/testsuite-07.sh
|
|
+++ b/test/units/testsuite-07.sh
|
|
@@ -3,16 +3,16 @@
|
|
set -eux
|
|
set -o pipefail
|
|
|
|
+# shellcheck source=test/units/test-control.sh
|
|
+. "$(dirname "$0")"/test-control.sh
|
|
+
|
|
: >/failed
|
|
|
|
# Issue: https://github.com/systemd/systemd/issues/2730
|
|
# See TEST-07-PID1/test.sh for the first "half" of the test
|
|
mountpoint /issue2730
|
|
|
|
-for script in "${0%.sh}".*.sh; do
|
|
- echo "Running $script"
|
|
- "./$script"
|
|
-done
|
|
+run_subtests
|
|
|
|
touch /testok
|
|
rm /failed
|
|
diff --git a/test/units/testsuite-17.sh b/test/units/testsuite-17.sh
|
|
index b389875ef1..72040f69d8 100755
|
|
--- a/test/units/testsuite-17.sh
|
|
+++ b/test/units/testsuite-17.sh
|
|
@@ -3,13 +3,14 @@
|
|
set -eux
|
|
set -o pipefail
|
|
|
|
+# shellcheck source=test/units/test-control.sh
|
|
+. "$(dirname "$0")"/test-control.sh
|
|
+
|
|
: >/failed
|
|
|
|
udevadm settle
|
|
|
|
-for t in "${0%.sh}".*.sh; do
|
|
- echo "Running $t"; ./"$t"
|
|
-done
|
|
+run_subtests
|
|
|
|
touch /testok
|
|
rm /failed
|
|
diff --git a/test/units/testsuite-22.sh b/test/units/testsuite-22.sh
|
|
index 43823f1d46..5a07e7b78c 100755
|
|
--- a/test/units/testsuite-22.sh
|
|
+++ b/test/units/testsuite-22.sh
|
|
@@ -3,11 +3,12 @@
|
|
set -eux
|
|
set -o pipefail
|
|
|
|
+# shellcheck source=test/units/test-control.sh
|
|
+. "$(dirname "$0")"/test-control.sh
|
|
+
|
|
: >/failed
|
|
|
|
-for t in "${0%.sh}".*.sh; do
|
|
- echo "Running $t"; ./"$t"
|
|
-done
|
|
+run_subtests
|
|
|
|
touch /testok
|
|
rm /failed
|
|
diff --git a/test/units/testsuite-23.sh b/test/units/testsuite-23.sh
|
|
index a6b8da34c9..3be645e20a 100755
|
|
--- a/test/units/testsuite-23.sh
|
|
+++ b/test/units/testsuite-23.sh
|
|
@@ -5,62 +5,11 @@ set -o pipefail
|
|
|
|
: >/failed
|
|
|
|
-declare -i CHILD_PID=0
|
|
+# shellcheck source=test/units/test-control.sh
|
|
+. "$(dirname "$0")"/test-control.sh
|
|
|
|
-# Note: all the signal shenanigans are necessary for the Upholds= tests
|
|
-
|
|
-# Like trap, but passes the signal name as the first argument
|
|
-trap_with_sig() {
|
|
- local fun="${1:?}"
|
|
- local sig
|
|
- shift
|
|
-
|
|
- for sig in "$@"; do
|
|
- # shellcheck disable=SC2064
|
|
- trap "$fun $sig" "$sig"
|
|
- done
|
|
-}
|
|
-
|
|
-# Propagate the caught signal to the current child process
|
|
-handle_signal() {
|
|
- local sig="${1:?}"
|
|
-
|
|
- if [[ $CHILD_PID -gt 0 ]]; then
|
|
- echo "Propagating signal $sig to child process $CHILD_PID"
|
|
- kill -s "$sig" "$CHILD_PID"
|
|
- fi
|
|
-}
|
|
-
|
|
-# In order to make the handle_signal() stuff above work, we have to execute
|
|
-# each script asynchronously, since bash won't execute traps until the currently
|
|
-# executed command finishes. This, however, introduces another issue regarding
|
|
-# how bash's wait works. Quoting:
|
|
-#
|
|
-# When bash is waiting for an asynchronous command via the wait builtin,
|
|
-# the reception of a signal for which a trap has been set will cause the wait
|
|
-# builtin to return immediately with an exit status greater than 128,
|
|
-# immediately after which the trap is executed.
|
|
-#
|
|
-# In other words - every time we propagate a signal, wait returns with
|
|
-# 128+signal, so we have to wait again - repeat until the process dies.
|
|
-wait_harder() {
|
|
- local pid="${1:?}"
|
|
-
|
|
- while kill -0 "$pid"; do
|
|
- wait "$pid" || :
|
|
- done
|
|
-
|
|
- wait "$pid"
|
|
-}
|
|
-
|
|
-trap_with_sig handle_signal SIGUSR1 SIGUSR2 SIGRTMIN+1
|
|
-
|
|
-for script in "${0%.sh}".*.sh; do
|
|
- echo "Running $script"
|
|
- "./$script" &
|
|
- CHILD_PID=$!
|
|
- wait_harder "$CHILD_PID"
|
|
-done
|
|
+# Note: the signal shenanigans are necessary for the Upholds= tests
|
|
+run_subtests_with_signals SIGUSR1 SIGUSR2 SIGRTMIN+1
|
|
|
|
touch /testok
|
|
rm /failed
|
|
diff --git a/test/units/testsuite-74.sh b/test/units/testsuite-74.sh
|
|
index 13c767e490..5a07e7b78c 100755
|
|
--- a/test/units/testsuite-74.sh
|
|
+++ b/test/units/testsuite-74.sh
|
|
@@ -3,12 +3,12 @@
|
|
set -eux
|
|
set -o pipefail
|
|
|
|
+# shellcheck source=test/units/test-control.sh
|
|
+. "$(dirname "$0")"/test-control.sh
|
|
+
|
|
: >/failed
|
|
|
|
-for script in "${0%.sh}".*.sh; do
|
|
- echo "Running $script"
|
|
- "./$script"
|
|
-done
|
|
+run_subtests
|
|
|
|
touch /testok
|
|
rm /failed
|