]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
test: validate that fdstore pinning works 27135/head
authorLennart Poettering <lennart@poettering.net>
Tue, 4 Apr 2023 09:41:55 +0000 (11:41 +0200)
committerLennart Poettering <lennart@poettering.net>
Thu, 13 Apr 2023 04:44:27 +0000 (06:44 +0200)
test/testsuite-80.units/fdstore-nopin.service [new file with mode: 0644]
test/testsuite-80.units/fdstore-pin.service [new file with mode: 0644]
test/testsuite-80.units/fdstore-pin.sh [new file with mode: 0755]
test/testsuite-80.units/fdstore-pin.target [new file with mode: 0644]
test/units/testsuite-80.service
test/units/testsuite-80.sh

diff --git a/test/testsuite-80.units/fdstore-nopin.service b/test/testsuite-80.units/fdstore-nopin.service
new file mode 100644 (file)
index 0000000..58a687a
--- /dev/null
@@ -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 (file)
index 0000000..bc78ee0
--- /dev/null
@@ -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 (executable)
index 0000000..4cb041a
--- /dev/null
@@ -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 (file)
index 0000000..319b7e1
--- /dev/null
@@ -0,0 +1,3 @@
+[Unit]
+After=fdstore-pin.service fdstore-nopin.service
+Wants=fdstore-pin.service fdstore-nopin.service
index 4c7f5d5ebd3ac9dfdc815db0be4752de68bee185..82b08a1c8b0601f0c62e8f13f674250145ceaa97 100644 (file)
@@ -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
index 15ea36bf88d7a8e9a3cee002350785649087c106..7440b241bee9f51f16861a3c7bb94881c6e3f8e7 100755 (executable)
@@ -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