diff options
Diffstat (limited to '')
-rwxr-xr-x | test/units/testsuite-15.sh | 474 |
1 files changed, 474 insertions, 0 deletions
diff --git a/test/units/testsuite-15.sh b/test/units/testsuite-15.sh new file mode 100755 index 0000000..b872a24 --- /dev/null +++ b/test/units/testsuite-15.sh @@ -0,0 +1,474 @@ +#! /bin/bash +set -e +set -x + +_clear_service () { + systemctl stop $1.service 2>/dev/null || : + rm -f /{etc,run,usr/lib}/systemd/system/$1.service + rm -fr /{etc,run,usr/lib}/systemd/system/$1.service.d + rm -fr /{etc,run,usr/lib}/systemd/system/$1.service.{wants,requires} + if [[ $1 == *@ ]]; then + systemctl stop $1*.service 2>/dev/null || : + rm -f /{etc,run,usr/lib}/systemd/system/$1*.service + rm -fr /{etc,run,usr/lib}/systemd/system/$1*.service.d + rm -fr /{etc,run,usr/lib}/systemd/system/$1*.service.{wants,requires} + fi +} + +clear_services () { + for u in $*; do + _clear_service $u + done + systemctl daemon-reload +} + +create_service () { + clear_services $1 + + cat >/etc/systemd/system/$1.service<<EOF +[Unit] +Description=$1 unit + +[Service] +ExecStart=/bin/sleep 100000 +EOF + mkdir -p /{etc,run,usr/lib}/systemd/system/$1.service.d + mkdir -p /etc/systemd/system/$1.service.{wants,requires} + mkdir -p /run/systemd/system/$1.service.{wants,requires} + mkdir -p /usr/lib/systemd/system/$1.service.{wants,requires} +} + +create_services () { + for u in $*; do + create_service $u + done +} + +check_ok () { + [ $# -eq 3 ] || return + + x="$(systemctl show --value -p $2 $1)" + case "$x" in + *$3*) return 0 ;; + *) return 1 ;; + esac +} + +check_ko () { + ! check_ok "$@" +} + +test_basic_dropins () { + echo "Testing basic dropins..." + + echo "*** test a wants b wants c" + create_services test15-a test15-b test15-c + ln -s ../test15-b.service /etc/systemd/system/test15-a.service.wants/ + ln -s ../test15-c.service /etc/systemd/system/test15-b.service.wants/ + check_ok test15-a Wants test15-b.service + check_ok test15-b Wants test15-c.service + + echo "*** test a wants,requires b" + create_services test15-a test15-b test15-c + ln -s ../test15-b.service /etc/systemd/system/test15-a.service.wants/ + ln -s ../test15-b.service /etc/systemd/system/test15-a.service.requires/ + check_ok test15-a Wants test15-b.service + check_ok test15-a Requires test15-b.service + + echo "*** test a wants nonexistent" + create_service test15-a + ln -s ../nonexistent.service /etc/systemd/system/test15-a.service.wants/ + check_ok test15-a Wants nonexistent.service + systemctl start test15-a + systemctl stop test15-a + + echo "*** test a requires nonexistent" + ln -sf ../nonexistent.service /etc/systemd/system/test15-a.service.requires/ + systemctl daemon-reload + check_ok test15-a Requires nonexistent.service + + # 'b' is already loaded when 'c' pulls it in via a dropin. + echo "*** test a,c require b" + create_services test15-a test15-b test15-c + ln -sf ../test15-b.service /etc/systemd/system/test15-a.service.requires/ + ln -sf ../test15-b.service /etc/systemd/system/test15-c.service.requires/ + systemctl start test15-a + check_ok test15-c Requires test15-b.service + systemctl stop test15-a test15-b + + # 'b' is already loaded when 'c' pulls it in via an alias dropin. + echo "*** test a wants alias" + create_services test15-a test15-b test15-c + ln -sf test15-c.service /etc/systemd/system/test15-c1.service + ln -sf ../test15-c.service /etc/systemd/system/test15-a.service.wants/ + ln -sf ../test15-c1.service /etc/systemd/system/test15-b.service.wants/ + systemctl start test15-a + check_ok test15-a Wants test15-c.service + check_ok test15-b Wants test15-c.service + systemctl stop test15-a test15-c + + echo "*** test service.d/ top level drop-in" + create_services test15-a test15-b + check_ko test15-a ExecCondition "/bin/echo a" + check_ko test15-b ExecCondition "/bin/echo b" + mkdir -p /usr/lib/systemd/system/service.d + cat >/usr/lib/systemd/system/service.d/override.conf <<EOF +[Service] +ExecCondition=/bin/echo %n +EOF + systemctl daemon-reload + check_ok test15-a ExecCondition "/bin/echo test15-a" + check_ok test15-b ExecCondition "/bin/echo test15-b" + rm -rf /usr/lib/systemd/system/service.d + + clear_services test15-a test15-b test15-c +} + +test_hierarchical_dropins () { + echo "Testing hierarchical dropins..." + echo "*** test service.d/ top level drop-in" + create_services a-b-c + check_ko a-b-c ExecCondition "/bin/echo service.d" + check_ko a-b-c ExecCondition "/bin/echo a-.service.d" + check_ko a-b-c ExecCondition "/bin/echo a-b-.service.d" + check_ko a-b-c ExecCondition "/bin/echo a-b-c.service.d" + + for dropin in service.d a-.service.d a-b-.service.d a-b-c.service.d; do + mkdir -p /usr/lib/systemd/system/$dropin + echo " +[Service] +ExecCondition=/bin/echo $dropin + " > /usr/lib/systemd/system/$dropin/override.conf + systemctl daemon-reload + check_ok a-b-c ExecCondition "/bin/echo $dropin" + done + for dropin in service.d a-.service.d a-b-.service.d a-b-c.service.d; do + rm -rf /usr/lib/systemd/system/$dropin + done + + clear_services a-b-c +} + +test_template_dropins () { + echo "Testing template dropins..." + + create_services foo bar@ yup@ + + # Declare some deps to check if the body was loaded + cat >>/etc/systemd/system/bar@.service <<EOF +[Unit] +After=bar-template-after.device +EOF + + cat >>/etc/systemd/system/yup@.service <<EOF +[Unit] +After=yup-template-after.device +EOF + + ln -s /etc/systemd/system/bar@.service /etc/systemd/system/foo.service.wants/bar@1.service + check_ok foo Wants bar@1.service + + echo "*** test bar-alias@.service→bar@.service, but instance symlinks point to yup@.service ***" + ln -s bar@.service /etc/systemd/system/bar-alias@.service + ln -s bar@1.service /etc/systemd/system/bar-alias@1.service + ln -s yup@.service /etc/systemd/system/bar-alias@2.service + ln -s yup@3.service /etc/systemd/system/bar-alias@3.service + + # create some dropin deps + mkdir -p /etc/systemd/system/bar@{,0,1,2,3}.service.requires/ + mkdir -p /etc/systemd/system/yup@{,0,1,2,3}.service.requires/ + mkdir -p /etc/systemd/system/bar-alias@{,0,1,2,3}.service.requires/ + + ln -s ../bar-template-requires.device /etc/systemd/system/bar@.service.requires/ + ln -s ../bar-0-requires.device /etc/systemd/system/bar@0.service.requires/ + ln -s ../bar-1-requires.device /etc/systemd/system/bar@1.service.requires/ + ln -s ../bar-2-requires.device /etc/systemd/system/bar@2.service.requires/ + ln -s ../bar-3-requires.device /etc/systemd/system/bar@3.service.requires/ + + ln -s ../yup-template-requires.device /etc/systemd/system/yup@.service.requires/ + ln -s ../yup-0-requires.device /etc/systemd/system/yup@0.service.requires/ + ln -s ../yup-1-requires.device /etc/systemd/system/yup@1.service.requires/ + ln -s ../yup-2-requires.device /etc/systemd/system/yup@2.service.requires/ + ln -s ../yup-3-requires.device /etc/systemd/system/yup@3.service.requires/ + + ln -s ../bar-alias-template-requires.device /etc/systemd/system/bar-alias@.service.requires/ + ln -s ../bar-alias-0-requires.device /etc/systemd/system/bar-alias@0.service.requires/ + ln -s ../bar-alias-1-requires.device /etc/systemd/system/bar-alias@1.service.requires/ + ln -s ../bar-alias-2-requires.device /etc/systemd/system/bar-alias@2.service.requires/ + ln -s ../bar-alias-3-requires.device /etc/systemd/system/bar-alias@3.service.requires/ + + systemctl daemon-reload + + echo '*** bar@0 is aliased by bar-alias@0 ***' + systemctl show -p Names,Requires bar@0 + systemctl show -p Names,Requires bar-alias@0 + check_ok bar@0 Names bar@0 + check_ok bar@0 Names bar-alias@0 + + check_ok bar@0 After bar-template-after.device + + check_ok bar@0 Requires bar-0-requires.device + check_ok bar@0 Requires bar-alias-0-requires.device + check_ok bar@0 Requires bar-template-requires.device + check_ok bar@0 Requires bar-alias-template-requires.device + check_ko bar@0 Requires yup-template-requires.device + + check_ok bar-alias@0 After bar-template-after.device + + check_ok bar-alias@0 Requires bar-0-requires.device + check_ok bar-alias@0 Requires bar-alias-0-requires.device + check_ok bar-alias@0 Requires bar-template-requires.device + check_ok bar-alias@0 Requires bar-alias-template-requires.device + check_ko bar-alias@0 Requires yup-template-requires.device + check_ko bar-alias@0 Requires yup-0-requires.device + + echo '*** bar@1 is aliased by bar-alias@1 ***' + systemctl show -p Names,Requires bar@1 + systemctl show -p Names,Requires bar-alias@1 + check_ok bar@1 Names bar@1 + check_ok bar@1 Names bar-alias@1 + + check_ok bar@1 After bar-template-after.device + + check_ok bar@1 Requires bar-1-requires.device + check_ok bar@1 Requires bar-alias-1-requires.device + check_ok bar@1 Requires bar-template-requires.device + # See https://github.com/systemd/systemd/pull/13119#discussion_r308145418 + check_ok bar@1 Requires bar-alias-template-requires.device + check_ko bar@1 Requires yup-template-requires.device + check_ko bar@1 Requires yup-1-requires.device + + check_ok bar-alias@1 After bar-template-after.device + + check_ok bar-alias@1 Requires bar-1-requires.device + check_ok bar-alias@1 Requires bar-alias-1-requires.device + check_ok bar-alias@1 Requires bar-template-requires.device + check_ok bar-alias@1 Requires bar-alias-template-requires.device + check_ko bar-alias@1 Requires yup-template-requires.device + check_ko bar-alias@1 Requires yup-1-requires.device + + echo '*** bar-alias@2 aliases yup@2, bar@2 is independent ***' + systemctl show -p Names,Requires bar@2 + systemctl show -p Names,Requires bar-alias@2 + check_ok bar@2 Names bar@2 + check_ko bar@2 Names bar-alias@2 + + check_ok bar@2 After bar-template-after.device + + check_ok bar@2 Requires bar-2-requires.device + check_ko bar@2 Requires bar-alias-2-requires.device + check_ok bar@2 Requires bar-template-requires.device + check_ko bar@2 Requires bar-alias-template-requires.device + check_ko bar@2 Requires yup-template-requires.device + check_ko bar@2 Requires yup-2-requires.device + + check_ko bar-alias@2 After bar-template-after.device + + check_ko bar-alias@2 Requires bar-2-requires.device + check_ok bar-alias@2 Requires bar-alias-2-requires.device + check_ko bar-alias@2 Requires bar-template-requires.device + check_ok bar-alias@2 Requires bar-alias-template-requires.device + check_ok bar-alias@2 Requires yup-template-requires.device + check_ok bar-alias@2 Requires yup-2-requires.device + + echo '*** bar-alias@3 aliases yup@3, bar@3 is independent ***' + systemctl show -p Names,Requires bar@3 + systemctl show -p Names,Requires bar-alias@3 + check_ok bar@3 Names bar@3 + check_ko bar@3 Names bar-alias@3 + + check_ok bar@3 After bar-template-after.device + + check_ok bar@3 Requires bar-3-requires.device + check_ko bar@3 Requires bar-alias-3-requires.device + check_ok bar@3 Requires bar-template-requires.device + check_ko bar@3 Requires bar-alias-template-requires.device + check_ko bar@3 Requires yup-template-requires.device + check_ko bar@3 Requires yup-3-requires.device + + check_ko bar-alias@3 After bar-template-after.device + + check_ko bar-alias@3 Requires bar-3-requires.device + check_ok bar-alias@3 Requires bar-alias-3-requires.device + check_ko bar-alias@3 Requires bar-template-requires.device + check_ok bar-alias@3 Requires bar-alias-template-requires.device + check_ok bar-alias@3 Requires yup-template-requires.device + check_ok bar-alias@3 Requires yup-3-requires.device + + clear_services foo {bar,yup,bar-alias}@{,1,2,3} +} + +test_alias_dropins () { + echo "Testing alias dropins..." + + echo "*** test a wants b1 alias of b" + create_services test15-a test15-b + ln -sf test15-b.service /etc/systemd/system/test15-b1.service + ln -sf ../test15-b1.service /etc/systemd/system/test15-a.service.wants/ + check_ok test15-a Wants test15-b.service + systemctl start test15-a + systemctl --quiet is-active test15-b + systemctl stop test15-a test15-b + rm /etc/systemd/system/test15-b1.service + clear_services test15-a test15-b + + # Check that dependencies don't vary. + echo "*** test 2" + create_services test15-a test15-x test15-y + mkdir -p /etc/systemd/system/test15-a1.service.wants/ + ln -sf test15-a.service /etc/systemd/system/test15-a1.service + ln -sf ../test15-x.service /etc/systemd/system/test15-a.service.wants/ + ln -sf ../test15-y.service /etc/systemd/system/test15-a1.service.wants/ + check_ok test15-a1 Wants test15-x.service # see [1] + check_ok test15-a1 Wants test15-y.service + systemctl start test15-a + check_ok test15-a1 Wants test15-x.service # see [2] + check_ok test15-a1 Wants test15-y.service + systemctl stop test15-a test15-x test15-y + rm /etc/systemd/system/test15-a1.service + + clear_services test15-a test15-x test15-y +} + +test_masked_dropins () { + echo "Testing masked dropins..." + + create_services test15-a test15-b + + # 'b' is masked for both deps + echo "*** test a wants,requires b is masked" + ln -sf /dev/null /etc/systemd/system/test15-a.service.wants/test15-b.service + ln -sf /dev/null /etc/systemd/system/test15-a.service.requires/test15-b.service + check_ko test15-a Wants test15-b.service + check_ko test15-a Requires test15-b.service + + # 'a' wants 'b' and 'b' is masked at a lower level + echo "*** test a wants b, mask override" + ln -sf ../test15-b.service /etc/systemd/system/test15-a.service.wants/test15-b.service + ln -sf /dev/null /usr/lib/systemd/system/test15-a.service.wants/test15-b.service + check_ok test15-a Wants test15-b.service + + # 'a' wants 'b' and 'b' is masked at a higher level + echo "*** test a wants b, mask" + ln -sf /dev/null /etc/systemd/system/test15-a.service.wants/test15-b.service + ln -sf ../test15-b.service /usr/lib/systemd/system/test15-a.service.wants/test15-b.service + check_ko test15-a Wants test15-b.service + + # 'a' is masked but has an override config file + echo "*** test a is masked but has an override" + create_services test15-a test15-b + ln -sf /dev/null /etc/systemd/system/test15-a.service + cat >/usr/lib/systemd/system/test15-a.service.d/override.conf <<EOF +[Unit] +After=test15-b.service +EOF + check_ok test15-a UnitFileState masked + + # 'b1' is an alias for 'b': masking 'b' dep should not influence 'b1' dep + echo "*** test a wants b, b1, and one is masked" + create_services test15-a test15-b + ln -sf test15-b.service /etc/systemd/system/test15-b1.service + ln -sf /dev/null /etc/systemd/system/test15-a.service.wants/test15-b.service + ln -sf ../test15-b1.service /usr/lib/systemd/system/test15-a.service.wants/test15-b1.service + systemctl cat test15-a + systemctl show -p Wants,Requires test15-a + systemctl cat test15-b1 + systemctl show -p Wants,Requires test15-b1 + check_ok test15-a Wants test15-b.service + check_ko test15-a Wants test15-b1.service # the alias does not show up in the list of units + rm /etc/systemd/system/test15-b1.service + + # 'b1' is an alias for 'b': masking 'b1' should not influence 'b' dep + echo "*** test a wants b, alias dep is masked" + create_services test15-a test15-b + ln -sf test15-b.service /etc/systemd/system/test15-b1.service + ln -sf /dev/null /etc/systemd/system/test15-a.service.wants/test15-b1.service + ln -sf ../test15-b.service /usr/lib/systemd/system/test15-a.service.wants/test15-b.service + check_ok test15-a Wants test15-b.service + check_ko test15-a Wants test15-b1.service # the alias does not show up in the list of units + rm /etc/systemd/system/test15-b1.service + + # 'a' has Wants=b.service but also has a masking + # dropin 'b': 'b' should still be pulled in. + echo "*** test a wants b both ways" + create_services test15-a test15-b + ln -sf /dev/null /etc/systemd/system/test15-a.service.wants/test15-b.service + cat >/usr/lib/systemd/system/test15-a.service.d/wants-b.conf<<EOF +[Unit] +Wants=test15-b.service +EOF + check_ok test15-a Wants test15-b.service + + # mask a dropin that points to an nonexistent unit. + echo "*** test a wants nonexistent is masked" + create_services test15-a + ln -sf /dev/null /etc/systemd/system/test15-a.service.requires/nonexistent.service + ln -sf ../nonexistent.service /usr/lib/systemd/system/test15-a.service.requires/ + check_ko test15-a Requires nonexistent.service + + # 'b' is already loaded when 'c' pulls it in via a dropin but 'b' is + # masked at a higher level. + echo "*** test a wants b is masked" + create_services test15-a test15-b test15-c + ln -sf ../test15-b.service /etc/systemd/system/test15-a.service.requires/ + ln -sf ../test15-b.service /run/systemd/system/test15-c.service.requires/ + ln -sf /dev/null /etc/systemd/system/test15-c.service.requires/test15-b.service + systemctl start test15-a + check_ko test15-c Requires test15-b.service + systemctl stop test15-a test15-b + + # 'b' is already loaded when 'c' pulls it in via a dropin but 'b' is + # masked at a lower level. + echo "*** test a requires b is masked" + create_services test15-a test15-b test15-c + ln -sf ../test15-b.service /etc/systemd/system/test15-a.service.requires/ + ln -sf ../test15-b.service /etc/systemd/system/test15-c.service.requires/ + ln -sf /dev/null /run/systemd/system/test15-c.service.requires/test15-b.service + systemctl start test15-a + check_ok test15-c Requires test15-b.service + systemctl stop test15-a test15-b + + # 'a' requires 2 aliases of 'b' and one of them is a mask. + echo "*** test a requires alias of b, other alias masked" + create_services test15-a test15-b + ln -sf test15-b.service /etc/systemd/system/test15-b1.service + ln -sf test15-b.service /etc/systemd/system/test15-b2.service + ln -sf /dev/null /etc/systemd/system/test15-a.service.requires/test15-b1.service + ln -sf ../test15-b1.service /run/systemd/system/test15-a.service.requires/ + ln -sf ../test15-b2.service /usr/lib/systemd/system/test15-a.service.requires/ + check_ok test15-a Requires test15-b + + # Same as above but now 'b' is masked. + echo "*** test a requires alias of b, b dep masked" + create_services test15-a test15-b + ln -sf test15-b.service /etc/systemd/system/test15-b1.service + ln -sf test15-b.service /etc/systemd/system/test15-b2.service + ln -sf ../test15-b1.service /run/systemd/system/test15-a.service.requires/ + ln -sf ../test15-b2.service /usr/lib/systemd/system/test15-a.service.requires/ + ln -sf /dev/null /etc/systemd/system/test15-a.service.requires/test15-b.service + check_ok test15-a Requires test15-b + + clear_services test15-a test15-b +} + +test_invalid_dropins () { + echo "Testing invalid dropins..." + # Assertion failed on earlier versions, command exits unsuccessfully on later versions + systemctl cat nonexistent@.service || true + create_services a + systemctl daemon-reload + # Assertion failed on earlier versions, command exits unsuccessfully on later versions + systemctl cat a@.service || true + systemctl stop a + clear_services a + return 0 +} + +test_basic_dropins +test_hierarchical_dropins +test_template_dropins +test_alias_dropins +test_masked_dropins +test_invalid_dropins + +touch /testok |