8d419f
From e7bd636e75a5435b80a1df478e9e637dd2f7b851 Mon Sep 17 00:00:00 2001
8d419f
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
8d419f
Date: Mon, 7 Mar 2022 12:15:42 +0100
8d419f
Subject: [PATCH] test: add test for systemctl link & enable
8d419f
8d419f
This test has overlap with test-install-root, but it tests things at a
8d419f
different level, so I think it's useful to add. It immediately shows various
8d419f
bugs which will be fixed in later patches.
8d419f
8d419f
(cherry picked from commit 50c5f5a3d907f819fa139e1853f660ad4fd82c55)
8d419f
8d419f
Related: #2082131
8d419f
---
8d419f
 meson.build                   |   9 +-
8d419f
 test/meson.build              |   1 +
8d419f
 test/test-systemctl-enable.sh | 523 ++++++++++++++++++++++++++++++++++
8d419f
 3 files changed, 532 insertions(+), 1 deletion(-)
8d419f
 create mode 100644 test/test-systemctl-enable.sh
8d419f
8d419f
diff --git a/meson.build b/meson.build
8d419f
index fdf02b8110..005af872cf 100644
8d419f
--- a/meson.build
8d419f
+++ b/meson.build
8d419f
@@ -2371,7 +2371,7 @@ public_programs += executable(
8d419f
         install_rpath : rootlibexecdir,
8d419f
         install : true)
8d419f
 
8d419f
-public_programs += executable(
8d419f
+exe = executable(
8d419f
         'systemctl',
8d419f
         systemctl_sources,
8d419f
         include_directories : includes,
8d419f
@@ -2385,6 +2385,13 @@ public_programs += executable(
8d419f
         install_rpath : rootlibexecdir,
8d419f
         install : true,
8d419f
         install_dir : rootbindir)
8d419f
+public_programs += exe
8d419f
+if want_tests != 'false'
8d419f
+        test('test-systemctl-enable',
8d419f
+             test_systemctl_enable_sh,
8d419f
+             # https://github.com/mesonbuild/meson/issues/2681
8d419f
+             args : exe.full_path())
8d419f
+endif
8d419f
 
8d419f
 if conf.get('ENABLE_PORTABLED') == 1
8d419f
         dbus_programs += executable(
8d419f
diff --git a/test/meson.build b/test/meson.build
8d419f
index c5d8d6917b..c69d8a0204 100644
8d419f
--- a/test/meson.build
8d419f
+++ b/test/meson.build
8d419f
@@ -88,6 +88,7 @@ endif
8d419f
 
8d419f
 test_fstab_generator_sh = find_program('test-fstab-generator.sh')
8d419f
 test_network_generator_conversion_sh = find_program('test-network-generator-conversion.sh')
8d419f
+test_systemctl_enable_sh = find_program('test-systemctl-enable.sh')
8d419f
 test_systemd_tmpfiles_py = find_program('test-systemd-tmpfiles.py')
8d419f
 hwdb_test_sh = find_program('hwdb-test.sh')
8d419f
 
8d419f
diff --git a/test/test-systemctl-enable.sh b/test/test-systemctl-enable.sh
8d419f
new file mode 100644
8d419f
index 0000000000..30ba6532e7
8d419f
--- /dev/null
8d419f
+++ b/test/test-systemctl-enable.sh
8d419f
@@ -0,0 +1,523 @@
8d419f
+#!/usr/bin/env bash
8d419f
+# SPDX-License-Identifier: LGPL-2.1-or-later
8d419f
+set -ex
8d419f
+
8d419f
+# Silence warning from running_in_chroot_or_offline()
8d419f
+export SYSTEMD_IGNORE_CHROOT=1
8d419f
+
8d419f
+systemctl=${1:-systemctl}
8d419f
+
8d419f
+unset root
8d419f
+cleanup() {
8d419f
+    [ -n "$root" ] && rm -rf "$root"
8d419f
+}
8d419f
+trap cleanup exit
8d419f
+root=$(mktemp -d --tmpdir systemctl-test.XXXXXX)
8d419f
+
8d419f
+islink() {
8d419f
+    test -h "$1" || return 1
8d419f
+    test "$(readlink "$1")" = "$2" || return 2
8d419f
+}
8d419f
+
8d419f
+: ------enablement nonexistent--------------------------------
8d419f
+"$systemctl" --root="$root" enable test1.service && { echo "Expected failure" >&2; exit 1; }
8d419f
+
8d419f
+: ------basic enablement--------------------------------------
8d419f
+mkdir -p "$root/etc/systemd/system"
8d419f
+cat >"$root/etc/systemd/system/test1.service" <
8d419f
+[Install]
8d419f
+WantedBy=default.target
8d419f
+RequiredBy=special.target
8d419f
+EOF
8d419f
+
8d419f
+"$systemctl" --root="$root" enable test1.service
8d419f
+test -h "$root/etc/systemd/system/default.target.wants/test1.service"
8d419f
+test -h "$root/etc/systemd/system/special.target.requires/test1.service"
8d419f
+
8d419f
+"$systemctl" --root="$root" reenable test1.service
8d419f
+test -h "$root/etc/systemd/system/default.target.wants/test1.service"
8d419f
+test -h "$root/etc/systemd/system/special.target.requires/test1.service"
8d419f
+
8d419f
+"$systemctl" --root="$root" disable test1.service
8d419f
+test ! -e "$root/etc/systemd/system/default.target.wants/test1.service"
8d419f
+test ! -e "$root/etc/systemd/system/special.target.requires/test1.service"
8d419f
+
8d419f
+: ------suffix guessing---------------------------------------
8d419f
+"$systemctl" --root="$root" enable test1
8d419f
+test -h "$root/etc/systemd/system/default.target.wants/test1.service"
8d419f
+test -h "$root/etc/systemd/system/special.target.requires/test1.service"
8d419f
+
8d419f
+"$systemctl" --root="$root" reenable test1
8d419f
+test -h "$root/etc/systemd/system/default.target.wants/test1.service"
8d419f
+test -h "$root/etc/systemd/system/special.target.requires/test1.service"
8d419f
+
8d419f
+"$systemctl" --root="$root" disable test1
8d419f
+test ! -e "$root/etc/systemd/system/default.target.wants/test1.service"
8d419f
+test ! -e "$root/etc/systemd/system/special.target.requires/test1.service"
8d419f
+
8d419f
+: -------aliases----------------------------------------------
8d419f
+"$systemctl" --root="$root" enable test1
8d419f
+test -h "$root/etc/systemd/system/default.target.wants/test1.service"
8d419f
+test -h "$root/etc/systemd/system/special.target.requires/test1.service"
8d419f
+
8d419f
+cat >>"$root/etc/systemd/system/test1.service" <
8d419f
+Alias=test1-goodalias.service
8d419f
+Alias=test1@badalias.service
8d419f
+Alias=test1-badalias.target
8d419f
+Alias=test1-badalias.socket
8d419f
+EOF
8d419f
+
8d419f
+: -------aliases in reeanble----------------------------------
8d419f
+"$systemctl" --root="$root" reenable test1
8d419f
+test -h "$root/etc/systemd/system/default.target.wants/test1.service"
8d419f
+test ! -e "$root/etc/systemd/system/test1-goodalias.service"
8d419f
+test -h "$root/etc/systemd/system/test1-goodalias.service"
8d419f
+
8d419f
+test ! -e "$root/etc/systemd/system/test1@badalias.service"
8d419f
+test ! -e "$root/etc/systemd/system/test1-badalias.target"
8d419f
+test ! -e "$root/etc/systemd/system/test1-badalias.socket"
8d419f
+
8d419f
+"$systemctl" --root="$root" disable test1
8d419f
+test ! -e "$root/etc/systemd/system/default.target.wants/test1.service"
8d419f
+test ! -e "$root/etc/systemd/system/special.target.requires/test1.service"
8d419f
+test ! -e "$root/etc/systemd/system/test1-goodalias.service"
8d419f
+
8d419f
+: -------also units-------------------------------------------
8d419f
+cat >"$root/etc/systemd/system/test2.socket" <
8d419f
+[Install]
8d419f
+WantedBy=sockets.target
8d419f
+Also=test2.service
8d419f
+EOF
8d419f
+
8d419f
+cat >"$root/etc/systemd/system/test2.service" <
8d419f
+[Install]
8d419f
+WantedBy=default.target
8d419f
+Also=test2.socket
8d419f
+EOF
8d419f
+
8d419f
+"$systemctl" --root="$root" reenable test2.service
8d419f
+test -h "$root/etc/systemd/system/default.target.wants/test2.service"
8d419f
+test -h "$root/etc/systemd/system/sockets.target.wants/test2.socket"
8d419f
+
8d419f
+"$systemctl" --root="$root" reenable test2.socket
8d419f
+test -h "$root/etc/systemd/system/default.target.wants/test2.service"
8d419f
+test -h "$root/etc/systemd/system/sockets.target.wants/test2.socket"
8d419f
+
8d419f
+"$systemctl" --root="$root" disable test2.socket
8d419f
+test ! -e "$root/etc/systemd/system/default.target.wants/test2.service"
8d419f
+test ! -e "$root/etc/systemd/system/sockets.target.wants/test2.socket"
8d419f
+
8d419f
+
8d419f
+: -------link-------------------------------------------------
8d419f
+# File doesn't exist yet
8d419f
+test ! -e "$root/link1.path"
8d419f
+"$systemctl" --root="$root" link '/link1.path' && { echo "Expected failure" >&2; exit 1; }
8d419f
+test ! -e "$root/etc/systemd/system/link1.path"
8d419f
+
8d419f
+cat >"$root/link1.path" <
8d419f
+[Install]
8d419f
+WantedBy=paths.target
8d419f
+EOF
8d419f
+
8d419f
+"$systemctl" --root="$root" link '/link1.path'
8d419f
+islink "$root/etc/systemd/system/link1.path" "/link1.path"
8d419f
+
8d419f
+: -------link already linked same path------------------------
8d419f
+SYSTEMD_LOG_LEVEL=debug "$systemctl" --root="$root" link '/link1.path'  # this passes
8d419f
+islink "$root/etc/systemd/system/link1.path" "/link1.path"
8d419f
+
8d419f
+: -------link already linked different path-------------------
8d419f
+mkdir "$root/subdir"
8d419f
+cp "$root/link1.path" "$root/subdir/"
8d419f
+"$systemctl" --root="$root" link '/subdir/link1.path' && { echo "Expected failure" >&2; exit 1; }
8d419f
+islink "$root/etc/systemd/system/link1.path" "/link1.path"
8d419f
+
8d419f
+: -------link bad suffix--------------------------------------
8d419f
+cp "$root/link1.path" "$root/subdir/link1.suffix"
8d419f
+"$systemctl" --root="$root" link '/subdir/link1.suffix' && { echo "Expected failure" >&2; exit 1; }
8d419f
+test ! -e "$root/etc/systemd/system/link1.suffix"
8d419f
+
8d419f
+: -------unlink by unit name----------------------------------
8d419f
+"$systemctl" --root="$root" disable 'link1.path'
8d419f
+test ! -e "$root/etc/systemd/system/link1.path"
8d419f
+
8d419f
+: -------unlink by path---------------------------------------
8d419f
+"$systemctl" --root="$root" link '/link1.path'
8d419f
+test -h "$root/etc/systemd/system/link1.path"
8d419f
+"$systemctl" --root="$root" disable '/link1.path'
8d419f
+test ! -e "$root/etc/systemd/system/link1.path"
8d419f
+
8d419f
+: -------unlink by wrong path---------------------------------
8d419f
+"$systemctl" --root="$root" link '/link1.path'
8d419f
+test -h "$root/etc/systemd/system/link1.path"
8d419f
+"$systemctl" --root="$root" disable '/subdir/link1.path'  # we only care about the name
8d419f
+test ! -e "$root/etc/systemd/system/link1.path"
8d419f
+
8d419f
+
8d419f
+: -------link and enable--------------------------------------
8d419f
+"$systemctl" --root="$root" enable '/link1.path'
8d419f
+islink "$root/etc/systemd/system/link1.path" "/link1.path"
8d419f
+islink "$root/etc/systemd/system/paths.target.wants/link1.path" "/link1.path"
8d419f
+
8d419f
+: -------enable already linked same path----------------------
8d419f
+"$systemctl" --root="$root" enable '/link1.path'
8d419f
+islink "$root/etc/systemd/system/link1.path" "/link1.path"
8d419f
+islink "$root/etc/systemd/system/paths.target.wants/link1.path" "/link1.path"
8d419f
+
8d419f
+: -------enable already linked different path-----------------
8d419f
+# FIXME
8d419f
+# "$systemctl" --root="$root" enable '/subdir/link1.path' && { echo "Expected failure" >&2; exit 1; }
8d419f
+# test -h "$root/etc/systemd/system/link1.path"
8d419f
+# readlink "$root/etc/systemd/system/link1.path"
8d419f
+# test -h "$root/etc/systemd/system/paths.target.wants/link1.path"
8d419f
+# readlink "$root/etc/systemd/system/paths.target.wants/link1.path"
8d419f
+
8d419f
+: -------enable bad suffix------------------------------------
8d419f
+cp "$root/link1.path" "$root/subdir/link1.suffix"
8d419f
+"$systemctl" --root="$root" enable '/subdir/link1.suffix' && { echo "Expected failure" >&2; exit 1; }
8d419f
+test ! -e "$root/etc/systemd/system/link1.suffix"
8d419f
+test ! -e "$root/etc/systemd/system/paths.target.wants/link1.suffix"
8d419f
+
8d419f
+: -------disable by unit name---------------------------------
8d419f
+"$systemctl" --root="$root" disable 'link1.path'
8d419f
+test ! -e "$root/etc/systemd/system/link1.path"
8d419f
+test ! -e "$root/etc/systemd/system/paths.target.wants/link1.path"
8d419f
+
8d419f
+: -------disable by path--------------------------------------
8d419f
+"$systemctl" --root="$root" enable '/link1.path'
8d419f
+test -h "$root/etc/systemd/system/link1.path"
8d419f
+test -h "$root/etc/systemd/system/paths.target.wants/link1.path"
8d419f
+"$systemctl" --root="$root" disable '/link1.path'
8d419f
+test ! -e "$root/etc/systemd/system/link1.path"
8d419f
+test ! -e "$root/etc/systemd/system/paths.target.wants/link1.path"
8d419f
+
8d419f
+
8d419f
+: -------link then enable-------------------------------------
8d419f
+"$systemctl" --root="$root" link '/link1.path'
8d419f
+islink "$root/etc/systemd/system/link1.path" "/link1.path"
8d419f
+test ! -h "$root/etc/systemd/system/paths.target.wants/link1.path"
8d419f
+
8d419f
+"$systemctl" --root="$root" enable 'link1.path'
8d419f
+islink "$root/etc/systemd/system/link1.path" "/link1.path"
8d419f
+islink "$root/etc/systemd/system/paths.target.wants/link1.path" "/link1.path"
8d419f
+
8d419f
+# FIXME
8d419f
+# "$systemctl" --root="$root" reenable 'link1.path'
8d419f
+# islink "$root/etc/systemd/system/link1.path" "/link1.path"
8d419f
+# islink "$root/etc/systemd/system/paths.target.wants/link1.path" "/link1.path"
8d419f
+
8d419f
+
8d419f
+: -------manual link------------------------------------------
8d419f
+cat >"$root/link3.suffix" <
8d419f
+[Install]
8d419f
+WantedBy=services.target
8d419f
+EOF
8d419f
+
8d419f
+ln -s "/link3.suffix" "$root/etc/systemd/system/link3.service"
8d419f
+
8d419f
+# SYSTEMD_LOG_LEVEL=debug SYSTEMD_LOG_LOCATION=1 "$systemctl" --root="$root" enable 'link3.service'
8d419f
+# islink "$root/etc/systemd/system/link3.service" "/link3.suffix"
8d419f
+# islink "$root/etc/systemd/system/services.target.wants/link3.service" "../link3.service"
8d419f
+# unit_file_load_or_readlink() needs to be fixed to not follow links
8d419f
+
8d419f
+: -------enable on masked-------------------------------------
8d419f
+ln -s "/dev/null" "$root/etc/systemd/system/masked.service"
8d419f
+"$systemctl" --root="$root" enable 'masked.service' && { echo "Expected failure" >&2; exit 1; }
8d419f
+"$systemctl" --root="$root" enable '/etc/systemd/system/masked.service' && { echo "Expected failure" >&2; exit 1; }
8d419f
+
8d419f
+: -------enable on masked alias-------------------------------
8d419f
+test -h "$root/etc/systemd/system/masked.service"
8d419f
+ln -s "masked.service" "$root/etc/systemd/system/masked-alias.service"
8d419f
+"$systemctl" --root="$root" enable 'masked-alias.service' && { echo "Expected failure" >&2; exit 1; }
8d419f
+"$systemctl" --root="$root" enable '/etc/systemd/system/masked-alias.service' && { echo "Expected failure" >&2; exit 1; }
8d419f
+
8d419f
+: -------issue 22000: link in subdirectory--------------------
8d419f
+mkdir -p "$root/etc/systemd/system/myown.d"
8d419f
+cat >"$root/etc/systemd/system/link5-also.service" <
8d419f
+[Install]
8d419f
+WantedBy=services.target
8d419f
+Also=link5.service
8d419f
+EOF
8d419f
+cat >"$root/etc/systemd/system/myown.d/link5.service" <
8d419f
+[Install]
8d419f
+WantedBy=services.target
8d419f
+Also=link5-also.service
8d419f
+EOF
8d419f
+
8d419f
+"$systemctl" --root="$root" enable 'link5.service' && { echo "Expected failure" >&2; exit 1; }
8d419f
+test ! -h "$root/etc/systemd/system/services.target.wants/link5.service"
8d419f
+test ! -h "$root/etc/systemd/system/services.target.wants/link5-also.service"
8d419f
+
8d419f
+"$systemctl" --root="$root" enable 'link5-also.service'
8d419f
+test ! -h "$root/etc/systemd/system/services.target.wants/link5.service"
8d419f
+islink "$root/etc/systemd/system/services.target.wants/link5-also.service" "/etc/systemd/system/link5-also.service"
8d419f
+
8d419f
+: -------template enablement----------------------------------
8d419f
+cat >"$root/etc/systemd/system/templ1@.service" <
8d419f
+[Install]
8d419f
+WantedBy=services.target
8d419f
+EOF
8d419f
+
8d419f
+# No instance here — this can't succeed.
8d419f
+"$systemctl" --root="$root" enable 'templ1@.service' && { echo "Expected failure" >&2; exit 1; }
8d419f
+test ! -h "$root/etc/systemd/system/services.target.wants/templ1@.service"
8d419f
+
8d419f
+"$systemctl" --root="$root" enable 'templ1@one.service'
8d419f
+test ! -h "$root/etc/systemd/system/services.target.wants/templ1@.service"
8d419f
+islink "$root/etc/systemd/system/services.target.wants/templ1@one.service" "/etc/systemd/system/templ1@.service"
8d419f
+
8d419f
+"$systemctl" --root="$root" enable 'templ1@two.service'
8d419f
+test ! -h "$root/etc/systemd/system/services.target.wants/templ1@.service"
8d419f
+islink "$root/etc/systemd/system/services.target.wants/templ1@one.service" "/etc/systemd/system/templ1@.service"
8d419f
+islink "$root/etc/systemd/system/services.target.wants/templ1@two.service" "/etc/systemd/system/templ1@.service"
8d419f
+
8d419f
+"$systemctl" --root="$root" disable 'templ1@one.service'
8d419f
+test ! -h "$root/etc/systemd/system/services.target.wants/templ1@.service"
8d419f
+test ! -h "$root/etc/systemd/system/services.target.wants/templ1@one.service"
8d419f
+islink "$root/etc/systemd/system/services.target.wants/templ1@two.service" "/etc/systemd/system/templ1@.service"
8d419f
+
8d419f
+"$systemctl" --root="$root" disable 'templ1@two.service'
8d419f
+test ! -h "$root/etc/systemd/system/services.target.wants/templ1@.service"
8d419f
+test ! -h "$root/etc/systemd/system/services.target.wants/templ1@one.service"
8d419f
+test ! -h "$root/etc/systemd/system/services.target.wants/templ1@two.service"
8d419f
+
8d419f
+: -------template enablement w/ default instance--------------
8d419f
+cat >>"$root/etc/systemd/system/templ1@.service" <
8d419f
+DefaultInstance=333
8d419f
+EOF
8d419f
+# FIXME: should we deduplicate the target? Right now we warn twice if WantedBy= is repeated.
8d419f
+# WantedBy=services.target services.target
8d419f
+
8d419f
+"$systemctl" --root="$root" enable 'templ1@.service'
8d419f
+test ! -h "$root/etc/systemd/system/services.target.wants/templ1@.service"
8d419f
+islink "$root/etc/systemd/system/services.target.wants/templ1@333.service" "/etc/systemd/system/templ1@.service"
8d419f
+
8d419f
+"$systemctl" --root="$root" enable 'templ1@one.service'
8d419f
+test ! -h "$root/etc/systemd/system/services.target.wants/templ1@.service"
8d419f
+islink "$root/etc/systemd/system/services.target.wants/templ1@333.service" "/etc/systemd/system/templ1@.service"
8d419f
+islink "$root/etc/systemd/system/services.target.wants/templ1@one.service" "/etc/systemd/system/templ1@.service"
8d419f
+
8d419f
+"$systemctl" --root="$root" enable 'templ1@two.service'
8d419f
+test ! -h "$root/etc/systemd/system/services.target.wants/templ1@.service"
8d419f
+islink "$root/etc/systemd/system/services.target.wants/templ1@333.service" "/etc/systemd/system/templ1@.service"
8d419f
+islink "$root/etc/systemd/system/services.target.wants/templ1@one.service" "/etc/systemd/system/templ1@.service"
8d419f
+islink "$root/etc/systemd/system/services.target.wants/templ1@two.service" "/etc/systemd/system/templ1@.service"
8d419f
+
8d419f
+"$systemctl" --root="$root" disable 'templ1@one.service'
8d419f
+test ! -h "$root/etc/systemd/system/services.target.wants/templ1@.service"
8d419f
+islink "$root/etc/systemd/system/services.target.wants/templ1@333.service" "/etc/systemd/system/templ1@.service"
8d419f
+test ! -h "$root/etc/systemd/system/services.target.wants/templ1@one.service"
8d419f
+islink "$root/etc/systemd/system/services.target.wants/templ1@two.service" "/etc/systemd/system/templ1@.service"
8d419f
+
8d419f
+# disable both remaining links here
8d419f
+"$systemctl" --root="$root" disable 'templ1@.service'
8d419f
+test ! -h "$root/etc/systemd/system/services.target.wants/templ1@.service"
8d419f
+test ! -h "$root/etc/systemd/system/services.target.wants/templ1@333.service"
8d419f
+test ! -h "$root/etc/systemd/system/services.target.wants/templ1@one.service"
8d419f
+test ! -h "$root/etc/systemd/system/services.target.wants/templ1@two.service"
8d419f
+
8d419f
+: -------aliases w/ and w/o instance--------------------------
8d419f
+test ! -e "$root/etc/systemd/system/link4.service"
8d419f
+cat >"$root/etc/systemd/system/link4.service" <
8d419f
+[Install]
8d419f
+# FIXME: self-alias should be ignored
8d419f
+# Alias=link4.service
8d419f
+Alias=link4@.service
8d419f
+Alias=link4@inst.service
8d419f
+Alias=link4alias.service
8d419f
+Alias=link4alias2.service
8d419f
+EOF
8d419f
+
8d419f
+"$systemctl" --root="$root" enable 'link4.service'
8d419f
+test ! -h "$root/etc/systemd/system/link4.service"  # this is our file
8d419f
+test ! -h "$root/etc/systemd/system/link4@.service"
8d419f
+test ! -h "$root/etc/systemd/system/link4@inst.service"
8d419f
+islink "$root/etc/systemd/system/link4alias.service" "/etc/systemd/system/link4.service"
8d419f
+islink "$root/etc/systemd/system/link4alias2.service" "/etc/systemd/system/link4.service"
8d419f
+
8d419f
+"$systemctl" --root="$root" disable 'link4.service'
8d419f
+test ! -h "$root/etc/systemd/system/link4.service"
8d419f
+test ! -h "$root/etc/systemd/system/link4@.service"
8d419f
+test ! -h "$root/etc/systemd/system/link4@inst.service"
8d419f
+test ! -h "$root/etc/systemd/system/link4alias.service"
8d419f
+test ! -h "$root/etc/systemd/system/link4alias2.service"
8d419f
+
8d419f
+: -------systemctl enable on path to unit file----------------
8d419f
+# Apparently this works. I'm not sure what to think.
8d419f
+"$systemctl" --root="$root" enable '/etc/systemd/system/link4.service'
8d419f
+test ! -h "$root/etc/systemd/system/link4.service"  # this is our file
8d419f
+test ! -h "$root/etc/systemd/system/link4@.service"
8d419f
+test ! -h "$root/etc/systemd/system/link4@inst.service"
8d419f
+islink "$root/etc/systemd/system/link4alias.service" "/etc/systemd/system/link4.service"
8d419f
+islink "$root/etc/systemd/system/link4alias2.service" "/etc/systemd/system/link4.service"
8d419f
+
8d419f
+"$systemctl" --root="$root" disable '/etc/systemd/system/link4.service'
8d419f
+test ! -h "$root/etc/systemd/system/link4.service"
8d419f
+test ! -h "$root/etc/systemd/system/link4@.service"
8d419f
+test ! -h "$root/etc/systemd/system/link4@inst.service"
8d419f
+test ! -h "$root/etc/systemd/system/link4alias.service"
8d419f
+test ! -h "$root/etc/systemd/system/link4alias2.service"
8d419f
+
8d419f
+: -------issue 661: link and enable on unit file--------------
8d419f
+test ! -e "$root/etc/systemd/system/link5.service"
8d419f
+cat >"$root/etc/systemd/system/link5.service" <
8d419f
+[Install]
8d419f
+# FIXME: self-alias should be ignored
8d419f
+# Alias=link5.service
8d419f
+Alias=link5@.service
8d419f
+Alias=link5@inst.service
8d419f
+Alias=link5alias.service
8d419f
+Alias=link5alias2.service
8d419f
+EOF
8d419f
+
8d419f
+"$systemctl" --root="$root" enable 'link5.service'
8d419f
+test ! -h "$root/etc/systemd/system/link5.service"  # this is our file
8d419f
+test ! -h "$root/etc/systemd/system/link5@.service"
8d419f
+test ! -h "$root/etc/systemd/system/link5@inst.service"
8d419f
+# FIXME/CLARIFYME: will systemd think that link5alias2, link5alias, link5 are all aliases?
8d419f
+# https://github.com/systemd/systemd/issues/661#issuecomment-1057931149
8d419f
+islink "$root/etc/systemd/system/link5alias.service" "/etc/systemd/system/link5.service"
8d419f
+islink "$root/etc/systemd/system/link5alias2.service" "/etc/systemd/system/link5.service"
8d419f
+
8d419f
+"$systemctl" --root="$root" disable 'link5.service'
8d419f
+test ! -h "$root/etc/systemd/system/link5.service"
8d419f
+test ! -h "$root/etc/systemd/system/link5@.service"
8d419f
+test ! -h "$root/etc/systemd/system/link5@inst.service"
8d419f
+test ! -h "$root/etc/systemd/system/link5alias.service"
8d419f
+test ! -h "$root/etc/systemd/system/link5alias2.service"
8d419f
+
8d419f
+: ----issue 19437: plain templates in .wants/ or .requires/---
8d419f
+test ! -e "$root/etc/systemd/system/link5@.path"
8d419f
+cat >"$root/etc/systemd/system/link5@.path" <
8d419f
+[Install]
8d419f
+WantedBy=target5@.target
8d419f
+RequiredBy=target5@.target
8d419f
+WantedBy=target5@inst.target
8d419f
+RequiredBy=target5@inst.target
8d419f
+EOF
8d419f
+
8d419f
+"$systemctl" --root="$root" enable 'link5@.path'
8d419f
+test ! -h "$root/etc/systemd/system/link5@.path"  # this is our file
8d419f
+islink "$root/etc/systemd/system/target5@.target.wants/link5@.path" "/etc/systemd/system/link5@.path"
8d419f
+islink "$root/etc/systemd/system/target5@.target.requires/link5@.path" "/etc/systemd/system/link5@.path"
8d419f
+islink "$root/etc/systemd/system/target5@inst.target.wants/link5@.path" "/etc/systemd/system/link5@.path"
8d419f
+islink "$root/etc/systemd/system/target5@inst.target.requires/link5@.path" "/etc/systemd/system/link5@.path"
8d419f
+
8d419f
+"$systemctl" --root="$root" disable 'link5@.path'
8d419f
+test ! -h "$root/etc/systemd/system/link5@.path"  # this is our file
8d419f
+test ! -h "$root/etc/systemd/system/target5@.target.wants/link5@.path"
8d419f
+test ! -h "$root/etc/systemd/system/target5@.target.requires/link5@.path"
8d419f
+test ! -h "$root/etc/systemd/system/target5@inst.target.wants/link5@.path"
8d419f
+test ! -h "$root/etc/systemd/system/target5@inst.target.requires/link5@.path"
8d419f
+
8d419f
+: -------removal of symlinks not listed in [Install]----------
8d419f
+# c.f. 66a19d85a533b15ed32f4066ec880b5a8c06babd
8d419f
+test ! -e "$root/etc/systemd/system/multilink.mount"
8d419f
+cat >"$root/etc/systemd/system/multilink.mount" <
8d419f
+[Install]
8d419f
+WantedBy=multilink.target
8d419f
+EOF
8d419f
+
8d419f
+mkdir -p "$root/etc/systemd/system/default.target.wants"
8d419f
+ln -s ../multilink.mount "$root/etc/systemd/system/default.target.wants/"
8d419f
+ln -s ../multilink.mount "$root/etc/systemd/system/multilink-alias.mount"
8d419f
+ln -s ../multilink.mount "$root/etc/systemd/system/multilink-badalias.service"
8d419f
+
8d419f
+"$systemctl" --root="$root" disable 'multilink.mount'
8d419f
+test -e "$root/etc/systemd/system/multilink.mount"  # this is our file
8d419f
+test ! -h "$root/etc/systemd/system/default.target.wants/"
8d419f
+test ! -h "$root/etc/systemd/system/multilink-alias.mount"
8d419f
+test ! -h "$root/etc/systemd/system/multilink-badalias.service"
8d419f
+
8d419f
+: -------merge 20017: specifiers in the unit file-------------
8d419f
+test ! -e "$root/etc/systemd/system/some-some-link6@.socket"
8d419f
+# c.f. de61a04b188f81a85cdb5c64ddb4987dcd9d30d3
8d419f
+
8d419f
+check_alias() {
8d419f
+    : ------------------ %$1 -------------------------------------
8d419f
+    cat >"$root/etc/systemd/system/some-some-link6@.socket" <
8d419f
+[Install]
8d419f
+Alias=target@$1:%$1.socket
8d419f
+EOF
8d419f
+    SYSTEMD_LOG_LEVEL=debug "$systemctl" --root="$root" enable 'some-some-link6@.socket' || return 1
8d419f
+    islink "$root/etc/systemd/system/target@$1:$2.socket" "/etc/systemd/system/some-some-link6@.socket" || return 2
8d419f
+}
8d419f
+
8d419f
+check_alias a "$(uname -m | tr '_' '-')"
8d419f
+
8d419f
+# FIXME: when os-release is not found, we fail we a cryptic error
8d419f
+# Alias=target@%A.socket
8d419f
+
8d419f
+check_alias b "$(systemd-id128 boot-id)"
8d419f
+
8d419f
+# Alias=target@%B.socket
8d419f
+
8d419f
+# FIXME: Failed to enable: Invalid slot.
8d419f
+# Alias=target@%C.socket
8d419f
+# Alias=target@%E.socket
8d419f
+# Alias=target@%f.socket
8d419f
+
8d419f
+# FIXME: we use the calling user instead of root :(
8d419f
+check_alias g root || :
8d419f
+check_alias G 0 || :
8d419f
+
8d419f
+# FIXME: Failed to enable: Invalid slot.
8d419f
+# Alias=target@%h.socket
8d419f
+
8d419f
+check_alias i ""
8d419f
+
8d419f
+# FIXME: Failed to enable: Invalid slot.
8d419f
+# Alias=target@%I.socket
8d419f
+
8d419f
+check_alias j 'link6'
8d419f
+
8d419f
+# FIXME: Failed to enable: Invalid slot.
8d419f
+# Alias=target@%J.socket
8d419f
+
8d419f
+check_alias l "$(uname -n | sed 's/\..*//')"
8d419f
+
8d419f
+# FIXME: Failed to enable: Invalid slot.
8d419f
+# Alias=target@%L.socket
8d419f
+
8d419f
+# FIXME: Failed to enable: No such file or directory.
8d419f
+# Alias=target@%m.socket
8d419f
+
8d419f
+# FIXME: Failed to enable: No such file or directory.
8d419f
+# Alias=target@%M.socket
8d419f
+
8d419f
+check_alias n 'some-some-link6@.socket'
8d419f
+check_alias N 'some-some-link6@'
8d419f
+
8d419f
+# FIXME: Failed to enable: No such file or directory.
8d419f
+# Alias=target@%o.socket
8d419f
+
8d419f
+check_alias p 'some-some-link6'
8d419f
+
8d419f
+# FIXME: Failed to enable: Invalid slot.
8d419f
+# Alias=target@%P.socket
8d419f
+# Alias=target@%s.socket
8d419f
+# Alias=target@%S.socket
8d419f
+# Alias=target@%t.socket
8d419f
+# Alias=target@%T.socket
8d419f
+
8d419f
+# FIXME: we use the calling user instead of root :(
8d419f
+check_alias u root || :
8d419f
+check_alias U 0 || :
8d419f
+
8d419f
+check_alias v "$(uname -r)"
8d419f
+
8d419f
+# FIXME: Failed to enable: Invalid slot.
8d419f
+# Alias=target@%V.socket
8d419f
+
8d419f
+# Alias=target@%w.socket
8d419f
+# Alias=target@%W.socket
8d419f
+
8d419f
+check_alias % '%' && { echo "Expected failure because % is not legal in unit name" >&2; exit 1; }
8d419f
+
8d419f
+check_alias z 'z' && { echo "Expected failure because %z is not known" >&2; exit 1; }
8d419f
+
8d419f
+# FIXME: if there's an invalid Alias=, we shouldn't preach about empty [Install]
8d419f
+
8d419f
+exit 0  # yes, this is needed because the last test above fails
8d419f
+
8d419f
+# TODO: repeat the tests above for presets