]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/test/test-install-root.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
5 #include "alloc-util.h"
11 #include "string-util.h"
14 static void test_basic_mask_and_enable(const char *root
) {
17 UnitFileChange
*changes
= NULL
;
20 test_setup_logging(LOG_DEBUG
);
22 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "a.service", NULL
) == -ENOENT
);
23 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "b.service", NULL
) == -ENOENT
);
24 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "c.service", NULL
) == -ENOENT
);
25 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "d.service", NULL
) == -ENOENT
);
27 p
= strjoina(root
, "/usr/lib/systemd/system/a.service");
28 assert_se(write_string_file(p
,
30 "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE
) >= 0);
32 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "a.service", NULL
) >= 0);
33 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "a.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
35 p
= strjoina(root
, "/usr/lib/systemd/system/b.service");
36 assert_se(symlink("a.service", p
) >= 0);
38 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "b.service", NULL
) >= 0);
39 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "b.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
41 p
= strjoina(root
, "/usr/lib/systemd/system/c.service");
42 assert_se(symlink("/usr/lib/systemd/system/a.service", p
) >= 0);
44 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "c.service", NULL
) >= 0);
45 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "c.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
47 p
= strjoina(root
, "/usr/lib/systemd/system/d.service");
48 assert_se(symlink("c.service", p
) >= 0);
50 /* This one is interesting, as d follows a relative, then an absolute symlink */
51 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "d.service", NULL
) >= 0);
52 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "d.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
54 assert_se(unit_file_mask(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("a.service"), &changes
, &n_changes
) >= 0);
55 assert_se(n_changes
== 1);
56 assert_se(changes
[0].type
== UNIT_FILE_SYMLINK
);
57 assert_se(streq(changes
[0].source
, "/dev/null"));
58 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/a.service");
59 assert_se(streq(changes
[0].path
, p
));
61 unit_file_changes_free(changes
, n_changes
);
62 changes
= NULL
; n_changes
= 0;
64 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "a.service", &state
) >= 0 && state
== UNIT_FILE_MASKED
);
65 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "b.service", &state
) >= 0 && state
== UNIT_FILE_MASKED
);
66 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "c.service", &state
) >= 0 && state
== UNIT_FILE_MASKED
);
67 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "d.service", &state
) >= 0 && state
== UNIT_FILE_MASKED
);
69 /* Enabling a masked unit should fail! */
70 assert_se(unit_file_enable(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("a.service"), &changes
, &n_changes
) == -ERFKILL
);
71 unit_file_changes_free(changes
, n_changes
);
72 changes
= NULL
; n_changes
= 0;
74 assert_se(unit_file_unmask(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("a.service"), &changes
, &n_changes
) >= 0);
75 assert_se(n_changes
== 1);
76 assert_se(changes
[0].type
== UNIT_FILE_UNLINK
);
77 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/a.service");
78 assert_se(streq(changes
[0].path
, p
));
79 unit_file_changes_free(changes
, n_changes
);
80 changes
= NULL
; n_changes
= 0;
82 assert_se(unit_file_enable(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("a.service"), &changes
, &n_changes
) == 1);
83 assert_se(n_changes
== 1);
84 assert_se(changes
[0].type
== UNIT_FILE_SYMLINK
);
85 assert_se(streq(changes
[0].source
, "/usr/lib/systemd/system/a.service"));
86 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/multi-user.target.wants/a.service");
87 assert_se(streq(changes
[0].path
, p
));
88 unit_file_changes_free(changes
, n_changes
);
89 changes
= NULL
; n_changes
= 0;
91 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "a.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
92 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "b.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
93 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "c.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
94 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "d.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
96 /* Enabling it again should succeed but be a NOP */
97 assert_se(unit_file_enable(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("a.service"), &changes
, &n_changes
) >= 0);
98 assert_se(n_changes
== 0);
99 unit_file_changes_free(changes
, n_changes
);
100 changes
= NULL
; n_changes
= 0;
102 assert_se(unit_file_disable(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("a.service"), &changes
, &n_changes
) >= 0);
103 assert_se(n_changes
== 1);
104 assert_se(changes
[0].type
== UNIT_FILE_UNLINK
);
105 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/multi-user.target.wants/a.service");
106 assert_se(streq(changes
[0].path
, p
));
107 unit_file_changes_free(changes
, n_changes
);
108 changes
= NULL
; n_changes
= 0;
110 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "a.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
111 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "b.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
112 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "c.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
113 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "d.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
115 /* Disabling a disabled unit must suceed but be a NOP */
116 assert_se(unit_file_disable(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("a.service"), &changes
, &n_changes
) >= 0);
117 assert_se(n_changes
== 0);
118 unit_file_changes_free(changes
, n_changes
);
119 changes
= NULL
; n_changes
= 0;
121 /* Let's enable this indirectly via a symlink */
122 assert_se(unit_file_enable(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("d.service"), &changes
, &n_changes
) >= 0);
123 assert_se(n_changes
== 1);
124 assert_se(changes
[0].type
== UNIT_FILE_SYMLINK
);
125 assert_se(streq(changes
[0].source
, "/usr/lib/systemd/system/a.service"));
126 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/multi-user.target.wants/a.service");
127 assert_se(streq(changes
[0].path
, p
));
128 unit_file_changes_free(changes
, n_changes
);
129 changes
= NULL
; n_changes
= 0;
131 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "a.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
132 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "b.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
133 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "c.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
134 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "d.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
136 /* Let's try to reenable */
138 assert_se(unit_file_reenable(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("b.service"), &changes
, &n_changes
) >= 0);
139 assert_se(n_changes
== 2);
140 assert_se(changes
[0].type
== UNIT_FILE_UNLINK
);
141 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/multi-user.target.wants/a.service");
142 assert_se(streq(changes
[0].path
, p
));
143 assert_se(changes
[1].type
== UNIT_FILE_SYMLINK
);
144 assert_se(streq(changes
[1].source
, "/usr/lib/systemd/system/a.service"));
145 assert_se(streq(changes
[1].path
, p
));
146 unit_file_changes_free(changes
, n_changes
);
147 changes
= NULL
; n_changes
= 0;
149 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "a.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
150 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "b.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
151 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "c.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
152 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "d.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
155 static void test_linked_units(const char *root
) {
158 UnitFileChange
*changes
= NULL
;
159 size_t n_changes
= 0, i
;
162 * We'll test three cases here:
164 * a) a unit file in /opt, that we use "systemctl link" and
165 * "systemctl enable" on to make it available to the system
167 * b) a unit file in /opt, that is statically linked into
168 * /usr/lib/systemd/system, that "enable" should work on
171 * c) a unit file in /opt, that is linked into
172 * /etc/systemd/system, and where "enable" should result in
173 * -ELOOP, since using information from /etc to generate
174 * information in /etc should not be allowed.
177 p
= strjoina(root
, "/opt/linked.service");
178 assert_se(write_string_file(p
,
180 "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE
) >= 0);
182 p
= strjoina(root
, "/opt/linked2.service");
183 assert_se(write_string_file(p
,
185 "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE
) >= 0);
187 p
= strjoina(root
, "/opt/linked3.service");
188 assert_se(write_string_file(p
,
190 "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE
) >= 0);
192 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "linked.service", NULL
) == -ENOENT
);
193 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "linked2.service", NULL
) == -ENOENT
);
194 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "linked3.service", NULL
) == -ENOENT
);
196 p
= strjoina(root
, "/usr/lib/systemd/system/linked2.service");
197 assert_se(symlink("/opt/linked2.service", p
) >= 0);
199 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/linked3.service");
200 assert_se(symlink("/opt/linked3.service", p
) >= 0);
202 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "linked.service", &state
) == -ENOENT
);
203 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "linked2.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
204 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "linked3.service", &state
) >= 0 && state
== UNIT_FILE_LINKED
);
206 /* First, let's link the unit into the search path */
207 assert_se(unit_file_link(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("/opt/linked.service"), &changes
, &n_changes
) >= 0);
208 assert_se(n_changes
== 1);
209 assert_se(changes
[0].type
== UNIT_FILE_SYMLINK
);
210 assert_se(streq(changes
[0].source
, "/opt/linked.service"));
211 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/linked.service");
212 assert_se(streq(changes
[0].path
, p
));
213 unit_file_changes_free(changes
, n_changes
);
214 changes
= NULL
; n_changes
= 0;
216 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "linked.service", &state
) >= 0 && state
== UNIT_FILE_LINKED
);
218 /* Let's unlink it from the search path again */
219 assert_se(unit_file_disable(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("linked.service"), &changes
, &n_changes
) >= 0);
220 assert_se(n_changes
== 1);
221 assert_se(changes
[0].type
== UNIT_FILE_UNLINK
);
222 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/linked.service");
223 assert_se(streq(changes
[0].path
, p
));
224 unit_file_changes_free(changes
, n_changes
);
225 changes
= NULL
; n_changes
= 0;
227 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "linked.service", NULL
) == -ENOENT
);
229 /* Now, let's not just link it, but also enable it */
230 assert_se(unit_file_enable(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("/opt/linked.service"), &changes
, &n_changes
) >= 0);
231 assert_se(n_changes
== 2);
232 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/multi-user.target.wants/linked.service");
233 q
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/linked.service");
234 for (i
= 0 ; i
< n_changes
; i
++) {
235 assert_se(changes
[i
].type
== UNIT_FILE_SYMLINK
);
236 assert_se(streq(changes
[i
].source
, "/opt/linked.service"));
238 if (p
&& streq(changes
[i
].path
, p
))
240 else if (q
&& streq(changes
[i
].path
, q
))
243 assert_not_reached("wut?");
246 unit_file_changes_free(changes
, n_changes
);
247 changes
= NULL
; n_changes
= 0;
249 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "linked.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
251 /* And let's unlink it again */
252 assert_se(unit_file_disable(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("linked.service"), &changes
, &n_changes
) >= 0);
253 assert_se(n_changes
== 2);
254 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/multi-user.target.wants/linked.service");
255 q
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/linked.service");
256 for (i
= 0; i
< n_changes
; i
++) {
257 assert_se(changes
[i
].type
== UNIT_FILE_UNLINK
);
259 if (p
&& streq(changes
[i
].path
, p
))
261 else if (q
&& streq(changes
[i
].path
, q
))
264 assert_not_reached("wut?");
267 unit_file_changes_free(changes
, n_changes
);
268 changes
= NULL
; n_changes
= 0;
270 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "linked.service", NULL
) == -ENOENT
);
272 assert_se(unit_file_enable(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("linked2.service"), &changes
, &n_changes
) >= 0);
273 assert_se(n_changes
== 2);
274 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/multi-user.target.wants/linked2.service");
275 q
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/linked2.service");
276 for (i
= 0 ; i
< n_changes
; i
++) {
277 assert_se(changes
[i
].type
== UNIT_FILE_SYMLINK
);
278 assert_se(streq(changes
[i
].source
, "/opt/linked2.service"));
280 if (p
&& streq(changes
[i
].path
, p
))
282 else if (q
&& streq(changes
[i
].path
, q
))
285 assert_not_reached("wut?");
288 unit_file_changes_free(changes
, n_changes
);
289 changes
= NULL
; n_changes
= 0;
291 assert_se(unit_file_enable(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("linked3.service"), &changes
, &n_changes
) >= 0);
292 assert_se(n_changes
== 1);
293 assert_se(changes
[0].type
== UNIT_FILE_SYMLINK
);
294 assert_se(startswith(changes
[0].path
, root
));
295 assert_se(endswith(changes
[0].path
, "linked3.service"));
296 assert_se(streq(changes
[0].source
, "/opt/linked3.service"));
297 unit_file_changes_free(changes
, n_changes
);
298 changes
= NULL
; n_changes
= 0;
301 static void test_default(const char *root
) {
302 _cleanup_free_
char *def
= NULL
;
303 UnitFileChange
*changes
= NULL
;
304 size_t n_changes
= 0;
307 p
= strjoina(root
, "/usr/lib/systemd/system/test-default-real.target");
308 assert_se(write_string_file(p
, "# pretty much empty", WRITE_STRING_FILE_CREATE
) >= 0);
310 p
= strjoina(root
, "/usr/lib/systemd/system/test-default.target");
311 assert_se(symlink("test-default-real.target", p
) >= 0);
313 assert_se(unit_file_get_default(UNIT_FILE_SYSTEM
, root
, &def
) == -ENOENT
);
315 assert_se(unit_file_set_default(UNIT_FILE_SYSTEM
, 0, root
, "idontexist.target", &changes
, &n_changes
) == -ENOENT
);
316 assert_se(n_changes
== 1);
317 assert_se(changes
[0].type
== -ENOENT
);
318 assert_se(streq_ptr(changes
[0].path
, "idontexist.target"));
319 unit_file_changes_free(changes
, n_changes
);
320 changes
= NULL
; n_changes
= 0;
322 assert_se(unit_file_get_default(UNIT_FILE_SYSTEM
, root
, &def
) == -ENOENT
);
324 assert_se(unit_file_set_default(UNIT_FILE_SYSTEM
, 0, root
, "test-default.target", &changes
, &n_changes
) >= 0);
325 assert_se(n_changes
== 1);
326 assert_se(changes
[0].type
== UNIT_FILE_SYMLINK
);
327 assert_se(streq(changes
[0].source
, "/usr/lib/systemd/system/test-default-real.target"));
328 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/" SPECIAL_DEFAULT_TARGET
);
329 assert_se(streq(changes
[0].path
, p
));
330 unit_file_changes_free(changes
, n_changes
);
331 changes
= NULL
; n_changes
= 0;
333 assert_se(unit_file_get_default(UNIT_FILE_SYSTEM
, root
, &def
) >= 0);
334 assert_se(streq_ptr(def
, "test-default-real.target"));
337 static void test_add_dependency(const char *root
) {
338 UnitFileChange
*changes
= NULL
;
339 size_t n_changes
= 0;
342 p
= strjoina(root
, "/usr/lib/systemd/system/real-add-dependency-test-target.target");
343 assert_se(write_string_file(p
, "# pretty much empty", WRITE_STRING_FILE_CREATE
) >= 0);
345 p
= strjoina(root
, "/usr/lib/systemd/system/add-dependency-test-target.target");
346 assert_se(symlink("real-add-dependency-test-target.target", p
) >= 0);
348 p
= strjoina(root
, "/usr/lib/systemd/system/real-add-dependency-test-service.service");
349 assert_se(write_string_file(p
, "# pretty much empty", WRITE_STRING_FILE_CREATE
) >= 0);
351 p
= strjoina(root
, "/usr/lib/systemd/system/add-dependency-test-service.service");
352 assert_se(symlink("real-add-dependency-test-service.service", p
) >= 0);
354 assert_se(unit_file_add_dependency(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("add-dependency-test-service.service"), "add-dependency-test-target.target", UNIT_WANTS
, &changes
, &n_changes
) >= 0);
355 assert_se(n_changes
== 1);
356 assert_se(changes
[0].type
== UNIT_FILE_SYMLINK
);
357 assert_se(streq(changes
[0].source
, "/usr/lib/systemd/system/real-add-dependency-test-service.service"));
358 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/real-add-dependency-test-target.target.wants/real-add-dependency-test-service.service");
359 assert_se(streq(changes
[0].path
, p
));
360 unit_file_changes_free(changes
, n_changes
);
361 changes
= NULL
; n_changes
= 0;
364 static void test_template_enable(const char *root
) {
365 UnitFileChange
*changes
= NULL
;
366 size_t n_changes
= 0;
370 log_info("== %s ==", __func__
);
372 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template@.service", &state
) == -ENOENT
);
373 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template@def.service", &state
) == -ENOENT
);
374 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template@foo.service", &state
) == -ENOENT
);
375 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template-symlink@foo.service", &state
) == -ENOENT
);
377 p
= strjoina(root
, "/usr/lib/systemd/system/template@.service");
378 assert_se(write_string_file(p
,
380 "DefaultInstance=def\n"
381 "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE
) >= 0);
383 p
= strjoina(root
, "/usr/lib/systemd/system/template-symlink@.service");
384 assert_se(symlink("template@.service", p
) >= 0);
386 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template@.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
387 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template@def.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
388 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template@foo.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
389 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template-symlink@.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
390 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template-symlink@def.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
391 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template-symlink@foo.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
393 log_info("== %s with template@.service enabled ==", __func__
);
395 assert_se(unit_file_enable(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("template@.service"), &changes
, &n_changes
) >= 0);
396 assert_se(n_changes
== 1);
397 assert_se(changes
[0].type
== UNIT_FILE_SYMLINK
);
398 assert_se(streq(changes
[0].source
, "/usr/lib/systemd/system/template@.service"));
399 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/multi-user.target.wants/template@def.service");
400 assert_se(streq(changes
[0].path
, p
));
401 unit_file_changes_free(changes
, n_changes
);
402 changes
= NULL
; n_changes
= 0;
404 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template@.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
405 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template@def.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
406 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template@foo.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
407 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template-symlink@.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
408 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template-symlink@def.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
409 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template-symlink@foo.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
411 assert_se(unit_file_disable(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("template@.service"), &changes
, &n_changes
) >= 0);
412 assert_se(n_changes
== 1);
413 assert_se(changes
[0].type
== UNIT_FILE_UNLINK
);
414 assert_se(streq(changes
[0].path
, p
));
415 unit_file_changes_free(changes
, n_changes
);
416 changes
= NULL
; n_changes
= 0;
418 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template@.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
419 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template@def.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
420 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template@foo.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
421 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template-symlink@.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
422 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template-symlink@def.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
423 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template-symlink@foo.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
425 log_info("== %s with template@foo.service enabled ==", __func__
);
427 assert_se(unit_file_enable(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("template@foo.service"), &changes
, &n_changes
) >= 0);
428 assert_se(changes
[0].type
== UNIT_FILE_SYMLINK
);
429 assert_se(streq(changes
[0].source
, "/usr/lib/systemd/system/template@.service"));
430 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/multi-user.target.wants/template@foo.service");
431 assert_se(streq(changes
[0].path
, p
));
432 unit_file_changes_free(changes
, n_changes
);
433 changes
= NULL
; n_changes
= 0;
435 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template@.service", &state
) >= 0 && state
== UNIT_FILE_INDIRECT
);
436 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template@def.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
437 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template@foo.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
438 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template-symlink@foo.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
439 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template-symlink@def.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
440 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template-symlink@foo.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
442 assert_se(unit_file_disable(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("template@foo.service"), &changes
, &n_changes
) >= 0);
443 assert_se(n_changes
== 1);
444 assert_se(changes
[0].type
== UNIT_FILE_UNLINK
);
445 assert_se(streq(changes
[0].path
, p
));
446 unit_file_changes_free(changes
, n_changes
);
447 changes
= NULL
; n_changes
= 0;
449 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template@.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
450 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template@def.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
451 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template@foo.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
452 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template@quux.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
453 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template-symlink@.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
454 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template-symlink@def.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
455 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template-symlink@foo.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
456 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template-symlink@quux.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
458 log_info("== %s with template-symlink@quux.service enabled ==", __func__
);
460 assert_se(unit_file_enable(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("template-symlink@quux.service"), &changes
, &n_changes
) >= 0);
461 assert_se(changes
[0].type
== UNIT_FILE_SYMLINK
);
462 assert_se(streq(changes
[0].source
, "/usr/lib/systemd/system/template@.service"));
463 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/multi-user.target.wants/template@quux.service");
464 assert_se(streq(changes
[0].path
, p
));
465 unit_file_changes_free(changes
, n_changes
);
466 changes
= NULL
; n_changes
= 0;
468 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template@.service", &state
) >= 0 && state
== UNIT_FILE_INDIRECT
);
469 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template@def.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
470 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template@foo.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
471 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template@quux.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
472 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template-symlink@.service", &state
) >= 0 && state
== UNIT_FILE_INDIRECT
);
473 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template-symlink@def.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
474 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template-symlink@foo.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
475 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template-symlink@quux.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
478 static void test_indirect(const char *root
) {
479 UnitFileChange
*changes
= NULL
;
480 size_t n_changes
= 0;
484 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "indirecta.service", &state
) == -ENOENT
);
485 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "indirectb.service", &state
) == -ENOENT
);
486 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "indirectc.service", &state
) == -ENOENT
);
488 p
= strjoina(root
, "/usr/lib/systemd/system/indirecta.service");
489 assert_se(write_string_file(p
,
491 "Also=indirectb.service\n", WRITE_STRING_FILE_CREATE
) >= 0);
493 p
= strjoina(root
, "/usr/lib/systemd/system/indirectb.service");
494 assert_se(write_string_file(p
,
496 "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE
) >= 0);
498 p
= strjoina(root
, "/usr/lib/systemd/system/indirectc.service");
499 assert_se(symlink("indirecta.service", p
) >= 0);
501 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "indirecta.service", &state
) >= 0 && state
== UNIT_FILE_INDIRECT
);
502 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "indirectb.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
503 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "indirectc.service", &state
) >= 0 && state
== UNIT_FILE_INDIRECT
);
505 assert_se(unit_file_enable(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("indirectc.service"), &changes
, &n_changes
) >= 0);
506 assert_se(n_changes
== 1);
507 assert_se(changes
[0].type
== UNIT_FILE_SYMLINK
);
508 assert_se(streq(changes
[0].source
, "/usr/lib/systemd/system/indirectb.service"));
509 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/multi-user.target.wants/indirectb.service");
510 assert_se(streq(changes
[0].path
, p
));
511 unit_file_changes_free(changes
, n_changes
);
512 changes
= NULL
; n_changes
= 0;
514 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "indirecta.service", &state
) >= 0 && state
== UNIT_FILE_INDIRECT
);
515 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "indirectb.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
516 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "indirectc.service", &state
) >= 0 && state
== UNIT_FILE_INDIRECT
);
518 assert_se(unit_file_disable(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("indirectc.service"), &changes
, &n_changes
) >= 0);
519 assert_se(n_changes
== 1);
520 assert_se(changes
[0].type
== UNIT_FILE_UNLINK
);
521 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/multi-user.target.wants/indirectb.service");
522 assert_se(streq(changes
[0].path
, p
));
523 unit_file_changes_free(changes
, n_changes
);
524 changes
= NULL
; n_changes
= 0;
527 static void test_preset_and_list(const char *root
) {
528 UnitFileChange
*changes
= NULL
;
529 size_t n_changes
= 0, i
;
532 bool got_yes
= false, got_no
= false;
537 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "preset-yes.service", &state
) == -ENOENT
);
538 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "preset-no.service", &state
) == -ENOENT
);
540 p
= strjoina(root
, "/usr/lib/systemd/system/preset-yes.service");
541 assert_se(write_string_file(p
,
543 "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE
) >= 0);
545 p
= strjoina(root
, "/usr/lib/systemd/system/preset-no.service");
546 assert_se(write_string_file(p
,
548 "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE
) >= 0);
550 p
= strjoina(root
, "/usr/lib/systemd/system-preset/test.preset");
551 assert_se(write_string_file(p
,
553 "disable *\n", WRITE_STRING_FILE_CREATE
) >= 0);
555 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "preset-yes.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
556 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "preset-no.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
558 assert_se(unit_file_preset(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("preset-yes.service"), UNIT_FILE_PRESET_FULL
, &changes
, &n_changes
) >= 0);
559 assert_se(n_changes
== 1);
560 assert_se(changes
[0].type
== UNIT_FILE_SYMLINK
);
561 assert_se(streq(changes
[0].source
, "/usr/lib/systemd/system/preset-yes.service"));
562 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/multi-user.target.wants/preset-yes.service");
563 assert_se(streq(changes
[0].path
, p
));
564 unit_file_changes_free(changes
, n_changes
);
565 changes
= NULL
; n_changes
= 0;
567 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "preset-yes.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
568 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "preset-no.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
570 assert_se(unit_file_disable(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("preset-yes.service"), &changes
, &n_changes
) >= 0);
571 assert_se(n_changes
== 1);
572 assert_se(changes
[0].type
== UNIT_FILE_UNLINK
);
573 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/multi-user.target.wants/preset-yes.service");
574 assert_se(streq(changes
[0].path
, p
));
575 unit_file_changes_free(changes
, n_changes
);
576 changes
= NULL
; n_changes
= 0;
578 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "preset-yes.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
579 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "preset-no.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
581 assert_se(unit_file_preset(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("preset-no.service"), UNIT_FILE_PRESET_FULL
, &changes
, &n_changes
) >= 0);
582 assert_se(n_changes
== 0);
583 unit_file_changes_free(changes
, n_changes
);
584 changes
= NULL
; n_changes
= 0;
586 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "preset-yes.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
587 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "preset-no.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
589 assert_se(unit_file_preset_all(UNIT_FILE_SYSTEM
, 0, root
, UNIT_FILE_PRESET_FULL
, &changes
, &n_changes
) >= 0);
591 assert_se(n_changes
> 0);
593 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/multi-user.target.wants/preset-yes.service");
595 for (i
= 0; i
< n_changes
; i
++) {
597 if (changes
[i
].type
== UNIT_FILE_SYMLINK
) {
598 assert_se(streq(changes
[i
].source
, "/usr/lib/systemd/system/preset-yes.service"));
599 assert_se(streq(changes
[i
].path
, p
));
601 assert_se(changes
[i
].type
== UNIT_FILE_UNLINK
);
604 unit_file_changes_free(changes
, n_changes
);
605 changes
= NULL
; n_changes
= 0;
607 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "preset-yes.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
608 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "preset-no.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
610 assert_se(h
= hashmap_new(&string_hash_ops
));
611 assert_se(unit_file_get_list(UNIT_FILE_SYSTEM
, root
, h
, NULL
, NULL
) >= 0);
613 p
= strjoina(root
, "/usr/lib/systemd/system/preset-yes.service");
614 q
= strjoina(root
, "/usr/lib/systemd/system/preset-no.service");
616 HASHMAP_FOREACH(fl
, h
, j
) {
617 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, basename(fl
->path
), &state
) >= 0);
618 assert_se(fl
->state
== state
);
620 if (streq(fl
->path
, p
)) {
622 assert_se(fl
->state
== UNIT_FILE_ENABLED
);
623 } else if (streq(fl
->path
, q
)) {
625 assert_se(fl
->state
== UNIT_FILE_DISABLED
);
627 assert_se(IN_SET(fl
->state
, UNIT_FILE_DISABLED
, UNIT_FILE_STATIC
, UNIT_FILE_INDIRECT
));
630 unit_file_list_free(h
);
632 assert_se(got_yes
&& got_no
);
635 static void test_revert(const char *root
) {
638 UnitFileChange
*changes
= NULL
;
639 size_t n_changes
= 0;
643 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "xx.service", NULL
) == -ENOENT
);
644 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "yy.service", NULL
) == -ENOENT
);
646 p
= strjoina(root
, "/usr/lib/systemd/system/xx.service");
647 assert_se(write_string_file(p
, "# Empty\n", WRITE_STRING_FILE_CREATE
) >= 0);
649 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "xx.service", NULL
) >= 0);
650 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "xx.service", &state
) >= 0 && state
== UNIT_FILE_STATIC
);
652 /* Initially there's nothing to revert */
653 assert_se(unit_file_revert(UNIT_FILE_SYSTEM
, root
, STRV_MAKE("xx.service"), &changes
, &n_changes
) >= 0);
654 assert_se(n_changes
== 0);
655 unit_file_changes_free(changes
, n_changes
);
656 changes
= NULL
; n_changes
= 0;
658 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/xx.service");
659 assert_se(write_string_file(p
, "# Empty override\n", WRITE_STRING_FILE_CREATE
) >= 0);
661 /* Revert the override file */
662 assert_se(unit_file_revert(UNIT_FILE_SYSTEM
, root
, STRV_MAKE("xx.service"), &changes
, &n_changes
) >= 0);
663 assert_se(n_changes
== 1);
664 assert_se(changes
[0].type
== UNIT_FILE_UNLINK
);
665 assert_se(streq(changes
[0].path
, p
));
666 unit_file_changes_free(changes
, n_changes
);
667 changes
= NULL
; n_changes
= 0;
669 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/xx.service.d/dropin.conf");
670 assert_se(mkdir_parents(p
, 0755) >= 0);
671 assert_se(write_string_file(p
, "# Empty dropin\n", WRITE_STRING_FILE_CREATE
) >= 0);
673 /* Revert the dropin file */
674 assert_se(unit_file_revert(UNIT_FILE_SYSTEM
, root
, STRV_MAKE("xx.service"), &changes
, &n_changes
) >= 0);
675 assert_se(n_changes
== 2);
676 assert_se(changes
[0].type
== UNIT_FILE_UNLINK
);
677 assert_se(streq(changes
[0].path
, p
));
679 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/xx.service.d");
680 assert_se(changes
[1].type
== UNIT_FILE_UNLINK
);
681 assert_se(streq(changes
[1].path
, p
));
682 unit_file_changes_free(changes
, n_changes
);
683 changes
= NULL
; n_changes
= 0;
686 static void test_preset_order(const char *root
) {
687 UnitFileChange
*changes
= NULL
;
688 size_t n_changes
= 0;
692 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "prefix-1.service", &state
) == -ENOENT
);
693 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "prefix-2.service", &state
) == -ENOENT
);
695 p
= strjoina(root
, "/usr/lib/systemd/system/prefix-1.service");
696 assert_se(write_string_file(p
,
698 "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE
) >= 0);
700 p
= strjoina(root
, "/usr/lib/systemd/system/prefix-2.service");
701 assert_se(write_string_file(p
,
703 "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE
) >= 0);
705 p
= strjoina(root
, "/usr/lib/systemd/system-preset/test.preset");
706 assert_se(write_string_file(p
,
707 "enable prefix-1.service\n"
708 "disable prefix-*.service\n"
709 "enable prefix-2.service\n", WRITE_STRING_FILE_CREATE
) >= 0);
711 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "prefix-1.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
712 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "prefix-2.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
714 assert_se(unit_file_preset(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("prefix-1.service"), UNIT_FILE_PRESET_FULL
, &changes
, &n_changes
) >= 0);
715 assert_se(n_changes
== 1);
716 assert_se(changes
[0].type
== UNIT_FILE_SYMLINK
);
717 assert_se(streq(changes
[0].source
, "/usr/lib/systemd/system/prefix-1.service"));
718 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/multi-user.target.wants/prefix-1.service");
719 assert_se(streq(changes
[0].path
, p
));
720 unit_file_changes_free(changes
, n_changes
);
721 changes
= NULL
; n_changes
= 0;
723 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "prefix-1.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
724 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "prefix-2.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
726 assert_se(unit_file_preset(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("prefix-2.service"), UNIT_FILE_PRESET_FULL
, &changes
, &n_changes
) >= 0);
727 assert_se(n_changes
== 0);
729 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "prefix-1.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
730 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "prefix-2.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
733 static void test_static_instance(const char *root
) {
737 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "static-instance@.service", &state
) == -ENOENT
);
738 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "static-instance@foo.service", &state
) == -ENOENT
);
740 p
= strjoina(root
, "/usr/lib/systemd/system/static-instance@.service");
741 assert_se(write_string_file(p
,
743 "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE
) >= 0);
745 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "static-instance@.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
746 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "static-instance@foo.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
748 p
= strjoina(root
, "/usr/lib/systemd/system/static-instance@foo.service");
749 assert_se(symlink("static-instance@.service", p
) >= 0);
751 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "static-instance@.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
752 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "static-instance@foo.service", &state
) >= 0 && state
== UNIT_FILE_STATIC
);
755 static void test_with_dropin(const char *root
) {
758 UnitFileChange
*changes
= NULL
;
759 size_t n_changes
= 0;
761 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "with-dropin-1.service", &state
) == -ENOENT
);
762 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "with-dropin-2.service", &state
) == -ENOENT
);
763 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "with-dropin-3.service", &state
) == -ENOENT
);
764 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "with-dropin-4a.service", &state
) == -ENOENT
);
765 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "with-dropin-4b.service", &state
) == -ENOENT
);
767 p
= strjoina(root
, "/usr/lib/systemd/system/with-dropin-1.service");
768 assert_se(write_string_file(p
,
770 "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE
) >= 0);
772 p
= strjoina(root
, "/usr/lib/systemd/system/with-dropin-1.service.d/dropin.conf");
773 assert_se(mkdir_parents(p
, 0755) >= 0);
774 assert_se(write_string_file(p
,
776 "WantedBy=graphical.target\n", WRITE_STRING_FILE_CREATE
) >= 0);
778 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "with-dropin-1.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
780 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/with-dropin-2.service");
781 assert_se(write_string_file(p
,
783 "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE
) >= 0);
785 p
= strjoina(root
, "/usr/lib/systemd/system/with-dropin-2.service.d/dropin.conf");
786 assert_se(mkdir_parents(p
, 0755) >= 0);
787 assert_se(write_string_file(p
,
789 "WantedBy=graphical.target\n", WRITE_STRING_FILE_CREATE
) >= 0);
791 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "with-dropin-2.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
793 p
= strjoina(root
, "/usr/lib/systemd/system/with-dropin-3.service");
794 assert_se(write_string_file(p
,
796 "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE
) >= 0);
798 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/with-dropin-3.service.d/dropin.conf");
799 assert_se(mkdir_parents(p
, 0755) >= 0);
800 assert_se(write_string_file(p
,
802 "WantedBy=graphical.target\n", WRITE_STRING_FILE_CREATE
) >= 0);
804 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "with-dropin-3.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
806 p
= strjoina(root
, "/usr/lib/systemd/system/with-dropin-4a.service");
807 assert_se(write_string_file(p
,
809 "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE
) >= 0);
811 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/with-dropin-4a.service.d/dropin.conf");
812 assert_se(mkdir_parents(p
, 0755) >= 0);
813 assert_se(write_string_file(p
,
815 "Also=with-dropin-4b.service\n", WRITE_STRING_FILE_CREATE
) >= 0);
817 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "with-dropin-4a.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
819 p
= strjoina(root
, "/usr/lib/systemd/system/with-dropin-4b.service");
820 assert_se(write_string_file(p
,
822 "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE
) >= 0);
824 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "with-dropin-4b.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
826 assert_se(unit_file_enable(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("with-dropin-1.service"), &changes
, &n_changes
) == 1);
827 assert_se(n_changes
== 2);
828 assert_se(changes
[0].type
== UNIT_FILE_SYMLINK
);
829 assert_se(changes
[1].type
== UNIT_FILE_SYMLINK
);
830 assert_se(streq(changes
[0].source
, "/usr/lib/systemd/system/with-dropin-1.service"));
831 assert_se(streq(changes
[1].source
, "/usr/lib/systemd/system/with-dropin-1.service"));
832 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/multi-user.target.wants/with-dropin-1.service");
833 assert_se(streq(changes
[0].path
, p
));
834 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/graphical.target.wants/with-dropin-1.service");
835 assert_se(streq(changes
[1].path
, p
));
836 unit_file_changes_free(changes
, n_changes
);
837 changes
= NULL
; n_changes
= 0;
839 assert_se(unit_file_enable(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("with-dropin-2.service"), &changes
, &n_changes
) == 1);
840 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "with-dropin-2.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
841 assert_se(n_changes
== 2);
842 assert_se(changes
[0].type
== UNIT_FILE_SYMLINK
);
843 assert_se(changes
[1].type
== UNIT_FILE_SYMLINK
);
844 assert_se(streq(changes
[0].source
, SYSTEM_CONFIG_UNIT_PATH
"/with-dropin-2.service"));
845 assert_se(streq(changes
[1].source
, SYSTEM_CONFIG_UNIT_PATH
"/with-dropin-2.service"));
846 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/multi-user.target.wants/with-dropin-2.service");
847 assert_se(streq(changes
[0].path
, p
));
848 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/graphical.target.wants/with-dropin-2.service");
849 assert_se(streq(changes
[1].path
, p
));
850 unit_file_changes_free(changes
, n_changes
);
851 changes
= NULL
; n_changes
= 0;
853 assert_se(unit_file_enable(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("with-dropin-3.service"), &changes
, &n_changes
) == 1);
854 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "with-dropin-3.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
855 assert_se(n_changes
== 2);
856 assert_se(changes
[0].type
== UNIT_FILE_SYMLINK
);
857 assert_se(changes
[1].type
== UNIT_FILE_SYMLINK
);
858 assert_se(streq(changes
[0].source
, "/usr/lib/systemd/system/with-dropin-3.service"));
859 assert_se(streq(changes
[1].source
, "/usr/lib/systemd/system/with-dropin-3.service"));
860 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/multi-user.target.wants/with-dropin-3.service");
861 assert_se(streq(changes
[0].path
, p
));
862 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/graphical.target.wants/with-dropin-3.service");
863 assert_se(streq(changes
[1].path
, p
));
864 unit_file_changes_free(changes
, n_changes
);
865 changes
= NULL
; n_changes
= 0;
867 assert_se(unit_file_enable(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("with-dropin-4a.service"), &changes
, &n_changes
) == 2);
868 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "with-dropin-3.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
869 assert_se(n_changes
== 2);
870 assert_se(changes
[0].type
== UNIT_FILE_SYMLINK
);
871 assert_se(changes
[1].type
== UNIT_FILE_SYMLINK
);
872 assert_se(streq(changes
[0].source
, "/usr/lib/systemd/system/with-dropin-4a.service"));
873 assert_se(streq(changes
[1].source
, "/usr/lib/systemd/system/with-dropin-4b.service"));
874 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/multi-user.target.wants/with-dropin-4a.service");
875 assert_se(streq(changes
[0].path
, p
));
876 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/multi-user.target.wants/with-dropin-4b.service");
877 assert_se(streq(changes
[1].path
, p
));
878 unit_file_changes_free(changes
, n_changes
);
879 changes
= NULL
; n_changes
= 0;
881 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "with-dropin-1.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
882 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "with-dropin-2.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
883 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "with-dropin-3.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
884 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "with-dropin-4a.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
885 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "with-dropin-4b.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
888 static void test_with_dropin_template(const char *root
) {
891 UnitFileChange
*changes
= NULL
;
892 size_t n_changes
= 0;
894 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "with-dropin-1@.service", &state
) == -ENOENT
);
895 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "with-dropin-2@.service", &state
) == -ENOENT
);
896 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "with-dropin-3@.service", &state
) == -ENOENT
);
898 p
= strjoina(root
, "/usr/lib/systemd/system/with-dropin-1@.service");
899 assert_se(write_string_file(p
,
901 "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE
) >= 0);
903 p
= strjoina(root
, "/usr/lib/systemd/system/with-dropin-1@.service.d/dropin.conf");
904 assert_se(mkdir_parents(p
, 0755) >= 0);
905 assert_se(write_string_file(p
,
907 "WantedBy=graphical.target\n", WRITE_STRING_FILE_CREATE
) >= 0);
909 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "with-dropin-1@.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
911 p
= strjoina(root
, "/usr/lib/systemd/system/with-dropin-2@.service");
912 assert_se(write_string_file(p
,
914 "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE
) >= 0);
916 p
= strjoina(root
, "/usr/lib/systemd/system/with-dropin-2@instance-1.service.d/dropin.conf");
917 assert_se(mkdir_parents(p
, 0755) >= 0);
918 assert_se(write_string_file(p
,
920 "WantedBy=graphical.target\n", WRITE_STRING_FILE_CREATE
) >= 0);
922 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "with-dropin-2@.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
924 p
= strjoina(root
, "/usr/lib/systemd/system/with-dropin-3@.service");
925 assert_se(write_string_file(p
,
927 "DefaultInstance=instance-1\n"
928 "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE
) >= 0);
930 p
= strjoina(root
, "/usr/lib/systemd/system/with-dropin-3@.service.d/dropin.conf");
931 assert_se(mkdir_parents(p
, 0755) >= 0);
932 assert_se(write_string_file(p
,
934 "DefaultInstance=instance-2\n", WRITE_STRING_FILE_CREATE
) >= 0);
936 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "with-dropin-3@.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
938 assert_se(unit_file_enable(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("with-dropin-1@instance-1.service"), &changes
, &n_changes
) == 1);
939 assert_se(n_changes
== 2);
940 assert_se(changes
[0].type
== UNIT_FILE_SYMLINK
);
941 assert_se(changes
[1].type
== UNIT_FILE_SYMLINK
);
942 assert_se(streq(changes
[0].source
, "/usr/lib/systemd/system/with-dropin-1@.service"));
943 assert_se(streq(changes
[1].source
, "/usr/lib/systemd/system/with-dropin-1@.service"));
944 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/multi-user.target.wants/with-dropin-1@instance-1.service");
945 assert_se(streq(changes
[0].path
, p
));
946 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/graphical.target.wants/with-dropin-1@instance-1.service");
947 assert_se(streq(changes
[1].path
, p
));
948 unit_file_changes_free(changes
, n_changes
);
949 changes
= NULL
; n_changes
= 0;
951 assert_se(unit_file_enable(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("with-dropin-2@instance-1.service"), &changes
, &n_changes
) == 1);
952 assert_se(n_changes
== 2);
953 assert_se(changes
[0].type
== UNIT_FILE_SYMLINK
);
954 assert_se(changes
[1].type
== UNIT_FILE_SYMLINK
);
955 assert_se(streq(changes
[0].source
, "/usr/lib/systemd/system/with-dropin-2@.service"));
956 assert_se(streq(changes
[1].source
, "/usr/lib/systemd/system/with-dropin-2@.service"));
957 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/multi-user.target.wants/with-dropin-2@instance-1.service");
958 assert_se(streq(changes
[0].path
, p
));
959 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/graphical.target.wants/with-dropin-2@instance-1.service");
960 assert_se(streq(changes
[1].path
, p
));
961 unit_file_changes_free(changes
, n_changes
);
962 changes
= NULL
; n_changes
= 0;
964 assert_se(unit_file_enable(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("with-dropin-2@instance-2.service"), &changes
, &n_changes
) == 1);
965 assert_se(n_changes
== 1);
966 assert_se(changes
[0].type
== UNIT_FILE_SYMLINK
);
967 assert_se(streq(changes
[0].source
, "/usr/lib/systemd/system/with-dropin-2@.service"));
968 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/multi-user.target.wants/with-dropin-2@instance-2.service");
969 assert_se(streq(changes
[0].path
, p
));
970 unit_file_changes_free(changes
, n_changes
);
971 changes
= NULL
; n_changes
= 0;
973 assert_se(unit_file_enable(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("with-dropin-3@.service"), &changes
, &n_changes
) == 1);
974 assert_se(n_changes
== 1);
975 assert_se(changes
[0].type
== UNIT_FILE_SYMLINK
);
976 assert_se(streq(changes
[0].source
, "/usr/lib/systemd/system/with-dropin-3@.service"));
977 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/multi-user.target.wants/with-dropin-3@instance-2.service");
978 assert_se(streq(changes
[0].path
, p
));
979 unit_file_changes_free(changes
, n_changes
);
980 changes
= NULL
; n_changes
= 0;
982 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "with-dropin-1@instance-1.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
983 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "with-dropin-2@instance-1.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
984 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "with-dropin-2@instance-2.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
985 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "with-dropin-3@instance-1.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
986 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "with-dropin-3@instance-2.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
989 static void test_preset_multiple_instances(const char *root
) {
990 UnitFileChange
*changes
= NULL
;
991 size_t n_changes
= 0;
995 /* Set up template service files and preset file */
996 p
= strjoina(root
, "/usr/lib/systemd/system/foo@.service");
997 assert_se(write_string_file(p
,
999 "DefaultInstance=def\n"
1000 "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE
) >= 0);
1002 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "foo@.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
1004 p
= strjoina(root
, "/usr/lib/systemd/system-preset/test.preset");
1005 assert_se(write_string_file(p
,
1006 "enable foo@.service bar0 bar1 bartest\n"
1007 "enable emptylist@.service\n" /* This line ensures the old functionality for templated unit still works */
1008 "disable *\n" , WRITE_STRING_FILE_CREATE
) >= 0);
1010 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "foo@bar0.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
1012 /* Preset a single instantiated unit specified in the list */
1013 assert_se(unit_file_preset(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("foo@bar0.service"), UNIT_FILE_PRESET_FULL
, &changes
, &n_changes
) >= 0);
1014 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "foo@bar0.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
1015 assert_se(n_changes
== 1);
1016 assert_se(changes
[0].type
== UNIT_FILE_SYMLINK
);
1017 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/multi-user.target.wants/foo@bar0.service");
1018 assert_se(streq(changes
[0].path
, p
));
1019 unit_file_changes_free(changes
, n_changes
);
1020 changes
= NULL
; n_changes
= 0;
1022 assert_se(unit_file_disable(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("foo@bar0.service"), &changes
, &n_changes
) >= 0);
1023 assert_se(n_changes
== 1);
1024 assert_se(changes
[0].type
== UNIT_FILE_UNLINK
);
1025 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/multi-user.target.wants/foo@bar0.service");
1026 assert_se(streq(changes
[0].path
, p
));
1027 unit_file_changes_free(changes
, n_changes
);
1028 changes
= NULL
; n_changes
= 0;
1030 /* Check for preset-all case, only instances on the list should be enabled, not including the default instance */
1031 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "foo@def.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
1032 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "foo@bar1.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
1033 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "foo@bartest.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
1035 assert_se(unit_file_preset_all(UNIT_FILE_SYSTEM
, 0, root
, UNIT_FILE_PRESET_FULL
, &changes
, &n_changes
) >= 0);
1036 assert_se(n_changes
> 0);
1038 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "foo@def.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
1039 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "foo@bar0.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
1040 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "foo@bar1.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
1041 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "foo@bartest.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
1043 unit_file_changes_free(changes
, n_changes
);
1046 int main(int argc
, char *argv
[]) {
1047 char root
[] = "/tmp/rootXXXXXX";
1050 assert_se(mkdtemp(root
));
1052 p
= strjoina(root
, "/usr/lib/systemd/system/");
1053 assert_se(mkdir_p(p
, 0755) >= 0);
1055 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/");
1056 assert_se(mkdir_p(p
, 0755) >= 0);
1058 p
= strjoina(root
, "/run/systemd/system/");
1059 assert_se(mkdir_p(p
, 0755) >= 0);
1061 p
= strjoina(root
, "/opt/");
1062 assert_se(mkdir_p(p
, 0755) >= 0);
1064 p
= strjoina(root
, "/usr/lib/systemd/system-preset/");
1065 assert_se(mkdir_p(p
, 0755) >= 0);
1067 test_basic_mask_and_enable(root
);
1068 test_linked_units(root
);
1070 test_add_dependency(root
);
1071 test_template_enable(root
);
1072 test_indirect(root
);
1073 test_preset_and_list(root
);
1074 test_preset_order(root
);
1075 test_preset_multiple_instances(root
);
1077 test_static_instance(root
);
1078 test_with_dropin(root
);
1079 test_with_dropin_template(root
);
1081 assert_se(rm_rf(root
, REMOVE_ROOT
|REMOVE_PHYSICAL
) >= 0);