]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
test: fix racy machined test
authorLennart Poettering <lennart@poettering.net>
Mon, 17 Feb 2025 10:34:27 +0000 (11:34 +0100)
committerLennart Poettering <lennart@poettering.net>
Thu, 20 Feb 2025 17:12:13 +0000 (18:12 +0100)
Previously, one of the io.systemd.Machine.Open() tests would invoke a
command line via machined, and then check if it ran properly. This was
implemented in a racy fashion: the client side would immediately close
the pty fd allocated for the operation, thus triggering an immediate
SIGHUP on the other side. Now, depending whether this client was quicker
in closing or the server was quicker in executing the command line this
was a race.

Fix this comprehensively: let's first wait for the varlink operation to
complete via the new "systemd-notify --fork" logic (because varlinkctl
sends out READY=1 once handing off to --exec). Secondly let's use
varlinkctl's --exec logic to invoke a process which keeps open the open
pty until we kill it (we just use sleep for that).

(Also add some more tests for the varlinkctl --exec stuff)

test/units/TEST-13-NSPAWN.machined.sh
test/units/TEST-74-AUX-UTILS.varlinkctl.sh

index 5bc24236747a061b947a42cb5d8a1d67f0d128bf..4875e48f8095c3321beab9eaf901d973f8b72b7c 100755 (executable)
@@ -388,9 +388,18 @@ varlinkctl call /run/systemd/machine/io.systemd.Machine io.systemd.Machine.Open
 varlinkctl call /run/systemd/machine/io.systemd.Machine io.systemd.Machine.Open '{"name": ".host", "mode": "shell"}'
 
 rm -f /tmp/none-existent-file
-varlinkctl call /run/systemd/machine/io.systemd.Machine io.systemd.Machine.Open '{"name": ".host", "mode": "shell", "user": "root", "path": "/bin/sh", "args": ["/bin/sh", "-c", "echo $FOO > /tmp/none-existent-file"], "environment": ["FOO=BAR"]}'
+
+# We need to make sure the acquired pty fd stays open if we invoke a command
+# server side, to not generate early SIGHUP. Hence, let's just invoke "sleep
+# infinity" client side, once we acquired the fd (passing it to it), and kill
+# it once we verified everything worked.
+PID=$(systemd-notify --fork -- varlinkctl --exec call /run/systemd/machine/io.systemd.Machine io.systemd.Machine.Open '{"name": ".host", "mode": "shell", "user": "root", "path": "/bin/bash", "args": ["/bin/bash", "-c", "echo $FOO > /tmp/none-existent-file"], "environment": ["FOO=BAR"]}' -- sleep infinity)
 timeout 30 bash -c "until test -e /tmp/none-existent-file; do sleep .5; done"
 grep -q "BAR" /tmp/none-existent-file
+kill "$PID"
+
+# Test varlinkctl's --exec fd passing logic properly
+assert_eq "$(varlinkctl --exec call /run/systemd/machine/io.systemd.Machine io.systemd.Machine.Open '{"name": ".host", "mode": "shell", "user": "root", "path": "/bin/bash", "args": ["/bin/bash", "-c", "echo $((7 + 8))"]}' -- bash -c 'read -r -N 2 x <&3 ; echo "$x"')" 15
 
 # test io.systemd.Machine.MapFrom
 varlinkctl call /run/systemd/machine/io.systemd.Machine io.systemd.Machine.MapFrom '{"name": "long-running", "uid":0, "gid": 0}'
index a0797469a46cbdb53cab64ccdb55fb61be12dd7f..921fadf998cbe2c9b2f23150963fcac19d9227b8 100755 (executable)
@@ -160,3 +160,9 @@ done
 varlinkctl info /run/systemd/io.systemd.Hostname
 varlinkctl introspect /run/systemd/io.systemd.Hostname io.systemd.Hostname
 varlinkctl call /run/systemd/io.systemd.Hostname io.systemd.Hostname.Describe '{}'
+
+# Validate that --exec results in the very same values
+varlinkctl call /run/systemd/io.systemd.Hostname io.systemd.Hostname.Describe '{}' | jq > /tmp/describe1.json
+varlinkctl --exec call /run/systemd/io.systemd.Hostname io.systemd.Hostname.Describe '{}' -- jq > /tmp/describe2.json
+cmp /tmp/describe1.json /tmp/describe2.json
+rm /tmp/describe1.json /tmp/describe2.json