]> git.ipfire.org Git - thirdparty/systemd.git/blob - test/units/testsuite-63.sh
core: path: Re-enter waiting if target is deactivating
[thirdparty/systemd.git] / test / units / testsuite-63.sh
1 #!/usr/bin/env bash
2 # SPDX-License-Identifier: LGPL-2.1-or-later
3 set -ex
4 set -o pipefail
5
6 # shellcheck source=test/units/util.sh
7 . "$(dirname "$0")"/util.sh
8
9 systemctl log-level debug
10
11 # Test that a path unit continuously triggering a service that fails condition checks eventually fails with
12 # the trigger-limit-hit error.
13 rm -f /tmp/nonexistent
14 systemctl start test63.path
15 touch /tmp/test63
16
17 # Make sure systemd has sufficient time to hit the trigger limit for test63.path.
18 # shellcheck disable=SC2016
19 timeout 30 bash -c 'until test "$(systemctl show test63.path -P ActiveState)" = failed; do sleep .2; done'
20 test "$(systemctl show test63.service -P ActiveState)" = inactive
21 test "$(systemctl show test63.service -P Result)" = success
22 test "$(systemctl show test63.path -P Result)" = trigger-limit-hit
23
24 # Test that starting the service manually doesn't affect the path unit.
25 rm -f /tmp/test63
26 systemctl reset-failed
27 systemctl start test63.path
28 systemctl start test63.service
29 test "$(systemctl show test63.service -P ActiveState)" = inactive
30 test "$(systemctl show test63.service -P Result)" = success
31 test "$(systemctl show test63.path -P ActiveState)" = active
32 test "$(systemctl show test63.path -P Result)" = success
33
34 # Test that glob matching works too, with $TRIGGER_PATH
35 systemctl start test63-glob.path
36 touch /tmp/test63-glob-foo
37 timeout 60 bash -c 'until systemctl -q is-active test63-glob.service; do sleep .2; done'
38 test "$(systemctl show test63-glob.service -P ActiveState)" = active
39 test "$(systemctl show test63-glob.service -P Result)" = success
40
41 test "$(busctl --json=short get-property org.freedesktop.systemd1 /org/freedesktop/systemd1/unit/test63_2dglob_2eservice org.freedesktop.systemd1.Unit ActivationDetails)" = '{"type":"a(ss)","data":[["trigger_unit","test63-glob.path"],["trigger_path","/tmp/test63-glob-foo"]]}'
42
43 systemctl stop test63-glob.path test63-glob.service
44
45 test "$(busctl --json=short get-property org.freedesktop.systemd1 /org/freedesktop/systemd1/unit/test63_2dglob_2eservice org.freedesktop.systemd1.Unit ActivationDetails)" = '{"type":"a(ss)","data":[]}'
46
47 # tests for issue https://github.com/systemd/systemd/issues/24577#issuecomment-1522628906
48 rm -f /tmp/hoge
49 systemctl start test63-issue-24577.path
50 systemctl status -n 0 test63-issue-24577.path
51 systemctl status -n 0 test63-issue-24577.service || :
52 systemctl list-jobs
53 output=$(systemctl list-jobs --no-legend)
54 assert_not_in "test63-issue-24577.service" "$output"
55 assert_not_in "test63-issue-24577-dep.service" "$output"
56
57 touch /tmp/hoge
58 systemctl status -n 0 test63-issue-24577.path
59 systemctl status -n 0 test63-issue-24577.service || :
60 systemctl list-jobs
61 output=$(systemctl list-jobs --no-legend)
62 assert_in "test63-issue-24577.service" "$output"
63 assert_in "test63-issue-24577-dep.service" "$output"
64
65 # even if the service is stopped, it will be soon retriggered.
66 systemctl stop test63-issue-24577.service
67 systemctl status -n 0 test63-issue-24577.path
68 systemctl status -n 0 test63-issue-24577.service || :
69 systemctl list-jobs
70 output=$(systemctl list-jobs --no-legend)
71 assert_in "test63-issue-24577.service" "$output"
72 assert_in "test63-issue-24577-dep.service" "$output"
73
74 rm -f /tmp/hoge
75 systemctl stop test63-issue-24577.service
76 systemctl status -n 0 test63-issue-24577.path
77 systemctl status -n 0 test63-issue-24577.service || :
78 systemctl list-jobs
79 output=$(systemctl list-jobs --no-legend)
80 assert_not_in "test63-issue-24577.service" "$output"
81 assert_in "test63-issue-24577-dep.service" "$output"
82
83 # Test for race condition fixed by https://github.com/systemd/systemd/pull/30768
84 # Here's the schedule of events that we to happen during this test:
85 # (This test) (The service)
86 # .path unit monitors /tmp/copyme for changes
87 # Take lock on /tmp/noexeit ↓
88 # Write to /tmp/copyme ↓
89 # Wait for deactivating Started
90 # ↓ Copies /tmp/copyme to /tmp/copied
91 # ↓ Tells manager it's shutting down
92 # Ensure service did the copy Tries to lock /tmp/noexit and blocks
93 # Write to /tmp/copyme ↓
94 #
95 # Now at this point the test can diverge. If we regress, this second write is
96 # missed and we'll see:
97 # ... (second write) ... (blocked)
98 # Drop lock on /tmp/noexit ↓
99 # Wait for service to do copy Unblocks and exits
100 # ↓ (dead)
101 # ↓
102 # (timeout)
103 # Test fails
104 #
105 # Otherwise, we'll see:
106 # ... (second write) ... (blocked)
107 # Drop lock on /tmp/noexit ↓ and .path unit queues a new start job
108 # Wait for service to do copy Unblocks and exits
109 # ↓ Starts again b/c of queued job
110 # ↓ Copies again
111 # Test Passes
112 systemctl start test63-pr-30768.path
113 exec {lock}<>/tmp/noexit
114 flock -e $lock
115 echo test1 > /tmp/copyme
116 # shellcheck disable=SC2016
117 timeout 30 bash -c 'until test "$(systemctl show test63-pr-30768.service -P ActiveState)" = deactivating; do sleep .2; done'
118 diff /tmp/copyme /tmp/copied
119 echo test2 > /tmp/copyme
120 exec {lock}<&-
121 timeout 30 bash -c 'until diff /tmp/copyme /tmp/copied; do sleep .2; done'
122
123 systemctl log-level info
124
125 touch /testok