From: Frantisek Sumsal Date: Sat, 23 Sep 2023 16:17:04 +0000 (+0200) Subject: test: introduce TEST-09-REBOOT X-Git-Tag: v255-rc1~414^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c1b129f4ad8a4e6b7bba763d4400a8957c01c803;p=thirdparty%2Fsystemd.git test: introduce TEST-09-REBOOT To test stuff involving state preserved across (multiple) reboots, like journal boot IDs. --- diff --git a/test/TEST-09-REBOOT/Makefile b/test/TEST-09-REBOOT/Makefile new file mode 120000 index 00000000000..e9f93b1104c --- /dev/null +++ b/test/TEST-09-REBOOT/Makefile @@ -0,0 +1 @@ +../TEST-01-BASIC/Makefile \ No newline at end of file diff --git a/test/TEST-09-REBOOT/test.sh b/test/TEST-09-REBOOT/test.sh new file mode 100755 index 00000000000..53c5974efa8 --- /dev/null +++ b/test/TEST-09-REBOOT/test.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: LGPL-2.1-or-later +set -e + +TEST_DESCRIPTION="Test various scenarios involving (multiple) machine reboots" + +# shellcheck source=test/test-functions +. "${TEST_BASE_DIR:?}/test-functions" + +do_test "$@" diff --git a/test/test-functions b/test/test-functions index 6187aa84e8d..3b26b0ca06d 100644 --- a/test/test-functions +++ b/test/test-functions @@ -3311,6 +3311,9 @@ test_run() { local test_id="${1:?}" mount_initdir + # Reset the boot counter, if present + rm -f "${initdir:?}/var/tmp/.systemd_reboot_count" + if ! get_bool "${TEST_NO_QEMU:=}"; then if run_qemu "$test_id"; then check_result_qemu || { echo "qemu test failed"; return 1; } diff --git a/test/units/testsuite-09.journal.sh b/test/units/testsuite-09.journal.sh new file mode 100755 index 00000000000..c6c1f6eccb8 --- /dev/null +++ b/test/units/testsuite-09.journal.sh @@ -0,0 +1,72 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: LGPL-2.1-or-later +set -eux +set -o pipefail + +# shellcheck source=test/units/util.sh +. "$(dirname "$0")"/util.sh + +get_first_boot_id() { + journalctl -b "${1:?}" -o json | jq -sr '.[0]._BOOT_ID' +} + +get_last_boot_id() { + journalctl -b "${1:?}" -o json -n 1 | jq -r '._BOOT_ID' +} + +get_first_timestamp() { + journalctl -b "${1:?}" -o json | jq -sr '.[0].__REALTIME_TIMESTAMP' +} + +get_last_timestamp() { + journalctl -b "${1:?}" -o json -n 1 | jq -r '.__REALTIME_TIMESTAMP' +} + +# Issue: #29275, second part +# Now let's check if the boot entries are in the correct/expected order +index=0 +SYSTEMD_LOG_LEVEL=debug journalctl --list-boots +journalctl --list-boots -o json | jq -r '.[] | [.index, .boot_id, .first_entry, .last_entry] | @tsv' | + while read -r offset boot_id first_ts last_ts; do + : "Boot #$((++index)) ($offset) with ID $boot_id" + + # Try the "regular" (non-json) variants first, as they provide a helpful + # error message if something is not right + SYSTEMD_LOG_LEVEL=debug journalctl -q -n 0 -b "$index" + SYSTEMD_LOG_LEVEL=debug journalctl -q -n 0 -b "$offset" + SYSTEMD_LOG_LEVEL=debug journalctl -q -n 0 -b "$boot_id" + + # Check the boot ID of the first entry + entry_boot_id="$(get_first_boot_id "$index")" + assert_eq "$entry_boot_id" "$boot_id" + entry_boot_id="$(get_first_boot_id "$offset")" + assert_eq "$entry_boot_id" "$boot_id" + entry_boot_id="$(get_first_boot_id "$boot_id")" + assert_eq "$entry_boot_id" "$boot_id" + + # Check the timestamp of the first entry + entry_ts="$(get_first_timestamp "$index")" + assert_eq "$entry_ts" "$first_ts" + entry_ts="$(get_first_timestamp "$offset")" + assert_eq "$entry_ts" "$first_ts" + entry_ts="$(get_first_timestamp "$boot_id")" + assert_eq "$entry_ts" "$first_ts" + + # Check the boot ID of the last entry + entry_boot_id="$(get_last_boot_id "$index")" + assert_eq "$entry_boot_id" "$boot_id" + entry_boot_id="$(get_last_boot_id "$offset")" + assert_eq "$entry_boot_id" "$boot_id" + entry_boot_id="$(get_last_boot_id "$boot_id")" + assert_eq "$entry_boot_id" "$boot_id" + + # Check the timestamp of the last entry + if [[ "$offset" != "0" ]]; then + entry_ts="$(get_last_timestamp "$index")" + assert_eq "$entry_ts" "$last_ts" + entry_ts="$(get_last_timestamp "$offset")" + assert_eq "$entry_ts" "$last_ts" + entry_ts="$(get_last_timestamp "$boot_id")" + assert_eq "$entry_ts" "$last_ts" + fi + done diff --git a/test/units/testsuite-09.service b/test/units/testsuite-09.service new file mode 100644 index 00000000000..6c957ecbd1b --- /dev/null +++ b/test/units/testsuite-09.service @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later +[Unit] +Description=TEST-09-REBOOT +After=multi-user.target + +[Service] +ExecStartPre=rm -f /failed /testok +ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh +Type=oneshot diff --git a/test/units/testsuite-09.sh b/test/units/testsuite-09.sh new file mode 100755 index 00000000000..cd956600211 --- /dev/null +++ b/test/units/testsuite-09.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: LGPL-2.1-or-later +set -eux +set -o pipefail + +NUM_REBOOT=4 + +# shellcheck source=test/units/test-control.sh +. "$(dirname "$0")"/test-control.sh + +# shellcheck source=test/units/util.sh +. "$(dirname "$0")"/util.sh + +systemd-cat echo "Reboot count: $REBOOT_COUNT" +systemd-cat journalctl --list-boots + +run_subtests + +if [[ "$REBOOT_COUNT" -lt "$NUM_REBOOT" ]]; then + systemctl_final reboot +elif [[ "$REBOOT_COUNT" -gt "$NUM_REBOOT" ]]; then + assert_not_reached +fi + +touch /testok diff --git a/test/units/util.sh b/test/units/util.sh index 932fe1e6038..8a01c5c07a9 100755 --- a/test/units/util.sh +++ b/test/units/util.sh @@ -3,6 +3,9 @@ # Utility functions for shell tests +# shellcheck disable=SC2034 +[[ -e /var/tmp/.systemd_reboot_count ]] && REBOOT_COUNT="$(&2 "Code should not be reached at ${BASH_SOURCE[1]}:${BASH_LINENO[1]}, function ${FUNCNAME[1]}()" + exit 1 +} + run_and_grep() {( set +ex @@ -149,3 +156,18 @@ create_dummy_container() { cp -a /testsuite-13-container-template/* "$root" coverage_create_nspawn_dropin "$root" } + +# Bump the reboot counter and call systemctl with the given arguments +systemctl_final() { + local counter + + if [[ $# -eq 0 ]]; then + echo >&2 "Missing arguments" + exit 1 + fi + + [[ -e /var/tmp/.systemd_reboot_count ]] && counter="$(/var/tmp/.systemd_reboot_count + + systemctl "$@" +}