]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
test: add integration test for soft reboots incl. fdstore passing
authorLennart Poettering <lennart@poettering.net>
Wed, 3 May 2023 13:05:12 +0000 (15:05 +0200)
committerLennart Poettering <lennart@poettering.net>
Fri, 2 Jun 2023 16:43:11 +0000 (18:43 +0200)
test/TEST-82-SOFTREBOOT/Makefile [new symlink]
test/TEST-82-SOFTREBOOT/test.sh [new file with mode: 0755]
test/units/testsuite-82.service [new file with mode: 0644]
test/units/testsuite-82.sh [new file with mode: 0755]

diff --git a/test/TEST-82-SOFTREBOOT/Makefile b/test/TEST-82-SOFTREBOOT/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-82-SOFTREBOOT/test.sh b/test/TEST-82-SOFTREBOOT/test.sh
new file mode 100755 (executable)
index 0000000..9d88c94
--- /dev/null
@@ -0,0 +1,21 @@
+#!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
+set -e
+
+TEST_DESCRIPTION="Test Soft-Rebooting"
+
+# shellcheck source=test/test-functions
+. "$TEST_BASE_DIR/test-functions"
+
+test_append_files() {
+    local workspace="${1:?}"
+    # prevent shutdown in test suite, the expect script does that manually.
+    mkdir -p "${workspace:?}/etc/systemd/system/end.service.d"
+    cat >"$workspace/etc/systemd/system/end.service.d/99-override.conf" <<EOF
+[Service]
+ExecStart=
+ExecStart=/bin/true
+EOF
+}
+
+do_test "$@"
diff --git a/test/units/testsuite-82.service b/test/units/testsuite-82.service
new file mode 100644 (file)
index 0000000..a8fc4f9
--- /dev/null
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+[Unit]
+Description=TEST-82-SOFTREBOOT
+DefaultDependencies=no
+After=basic.target
+
+[Service]
+Type=oneshot
+ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh
+FileDescriptorStoreMax=3
+NotifyAccess=all
diff --git a/test/units/testsuite-82.sh b/test/units/testsuite-82.sh
new file mode 100755 (executable)
index 0000000..a9e4411
--- /dev/null
@@ -0,0 +1,147 @@
+#!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
+set -ex
+set -o pipefail
+
+systemd-analyze log-level debug
+
+export SYSTEMD_LOG_LEVEL=debug
+
+if [ -f /run/testsuite82.touch3 ]; then
+    echo "This is the fourth boot!"
+    systemd-notify --status="Fourth Boot"
+
+    rm /run/testsuite82.touch3
+    mount
+    rmdir /original-root /run/nextroot
+
+    # Check that the fdstore entry still exists
+    test "$LISTEN_FDS" -eq 3
+    read -r x <&5
+    test "$x" = "oinkoink"
+
+    # Check that the surviving service is still around
+    test "$(systemctl show -P ActiveState testsuite-82-survive.service)" = "active"
+    test "$(systemctl show -P ActiveState testsuite-82-nosurvive.service)" != "active"
+
+    # Take out the big guns now, and kill the service via SIGKILL (SIGTERM is blocked after all, see below)
+    systemctl --signal=KILL kill testsuite-82-survive.service
+    systemctl stop testsuite-82-survive.service
+
+    # All succeeded, exit cleanly now
+
+elif [ -f /run/testsuite82.touch2 ]; then
+    echo "This is the third boot!"
+    systemd-notify --status="Third Boot"
+
+    rm /run/testsuite82.touch2
+
+    # Check that the fdstore entry still exists
+    test "$LISTEN_FDS" -eq 2
+    read -r x <&4
+    test "$x" = "miaumiau"
+
+    # Upload another entry
+    T="/dev/shm/fdstore.$RANDOM"
+    echo "oinkoink" >"$T"
+    systemd-notify --fd=3 --pid=parent 3<"$T"
+    rm "$T"
+
+    # Check that the surviving service is still around
+    test "$(systemctl show -P ActiveState testsuite-82-survive.service)" = "active"
+    test "$(systemctl show -P ActiveState testsuite-82-nosurvive.service)" != "active"
+
+    # Test that we really are in the new overlayfs root fs
+    read -r x </lower
+    test "$x" = "miep"
+
+    # Switch back to the original root, away from the overlayfs
+    mount --bind /original-root /run/nextroot
+    mount
+
+    # Now issue the soft reboot. We should be right back soon.
+    touch /run/testsuite82.touch3
+    systemctl --no-block soft-reboot
+
+    # Now block until the soft-boot killing spree kills us
+    exec sleep infinity
+
+elif [ -f /run/testsuite82.touch ]; then
+    echo "This is the second boot!"
+    systemd-notify --status="Second Boot"
+
+    # Clean up what we created earlier
+    rm /run/testsuite82.touch
+
+    # Check that the fdstore entry still exists
+    test "$LISTEN_FDS" -eq 1
+    read -r x <&3
+    test "$x" = "wuffwuff"
+
+    # Upload another entry
+    T="/dev/shm/fdstore.$RANDOM"
+    echo "miaumiau" >"$T"
+    systemd-notify --fd=3 --pid=parent 3<"$T"
+    rm "$T"
+
+    # Check that the surviving service is still around
+    test "$(systemctl show -P ActiveState testsuite-82-survive.service)" = "active"
+    test "$(systemctl show -P ActiveState testsuite-82-nosurvive.service)" != "active"
+
+    # This time we test the /run/nextroot/ root switching logic. (We synthesize a new rootfs from the old via overlayfs)
+    mkdir -p /run/nextroot /tmp/nextroot-lower /original-root
+    mount -t tmpfs tmpfs /tmp/nextroot-lower
+    echo miep >/tmp/nextroot-lower/lower
+    mount -t overlay nextroot /run/nextroot -o lowerdir=/:/tmp/nextroot-lower,ro
+
+    # Bind our current root into the target so that we later can return to it
+    mount --bind / /run/nextroot/original-root
+
+    # Now issue the soft reboot. We should be right back soon.
+    touch /run/testsuite82.touch2
+    systemctl --no-block soft-reboot
+
+    # Now block until the soft-boot killing spree kills us
+    exec sleep infinity
+else
+    # This is the first boot
+    systemd-notify --status="First Boot"
+
+    # Let's upload an fd to the fdstore, so that we can verify fdstore passing works correcly
+    T="/dev/shm/fdstore.$RANDOM"
+    echo "wuffwuff" >"$T"
+    systemd-notify --fd=3 --pid=parent 3<"$T"
+    rm "$T"
+
+    # Create a script that can survive the soft reboot by ignoring SIGTERM (we
+    # do this instead of the argv[0][0] = '@' thing because that's so hard to
+    # do from a shell
+    T="/dev/shm/survive-$RANDOM.sh"
+    cat >$T <<EOF
+#!/bin/bash
+trap "" TERM
+systemd-notify --ready
+rm "$T"
+exec sleep infinity
+EOF
+    chmod +x "$T"
+    # This sets DefaultDependencies=no so that it remains running until the
+    # very end, and IgnoreOnIsolate=yes so that it isn't stopped via the
+    # "testsuite.target" isolation we do on next boot
+    systemd-run -p Type=notify -p DefaultDependencies=no -p IgnoreOnIsolate=yes --unit=testsuite-82-survive.service "$T"
+    systemd-run -p Type=exec -p DefaultDependencies=no -p IgnoreOnIsolate=yes --unit=testsuite-82-nosurvive.service sleep infinity
+
+    # Now issue the soft reboot. We should be right back soon.
+    touch /run/testsuite82.touch
+    systemctl --no-block soft-reboot
+
+    # Now block until the soft-boot killing spree kills us
+    exec sleep infinity
+fi
+
+systemd-analyze log-level info
+echo OK >/testok
+
+systemctl --no-block poweroff
+
+exit 0