]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
test: introduce TEST-09-REBOOT
authorFrantisek Sumsal <frantisek@sumsal.cz>
Sat, 23 Sep 2023 16:17:04 +0000 (18:17 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Wed, 27 Sep 2023 12:50:19 +0000 (14:50 +0200)
To test stuff involving state preserved across (multiple) reboots, like
journal boot IDs.

test/TEST-09-REBOOT/Makefile [new symlink]
test/TEST-09-REBOOT/test.sh [new file with mode: 0755]
test/test-functions
test/units/testsuite-09.journal.sh [new file with mode: 0755]
test/units/testsuite-09.service [new file with mode: 0644]
test/units/testsuite-09.sh [new file with mode: 0755]
test/units/util.sh

diff --git a/test/TEST-09-REBOOT/Makefile b/test/TEST-09-REBOOT/Makefile
new file mode 120000 (symlink)
index 0000000..e9f93b1
--- /dev/null
@@ -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 (executable)
index 0000000..53c5974
--- /dev/null
@@ -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 "$@"
index 6187aa84e8d72d0faa3d2964a35df6bd35032a9f..3b26b0ca06dbface3d31a4d235c206ecc27518a1 100644 (file)
@@ -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 (executable)
index 0000000..c6c1f6e
--- /dev/null
@@ -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 (file)
index 0000000..6c957ec
--- /dev/null
@@ -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 (executable)
index 0000000..cd95660
--- /dev/null
@@ -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
index 932fe1e60381f7d98b73864099a20438c7c0e0c8..8a01c5c07a9ca4016a67686a436531e847d392a7 100755 (executable)
@@ -3,6 +3,9 @@
 
 # Utility functions for shell tests
 
+# shellcheck disable=SC2034
+[[ -e /var/tmp/.systemd_reboot_count ]] && REBOOT_COUNT="$(</var/tmp/.systemd_reboot_count)" || REBOOT_COUNT=0
+
 assert_true() {(
     set +ex
 
@@ -16,7 +19,6 @@ assert_true() {(
     fi
 )}
 
-
 assert_eq() {(
     set +ex
 
@@ -57,6 +59,11 @@ assert_rc() {(
     assert_eq "$rc" "$exp"
 )}
 
+assert_not_reached() {
+    echo >&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)" || counter=0
+    echo "$((counter + 1))" >/var/tmp/.systemd_reboot_count
+
+    systemctl "$@"
+}