]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
tests: add dropin dependency tests 5231/head
authorFranck Bui <fbui@suse.com>
Fri, 27 Jan 2017 15:02:22 +0000 (16:02 +0100)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Wed, 8 Feb 2017 02:32:10 +0000 (21:32 -0500)
[zj: tests assertions adjusted to the different logic in which masking
     of a dependency through one name, does not forbid the dependency
     being added through another name.]

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

diff --git a/test/TEST-15-DROPIN/Makefile b/test/TEST-15-DROPIN/Makefile
new file mode 120000 (symlink)
index 0000000..e9f93b1
--- /dev/null
@@ -0,0 +1 @@
+../TEST-01-BASIC/Makefile
\ No newline at end of file
diff --git a/test/TEST-15-DROPIN/test-dropin.sh b/test/TEST-15-DROPIN/test-dropin.sh
new file mode 100755 (executable)
index 0000000..9d8af99
--- /dev/null
@@ -0,0 +1,274 @@
+#! /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
+
+        clear_services a b c
+}
+
+test_template_dropins () {
+        echo "Testing template dropins..."
+
+        create_services foo bar@ yup@
+
+        ln -s /etc/systemd/system/bar@.service /etc/systemd/system/foo.service.wants/bar@1.service
+        check_ok foo Wants bar@1.service
+
+        clear_services foo bar@ yup@
+}
+
+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
+
+        # A weird behavior: the dependencies for 'a' may vary. It can be
+        # changed by loading an alias...
+        #
+        # [1] 'a1' is loaded and then "renamed" into 'a'. 'a1' is therefore
+        # part of the names set so all its specific dropins are loaded.
+        #
+        # [2] 'a' is already loaded. 'a1' is simply only merged into 'a' so
+        # none of its dropins are loaded ('y' is missing from the deps).
+        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_ko 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
+
+        # '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_basic_dropins
+test_template_dropins
+test_alias_dropins
+test_masked_dropins
+
+touch /testok
diff --git a/test/TEST-15-DROPIN/test.sh b/test/TEST-15-DROPIN/test.sh
new file mode 100755 (executable)
index 0000000..1b460db
--- /dev/null
@@ -0,0 +1,46 @@
+#!/bin/bash
+# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
+# ex: ts=8 sw=4 sts=4 et filetype=sh
+
+TEST_DESCRIPTION="Dropin tests"
+
+. $TEST_BASE_DIR/test-functions
+
+
+test_run_nspawn() {
+        if ! run_nspawn; then
+                dwarn "can't run systemd-nspawn, skipping"
+                return 0
+        fi
+        check_result_nspawn
+}
+
+test_run() {
+        test_run_nspawn || return
+}
+
+test_setup() {
+        # create the basic filesystem layout
+        setup_basic_environment >/dev/null
+
+        # mask some services that we do not want to run in these tests
+        ln -s /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service
+        ln -s /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service
+        ln -s /dev/null $initdir/etc/systemd/system/systemd-networkd.service
+        ln -s /dev/null $initdir/etc/systemd/system/systemd-networkd.socket
+        ln -s /dev/null $initdir/etc/systemd/system/systemd-resolved.service
+
+        # 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
+}
+
+test_cleanup() {
+        return 0
+}
+
+do_test "$@"
diff --git a/test/TEST-15-DROPIN/testsuite.service b/test/TEST-15-DROPIN/testsuite.service
new file mode 100644 (file)
index 0000000..d9790c2
--- /dev/null
@@ -0,0 +1,7 @@
+[Unit]
+Description=Testsuite service
+After=multi-user.target
+
+[Service]
+ExecStart=/test-dropin.sh
+Type=oneshot