test: move TEST-15-DROPIN setup to static files
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Mon, 9 Dec 2019 22:29:18 +0000 (23:29 +0100)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Sat, 28 Mar 2020 10:46:47 +0000 (11:46 +0100)
Unfortunately the services needed to be renamed because of conflicts with other
services that exist in the shared dir.

test/TEST-15-DROPIN/test-dropin.sh [deleted file]
test/TEST-15-DROPIN/test.sh
test/TEST-15-DROPIN/testsuite.service [deleted file]
test/units/testsuite-15.service [new file with mode: 0644]
test/units/testsuite-15.sh [new file with mode: 0755]

diff --git a/test/TEST-15-DROPIN/test-dropin.sh b/test/TEST-15-DROPIN/test-dropin.sh
deleted file mode 100755 (executable)
index f80c9df..0000000
+++ /dev/null
@@ -1,466 +0,0 @@
-#! /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}
-}
-
-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 a b c
-    ln -s ../b.service /etc/systemd/system/a.service.wants/
-    ln -s ../c.service /etc/systemd/system/b.service.wants/
-    check_ok a Wants b.service
-    check_ok b Wants c.service
-
-    echo "*** test a wants,requires b"
-    create_services a b c
-    ln -s ../b.service /etc/systemd/system/a.service.wants/
-    ln -s ../b.service /etc/systemd/system/a.service.requires/
-    check_ok a Wants b.service
-    check_ok a Requires b.service
-
-    echo "*** test a wants nonexistent"
-    create_service a
-    ln -s ../nonexistent.service /etc/systemd/system/a.service.wants/
-    check_ok a Wants nonexistent.service
-    systemctl start a
-    systemctl stop  a
-
-    echo "*** test a requires nonexistent"
-    ln -sf ../nonexistent.service /etc/systemd/system/a.service.requires/
-    systemctl daemon-reload
-    check_ok a Requires nonexistent.service
-
-    # 'b' is already loaded when 'c' pulls it in via a dropin.
-    echo "*** test a,c require b"
-    create_services a b c
-    ln -sf ../b.service /etc/systemd/system/a.service.requires/
-    ln -sf ../b.service /etc/systemd/system/c.service.requires/
-    systemctl start a
-    check_ok c Requires b.service
-    systemctl stop a b
-
-    # 'b'  is already loaded when 'c' pulls it in via an alias dropin.
-    echo "*** test a wants alias"
-    create_services a b c
-    ln -sf c.service /etc/systemd/system/c1.service
-    ln -sf ../c.service  /etc/systemd/system/a.service.wants/
-    ln -sf ../c1.service /etc/systemd/system/b.service.wants/
-    systemctl start a
-    check_ok a Wants c.service
-    check_ok b Wants c.service
-    systemctl stop a c
-
-    echo "*** test service.d/ top level drop-in"
-    create_services a b
-    check_ko a ExecCondition "/bin/echo a"
-    check_ko 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
-    check_ok a ExecCondition "/bin/echo a"
-    check_ok b ExecCondition "/bin/echo b"
-    rm -rf /usr/lib/systemd/system/service.d
-
-    clear_services a b 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
-        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 a b
-    ln -sf b.service /etc/systemd/system/b1.service
-    ln -sf ../b1.service /etc/systemd/system/a.service.wants/
-    check_ok a Wants b.service
-    systemctl start a
-    systemctl --quiet is-active b
-    systemctl stop a b
-    rm /etc/systemd/system/b1.service
-    clear_services a b
-
-    # Check that dependencies don't vary.
-    echo "*** test 2"
-    create_services a x y
-    mkdir -p /etc/systemd/system/a1.service.wants/
-    ln -sf a.service /etc/systemd/system/a1.service
-    ln -sf ../x.service /etc/systemd/system/a.service.wants/
-    ln -sf ../y.service /etc/systemd/system/a1.service.wants/
-    check_ok a1 Wants x.service # see [1]
-    check_ok a1 Wants y.service
-    systemctl start a
-    check_ok a1 Wants x.service # see [2]
-    check_ok a1 Wants y.service
-    systemctl stop a x y
-    rm /etc/systemd/system/a1.service
-
-    clear_services a x y
-}
-
-test_masked_dropins () {
-    echo "Testing masked dropins..."
-
-    create_services a b
-
-    # 'b' is masked for both deps
-    echo "*** test a wants,requires b is masked"
-    ln -sf /dev/null /etc/systemd/system/a.service.wants/b.service
-    ln -sf /dev/null /etc/systemd/system/a.service.requires/b.service
-    check_ko a Wants b.service
-    check_ko a Requires b.service
-
-    # 'a' wants 'b' and 'b' is masked at a lower level
-    echo "*** test a wants b, mask override"
-    ln -sf ../b.service /etc/systemd/system/a.service.wants/b.service
-    ln -sf /dev/null /usr/lib/systemd/system/a.service.wants/b.service
-    check_ok a Wants 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/a.service.wants/b.service
-    ln -sf ../b.service /usr/lib/systemd/system/a.service.wants/b.service
-    check_ko a Wants b.service
-
-    # 'a' is masked but has an override config file
-    echo "*** test a is masked but has an override"
-    create_services a b
-    ln -sf /dev/null /etc/systemd/system/a.service
-    cat >/usr/lib/systemd/system/a.service.d/override.conf <<EOF
-[Unit]
-After=b.service
-EOF
-    check_ok 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 a b
-    ln -sf b.service /etc/systemd/system/b1.service
-    ln -sf /dev/null /etc/systemd/system/a.service.wants/b.service
-    ln -sf ../b1.service /usr/lib/systemd/system/a.service.wants/b1.service
-    systemctl cat a
-    systemctl show -p Wants,Requires a
-    systemctl cat b1
-    systemctl show -p Wants,Requires b1
-    check_ok a Wants b.service
-    check_ko a Wants b1.service # the alias does not show up in the list of units
-    rm /etc/systemd/system/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 a b
-    ln -sf b.service /etc/systemd/system/b1.service
-    ln -sf /dev/null /etc/systemd/system/a.service.wants/b1.service
-    ln -sf ../b.service /usr/lib/systemd/system/a.service.wants/b.service
-    check_ok a Wants b.service
-    check_ko a Wants b1.service # the alias does not show up in the list of units
-    rm /etc/systemd/system/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 a b
-    ln -sf /dev/null /etc/systemd/system/a.service.wants/b.service
-    cat >/usr/lib/systemd/system/a.service.d/wants-b.conf<<EOF
-[Unit]
-Wants=b.service
-EOF
-    check_ok a Wants b.service
-
-    # mask a dropin that points to an nonexistent unit.
-    echo "*** test a wants nonexistent is masked"
-    create_services a
-    ln -sf /dev/null /etc/systemd/system/a.service.requires/nonexistent.service
-    ln -sf ../nonexistent.service /usr/lib/systemd/system/a.service.requires/
-    check_ko 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 a b c
-    ln -sf ../b.service /etc/systemd/system/a.service.requires/
-    ln -sf ../b.service /run/systemd/system/c.service.requires/
-    ln -sf /dev/null /etc/systemd/system/c.service.requires/b.service
-    systemctl start a
-    check_ko c Requires b.service
-    systemctl stop a 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 a b c
-    ln -sf ../b.service /etc/systemd/system/a.service.requires/
-    ln -sf ../b.service /etc/systemd/system/c.service.requires/
-    ln -sf /dev/null /run/systemd/system/c.service.requires/b.service
-    systemctl start a
-    check_ok c Requires b.service
-    systemctl stop a 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 a b
-    ln -sf b.service /etc/systemd/system/b1.service
-    ln -sf b.service /etc/systemd/system/b2.service
-    ln -sf /dev/null /etc/systemd/system/a.service.requires/b1.service
-    ln -sf ../b1.service /run/systemd/system/a.service.requires/
-    ln -sf ../b2.service /usr/lib/systemd/system/a.service.requires/
-    check_ok a Requires b
-
-    # Same as above but now 'b' is masked.
-    echo "*** test a requires alias of b, b dep masked"
-    create_services a b
-    ln -sf b.service /etc/systemd/system/b1.service
-    ln -sf b.service /etc/systemd/system/b2.service
-    ln -sf ../b1.service /run/systemd/system/a.service.requires/
-    ln -sf ../b2.service /usr/lib/systemd/system/a.service.requires/
-    ln -sf /dev/null /etc/systemd/system/a.service.requires/b.service
-    check_ok a Requires b
-
-    clear_services a 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
index 63bbd3505174f4c7b1c1857bf803d4a4a0905f44..42d6c3dd79bb09664baac6bccc5604f843976588 100755 (executable)
@@ -10,13 +10,8 @@ test_setup() {
     setup_basic_environment
     mask_supporting_services
 
-    # import the test scripts in the rootfs and plug them in systemd
-    cp testsuite.service $initdir/etc/systemd/system/
-    cp test-dropin.sh    $initdir/
-    setup_testsuite
-
     # create dedicated rootfs for nspawn (located in $TESTDIR/nspawn-root)
     setup_nspawn_root
 }
 
-do_test "$@"
+do_test "$@" 15
diff --git a/test/TEST-15-DROPIN/testsuite.service b/test/TEST-15-DROPIN/testsuite.service
deleted file mode 100644 (file)
index 4c9f65e..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-[Unit]
-Description=Testsuite service
-
-[Service]
-ExecStart=/test-dropin.sh
-Type=oneshot
diff --git a/test/units/testsuite-15.service b/test/units/testsuite-15.service
new file mode 100644 (file)
index 0000000..2d07bd6
--- /dev/null
@@ -0,0 +1,6 @@
+[Unit]
+Description=TEST-15-DROPIN
+
+[Service]
+ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh
+Type=oneshot
diff --git a/test/units/testsuite-15.sh b/test/units/testsuite-15.sh
new file mode 100755 (executable)
index 0000000..c1d640a
--- /dev/null
@@ -0,0 +1,466 @@
+#! /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}
+}
+
+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
+    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
+        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