From: Lennart Poettering Date: Tue, 4 Apr 2023 09:41:55 +0000 (+0200) Subject: test: validate that fdstore pinning works X-Git-Tag: v254-rc1~736^2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=3540ce8587cbd21ce9c2dbec72ea7fa3d1b38a5f;p=thirdparty%2Fsystemd.git test: validate that fdstore pinning works --- diff --git a/test/testsuite-80.units/fdstore-nopin.service b/test/testsuite-80.units/fdstore-nopin.service new file mode 100644 index 00000000000..58a687a411c --- /dev/null +++ b/test/testsuite-80.units/fdstore-nopin.service @@ -0,0 +1,8 @@ +[Service] +Type=notify +NotifyAccess=all +FileDescriptorStoreMax=10 +FileDescriptorStorePreserve=restart +ExecStart=/usr/lib/systemd/tests/testdata/testsuite-80.units/fdstore-pin.sh 0 +StandardOutput=journal+console +StandardError=journal+console diff --git a/test/testsuite-80.units/fdstore-pin.service b/test/testsuite-80.units/fdstore-pin.service new file mode 100644 index 00000000000..bc78ee0a4cb --- /dev/null +++ b/test/testsuite-80.units/fdstore-pin.service @@ -0,0 +1,8 @@ +[Service] +Type=notify +NotifyAccess=all +FileDescriptorStoreMax=10 +FileDescriptorStorePreserve=yes +ExecStart=/usr/lib/systemd/tests/testdata/testsuite-80.units/fdstore-pin.sh 1 +StandardOutput=journal+console +StandardError=journal+console diff --git a/test/testsuite-80.units/fdstore-pin.sh b/test/testsuite-80.units/fdstore-pin.sh new file mode 100755 index 00000000000..4cb041a2845 --- /dev/null +++ b/test/testsuite-80.units/fdstore-pin.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: LGPL-2.1-or-later +set -eux +set -o pipefail + +PINNED="$1" +COUNTER="/tmp/fdstore-invoked.$PINNED" +FILE="/tmp/fdstore-data.$PINNED" + +# This script is called six times: thrice from a service unit where the fdstore +# is pinned, and thrice where it isn't. The second iteration of each series is +# a restart, the third a stop followed by a start + +if [ -e "$COUNTER" ] ; then + read -r N < "$COUNTER" +else + N=0 +fi + +echo "Invocation #$N with PINNED=$PINNED." + +if [ "$N" -eq 0 ] ; then + # First iteration + test "${LISTEN_FDS:-0}" -eq 0 + test ! -e "$FILE" + echo waldi > "$FILE" + systemd-notify --fd=3 --fdname="fd-$N-$PINNED" 3< "$FILE" +elif [ "$N" -eq 1 ] || { [ "$N" -eq 2 ] && [ "$PINNED" -eq 1 ]; } ; then + # Second iteration, or iteration with pinning on + test "${LISTEN_FDS:-0}" -eq 1 + # We reopen fd #3 here, so that the read offset is at zero each time (hence no <&3 here…) + read -r word < /proc/self/fd/3 + test "$word" = "waldi" +else + test "${LISTEN_FDS:-0}" -eq 0 + test -e "$FILE" +fi + +if [ "$N" -ge 2 ] ; then + rm "$COUNTER" "$FILE" +else + echo $((N + 1)) > "$COUNTER" +fi + +systemd-notify --ready --status="Ready" + +exec sleep infinity diff --git a/test/testsuite-80.units/fdstore-pin.target b/test/testsuite-80.units/fdstore-pin.target new file mode 100644 index 00000000000..319b7e1da85 --- /dev/null +++ b/test/testsuite-80.units/fdstore-pin.target @@ -0,0 +1,3 @@ +[Unit] +After=fdstore-pin.service fdstore-nopin.service +Wants=fdstore-pin.service fdstore-nopin.service diff --git a/test/units/testsuite-80.service b/test/units/testsuite-80.service index 4c7f5d5ebd3..82b08a1c8b0 100644 --- a/test/units/testsuite-80.service +++ b/test/units/testsuite-80.service @@ -6,3 +6,5 @@ Description=TEST-80-NOTIFYACCESS ExecStartPre=rm -f /failed /testok ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh Type=oneshot +StandardOutput=journal+console +StandardError=journal+console diff --git a/test/units/testsuite-80.sh b/test/units/testsuite-80.sh index 15ea36bf88d..7440b241bee 100755 --- a/test/units/testsuite-80.sh +++ b/test/units/testsuite-80.sh @@ -48,6 +48,8 @@ assert_eq "$(systemctl show notify.service -p NotifyAccess --value)" "all" rm /tmp/syncfifo1 /tmp/syncfifo2 +# Now test basic fdstore behaviour + MYSCRIPT="/tmp/myscript$RANDOM.sh" cat >> "$MYSCRIPT" <<'EOF' #!/usr/bin/env bash @@ -74,6 +76,55 @@ systemd-analyze fdstore "$MYUNIT" --json=short | grep -P -q '\[{"fdname":"quux", systemctl stop "$MYUNIT" rm "$MYSCRIPT" +systemd-analyze log-level debug + +# Test fdstore pinning (this will pull in fdstore-pin.service fdstore-nopin.service) +systemctl start fdstore-pin.target + +assert_eq "$(systemctl show fdstore-pin.service -P FileDescriptorStorePreserve)" yes +assert_eq "$(systemctl show fdstore-nopin.service -P FileDescriptorStorePreserve)" restart +assert_eq "$(systemctl show fdstore-pin.service -P SubState)" running +assert_eq "$(systemctl show fdstore-nopin.service -P SubState)" running +assert_eq "$(systemctl show fdstore-pin.service -P NFileDescriptorStore)" 1 +assert_eq "$(systemctl show fdstore-nopin.service -P NFileDescriptorStore)" 1 + +# The file descriptor store should survive service restarts +systemctl restart fdstore-pin.service fdstore-nopin.service + +assert_eq "$(systemctl show fdstore-pin.service -P NFileDescriptorStore)" 1 +assert_eq "$(systemctl show fdstore-nopin.service -P NFileDescriptorStore)" 1 +assert_eq "$(systemctl show fdstore-pin.service -P SubState)" running +assert_eq "$(systemctl show fdstore-nopin.service -P SubState)" running + +# It should not survive the service stop plus a later start (unless pinned) +systemctl stop fdstore-pin.service fdstore-nopin.service + +assert_eq "$(systemctl show fdstore-pin.service -P NFileDescriptorStore)" 1 +assert_eq "$(systemctl show fdstore-nopin.service -P NFileDescriptorStore)" 0 +assert_eq "$(systemctl show fdstore-pin.service -P SubState)" dead-resources-pinned +assert_eq "$(systemctl show fdstore-nopin.service -P SubState)" dead + +systemctl start fdstore-pin.service fdstore-nopin.service + +assert_eq "$(systemctl show fdstore-pin.service -P NFileDescriptorStore)" 1 +assert_eq "$(systemctl show fdstore-nopin.service -P NFileDescriptorStore)" 0 +assert_eq "$(systemctl show fdstore-pin.service -P SubState)" running +assert_eq "$(systemctl show fdstore-nopin.service -P SubState)" running + +systemctl stop fdstore-pin.service fdstore-nopin.service + +assert_eq "$(systemctl show fdstore-pin.service -P NFileDescriptorStore)" 1 +assert_eq "$(systemctl show fdstore-nopin.service -P NFileDescriptorStore)" 0 +assert_eq "$(systemctl show fdstore-pin.service -P SubState)" dead-resources-pinned +assert_eq "$(systemctl show fdstore-nopin.service -P SubState)" dead + +systemctl clean fdstore-pin.service --what=fdstore + +assert_eq "$(systemctl show fdstore-pin.service -P NFileDescriptorStore)" 0 +assert_eq "$(systemctl show fdstore-nopin.service -P NFileDescriptorStore)" 0 +assert_eq "$(systemctl show fdstore-pin.service -P SubState)" dead +assert_eq "$(systemctl show fdstore-nopin.service -P SubState)" dead + touch /testok rm /failed