mirror of
https://github.com/systemd/systemd.git
synced 2025-01-23 02:04:32 +03:00
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).
This commit is contained in:
parent
3a4b86264e
commit
15bbc0c107
126
test/units/test-control.sh
Normal file
126
test/units/test-control.sh
Normal file
@ -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 ]]
|
||||
)}
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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" &>/dev/null; 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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user