diff options
Diffstat (limited to '')
-rwxr-xr-x | test/units/testsuite-04.bsod.sh | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/test/units/testsuite-04.bsod.sh b/test/units/testsuite-04.bsod.sh new file mode 100755 index 0000000..30f0cb0 --- /dev/null +++ b/test/units/testsuite-04.bsod.sh @@ -0,0 +1,103 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: LGPL-2.1-or-later +set -eux +set -o pipefail + +if systemd-detect-virt -cq; then + echo "This test requires a VM, skipping the test" + exit 0 +fi + +# shellcheck disable=SC2317 +at_exit() { + local EC=$? + + if [[ $EC -ne 0 ]] && [[ -e /tmp/console.dump ]]; then + cat /tmp/console.dump + fi + + if mountpoint -q /var/log/journal; then + journalctl --relinquish-var + umount /var/log/journal + journalctl --flush + fi + + return 0 +} + +vcs_dump_and_check() { + local expected_message="${1:?}" + + # It might take a while before the systemd-bsod stuff appears on the VCS, + # so try it a couple of times + for _ in {0..9}; do + setterm --term linux --dump --file /tmp/console.dump + if grep -aq "Press any key to exit" /tmp/console.dump && + grep -aq "$expected_message" /tmp/console.dump && + grep -aq "The current boot has failed" /tmp/console.dump; then + + return 0 + fi + + sleep .5 + done + + return 1 +} + +# Since systemd-bsod always fetches only the first emergency message from the +# current boot, let's temporarily overmount /var/log/journal with a tmpfs, +# as we're going to wipe it multiple times, but we need to keep the original +# journal intact for the other tests to work correctly. +trap at_exit EXIT +mount -t tmpfs tmpfs /var/log/journal +systemctl restart systemd-journald + +systemctl stop systemd-bsod + +# Since we just wiped the journal, there should be no emergency messages and +# systemd-bsod should be just a no-op +timeout 10s /usr/lib/systemd/systemd-bsod +setterm --term linux --dump --file /tmp/console.dump +(! grep "The current boot has failed" /tmp/console.dump) + +# systemd-bsod should pick up emergency messages only with UID=0, so let's check +# that as well +systemd-run --user --machine testuser@ --wait --pipe systemd-cat -p emerg echo "User emergency message" +systemd-cat -p emerg echo "Root emergency message" +journalctl --sync +# Set $SYSTEMD_COLORS so systemd-bsod also prints out the QR code +SYSTEMD_COLORS=256 /usr/lib/systemd/systemd-bsod & +PID=$! +vcs_dump_and_check "Root emergency message" +grep -aq "Scan the QR code" /tmp/console.dump +# TODO: check if systemd-bsod exits on a key press (didn't figure this one out yet) +kill $PID +timeout 10 bash -c "while kill -0 $PID; do sleep .5; done" + +# Wipe the journal +journalctl --vacuum-size=1 --rotate +(! journalctl -q -b -p emerg --grep .) + +# Check the systemd-bsod.service as well +# Note: the systemd-bsod.service unit has ConditionVirtualization=no, so let's +# temporarily override it just for the test +mkdir /run/systemd/system/systemd-bsod.service.d +printf '[Unit]\nConditionVirtualization=\n' >/run/systemd/system/systemd-bsod.service.d/99-override.conf +systemctl daemon-reload +systemctl start systemd-bsod +systemd-cat -p emerg echo "Service emergency message" +vcs_dump_and_check "Service emergency message" +systemctl stop systemd-bsod + +# Wipe the journal +journalctl --vacuum-size=1 --rotate +(! journalctl -q -b -p emerg --grep .) + +# Same as above, but make sure the service responds to signals even when there are +# no "emerg" messages, see systemd/systemd#30084 +(! systemctl is-active systemd-bsod) +systemctl start systemd-bsod +timeout 5s bash -xec 'until systemctl is-active systemd-bsod; do sleep .5; done' +timeout 5s systemctl stop systemd-bsod +timeout 5s bash -xec 'while systemctl is-active systemd-bsod; do sleep .5; done' |