2 # SPDX-License-Identifier: LGPL-2.1-or-later
3 # shellcheck disable=SC2016
7 # shellcheck source=test/units/assert.sh
8 .
"$(dirname "$0")"/assert.sh
13 if [[ -v UNIT_NAME
&& -e "/usr/lib/systemd/system/$UNIT_NAME" ]]; then
14 rm -fvr "/usr/lib/systemd/system/$UNIT_NAME" "/etc/systemd/system/$UNIT_NAME.d" "+4"
17 rm -f /etc
/init.d
/issue-24990
21 # shellcheck source=test/units/assert.sh
22 .
"$(dirname "$0")"/assert.sh
26 # Create a simple unit file for testing
27 # Note: the service file is created under /usr on purpose to test
28 # the 'revert' verb as well
29 export UNIT_NAME
="systemctl-test-$RANDOM.service"
30 cat >"/usr/lib/systemd/system/$UNIT_NAME" <<\EOF
32 Description
=systemctl
test
35 ExecStart
=sleep infinity
40 ConfigurationDirectory
=%n
46 WantedBy
=multi-user.target
49 # Configure the preset setting for the unit file
50 mkdir
/run
/systemd
/system-preset
/
51 echo "disable $UNIT_NAME" >/run
/systemd
/system-preset
/99-systemd-test.preset
53 EDITOR
='true' script -ec 'systemctl edit "$UNIT_NAME"' /dev
/null
54 [ ! -e "/etc/systemd/system/$UNIT_NAME.d/override.conf" ]
56 printf '%s\n' '[Service]' 'ExecStart=' 'ExecStart=sleep 10d' > "+4"
57 EDITOR
='mv' script -ec 'systemctl edit "$UNIT_NAME"' /dev
/null
58 printf '%s\n' '[Service]' 'ExecStart=' 'ExecStart=sleep 10d' |
cmp - "/etc/systemd/system/$UNIT_NAME.d/override.conf"
60 printf '%b' '[Service]\n' 'ExecStart=\n' 'ExecStart=sleep 10d' > "+4"
61 EDITOR
='mv' script -ec 'systemctl edit "$UNIT_NAME"' /dev
/null
62 printf '%s\n' '[Service]' 'ExecStart=' 'ExecStart=sleep 10d' |
cmp - "/etc/systemd/system/$UNIT_NAME.d/override.conf"
65 systemctl
--state help
66 systemctl
--signal help
70 systemctl list-dependencies systemd-journald
71 systemctl list-dependencies
--after systemd-journald
72 systemctl list-dependencies
--before systemd-journald
73 systemctl list-dependencies
--after --reverse systemd-journald
74 systemctl list-dependencies
--before --reverse systemd-journald
75 systemctl list-dependencies
--plain systemd-journald
79 systemctl list-units
--recursive
80 systemctl list-units
--type=socket
81 systemctl list-units
--type=service
,timer
82 # Compat: --type= allows load states for compatibility reasons
83 systemctl list-units
--type=loaded
84 systemctl list-units
--type=loaded
,socket
85 systemctl list-units
--legend=yes -a "systemd-*"
86 systemctl list-units
--state=active
87 systemctl list-units
--with-dependencies systemd-journald.service
88 systemctl list-units
--with-dependencies --after systemd-journald.service
89 systemctl list-units
--with-dependencies --before --reverse systemd-journald.service
90 systemctl list-sockets
91 systemctl list-sockets
--legend=no
-a "*journal*"
92 systemctl list-sockets
--show-types
93 systemctl list-sockets
--state=listening
94 systemctl list-timers
-a -l
95 systemctl list-unit-files
96 systemctl list-unit-files
"*journal*"
98 systemctl list-jobs
--after
99 systemctl list-jobs
--before
100 systemctl list-jobs
--after --before
101 systemctl list-jobs
"*"
104 # Should return 4 for a missing unit file
105 assert_rc
4 systemctl
--quiet is-active not-found.service
106 assert_rc
4 systemctl
--quiet is-failed not-found.service
107 assert_rc
4 systemctl
--quiet is-enabled not-found.service
108 # is-active: return 3 when the unit exists but inactive
109 assert_rc
3 systemctl
--quiet is-active
"$UNIT_NAME"
110 # is-enabled: return 1 when the unit exists but disabled
111 assert_rc
1 systemctl
--quiet is-enabled
"$UNIT_NAME"
113 # Basic service management
114 systemctl start
--show-transaction "$UNIT_NAME"
115 systemctl status
-n 5 "$UNIT_NAME"
116 systemctl is-active
"$UNIT_NAME"
117 systemctl reload
-T "$UNIT_NAME"
118 systemctl restart
-T "$UNIT_NAME"
119 systemctl try-restart
--show-transaction "$UNIT_NAME"
120 systemctl try-reload-or-restart
--show-transaction "$UNIT_NAME"
121 systemctl
kill "$UNIT_NAME"
122 (! systemctl is-active
"$UNIT_NAME")
123 systemctl restart
"$UNIT_NAME"
124 systemctl is-active
"$UNIT_NAME"
125 systemctl restart
"$UNIT_NAME"
126 systemctl stop
"$UNIT_NAME"
127 (! systemctl is-active
"$UNIT_NAME")
129 # enable/disable/preset
130 (! systemctl is-enabled
"$UNIT_NAME")
131 systemctl
enable "$UNIT_NAME"
132 systemctl is-enabled
-l "$UNIT_NAME"
133 # We created a preset file for this unit above with a "disable" policy
134 systemctl preset
"$UNIT_NAME"
135 (! systemctl is-enabled
"$UNIT_NAME")
136 systemctl reenable
"$UNIT_NAME"
137 systemctl is-enabled
"$UNIT_NAME"
138 systemctl preset
--preset-mode=enable-only
"$UNIT_NAME"
139 systemctl is-enabled
"$UNIT_NAME"
140 systemctl preset
--preset-mode=disable-only
"$UNIT_NAME"
141 (! systemctl is-enabled
"$UNIT_NAME")
142 systemctl
enable --runtime "$UNIT_NAME"
143 [[ -e "/run/systemd/system/multi-user.target.wants/$UNIT_NAME" ]]
144 systemctl is-enabled
"$UNIT_NAME"
145 systemctl disable
"$UNIT_NAME"
146 # The unit should be still enabled, as we didn't use the --runtime switch
147 systemctl is-enabled
"$UNIT_NAME"
148 systemctl disable
--runtime "$UNIT_NAME"
149 (! systemctl is-enabled
"$UNIT_NAME")
152 systemctl disable
"$UNIT_NAME"
153 [[ "$(systemctl is-enabled "$UNIT_NAME")" == disabled
]]
154 systemctl mask
"$UNIT_NAME"
155 [[ "$(systemctl is-enabled "$UNIT_NAME")" == masked
]]
156 systemctl unmask
"$UNIT_NAME"
157 [[ "$(systemctl is-enabled "$UNIT_NAME")" == disabled
]]
158 systemctl mask
"$UNIT_NAME"
159 [[ "$(systemctl is-enabled "$UNIT_NAME")" == masked
]]
160 systemctl revert
"$UNIT_NAME"
161 [[ "$(systemctl is-enabled "$UNIT_NAME")" == disabled
]]
162 systemctl mask
--runtime "$UNIT_NAME"
163 [[ "$(systemctl is-enabled "$UNIT_NAME")" == masked-runtime
]]
164 # This should be a no-op without the --runtime switch
165 systemctl unmask
"$UNIT_NAME"
166 [[ "$(systemctl is-enabled "$UNIT_NAME")" == masked-runtime
]]
167 systemctl unmask
--runtime "$UNIT_NAME"
168 [[ "$(systemctl is-enabled "$UNIT_NAME")" == disabled
]]
170 # add-wants/add-requires
171 (! systemctl show
-P Wants
"$UNIT_NAME" |
grep "systemd-journald.service")
172 systemctl add-wants
"$UNIT_NAME" "systemd-journald.service"
173 systemctl show
-P Wants
"$UNIT_NAME" |
grep "systemd-journald.service"
174 (! systemctl show
-P Requires
"$UNIT_NAME" |
grep "systemd-journald.service")
175 systemctl add-requires
"$UNIT_NAME" "systemd-journald.service"
176 systemctl show
-P Requires
"$UNIT_NAME" |
grep "systemd-journald.service"
179 systemctl set-property
"$UNIT_NAME" IPAccounting
=yes MemoryMax
=1234567
180 systemctl
cat "$UNIT_NAME"
181 # These properties should be saved to a persistent storage
182 grep -r "IPAccounting=yes" "/etc/systemd/system.control/${UNIT_NAME}.d/"
183 grep -r "MemoryMax=1234567" "/etc/systemd/system.control/${UNIT_NAME}.d"
184 systemctl revert
"$UNIT_NAME"
185 (! grep -r "IPAccounting=" "/etc/systemd/system.control/${UNIT_NAME}.d/")
186 (! grep -r "MemoryMax=" "/etc/systemd/system.control/${UNIT_NAME}.d/")
187 # Same stuff, but with --runtime, which should use /run
188 systemctl set-property
--runtime "$UNIT_NAME" CPUAccounting
=no CPUQuota
=10%
189 systemctl
cat "$UNIT_NAME"
190 grep -r "CPUAccounting=no" "/run/systemd/system.control/${UNIT_NAME}.d/"
191 grep -r "CPUQuota=10%" "/run/systemd/system.control/${UNIT_NAME}.d/"
192 systemctl revert
"$UNIT_NAME"
193 (! grep -r "CPUAccounting=" "/run/systemd/system.control/${UNIT_NAME}.d/")
194 (! grep -r "CPUQuota=" "/run/systemd/system.control/${UNIT_NAME}.d/")
196 # Failed-unit related tests
197 (! systemd-run
--wait --unit "failed.service" /bin
/false
)
198 systemctl is-failed failed.service
199 systemctl
--state=failed |
grep failed.service
200 systemctl
--failed |
grep failed.service
201 systemctl reset-failed
"fail*.service"
202 (! systemctl is-failed failed.service
)
205 systemctl restart
"$UNIT_NAME"
206 systemctl stop
"$UNIT_NAME"
207 # Check if the directories from *Directory= directives exist
208 # (except RuntimeDirectory= in /run, which is removed when the unit is stopped)
209 for path
in /var
/lib
/var
/cache
/var
/log
/etc
; do
210 [[ -e "$path/$UNIT_NAME" ]]
213 for what
in "" configuration state cache logs runtime all
; do
214 systemctl clean
${what:+--what="$what"} "$UNIT_NAME"
216 # All respective directories should be removed
217 for path
in /run
/var
/lib
/var
/cache
/var
/log
/etc
; do
218 [[ ! -e "$path/$UNIT_NAME" ]]
222 for value
in pretty us µs utc us
+utc µs
+utc
; do
223 systemctl show
-P KernelTimestamp
--timestamp="$value"
226 # set-default/get-default
227 target
="$(systemctl get-default)"
228 systemctl set-default emergency.target
229 [[ "$(systemctl get-default)" == emergency.target
]]
230 systemctl set-default
"$target"
231 [[ "$(systemctl get-default)" == "$target" ]]
234 systemctl show
--property ""
235 # Pick a heavily sandboxed unit for the best effect on coverage
236 systemctl show systemd-logind.service
238 # Ignore the exit code in this case, as it might try to load non-existing units
239 systemctl status
-a >/dev
/null ||
:
240 systemctl status
-a --state active
,running
,plugged
>/dev
/null
241 systemctl status
"systemd-*.timer"
242 systemctl status
"systemd-journald*.socket"
243 systemctl status
"sys-devices-*-ttyS0.device"
244 systemctl status
-- -.mount
247 systemctl restart
"$UNIT_NAME"
248 systemctl set-property
"$UNIT_NAME" Markers
=needs-restart
249 systemctl show
-P Markers
"$UNIT_NAME" |
grep needs-restart
250 systemctl reload-or-restart
--marked
251 (! systemctl show
-P Markers
"$UNIT_NAME" |
grep needs-restart
)
253 # --dry-run with destructive verbs
254 # kexec is skipped intentionally, as it requires a bit more involved setup
266 suspend-then-hibernate
269 for verb
in "${VERBS[@]}"; do
270 systemctl
--dry-run "$verb"
272 if [[ "$verb" =~
(halt|poweroff|reboot
) ]]; then
273 systemctl
--dry-run --message "Hello world" "$verb"
274 systemctl
--dry-run --no-wall "$verb"
275 systemctl
--dry-run -f "$verb"
276 systemctl
--dry-run -ff "$verb"
280 # Aux verbs & assorted checks
281 systemctl is-active
"*-journald.service"
282 systemctl
cat "*journal*"
283 systemctl
cat "$UNIT_NAME"
284 systemctl
help "$UNIT_NAME"
285 systemctl service-watchdogs
286 systemctl service-watchdogs
"$(systemctl service-watchdogs)"
288 # show/set-environment
289 # Make sure PATH is set
290 systemctl show-environment |
grep -q '^PATH='
291 # Let's add an entry and override a built-in one
292 systemctl set-environment PATH
=/usr
/local
/sbin
:/usr
/local
/bin
:/usr
/sbin
:/usr
/bin
:/testaddition FOO
=BAR
293 # Check that both are set
294 systemctl show-environment |
grep -q '^PATH=.*testaddition$'
295 systemctl show-environment |
grep -q '^FOO=BAR$'
296 systemctl daemon-reload
297 # Check again after the reload
298 systemctl show-environment |
grep -q '^PATH=.*testaddition$'
299 systemctl show-environment |
grep -q '^FOO=BAR$'
300 # Check that JSON output is supported
301 systemctl show-environment
--output=json |
grep -q '^{.*"FOO":"BAR".*}$'
303 systemctl unset-environment FOO PATH
304 # Check that one is gone and the other reverted to the built-in
305 systemctl show-environment |
grep '^FOO=$' && exit 1
306 systemctl show-environment |
grep '^PATH=.*testaddition$' && exit 1
307 systemctl show-environment |
grep -q '^PATH='
308 # Check import-environment
309 export IMPORT_THIS
=hello
310 export IMPORT_THIS_TOO
=world
311 systemctl import-environment IMPORT_THIS IMPORT_THIS_TOO
312 systemctl show-environment |
grep "^IMPORT_THIS=$IMPORT_THIS"
313 systemctl show-environment |
grep "^IMPORT_THIS_TOO=$IMPORT_THIS_TOO"
314 systemctl unset-environment IMPORT_THIS IMPORT_THIS_TOO
315 (! systemctl show-environment |
grep "^IMPORT_THIS=")
316 (! systemctl show-environment |
grep "^IMPORT_THIS_TOO=")
318 # test for sysv-generator (issue #24990)
319 if [[ -x /usr
/lib
/systemd
/system-generators
/systemd-sysv-generator
]]; then
322 cat >/etc
/init.d
/issue-24990
<<\EOF
326 # Provides:test1 test2
327 # Required-Start:test1 $remote_fs $network
328 # Required-Stop:test1 $remote_fs $network
330 # Short-Description: Test
335 echo "Starting issue-24990.service"
339 echo "Stopping issue-24990.service"
343 echo "Usage: service test {start|stop|restart|status}"
348 chmod +x
/etc
/init.d
/issue-24990
349 systemctl daemon-reload
350 [[ -L /run
/systemd
/generator.late
/test1.service
]]
351 [[ -L /run
/systemd
/generator.late
/test2.service
]]
352 assert_eq
"$(readlink -f /run/systemd/generator.late/test1.service)" "/run/systemd/generator.late/issue-24990.service"
353 assert_eq
"$(readlink -f /run/systemd/generator.late/test2.service)" "/run/systemd/generator.late/issue-24990.service"
354 output
=$
(systemctl
cat issue-24990
)
355 assert_in
"SourcePath=/etc/init.d/issue-24990" "$output"
356 assert_in
"Description=LSB: Test" "$output"
357 assert_in
"After=test1.service" "$output"
358 assert_in
"After=remote-fs.target" "$output"
359 assert_in
"After=network-online.target" "$output"
360 assert_in
"Wants=network-online.target" "$output"
361 assert_in
"ExecStart=/etc/init.d/issue-24990 start" "$output"
362 assert_in
"ExecStop=/etc/init.d/issue-24990 stop" "$output"
363 systemctl status issue-24990 ||
:
364 systemctl show issue-24990
365 assert_not_in
"issue-24990.service" "$(systemctl show --property=After --value)"
366 assert_not_in
"issue-24990.service" "$(systemctl show --property=Before --value)"
368 if ! systemctl is-active network-online.target
; then
369 systemctl start network-online.target
372 systemctl restart issue-24990
373 systemctl stop issue-24990
376 cat >/etc
/init.d
/issue-24990
<<\EOF
380 # Provides:test1 test2
381 # Required-Start:$remote_fs
382 # Required-Stop:$remote_fs
384 # Short-Description: Test
389 echo "Starting issue-24990.service"
393 echo "Stopping issue-24990.service"
397 echo "Usage: service test {start|stop|restart|status}"
402 chmod +x
/etc
/init.d
/issue-24990
403 systemctl daemon-reload
404 [[ -L /run
/systemd
/generator.late
/test1.service
]]
405 [[ -L /run
/systemd
/generator.late
/test2.service
]]
406 assert_eq
"$(readlink -f /run/systemd/generator.late/test1.service)" "/run/systemd/generator.late/issue-24990.service"
407 assert_eq
"$(readlink -f /run/systemd/generator.late/test2.service)" "/run/systemd/generator.late/issue-24990.service"
408 output
=$
(systemctl
cat issue-24990
)
409 assert_in
"SourcePath=/etc/init.d/issue-24990" "$output"
410 assert_in
"Description=LSB: Test" "$output"
411 assert_in
"After=remote-fs.target" "$output"
412 assert_in
"ExecStart=/etc/init.d/issue-24990 start" "$output"
413 assert_in
"ExecStop=/etc/init.d/issue-24990 stop" "$output"
414 systemctl status issue-24990 ||
:
415 systemctl show issue-24990
416 assert_not_in
"issue-24990.service" "$(systemctl show --property=After --value)"
417 assert_not_in
"issue-24990.service" "$(systemctl show --property=Before --value)"
419 systemctl restart issue-24990
420 systemctl stop issue-24990