]> git.ipfire.org Git - thirdparty/systemd.git/blob - test/units/testsuite-15.sh
tests: add spdx headers to scripts and Makefiles
[thirdparty/systemd.git] / test / units / testsuite-15.sh
1 #!/bin/bash
2 # SPDX-License-Identifier: LGPL-2.1-or-later
3 set -eux
4 set -o pipefail
5
6 _clear_service () {
7 local SERVICE_NAME="${1:?_clear_service: missing argument}"
8 systemctl stop "$SERVICE_NAME.service" 2>/dev/null || :
9 rm -f /{etc,run,usr/lib}/systemd/system/"$SERVICE_NAME".service
10 rm -fr /{etc,run,usr/lib}/systemd/system/"$SERVICE_NAME".service.d
11 rm -fr /{etc,run,usr/lib}/systemd/system/"$SERVICE_NAME".service.{wants,requires}
12 if [[ $SERVICE_NAME == *@ ]]; then
13 systemctl stop "$SERVICE_NAME"*.service 2>/dev/null || :
14 rm -f /{etc,run,usr/lib}/systemd/system/"$SERVICE_NAME"*.service
15 rm -fr /{etc,run,usr/lib}/systemd/system/"$SERVICE_NAME"*.service.d
16 rm -fr /{etc,run,usr/lib}/systemd/system/"$SERVICE_NAME"*.service.{wants,requires}
17 fi
18 }
19
20 clear_services () {
21 for u in "$@"; do
22 _clear_service "$u"
23 done
24 systemctl daemon-reload
25 }
26
27 create_service () {
28 local SERVICE_NAME="${1:?create_service: missing argument}"
29 clear_services "$SERVICE_NAME"
30
31 cat >/etc/systemd/system/"$SERVICE_NAME".service <<EOF
32 [Unit]
33 Description=$SERVICE_NAME unit
34
35 [Service]
36 ExecStart=sleep 100000
37 EOF
38 mkdir -p /{etc,run,usr/lib}/systemd/system/"$SERVICE_NAME".service.{d,wants,requires}
39 }
40
41 create_services () {
42 for u in "$@"; do
43 create_service "$u"
44 done
45 }
46
47 check_ok () {
48 x="$(systemctl show --value -p "${2:?}" "${1:?}")"
49 case "$x" in
50 *${3:?}*) return 0 ;;
51 *) return 1 ;;
52 esac
53 }
54
55 check_ko () {
56 ! check_ok "$@"
57 }
58
59 test_basic_dropins () {
60 echo "Testing basic dropins..."
61
62 echo "*** test a wants b wants c"
63 create_services test15-a test15-b test15-c
64 ln -s ../test15-b.service /etc/systemd/system/test15-a.service.wants/
65 ln -s ../test15-c.service /etc/systemd/system/test15-b.service.wants/
66 check_ok test15-a Wants test15-b.service
67 check_ok test15-b Wants test15-c.service
68
69 echo "*** test a wants,requires b"
70 create_services test15-a test15-b test15-c
71 ln -s ../test15-b.service /etc/systemd/system/test15-a.service.wants/
72 ln -s ../test15-b.service /etc/systemd/system/test15-a.service.requires/
73 check_ok test15-a Wants test15-b.service
74 check_ok test15-a Requires test15-b.service
75
76 echo "*** test a wants nonexistent"
77 create_service test15-a
78 ln -s ../nonexistent.service /etc/systemd/system/test15-a.service.wants/
79 check_ok test15-a Wants nonexistent.service
80 systemctl start test15-a
81 systemctl stop test15-a
82
83 echo "*** test a requires nonexistent"
84 ln -sf ../nonexistent.service /etc/systemd/system/test15-a.service.requires/
85 systemctl daemon-reload
86 check_ok test15-a Requires nonexistent.service
87
88 # 'b' is already loaded when 'c' pulls it in via a dropin.
89 echo "*** test a,c require b"
90 create_services test15-a test15-b test15-c
91 ln -sf ../test15-b.service /etc/systemd/system/test15-a.service.requires/
92 ln -sf ../test15-b.service /etc/systemd/system/test15-c.service.requires/
93 systemctl start test15-a
94 check_ok test15-c Requires test15-b.service
95 systemctl stop test15-a test15-b
96
97 # 'b' is already loaded when 'c' pulls it in via an alias dropin.
98 echo "*** test a wants alias"
99 create_services test15-a test15-b test15-c
100 ln -sf test15-c.service /etc/systemd/system/test15-c1.service
101 ln -sf ../test15-c.service /etc/systemd/system/test15-a.service.wants/
102 ln -sf ../test15-c1.service /etc/systemd/system/test15-b.service.wants/
103 systemctl start test15-a
104 check_ok test15-a Wants test15-c.service
105 check_ok test15-b Wants test15-c.service
106 systemctl stop test15-a test15-c
107
108 echo "*** test service.d/ top level drop-in"
109 create_services test15-a test15-b
110 check_ko test15-a ExecCondition "/bin/echo a"
111 check_ko test15-b ExecCondition "/bin/echo b"
112 mkdir -p /usr/lib/systemd/system/service.d
113 cat >/usr/lib/systemd/system/service.d/override.conf <<EOF
114 [Service]
115 ExecCondition=/bin/echo %n
116 EOF
117 systemctl daemon-reload
118 check_ok test15-a ExecCondition "/bin/echo test15-a"
119 check_ok test15-b ExecCondition "/bin/echo test15-b"
120 rm -rf /usr/lib/systemd/system/service.d
121
122 clear_services test15-a test15-b test15-c test15-c1
123 }
124
125 test_linked_units () {
126 echo "Testing linked units..."
127 echo "*** test linked unit (same basename)"
128
129 create_service test15-a
130 mv /etc/systemd/system/test15-a.service /
131 ln -s /test15-a.service /etc/systemd/system/
132 ln -s test15-a.service /etc/systemd/system/test15-b.service
133
134 check_ok test15-a Names test15-a.service
135 check_ok test15-a Names test15-b.service
136
137 echo "*** test linked unit (cross basename)"
138
139 mv /test15-a.service /test15-a@.scope
140 ln -fs /test15-a@.scope /etc/systemd/system/test15-a.service
141 systemctl daemon-reload
142
143 check_ok test15-a Names test15-a.service
144 check_ok test15-a Names test15-b.service
145 check_ko test15-a Names test15-a@ # test15-a@.scope is the symlink target.
146 # Make sure it is completely ignored.
147
148 rm /test15-a@.scope
149 clear_services test15-a test15-b
150 }
151
152 test_template_alias() {
153 echo "Testing instance alias..."
154 echo "*** forward"
155
156 create_service test15-a@
157 ln -s test15-a@inst.service /etc/systemd/system/test15-b@inst.service # alias
158
159 check_ok test15-a@inst Names test15-a@inst.service
160 check_ok test15-a@inst Names test15-b@inst.service
161
162 check_ok test15-a@other Names test15-a@other.service
163 check_ko test15-a@other Names test15-b@other.service
164
165 echo "*** reverse"
166
167 systemctl daemon-reload
168
169 check_ok test15-b@inst Names test15-a@inst.service
170 check_ok test15-b@inst Names test15-b@inst.service
171
172 check_ko test15-b@other Names test15-a@other.service
173 check_ok test15-b@other Names test15-b@other.service
174
175 clear_services test15-a@ test15-b@
176 }
177
178 test_hierarchical_dropins () {
179 echo "Testing hierarchical dropins..."
180 echo "*** test service.d/ top level drop-in"
181 create_services a-b-c
182 check_ko a-b-c ExecCondition "/bin/echo service.d"
183 check_ko a-b-c ExecCondition "/bin/echo a-.service.d"
184 check_ko a-b-c ExecCondition "/bin/echo a-b-.service.d"
185 check_ko a-b-c ExecCondition "/bin/echo a-b-c.service.d"
186
187 for dropin in service.d a-.service.d a-b-.service.d a-b-c.service.d; do
188 mkdir -p /usr/lib/systemd/system/$dropin
189 echo "
190 [Service]
191 ExecCondition=/bin/echo $dropin
192 " >/usr/lib/systemd/system/$dropin/override.conf
193 systemctl daemon-reload
194 check_ok a-b-c ExecCondition "/bin/echo $dropin"
195 done
196 for dropin in service.d a-.service.d a-b-.service.d a-b-c.service.d; do
197 rm -rf /usr/lib/systemd/system/$dropin
198 done
199
200 clear_services a-b-c
201 }
202
203 test_template_dropins () {
204 echo "Testing template dropins..."
205
206 create_services foo bar@ yup@
207
208 # Declare some deps to check if the body was loaded
209 cat >>/etc/systemd/system/bar@.service <<EOF
210 [Unit]
211 After=bar-template-after.device
212 EOF
213
214 cat >>/etc/systemd/system/yup@.service <<EOF
215 [Unit]
216 After=yup-template-after.device
217 EOF
218
219 ln -s /etc/systemd/system/bar@.service /etc/systemd/system/foo.service.wants/bar@1.service
220 check_ok foo Wants bar@1.service
221
222 echo "*** test bar-alias@.service→bar@.service, but instance symlinks point to yup@.service ***"
223 ln -s bar@.service /etc/systemd/system/bar-alias@.service
224 ln -s bar@1.service /etc/systemd/system/bar-alias@1.service
225 ln -s yup@.service /etc/systemd/system/bar-alias@2.service
226 ln -s yup@3.service /etc/systemd/system/bar-alias@3.service
227
228 # create some dropin deps
229 mkdir -p /etc/systemd/system/bar@{,0,1,2,3}.service.requires/
230 mkdir -p /etc/systemd/system/yup@{,0,1,2,3}.service.requires/
231 mkdir -p /etc/systemd/system/bar-alias@{,0,1,2,3}.service.requires/
232
233 ln -s ../bar-template-requires.device /etc/systemd/system/bar@.service.requires/
234 ln -s ../bar-0-requires.device /etc/systemd/system/bar@0.service.requires/
235 ln -s ../bar-1-requires.device /etc/systemd/system/bar@1.service.requires/
236 ln -s ../bar-2-requires.device /etc/systemd/system/bar@2.service.requires/
237 ln -s ../bar-3-requires.device /etc/systemd/system/bar@3.service.requires/
238
239 ln -s ../yup-template-requires.device /etc/systemd/system/yup@.service.requires/
240 ln -s ../yup-0-requires.device /etc/systemd/system/yup@0.service.requires/
241 ln -s ../yup-1-requires.device /etc/systemd/system/yup@1.service.requires/
242 ln -s ../yup-2-requires.device /etc/systemd/system/yup@2.service.requires/
243 ln -s ../yup-3-requires.device /etc/systemd/system/yup@3.service.requires/
244
245 ln -s ../bar-alias-template-requires.device /etc/systemd/system/bar-alias@.service.requires/
246 ln -s ../bar-alias-0-requires.device /etc/systemd/system/bar-alias@0.service.requires/
247 ln -s ../bar-alias-1-requires.device /etc/systemd/system/bar-alias@1.service.requires/
248 ln -s ../bar-alias-2-requires.device /etc/systemd/system/bar-alias@2.service.requires/
249 ln -s ../bar-alias-3-requires.device /etc/systemd/system/bar-alias@3.service.requires/
250
251 systemctl daemon-reload
252
253 echo '*** bar@0 is aliased by bar-alias@0 ***'
254 systemctl show -p Names,Requires bar@0
255 systemctl show -p Names,Requires bar-alias@0
256 check_ok bar@0 Names bar@0
257 check_ok bar@0 Names bar-alias@0
258
259 check_ok bar@0 After bar-template-after.device
260
261 check_ok bar@0 Requires bar-0-requires.device
262 check_ok bar@0 Requires bar-alias-0-requires.device
263 check_ok bar@0 Requires bar-template-requires.device
264 check_ok bar@0 Requires bar-alias-template-requires.device
265 check_ko bar@0 Requires yup-template-requires.device
266
267 check_ok bar-alias@0 After bar-template-after.device
268
269 check_ok bar-alias@0 Requires bar-0-requires.device
270 check_ok bar-alias@0 Requires bar-alias-0-requires.device
271 check_ok bar-alias@0 Requires bar-template-requires.device
272 check_ok bar-alias@0 Requires bar-alias-template-requires.device
273 check_ko bar-alias@0 Requires yup-template-requires.device
274 check_ko bar-alias@0 Requires yup-0-requires.device
275
276 echo '*** bar@1 is aliased by bar-alias@1 ***'
277 systemctl show -p Names,Requires bar@1
278 systemctl show -p Names,Requires bar-alias@1
279 check_ok bar@1 Names bar@1
280 check_ok bar@1 Names bar-alias@1
281
282 check_ok bar@1 After bar-template-after.device
283
284 check_ok bar@1 Requires bar-1-requires.device
285 check_ok bar@1 Requires bar-alias-1-requires.device
286 check_ok bar@1 Requires bar-template-requires.device
287 # See https://github.com/systemd/systemd/pull/13119#discussion_r308145418
288 check_ok bar@1 Requires bar-alias-template-requires.device
289 check_ko bar@1 Requires yup-template-requires.device
290 check_ko bar@1 Requires yup-1-requires.device
291
292 check_ok bar-alias@1 After bar-template-after.device
293
294 check_ok bar-alias@1 Requires bar-1-requires.device
295 check_ok bar-alias@1 Requires bar-alias-1-requires.device
296 check_ok bar-alias@1 Requires bar-template-requires.device
297 check_ok bar-alias@1 Requires bar-alias-template-requires.device
298 check_ko bar-alias@1 Requires yup-template-requires.device
299 check_ko bar-alias@1 Requires yup-1-requires.device
300
301 echo '*** bar-alias@2 aliases yup@2, bar@2 is independent ***'
302 systemctl show -p Names,Requires bar@2
303 systemctl show -p Names,Requires bar-alias@2
304 check_ok bar@2 Names bar@2
305 check_ko bar@2 Names bar-alias@2
306
307 check_ok bar@2 After bar-template-after.device
308
309 check_ok bar@2 Requires bar-2-requires.device
310 check_ko bar@2 Requires bar-alias-2-requires.device
311 check_ok bar@2 Requires bar-template-requires.device
312 check_ko bar@2 Requires bar-alias-template-requires.device
313 check_ko bar@2 Requires yup-template-requires.device
314 check_ko bar@2 Requires yup-2-requires.device
315
316 check_ko bar-alias@2 After bar-template-after.device
317
318 check_ko bar-alias@2 Requires bar-2-requires.device
319 check_ok bar-alias@2 Requires bar-alias-2-requires.device
320 check_ko bar-alias@2 Requires bar-template-requires.device
321 check_ok bar-alias@2 Requires bar-alias-template-requires.device
322 check_ok bar-alias@2 Requires yup-template-requires.device
323 check_ok bar-alias@2 Requires yup-2-requires.device
324
325 echo '*** bar-alias@3 aliases yup@3, bar@3 is independent ***'
326 systemctl show -p Names,Requires bar@3
327 systemctl show -p Names,Requires bar-alias@3
328 check_ok bar@3 Names bar@3
329 check_ko bar@3 Names bar-alias@3
330
331 check_ok bar@3 After bar-template-after.device
332
333 check_ok bar@3 Requires bar-3-requires.device
334 check_ko bar@3 Requires bar-alias-3-requires.device
335 check_ok bar@3 Requires bar-template-requires.device
336 check_ko bar@3 Requires bar-alias-template-requires.device
337 check_ko bar@3 Requires yup-template-requires.device
338 check_ko bar@3 Requires yup-3-requires.device
339
340 check_ko bar-alias@3 After bar-template-after.device
341
342 check_ko bar-alias@3 Requires bar-3-requires.device
343 check_ok bar-alias@3 Requires bar-alias-3-requires.device
344 check_ko bar-alias@3 Requires bar-template-requires.device
345 check_ok bar-alias@3 Requires bar-alias-template-requires.device
346 check_ok bar-alias@3 Requires yup-template-requires.device
347 check_ok bar-alias@3 Requires yup-3-requires.device
348
349 clear_services foo {bar,yup,bar-alias}@{,1,2,3}
350 }
351
352 test_alias_dropins () {
353 echo "Testing alias dropins..."
354
355 echo "*** test a wants b1 alias of b"
356 create_services test15-a test15-b
357 ln -sf test15-b.service /etc/systemd/system/test15-b1.service
358 ln -sf ../test15-b1.service /etc/systemd/system/test15-a.service.wants/
359 check_ok test15-a Wants test15-b.service
360 systemctl start test15-a
361 systemctl --quiet is-active test15-b
362 systemctl stop test15-a test15-b
363 rm /etc/systemd/system/test15-b1.service
364 clear_services test15-a test15-b
365
366 # Check that dependencies don't vary.
367 echo "*** test 2"
368 create_services test15-a test15-x test15-y
369 mkdir -p /etc/systemd/system/test15-a1.service.wants/
370 ln -sf test15-a.service /etc/systemd/system/test15-a1.service
371 ln -sf ../test15-x.service /etc/systemd/system/test15-a.service.wants/
372 ln -sf ../test15-y.service /etc/systemd/system/test15-a1.service.wants/
373 check_ok test15-a1 Wants test15-x.service # see [1]
374 check_ok test15-a1 Wants test15-y.service
375 systemctl start test15-a
376 check_ok test15-a1 Wants test15-x.service # see [2]
377 check_ok test15-a1 Wants test15-y.service
378 systemctl stop test15-a test15-x test15-y
379 rm /etc/systemd/system/test15-a1.service
380
381 clear_services test15-a test15-x test15-y
382 }
383
384 test_masked_dropins () {
385 echo "Testing masked dropins..."
386
387 create_services test15-a test15-b
388
389 # 'b' is masked for both deps
390 echo "*** test a wants,requires b is masked"
391 ln -sf /dev/null /etc/systemd/system/test15-a.service.wants/test15-b.service
392 ln -sf /dev/null /etc/systemd/system/test15-a.service.requires/test15-b.service
393 check_ko test15-a Wants test15-b.service
394 check_ko test15-a Requires test15-b.service
395
396 # 'a' wants 'b' and 'b' is masked at a lower level
397 echo "*** test a wants b, mask override"
398 ln -sf ../test15-b.service /etc/systemd/system/test15-a.service.wants/test15-b.service
399 ln -sf /dev/null /usr/lib/systemd/system/test15-a.service.wants/test15-b.service
400 check_ok test15-a Wants test15-b.service
401
402 # 'a' wants 'b' and 'b' is masked at a higher level
403 echo "*** test a wants b, mask"
404 ln -sf /dev/null /etc/systemd/system/test15-a.service.wants/test15-b.service
405 ln -sf ../test15-b.service /usr/lib/systemd/system/test15-a.service.wants/test15-b.service
406 check_ko test15-a Wants test15-b.service
407
408 # 'a' is masked but has an override config file
409 echo "*** test a is masked but has an override"
410 create_services test15-a test15-b
411 ln -sf /dev/null /etc/systemd/system/test15-a.service
412 cat >/usr/lib/systemd/system/test15-a.service.d/override.conf <<EOF
413 [Unit]
414 After=test15-b.service
415 EOF
416 check_ok test15-a UnitFileState masked
417
418 # 'b1' is an alias for 'b': masking 'b' dep should not influence 'b1' dep
419 echo "*** test a wants b, b1, and one is masked"
420 create_services test15-a test15-b
421 ln -sf test15-b.service /etc/systemd/system/test15-b1.service
422 ln -sf /dev/null /etc/systemd/system/test15-a.service.wants/test15-b.service
423 ln -sf ../test15-b1.service /usr/lib/systemd/system/test15-a.service.wants/test15-b1.service
424 systemctl cat test15-a
425 systemctl show -p Wants,Requires test15-a
426 systemctl cat test15-b1
427 systemctl show -p Wants,Requires test15-b1
428 check_ok test15-a Wants test15-b.service
429 check_ko test15-a Wants test15-b1.service # the alias does not show up in the list of units
430 rm /etc/systemd/system/test15-b1.service
431
432 # 'b1' is an alias for 'b': masking 'b1' should not influence 'b' dep
433 echo "*** test a wants b, alias dep is masked"
434 create_services test15-a test15-b
435 ln -sf test15-b.service /etc/systemd/system/test15-b1.service
436 ln -sf /dev/null /etc/systemd/system/test15-a.service.wants/test15-b1.service
437 ln -sf ../test15-b.service /usr/lib/systemd/system/test15-a.service.wants/test15-b.service
438 check_ok test15-a Wants test15-b.service
439 check_ko test15-a Wants test15-b1.service # the alias does not show up in the list of units
440 rm /etc/systemd/system/test15-b1.service
441
442 # 'a' has Wants=b.service but also has a masking
443 # dropin 'b': 'b' should still be pulled in.
444 echo "*** test a wants b both ways"
445 create_services test15-a test15-b
446 ln -sf /dev/null /etc/systemd/system/test15-a.service.wants/test15-b.service
447 cat >/usr/lib/systemd/system/test15-a.service.d/wants-b.conf<<EOF
448 [Unit]
449 Wants=test15-b.service
450 EOF
451 check_ok test15-a Wants test15-b.service
452
453 # mask a dropin that points to an nonexistent unit.
454 echo "*** test a wants nonexistent is masked"
455 create_services test15-a
456 ln -sf /dev/null /etc/systemd/system/test15-a.service.requires/nonexistent.service
457 ln -sf ../nonexistent.service /usr/lib/systemd/system/test15-a.service.requires/
458 check_ko test15-a Requires nonexistent.service
459
460 # 'b' is already loaded when 'c' pulls it in via a dropin but 'b' is
461 # masked at a higher level.
462 echo "*** test a wants b is masked"
463 create_services test15-a test15-b test15-c
464 ln -sf ../test15-b.service /etc/systemd/system/test15-a.service.requires/
465 ln -sf ../test15-b.service /run/systemd/system/test15-c.service.requires/
466 ln -sf /dev/null /etc/systemd/system/test15-c.service.requires/test15-b.service
467 systemctl start test15-a
468 check_ko test15-c Requires test15-b.service
469 systemctl stop test15-a test15-b
470
471 # 'b' is already loaded when 'c' pulls it in via a dropin but 'b' is
472 # masked at a lower level.
473 echo "*** test a requires b is masked"
474 create_services test15-a test15-b test15-c
475 ln -sf ../test15-b.service /etc/systemd/system/test15-a.service.requires/
476 ln -sf ../test15-b.service /etc/systemd/system/test15-c.service.requires/
477 ln -sf /dev/null /run/systemd/system/test15-c.service.requires/test15-b.service
478 systemctl start test15-a
479 check_ok test15-c Requires test15-b.service
480 systemctl stop test15-a test15-b
481
482 # 'a' requires 2 aliases of 'b' and one of them is a mask.
483 echo "*** test a requires alias of b, other alias masked"
484 create_services test15-a test15-b
485 ln -sf test15-b.service /etc/systemd/system/test15-b1.service
486 ln -sf test15-b.service /etc/systemd/system/test15-b2.service
487 ln -sf /dev/null /etc/systemd/system/test15-a.service.requires/test15-b1.service
488 ln -sf ../test15-b1.service /run/systemd/system/test15-a.service.requires/
489 ln -sf ../test15-b2.service /usr/lib/systemd/system/test15-a.service.requires/
490 check_ok test15-a Requires test15-b
491
492 # Same as above but now 'b' is masked.
493 echo "*** test a requires alias of b, b dep masked"
494 create_services test15-a test15-b
495 ln -sf test15-b.service /etc/systemd/system/test15-b1.service
496 ln -sf test15-b.service /etc/systemd/system/test15-b2.service
497 ln -sf ../test15-b1.service /run/systemd/system/test15-a.service.requires/
498 ln -sf ../test15-b2.service /usr/lib/systemd/system/test15-a.service.requires/
499 ln -sf /dev/null /etc/systemd/system/test15-a.service.requires/test15-b.service
500 check_ok test15-a Requires test15-b
501
502 clear_services test15-a test15-b
503 }
504
505 test_invalid_dropins () {
506 echo "Testing invalid dropins..."
507 # Assertion failed on earlier versions, command exits unsuccessfully on later versions
508 systemctl cat nonexistent@.service || true
509 create_services a
510 systemctl daemon-reload
511 # Assertion failed on earlier versions, command exits unsuccessfully on later versions
512 systemctl cat a@.service || true
513 systemctl stop a
514 clear_services a
515 return 0
516 }
517
518 test_basic_dropins
519 test_linked_units
520 test_template_alias
521 test_hierarchical_dropins
522 test_template_dropins
523 test_alias_dropins
524 test_masked_dropins
525 test_invalid_dropins
526
527 touch /testok