test: report subtest skips (#43387)
`run_subtests` now handle exit 77 as skip status, making successful subtests distinguishable from passed tests. Introduce `run_subtests_and_exit` as a helper to automatically write `/testok` if all subtests passed, and to write `/skipped` and exit 77 if all subtests were skipped.
This commit is contained in:
@@ -8,7 +8,7 @@ set -o pipefail
|
||||
|
||||
if ! cgroupfs_supports_user_xattrs; then
|
||||
echo "CGroup does not support user xattrs, skipping LogFilterPatterns= tests."
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
# Unfortunately, journalctl -I/--invocation= is unstable when debug logging is enabled on service manager.
|
||||
|
||||
@@ -5,12 +5,12 @@ set -o pipefail
|
||||
|
||||
if systemd-detect-virt -cq; then
|
||||
echo "This test requires a VM, skipping the test"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
if [[ ! -x /usr/lib/systemd/systemd-bsod ]]; then
|
||||
echo "systemd-bsod is not installed, skipping the test"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
# shellcheck disable=SC2317
|
||||
|
||||
@@ -7,7 +7,7 @@ set -o pipefail
|
||||
|
||||
if ! journalctl --version | grep -F +OPENSSL >/dev/null; then
|
||||
echo "Built without openssl, skipping the FSS tests"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
# output key and related info in json format
|
||||
|
||||
@@ -5,7 +5,7 @@ set -o pipefail
|
||||
|
||||
if [[ ! -x /usr/lib/systemd/systemd-journal-gatewayd ]]; then
|
||||
echo "Built without systemd-journal-gatewayd support, skipping the test"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
LOG_FILE="$(mktemp)"
|
||||
|
||||
@@ -6,12 +6,12 @@ set -o pipefail
|
||||
|
||||
if [[ ! -x /usr/lib/systemd/systemd-journal-remote || ! -x /usr/lib/systemd/systemd-journal-upload ]]; then
|
||||
echo "Built without systemd-journal-remote/upload support, skipping the test"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
if ! command -v openssl >/dev/null; then
|
||||
echo "openssl command not available, skipping the tests"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
at_exit() {
|
||||
|
||||
@@ -6,6 +6,4 @@ set -o pipefail
|
||||
# shellcheck source=test/units/test-control.sh
|
||||
. "$(dirname "$0")"/test-control.sh
|
||||
|
||||
run_subtests
|
||||
|
||||
touch /testok
|
||||
run_subtests_and_exit
|
||||
|
||||
@@ -6,6 +6,4 @@ set -o pipefail
|
||||
# shellcheck source=test/units/test-control.sh
|
||||
. "$(dirname "$0")"/test-control.sh
|
||||
|
||||
run_subtests
|
||||
|
||||
touch /testok
|
||||
run_subtests_and_exit
|
||||
|
||||
@@ -8,7 +8,7 @@ if [[ -v ASAN_OPTIONS ]]; then
|
||||
# Under sanitizers the service is slow enough that the calendar timer with 5s resolution ends up
|
||||
# missing ticks, making the test flaky
|
||||
echo "Sanitizers detected, skipping the test..."
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
systemctl start defer-reactivation.timer
|
||||
|
||||
@@ -11,7 +11,7 @@ private_ipcns=$(systemd-run --quiet --wait --pipe -p PrivateIPC=yes readlink /pr
|
||||
|
||||
if [[ ! -d /proc/sys/fs/mqueue ]]; then
|
||||
echo "POSIX message queues are not supported, skipping ownership checks"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
# Verify ownership attributes are applied to message queues
|
||||
|
||||
@@ -5,7 +5,7 @@ set -o pipefail
|
||||
|
||||
if ! command -v nft >/dev/null; then
|
||||
echo "nftables is not installed. Skipped NFTSet= tests."
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
RUN_OUT="$(mktemp)"
|
||||
|
||||
@@ -9,7 +9,7 @@ set -o pipefail
|
||||
|
||||
if ! can_do_rootless_nspawn; then
|
||||
echo "Skipping unpriv nspawn test"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
# We need FSCONFIG_SET_FD support in overlayfs for .mstack to work. Let's skip
|
||||
@@ -18,7 +18,7 @@ fi
|
||||
# support for this from shell, hence let's do a version check instead.
|
||||
if systemd-analyze condition 'ConditionVersion= < 6.13' ; then
|
||||
echo "Kernel too old for FSCONFIG_SET_FD support on overlayfs, skipping pull-oci test".
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
export SYSTEMD_LOG_LEVEL=debug
|
||||
|
||||
@@ -18,6 +18,4 @@ fi
|
||||
# shellcheck source=test/units/test-control.sh
|
||||
. "$(dirname "$0")"/test-control.sh
|
||||
|
||||
run_subtests
|
||||
|
||||
touch /testok
|
||||
run_subtests_and_exit
|
||||
|
||||
@@ -9,7 +9,7 @@ set -o pipefail
|
||||
|
||||
if ! can_do_rootless_nspawn; then
|
||||
echo "Skipping unpriv nspawn test"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
at_exit() {
|
||||
|
||||
@@ -5,7 +5,7 @@ set -o pipefail
|
||||
|
||||
if ! command -v systemd-hwdb >/dev/null; then
|
||||
echo "systemd-hwdb not found, skipping."
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
# shellcheck source=test/units/util.sh
|
||||
|
||||
@@ -28,7 +28,7 @@ udevadm wait --settle --timeout=30 /sys/class/net/test1
|
||||
output=$(ip link show dev test1)
|
||||
if ! [[ "$output" =~ altname ]]; then
|
||||
echo "alternative name for network interface not supported, skipping test."
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
assert_not_in "altname test1" "$output"
|
||||
assert_in "altname test2" "$output"
|
||||
|
||||
@@ -8,6 +8,4 @@ set -o pipefail
|
||||
|
||||
udevadm settle
|
||||
|
||||
run_subtests
|
||||
|
||||
touch /testok
|
||||
run_subtests_and_exit
|
||||
|
||||
@@ -8,7 +8,7 @@ set -eux
|
||||
|
||||
if [[ "$(get_cgroup_hierarchy)" != unified ]]; then
|
||||
echo "Skipping $0 as we're not running with the unified cgroup hierarchy"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
# Multiple level process tree, parent process stays up
|
||||
|
||||
@@ -8,12 +8,12 @@ set -o pipefail
|
||||
|
||||
if [[ "$(get_cgroup_hierarchy)" != unified ]]; then
|
||||
echo "Skipping $0 as we're not running with the unified cgroup hierarchy."
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
if systemd-detect-virt --container --quiet; then
|
||||
echo "Skipping $0 as we're running on container."
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
ip netns add test-ns
|
||||
|
||||
@@ -22,7 +22,7 @@ set -o pipefail
|
||||
. /etc/os-release
|
||||
if [[ "$ID" =~ opensuse ]]; then
|
||||
echo "Skipping cgroup test with too small MemoryMax= setting on openSUSE."
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
cat >/run/systemd/system/testslice.slice <<EOF
|
||||
|
||||
@@ -13,7 +13,7 @@ set -o pipefail
|
||||
|
||||
if [[ "$(get_cgroup_hierarchy)" != unified ]]; then
|
||||
echo "Skipping $0 as we're not running with the unified cgroup hierarchy"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
testcase_controllers() {
|
||||
|
||||
@@ -10,7 +10,7 @@ set -o pipefail
|
||||
|
||||
if [[ "$(get_cgroup_hierarchy)" != unified ]]; then
|
||||
echo "Skipping $0 as we're not running with the unified cgroup hierarchy"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
testcase_iodevice_dbus () {
|
||||
|
||||
@@ -6,6 +6,4 @@ set -o pipefail
|
||||
# shellcheck source=test/units/test-control.sh
|
||||
. "$(dirname "$0")"/test-control.sh
|
||||
|
||||
run_subtests
|
||||
|
||||
touch /testok
|
||||
run_subtests_and_exit
|
||||
|
||||
@@ -14,6 +14,4 @@ if systemd-detect-virt --quiet --container; then
|
||||
ln -s /dev/null /run/tmpfiles.d/selinux-policy.conf
|
||||
fi
|
||||
|
||||
run_subtests
|
||||
|
||||
touch /testok
|
||||
run_subtests_and_exit
|
||||
|
||||
@@ -7,6 +7,4 @@ set -o pipefail
|
||||
. "$(dirname "$0")"/test-control.sh
|
||||
|
||||
# Note: the signal shenanigans are necessary for the Upholds= tests
|
||||
run_subtests_with_signals SIGUSR1 SIGUSR2 SIGRTMIN+1
|
||||
|
||||
touch /testok
|
||||
run_subtests_with_signals_and_exit SIGUSR1 SIGUSR2 SIGRTMIN+1
|
||||
|
||||
@@ -11,12 +11,12 @@ UNIT_FILE_LIST="/usr/lib/systemd/tests/testdata/installed-unit-files.txt"
|
||||
|
||||
if [[ ! -f "$UNIT_FILE_LIST" ]]; then
|
||||
echo "Couldn't find the list of installed units, skipping the test"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
if ! command -v systemd-analyze >/dev/null; then
|
||||
echo "Built without systemd-analyze, skipping the test"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
mapfile -t UNIT_FILES <"$UNIT_FILE_LIST"
|
||||
|
||||
@@ -18,7 +18,7 @@ if [[ ! -f /usr/lib/systemd/system/systemd-mountfsd.socket ]] ||
|
||||
systemd-analyze compare-versions "$(pkcheck --version | awk '{print $3}')" lt 124 ||
|
||||
systemctl --version | grep -- "-BTF" >/dev/null; then
|
||||
echo "Skipping mountfsd/nsresourced tests"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
systemctl start systemd-mountfsd.socket systemd-nsresourced.socket
|
||||
|
||||
@@ -14,7 +14,7 @@ if [[ ! -f /usr/lib/systemd/system/systemd-mountfsd.socket ]] ||
|
||||
systemd-analyze compare-versions "$(uname -r)" lt 6.5 ||
|
||||
systemd-analyze compare-versions "$(pkcheck --version | awk '{print $3}')" lt 124; then
|
||||
echo "Skipping mountfsd/nsresourced tests"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
at_exit() {
|
||||
|
||||
@@ -6,6 +6,4 @@ set -o pipefail
|
||||
# shellcheck source=test/units/test-control.sh
|
||||
. "$(dirname "$0")"/test-control.sh
|
||||
|
||||
run_subtests
|
||||
|
||||
touch /testok
|
||||
run_subtests_and_exit
|
||||
|
||||
@@ -20,7 +20,7 @@ trap at_exit EXIT
|
||||
# There is an external issue with libcryptsetup on ppc64 that hits 95% of Ubuntu ppc64 test runs, so skip it
|
||||
if [[ "$(uname -m)" == "ppc64le" ]]; then
|
||||
echo "Skipping systemd-cryptenroll tests on ppc64le, see https://github.com/systemd/systemd/issues/27716"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
export SYSTEMD_LOG_LEVEL=debug
|
||||
|
||||
@@ -17,7 +17,7 @@ export SYSTEMD_LOG_LEVEL=debug
|
||||
|
||||
if ! command -v systemd-cryptsetup >/dev/null || ! tpm_has_pcr sha256 15; then
|
||||
echo "systemd-cryptsetup or PCR 15 (sha256) not available, skipping cryptsetup measurement test"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
IMAGE=""
|
||||
|
||||
@@ -11,7 +11,7 @@ SD_MEASURE="/usr/lib/systemd/systemd-measure"
|
||||
|
||||
if [[ ! -x "${SD_MEASURE:?}" ]]; then
|
||||
echo "$SD_MEASURE not found, skipping the test"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
at_exit() {
|
||||
|
||||
@@ -13,7 +13,7 @@ SD_MEASURE="/usr/lib/systemd/systemd-measure"
|
||||
|
||||
if [[ ! -x "${SD_PCREXTEND:?}" ]] || [[ ! -x "${SD_MEASURE:?}" ]] || ! tpm_has_pcr sha256 11; then
|
||||
echo "$SD_PCREXTEND, $SD_MEASURE or PCR sysfs files not found, skipping PCR extension tests"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
at_exit() {
|
||||
|
||||
@@ -11,7 +11,7 @@ SD_PCREXTEND="/usr/lib/systemd/systemd-pcrextend"
|
||||
|
||||
if [[ ! -x "${SD_PCREXTEND:?}" ]] || ! tpm_has_pcr sha256 16 || ! tpm_has_pcr sha256 15; then
|
||||
echo "$SD_PCREXTEND or PCR sysfs files not found, skipping PCR extension tests"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
at_exit() {
|
||||
|
||||
@@ -14,7 +14,7 @@ SD_MEASURE="/usr/lib/systemd/systemd-measure"
|
||||
|
||||
if [[ ! -x "${SD_PCREXTEND:?}" ]] || [[ ! -x "${SD_PCRLOCK:?}" ]] || [[ ! -x "${SD_MEASURE:?}" ]] ; then
|
||||
echo "$SD_PCREXTEND or $SD_PCRLOCK or $SD_MEASURE not found, skipping pcrlock tests"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
at_exit() {
|
||||
|
||||
@@ -6,6 +6,4 @@ set -o pipefail
|
||||
# shellcheck source=test/units/test-control.sh
|
||||
. "$(dirname "$0")"/test-control.sh
|
||||
|
||||
run_subtests
|
||||
|
||||
touch /testok
|
||||
run_subtests_and_exit
|
||||
|
||||
@@ -8,7 +8,7 @@ SD_TPM2SETUP="/usr/lib/systemd/systemd-tpm2-setup"
|
||||
|
||||
if [[ ! -x "${SD_TPM2SETUP:?}" ]]; then
|
||||
echo "$SD_TPM2SETUP not found, skipping the test"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
# systemd-tpm2-setup returns EX_UNAVAILABLE rather than 0 when it cannot set something up but this
|
||||
|
||||
@@ -8,7 +8,7 @@ set -o pipefail
|
||||
|
||||
if ! command -v systemd-firstboot >/dev/null; then
|
||||
echo "systemd-firstboot not found, skipping the test"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
restore_etc_hostname() {
|
||||
|
||||
@@ -9,7 +9,7 @@ set -o pipefail
|
||||
|
||||
if ! test -x /usr/lib/systemd/systemd-imdsd ; then
|
||||
echo "No imdsd installed, skipping test."
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
at_exit() {
|
||||
|
||||
@@ -11,7 +11,7 @@ set -o pipefail
|
||||
|
||||
if ! command -v /usr/lib/systemd/systemd-keyutil >/dev/null; then
|
||||
echo "systemd-keyutil not found, skipping."
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
cat >/tmp/openssl.conf <<EOF
|
||||
|
||||
@@ -9,7 +9,7 @@ set -o pipefail
|
||||
|
||||
if ! command -v hostnamectl >/dev/null; then
|
||||
echo "hostnamectl not found, skipping the test"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
at_exit() {
|
||||
|
||||
@@ -5,7 +5,7 @@ set -o pipefail
|
||||
|
||||
if ! command -v systemd-mute-console >/dev/null; then
|
||||
echo "systemd-mute-console is not installed, skipping the test"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
PID="$(systemd-notify --fork -- systemd-mute-console)"
|
||||
|
||||
@@ -9,12 +9,12 @@ set -o pipefail
|
||||
|
||||
if ! command -v /usr/lib/systemd/systemd-sbsign >/dev/null; then
|
||||
echo "systemd-sbsign not found, skipping."
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
if [[ ! -d /usr/lib/systemd/boot/efi ]]; then
|
||||
echo "systemd-boot is not installed, skipping."
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
cat >/tmp/openssl.conf <<EOF
|
||||
|
||||
@@ -6,6 +6,4 @@ set -o pipefail
|
||||
# shellcheck source=test/units/test-control.sh
|
||||
. "$(dirname "$0")"/test-control.sh
|
||||
|
||||
run_subtests
|
||||
|
||||
touch /testok
|
||||
run_subtests_and_exit
|
||||
|
||||
@@ -12,7 +12,7 @@ set -o pipefail
|
||||
# indicator.
|
||||
if ! socket_inode_supports_user_xattrs; then
|
||||
echo "Socket inode extended attributes unsupported on this kernel, skipping." >&2
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
UNIT_SOCKET_PATH="/run/test-socket-xattr.sock"
|
||||
|
||||
@@ -5,7 +5,7 @@ set -o pipefail
|
||||
|
||||
if ! command -v ssh >/dev/null || ! command -v sshd >/dev/null ; then
|
||||
echo "ssh/sshd not found, skipping test." >&2
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
systemctl -q is-active sshd-unix-local.socket
|
||||
|
||||
@@ -5,7 +5,7 @@ set -o pipefail
|
||||
|
||||
if ! command -v userdbctl >/dev/null; then
|
||||
echo "userdbctl is not installed, skipping the test."
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
# shellcheck source=test/units/util.sh
|
||||
|
||||
@@ -11,7 +11,7 @@ set -o pipefail
|
||||
# unavailable, since the kernel version alone is not a reliable indicator.
|
||||
if ! socket_inode_supports_user_xattrs; then
|
||||
echo "Socket inode extended attributes unsupported on this kernel, skipping." >&2
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
ENTRYPOINT_PATH="/run/test-list-sockets-entrypoint.sock"
|
||||
|
||||
@@ -6,6 +6,4 @@ set -o pipefail
|
||||
# shellcheck source=test/units/test-control.sh
|
||||
. "$(dirname "$0")"/test-control.sh
|
||||
|
||||
run_subtests
|
||||
|
||||
touch /testok
|
||||
run_subtests_and_exit
|
||||
|
||||
@@ -17,33 +17,33 @@ set -o pipefail
|
||||
|
||||
if [[ -v ASAN_OPTIONS ]]; then
|
||||
echo "vmspawn launches QEMU which doesn't work under ASan, skipping"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
if ! command -v systemd-vmspawn >/dev/null 2>&1; then
|
||||
echo "systemd-vmspawn not found, skipping"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
if ! command -v storagectl >/dev/null 2>&1; then
|
||||
echo "storagectl not found, skipping"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
if ! find_qemu_binary; then
|
||||
echo "QEMU not found, skipping"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
if ! command -v mke2fs >/dev/null 2>&1; then
|
||||
echo "mke2fs not found, skipping"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
# Storage providers are socket-activated; skip if the fs provider socket isn't present.
|
||||
if ! test -S /run/systemd/io.systemd.StorageProvider/fs; then
|
||||
echo "StorageProvider fs socket not found, skipping"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
# Find a kernel for direct boot
|
||||
@@ -57,7 +57,7 @@ done
|
||||
|
||||
if [[ -z "$KERNEL" ]]; then
|
||||
echo "No kernel found for direct VM boot, skipping"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
WORKDIR="$(mktemp -d /tmp/test-bind-volume.XXXXXXXXXX)"
|
||||
@@ -90,24 +90,6 @@ mke2fs -t ext4 -q -d "$WORKDIR/rootfs" "$WORKDIR/root.raw"
|
||||
BOOT_VOL="test-bind-volume-boot-$$"
|
||||
RUNTIME_VOL="test-bind-volume-runtime-$$"
|
||||
|
||||
wait_for_machine() {
|
||||
local machine="$1" pid="$2" log="$3"
|
||||
timeout 30 bash -c "
|
||||
while ! machinectl list --no-legend 2>/dev/null | grep >/dev/null '$machine'; do
|
||||
if ! kill -0 $pid 2>/dev/null; then
|
||||
echo 'vmspawn exited before machine registration'
|
||||
cat '$log'
|
||||
exit 77
|
||||
fi
|
||||
sleep .5
|
||||
done
|
||||
" || {
|
||||
local rc=$?
|
||||
if [[ $rc -eq 77 ]]; then exit 0; fi
|
||||
exit "$rc"
|
||||
}
|
||||
}
|
||||
|
||||
# --- Boot the VM with one boot-time bind-volume ---
|
||||
MACHINE="test-bind-volume-$$"
|
||||
systemd-vmspawn \
|
||||
|
||||
@@ -5,12 +5,12 @@ set -o pipefail
|
||||
|
||||
if ! command -v bootctl >/dev/null; then
|
||||
echo "bootctl not found, skipping."
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
if [[ ! -d /usr/lib/systemd/boot/efi ]]; then
|
||||
echo "sd-boot is not installed, skipping."
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
# shellcheck source=test/units/util.sh
|
||||
|
||||
@@ -18,32 +18,32 @@ set -o pipefail
|
||||
|
||||
if [[ -v ASAN_OPTIONS ]]; then
|
||||
echo "vmspawn launches QEMU which doesn't work under ASan, skipping"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
if ! command -v systemd-vmspawn >/dev/null 2>&1; then
|
||||
echo "systemd-vmspawn not found, skipping"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
if ! command -v storagectl >/dev/null 2>&1; then
|
||||
echo "storagectl not found, skipping"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
if ! find_qemu_binary; then
|
||||
echo "QEMU not found, skipping"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
if ! command -v mke2fs >/dev/null 2>&1; then
|
||||
echo "mke2fs not found, skipping"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
if ! test -S /run/systemd/io.systemd.StorageProvider/fs; then
|
||||
echo "StorageProvider fs socket not found, skipping"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
KERNEL=""
|
||||
@@ -56,7 +56,7 @@ done
|
||||
|
||||
if [[ -z "$KERNEL" ]]; then
|
||||
echo "No kernel found for direct VM boot, skipping"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
WORKDIR="$(mktemp -d /tmp/test-replace-storage.XXXXXXXXXX)"
|
||||
@@ -92,24 +92,6 @@ RUNTIME_VOL="test-replace-storage-runtime-$$"
|
||||
truncate -s 32M "$WORKDIR/new-backing-1.raw"
|
||||
truncate -s 32M "$WORKDIR/new-backing-2.raw"
|
||||
|
||||
wait_for_machine() {
|
||||
local machine="$1" pid="$2" log="$3"
|
||||
timeout 30 bash -c "
|
||||
while ! machinectl list --no-legend 2>/dev/null | grep >/dev/null '$machine'; do
|
||||
if ! kill -0 $pid 2>/dev/null; then
|
||||
echo 'vmspawn exited before machine registration'
|
||||
cat '$log'
|
||||
exit 77
|
||||
fi
|
||||
sleep .5
|
||||
done
|
||||
" || {
|
||||
local rc=$?
|
||||
if [[ $rc -eq 77 ]]; then exit 0; fi
|
||||
exit "$rc"
|
||||
}
|
||||
}
|
||||
|
||||
MACHINE="test-replace-storage-$$"
|
||||
systemd-vmspawn \
|
||||
--machine="$MACHINE" \
|
||||
|
||||
@@ -5,33 +5,33 @@ set -o pipefail
|
||||
|
||||
if ! command -v systemd-sysinstall >/dev/null; then
|
||||
echo "systemd-sysinstall not found, skipping."
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
if ! command -v systemd-repart >/dev/null; then
|
||||
echo "systemd-repart not found, skipping."
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
if ! command -v bootctl >/dev/null; then
|
||||
echo "bootctl not found, skipping."
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
if ! command -v ukify >/dev/null; then
|
||||
echo "ukify not found, skipping."
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
if [[ ! -d /usr/lib/systemd/boot/efi ]]; then
|
||||
echo "sd-boot is not installed, skipping."
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
# We need a real environment to fiddle with loop devices.
|
||||
if systemd-detect-virt -cq; then
|
||||
echo "Running in a container, skipping."
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
# shellcheck source=test/units/test-control.sh
|
||||
|
||||
@@ -16,22 +16,22 @@ set -o pipefail
|
||||
|
||||
if [[ -v ASAN_OPTIONS ]]; then
|
||||
echo "vmspawn launches QEMU which doesn't work under ASan, skipping"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
if ! command -v systemd-vmspawn >/dev/null 2>&1; then
|
||||
echo "systemd-vmspawn not found, skipping"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
if ! find_qemu_binary; then
|
||||
echo "QEMU not found, skipping"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
if ! command -v mke2fs >/dev/null 2>&1; then
|
||||
echo "mke2fs not found, skipping"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
# Find a kernel for direct boot
|
||||
@@ -45,7 +45,7 @@ done
|
||||
|
||||
if [[ -z "$KERNEL" ]]; then
|
||||
echo "No kernel found for direct VM boot, skipping"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
echo "Using kernel: $KERNEL"
|
||||
|
||||
@@ -83,20 +83,6 @@ mke2fs -t ext4 -q -d "$WORKDIR/rootfs" "$WORKDIR/root.raw"
|
||||
truncate -s 64M "$WORKDIR/extra1.raw"
|
||||
truncate -s 32M "$WORKDIR/extra2.raw"
|
||||
|
||||
wait_for_machine() {
|
||||
local machine="$1" pid="$2" log="$3"
|
||||
timeout 30 bash -c "
|
||||
while ! machinectl list --no-legend 2>/dev/null | grep >/dev/null '$machine'; do
|
||||
if ! kill -0 $pid 2>/dev/null; then
|
||||
echo 'vmspawn exited before machine registration'
|
||||
cat '$log'
|
||||
exit 1
|
||||
fi
|
||||
sleep .5
|
||||
done
|
||||
"
|
||||
}
|
||||
|
||||
# --- Test 1: Multi-drive setup (root + 2 extra drives) ---
|
||||
# Verifies that --image with multiple --extra-drive flags works with the async
|
||||
# QMP pipeline. Three drives means three fdset allocations, three blockdev-add
|
||||
|
||||
@@ -9,17 +9,17 @@ set -o pipefail
|
||||
|
||||
if [[ -v ASAN_OPTIONS ]]; then
|
||||
echo "vmspawn launches QEMU which doesn't work under ASan, skipping"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
if ! command -v systemd-vmspawn >/dev/null 2>&1; then
|
||||
echo "systemd-vmspawn not found, skipping"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
if ! find_qemu_binary; then
|
||||
echo "QEMU not found, skipping"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
# --directory= needs virtiofsd (on Fedora it lives in /usr/libexec, not in PATH)
|
||||
@@ -27,7 +27,7 @@ if ! command -v virtiofsd >/dev/null 2>&1 &&
|
||||
! test -x /usr/libexec/virtiofsd &&
|
||||
! test -x /usr/lib/virtiofsd; then
|
||||
echo "virtiofsd not found, skipping"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
# Find a kernel for direct boot
|
||||
@@ -41,7 +41,7 @@ done
|
||||
|
||||
if [[ -z "$KERNEL" ]]; then
|
||||
echo "No kernel found for direct VM boot, skipping"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
echo "Using kernel: $KERNEL"
|
||||
|
||||
@@ -77,30 +77,6 @@ exec sleep infinity
|
||||
EOF
|
||||
chmod +x "$WORKDIR/root/sbin/init"
|
||||
|
||||
# Wait for a vmspawn machine to register with machined.
|
||||
# Skips the test gracefully if vmspawn fails due to missing vhost-user-fs support (nested VM).
|
||||
wait_for_machine() {
|
||||
local machine="$1" pid="$2" log="$3"
|
||||
timeout 30 bash -c "
|
||||
while ! machinectl list --no-legend 2>/dev/null | grep >/dev/null '$machine'; do
|
||||
if ! kill -0 $pid 2>/dev/null; then
|
||||
if grep >/dev/null 'virtiofs.*QMP\|vhost-user-fs-pci' '$log'; then
|
||||
echo 'vhost-user-fs not supported (nested VM?), skipping'
|
||||
exit 77
|
||||
fi
|
||||
echo 'vmspawn exited before registering'
|
||||
cat '$log'
|
||||
exit 1
|
||||
fi
|
||||
sleep .5
|
||||
done
|
||||
" || {
|
||||
local rc=$?
|
||||
if [[ $rc -eq 77 ]]; then exit 0; fi
|
||||
exit "$rc"
|
||||
}
|
||||
}
|
||||
|
||||
# Launch vmspawn in the background with direct kernel boot and headless console.
|
||||
systemd-vmspawn \
|
||||
--machine="$MACHINE" \
|
||||
|
||||
@@ -16,7 +16,7 @@ set -o pipefail
|
||||
# RestrictFileSystemAccess= requires +BPF_FRAMEWORK at compile time
|
||||
if systemctl --version | grep -F -- "-BPF_FRAMEWORK" >/dev/null; then
|
||||
echo "BPF framework not compiled in, skipping"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
HELPER=/usr/lib/systemd/tests/unit-tests/manual/test-bpf-restrict-fsaccess
|
||||
|
||||
@@ -13,24 +13,24 @@ set -o pipefail
|
||||
|
||||
if systemctl --version | grep -F -- "-BPF_FRAMEWORK" >/dev/null; then
|
||||
echo "BPF framework not compiled in, skipping"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
if ! kernel_supports_lsm bpf; then
|
||||
echo "BPF LSM not available in kernel, skipping"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
if command -v bpftool >/dev/null 2>&1; then
|
||||
if ! bpftool btf dump file /sys/kernel/btf/vmlinux 2>/dev/null | grep 'bpf_lsm_bdev_setintegrity' >/dev/null; then
|
||||
echo "Kernel lacks bdev_setintegrity LSM hook, skipping"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -v ASAN_OPTIONS ]]; then
|
||||
echo "Skipping under sanitizers"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
HELPER="/usr/lib/systemd/tests/unit-tests/manual/test-bpf-restrict-fsaccess"
|
||||
@@ -45,7 +45,7 @@ rc=0
|
||||
"$HELPER" check >/dev/null 2>&1 || rc=$?
|
||||
if [[ "$rc" -eq 77 ]]; then
|
||||
echo "test-bpf-restrict-fsaccess built without BPF attach support, skipping"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
if [[ ! -e /sys/module/dm_verity/parameters/require_signatures ]]; then
|
||||
@@ -54,7 +54,7 @@ fi
|
||||
val="$(cat /sys/module/dm_verity/parameters/require_signatures 2>/dev/null || echo)"
|
||||
if [[ "$val" != "Y" && "$val" != "1" ]]; then
|
||||
echo "require_signatures not enabled, skipping"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
# Provision the .dm-verity keyring. Empty description lets the kernel derive
|
||||
@@ -63,7 +63,7 @@ keyid=$(openssl x509 -in /usr/share/mkosi.crt -outform DER |
|
||||
keyctl padd asymmetric '' %:.dm-verity 2>/dev/null) || keyid=""
|
||||
if [[ -z "$keyid" ]]; then
|
||||
echo ".dm-verity keyring not provisionable (kernel < v7.0?), skipping"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
if ! keyctl restrict_keyring %:.dm-verity; then
|
||||
keyctl unlink "$keyid" %:.dm-verity 2>/dev/null || true
|
||||
|
||||
@@ -19,12 +19,12 @@ set -o pipefail
|
||||
# Skip if prerequisites not met
|
||||
if systemctl --version | grep -F -- "-BPF_FRAMEWORK" >/dev/null; then
|
||||
echo "BPF framework not compiled in, skipping"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
if ! kernel_supports_lsm bpf; then
|
||||
echo "BPF LSM not available in kernel, skipping"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
# Check that the kernel has the bdev_setintegrity LSM hook in BTF.
|
||||
@@ -32,13 +32,13 @@ fi
|
||||
if command -v bpftool >/dev/null 2>&1; then
|
||||
if ! bpftool btf dump file /sys/kernel/btf/vmlinux 2>/dev/null | grep 'bpf_lsm_bdev_setintegrity' >/dev/null; then
|
||||
echo "Kernel lacks bdev_setintegrity LSM hook (required for RestrictFileSystemAccess=), skipping"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -v ASAN_OPTIONS ]]; then
|
||||
echo "Skipping enforcement test under sanitizers"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
HELPER="/usr/lib/systemd/tests/unit-tests/manual/test-bpf-restrict-fsaccess"
|
||||
@@ -53,7 +53,7 @@ rc=0
|
||||
"$HELPER" check >/dev/null 2>&1 || rc=$?
|
||||
if [[ "$rc" -eq 77 ]]; then
|
||||
echo "test-bpf-restrict-fsaccess built without BPF attach support, skipping"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
# require_signatures is read-only — must be set via kernel cmdline
|
||||
@@ -62,12 +62,12 @@ if [[ ! -e /sys/module/dm_verity/parameters/require_signatures ]]; then
|
||||
fi
|
||||
if [[ ! -e /sys/module/dm_verity/parameters/require_signatures ]]; then
|
||||
echo "dm_verity module not available, skipping enforcement test"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
val="$(cat /sys/module/dm_verity/parameters/require_signatures)"
|
||||
if [[ "$val" != "Y" && "$val" != "1" ]]; then
|
||||
echo "require_signatures not enabled (need dm-verity.require_signatures=1 on cmdline), skipping"
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
|
||||
at_exit() {
|
||||
@@ -106,7 +106,7 @@ if ! /tmp/restrict-fsaccess-baseline/true 2>/dev/null; then
|
||||
echo "WARNING: tmpfs exec blocked BEFORE BPF attach (another LSM?)" >&2
|
||||
echo "Skipping enforcement test, baseline tmpfs exec fails"
|
||||
umount /tmp/restrict-fsaccess-baseline; rm -rf /tmp/restrict-fsaccess-baseline
|
||||
exit 0
|
||||
exit 77
|
||||
fi
|
||||
echo "Baseline: tmpfs exec works without BPF"
|
||||
umount /tmp/restrict-fsaccess-baseline; rm -rf /tmp/restrict-fsaccess-baseline
|
||||
|
||||
@@ -6,6 +6,4 @@ set -o pipefail
|
||||
# shellcheck source=test/units/test-control.sh
|
||||
. "$(dirname "$0")"/test-control.sh
|
||||
|
||||
run_subtests
|
||||
|
||||
touch /testok
|
||||
run_subtests_and_exit
|
||||
|
||||
+61
-15
@@ -8,6 +8,11 @@ fi
|
||||
|
||||
declare -i _CHILD_PID=0
|
||||
_PASSED_TESTS=()
|
||||
_SKIPPED_TESTS=()
|
||||
|
||||
# A subtest may exit with this code to report that it skipped itself,
|
||||
# matching the skip code used by the integration test harness.
|
||||
_SUBTEST_SKIP_RC=77
|
||||
|
||||
# Like trap, but passes the signal name as the first argument
|
||||
_trap_with_sig() {
|
||||
@@ -56,7 +61,7 @@ _wait_harder() {
|
||||
_show_summary() {(
|
||||
set +x
|
||||
|
||||
if [[ ${#_PASSED_TESTS[@]} -eq 0 ]]; then
|
||||
if [[ ${#_PASSED_TESTS[@]} -eq 0 && ${#_SKIPPED_TESTS[@]} -eq 0 ]]; then
|
||||
echo >&2 "No tests were executed, this is most likely an error"
|
||||
exit 1
|
||||
fi
|
||||
@@ -66,12 +71,34 @@ _show_summary() {(
|
||||
for t in "${_PASSED_TESTS[@]}"; do
|
||||
echo "$t"
|
||||
done
|
||||
|
||||
if [[ ${#_SKIPPED_TESTS[@]} -gt 0 ]]; then
|
||||
printf "SKIPPED TESTS: %3d:\n" "${#_SKIPPED_TESTS[@]}"
|
||||
echo "-------------------"
|
||||
for t in "${_SKIPPED_TESTS[@]}"; do
|
||||
echo "$t"
|
||||
done
|
||||
fi
|
||||
)}
|
||||
|
||||
_record_subtest_rc() {
|
||||
local subtest="${1:?}" rc="${2:?}"
|
||||
|
||||
if [[ $rc -eq $_SUBTEST_SKIP_RC ]]; then
|
||||
echo "Subtest $subtest skipped"
|
||||
_SKIPPED_TESTS+=("$subtest")
|
||||
elif [[ $rc -ne 0 ]]; then
|
||||
echo "Subtest $subtest failed"
|
||||
return 1
|
||||
else
|
||||
_PASSED_TESTS+=("$subtest")
|
||||
fi
|
||||
}
|
||||
|
||||
# Like run_subtests, but propagate specified signals to the subtest script
|
||||
run_subtests_with_signals() {
|
||||
local subtests=("${0%.sh}".*.sh)
|
||||
local subtest
|
||||
local subtest rc
|
||||
|
||||
if [[ "${#subtests[@]}" -eq 0 ]]; then
|
||||
echo >&2 "No subtests found for file $0"
|
||||
@@ -100,14 +127,11 @@ run_subtests_with_signals() {
|
||||
|
||||
: "--- $subtest BEGIN ---"
|
||||
SECONDS=0
|
||||
rc=0
|
||||
"./$subtest" &
|
||||
_CHILD_PID=$!
|
||||
if ! _wait_harder "$_CHILD_PID"; then
|
||||
echo "Subtest $subtest failed"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_PASSED_TESTS+=("$subtest")
|
||||
_wait_harder "$_CHILD_PID" || rc=$?
|
||||
_record_subtest_rc "$subtest" "$rc" || return 1
|
||||
: "--- $subtest END (${SECONDS}s) ---"
|
||||
done
|
||||
|
||||
@@ -117,7 +141,7 @@ run_subtests_with_signals() {
|
||||
# Run all subtests (i.e. files named as $TESTNAME.<subtest_name>.sh)
|
||||
run_subtests() {
|
||||
local subtests=("${0%.sh}".*.sh)
|
||||
local subtest
|
||||
local subtest rc
|
||||
|
||||
if [[ "${#subtests[@]}" -eq 0 ]]; then
|
||||
echo >&2 "No subtests found for file $0"
|
||||
@@ -139,18 +163,40 @@ run_subtests() {
|
||||
|
||||
: "--- $subtest BEGIN ---"
|
||||
SECONDS=0
|
||||
if ! "./$subtest"; then
|
||||
echo "Subtest $subtest failed"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_PASSED_TESTS+=("$subtest")
|
||||
rc=0
|
||||
"./$subtest" || rc=$?
|
||||
_record_subtest_rc "$subtest" "$rc" || return 1
|
||||
: "--- $subtest END (${SECONDS}s) ---"
|
||||
done
|
||||
|
||||
_show_summary
|
||||
}
|
||||
|
||||
_finalize_subtests() {
|
||||
if [[ ${#_PASSED_TESTS[@]} -eq 0 && ${#_SKIPPED_TESTS[@]} -gt 0 ]]; then
|
||||
echo "All subtests skipped" | tee --append /skipped
|
||||
exit "$_SUBTEST_SKIP_RC"
|
||||
fi
|
||||
|
||||
touch /testok
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Run all subtests and finalize the test in one shot: exit 77 (skipped) if every subtest skipped,
|
||||
# otherwise mark success (/testok) and exit. Use this ONLY for tests whose body is just subtests.
|
||||
# Do NOT use it if the parent script has meaningful test content of its own.
|
||||
run_subtests_and_exit() {
|
||||
run_subtests
|
||||
_finalize_subtests
|
||||
}
|
||||
|
||||
# Like run_subtests_and_exit, but propagates the given signals to the subtests (see
|
||||
# run_subtests_with_signals).
|
||||
run_subtests_with_signals_and_exit() {
|
||||
run_subtests_with_signals "$@"
|
||||
_finalize_subtests
|
||||
}
|
||||
|
||||
# Run all test cases (i.e. functions prefixed with testcase_ in the current namespace)
|
||||
run_testcases() {
|
||||
local testcase testcases
|
||||
|
||||
@@ -576,3 +576,24 @@ find_qemu_binary() {
|
||||
|
||||
command -v "qemu-system-$arch" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
# Waits for a systemd-vmspawn machine to register with machined. If vmspawn bailed out because
|
||||
# vhost-user-fs isn't available (e.g. inside a nested VM) the test is skipped gracefully; any other
|
||||
# early vmspawn exit is treated as a failure. Args: machine name, vmspawn PID, vmspawn console log.
|
||||
wait_for_machine() {
|
||||
local machine="$1" pid="$2" log="$3"
|
||||
timeout 30 bash -c "
|
||||
while ! machinectl list --no-legend 2>/dev/null | grep >/dev/null '$machine'; do
|
||||
if ! kill -0 $pid 2>/dev/null; then
|
||||
if grep >/dev/null 'virtiofs.*QMP\|vhost-user-fs-pci' '$log'; then
|
||||
echo 'vhost-user-fs not supported (nested VM?), skipping'
|
||||
exit 77
|
||||
fi
|
||||
echo 'vmspawn exited before registering'
|
||||
cat '$log'
|
||||
exit 1
|
||||
fi
|
||||
sleep .5
|
||||
done
|
||||
"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user