]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/test/test-install-root.c
2 This file is part of systemd.
4 Copyright 2011 Lennart Poettering
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 #include "alloc-util.h"
26 #include "string-util.h"
28 static void test_basic_mask_and_enable(const char *root
) {
31 UnitFileChange
*changes
= NULL
;
32 unsigned n_changes
= 0;
34 log_set_max_level(LOG_DEBUG
);
36 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "a.service", NULL
) == -ENOENT
);
37 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "b.service", NULL
) == -ENOENT
);
38 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "c.service", NULL
) == -ENOENT
);
39 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "d.service", NULL
) == -ENOENT
);
41 p
= strjoina(root
, "/usr/lib/systemd/system/a.service");
42 assert_se(write_string_file(p
,
44 "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE
) >= 0);
46 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "a.service", NULL
) >= 0);
47 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "a.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
49 p
= strjoina(root
, "/usr/lib/systemd/system/b.service");
50 assert_se(symlink("a.service", p
) >= 0);
52 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "b.service", NULL
) >= 0);
53 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "b.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
55 p
= strjoina(root
, "/usr/lib/systemd/system/c.service");
56 assert_se(symlink("/usr/lib/systemd/system/a.service", p
) >= 0);
58 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "c.service", NULL
) >= 0);
59 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "c.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
61 p
= strjoina(root
, "/usr/lib/systemd/system/d.service");
62 assert_se(symlink("c.service", p
) >= 0);
64 /* This one is interesting, as d follows a relative, then an absolute symlink */
65 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "d.service", NULL
) >= 0);
66 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "d.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
68 assert_se(unit_file_mask(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("a.service"), &changes
, &n_changes
) >= 0);
69 assert_se(n_changes
== 1);
70 assert_se(changes
[0].type
== UNIT_FILE_SYMLINK
);
71 assert_se(streq(changes
[0].source
, "/dev/null"));
72 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/a.service");
73 assert_se(streq(changes
[0].path
, p
));
75 unit_file_changes_free(changes
, n_changes
);
76 changes
= NULL
; n_changes
= 0;
78 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "a.service", &state
) >= 0 && state
== UNIT_FILE_MASKED
);
79 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "b.service", &state
) >= 0 && state
== UNIT_FILE_MASKED
);
80 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "c.service", &state
) >= 0 && state
== UNIT_FILE_MASKED
);
81 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "d.service", &state
) >= 0 && state
== UNIT_FILE_MASKED
);
83 /* Enabling a masked unit should fail! */
84 assert_se(unit_file_enable(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("a.service"), &changes
, &n_changes
) == -ERFKILL
);
85 unit_file_changes_free(changes
, n_changes
);
86 changes
= NULL
; n_changes
= 0;
88 assert_se(unit_file_unmask(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("a.service"), &changes
, &n_changes
) >= 0);
89 assert_se(n_changes
== 1);
90 assert_se(changes
[0].type
== UNIT_FILE_UNLINK
);
91 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/a.service");
92 assert_se(streq(changes
[0].path
, p
));
93 unit_file_changes_free(changes
, n_changes
);
94 changes
= NULL
; n_changes
= 0;
96 assert_se(unit_file_enable(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("a.service"), &changes
, &n_changes
) == 1);
97 assert_se(n_changes
== 1);
98 assert_se(changes
[0].type
== UNIT_FILE_SYMLINK
);
99 assert_se(streq(changes
[0].source
, "/usr/lib/systemd/system/a.service"));
100 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/multi-user.target.wants/a.service");
101 assert_se(streq(changes
[0].path
, p
));
102 unit_file_changes_free(changes
, n_changes
);
103 changes
= NULL
; n_changes
= 0;
105 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "a.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
106 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "b.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
107 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "c.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
108 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "d.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
110 /* Enabling it again should succeed but be a NOP */
111 assert_se(unit_file_enable(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("a.service"), &changes
, &n_changes
) >= 0);
112 assert_se(n_changes
== 0);
113 unit_file_changes_free(changes
, n_changes
);
114 changes
= NULL
; n_changes
= 0;
116 assert_se(unit_file_disable(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("a.service"), &changes
, &n_changes
) >= 0);
117 assert_se(n_changes
== 1);
118 assert_se(changes
[0].type
== UNIT_FILE_UNLINK
);
119 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/multi-user.target.wants/a.service");
120 assert_se(streq(changes
[0].path
, p
));
121 unit_file_changes_free(changes
, n_changes
);
122 changes
= NULL
; n_changes
= 0;
124 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "a.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
125 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "b.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
126 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "c.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
127 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "d.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
129 /* Disabling a disabled unit must suceed but be a NOP */
130 assert_se(unit_file_disable(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("a.service"), &changes
, &n_changes
) >= 0);
131 assert_se(n_changes
== 0);
132 unit_file_changes_free(changes
, n_changes
);
133 changes
= NULL
; n_changes
= 0;
135 /* Let's enable this indirectly via a symlink */
136 assert_se(unit_file_enable(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("d.service"), &changes
, &n_changes
) >= 0);
137 assert_se(n_changes
== 1);
138 assert_se(changes
[0].type
== UNIT_FILE_SYMLINK
);
139 assert_se(streq(changes
[0].source
, "/usr/lib/systemd/system/a.service"));
140 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/multi-user.target.wants/a.service");
141 assert_se(streq(changes
[0].path
, p
));
142 unit_file_changes_free(changes
, n_changes
);
143 changes
= NULL
; n_changes
= 0;
145 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "a.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
146 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "b.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
147 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "c.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
148 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "d.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
150 /* Let's try to reenable */
152 assert_se(unit_file_reenable(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("b.service"), &changes
, &n_changes
) >= 0);
153 assert_se(n_changes
== 2);
154 assert_se(changes
[0].type
== UNIT_FILE_UNLINK
);
155 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/multi-user.target.wants/a.service");
156 assert_se(streq(changes
[0].path
, p
));
157 assert_se(changes
[1].type
== UNIT_FILE_SYMLINK
);
158 assert_se(streq(changes
[1].source
, "/usr/lib/systemd/system/a.service"));
159 assert_se(streq(changes
[1].path
, p
));
160 unit_file_changes_free(changes
, n_changes
);
161 changes
= NULL
; n_changes
= 0;
163 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "a.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
164 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "b.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
165 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "c.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
166 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "d.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
169 static void test_linked_units(const char *root
) {
172 UnitFileChange
*changes
= NULL
;
173 unsigned n_changes
= 0, i
;
176 * We'll test three cases here:
178 * a) a unit file in /opt, that we use "systemctl link" and
179 * "systemctl enable" on to make it available to the system
181 * b) a unit file in /opt, that is statically linked into
182 * /usr/lib/systemd/system, that "enable" should work on
185 * c) a unit file in /opt, that is linked into
186 * /etc/systemd/system, and where "enable" should result in
187 * -ELOOP, since using information from /etc to generate
188 * information in /etc should not be allowed.
191 p
= strjoina(root
, "/opt/linked.service");
192 assert_se(write_string_file(p
,
194 "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE
) >= 0);
196 p
= strjoina(root
, "/opt/linked2.service");
197 assert_se(write_string_file(p
,
199 "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE
) >= 0);
201 p
= strjoina(root
, "/opt/linked3.service");
202 assert_se(write_string_file(p
,
204 "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE
) >= 0);
206 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "linked.service", NULL
) == -ENOENT
);
207 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "linked2.service", NULL
) == -ENOENT
);
208 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "linked3.service", NULL
) == -ENOENT
);
210 p
= strjoina(root
, "/usr/lib/systemd/system/linked2.service");
211 assert_se(symlink("/opt/linked2.service", p
) >= 0);
213 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/linked3.service");
214 assert_se(symlink("/opt/linked3.service", p
) >= 0);
216 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "linked.service", &state
) == -ENOENT
);
217 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "linked2.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
218 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "linked3.service", &state
) >= 0 && state
== UNIT_FILE_LINKED
);
220 /* First, let's link the unit into the search path */
221 assert_se(unit_file_link(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("/opt/linked.service"), &changes
, &n_changes
) >= 0);
222 assert_se(n_changes
== 1);
223 assert_se(changes
[0].type
== UNIT_FILE_SYMLINK
);
224 assert_se(streq(changes
[0].source
, "/opt/linked.service"));
225 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/linked.service");
226 assert_se(streq(changes
[0].path
, p
));
227 unit_file_changes_free(changes
, n_changes
);
228 changes
= NULL
; n_changes
= 0;
230 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "linked.service", &state
) >= 0 && state
== UNIT_FILE_LINKED
);
232 /* Let's unlink it from the search path again */
233 assert_se(unit_file_disable(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("linked.service"), &changes
, &n_changes
) >= 0);
234 assert_se(n_changes
== 1);
235 assert_se(changes
[0].type
== UNIT_FILE_UNLINK
);
236 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/linked.service");
237 assert_se(streq(changes
[0].path
, p
));
238 unit_file_changes_free(changes
, n_changes
);
239 changes
= NULL
; n_changes
= 0;
241 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "linked.service", NULL
) == -ENOENT
);
243 /* Now, let's not just link it, but also enable it */
244 assert_se(unit_file_enable(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("/opt/linked.service"), &changes
, &n_changes
) >= 0);
245 assert_se(n_changes
== 2);
246 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/multi-user.target.wants/linked.service");
247 q
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/linked.service");
248 for (i
= 0 ; i
< n_changes
; i
++) {
249 assert_se(changes
[i
].type
== UNIT_FILE_SYMLINK
);
250 assert_se(streq(changes
[i
].source
, "/opt/linked.service"));
252 if (p
&& streq(changes
[i
].path
, p
))
254 else if (q
&& streq(changes
[i
].path
, q
))
257 assert_not_reached("wut?");
260 unit_file_changes_free(changes
, n_changes
);
261 changes
= NULL
; n_changes
= 0;
263 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "linked.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
265 /* And let's unlink it again */
266 assert_se(unit_file_disable(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("linked.service"), &changes
, &n_changes
) >= 0);
267 assert_se(n_changes
== 2);
268 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/multi-user.target.wants/linked.service");
269 q
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/linked.service");
270 for (i
= 0; i
< n_changes
; i
++) {
271 assert_se(changes
[i
].type
== UNIT_FILE_UNLINK
);
273 if (p
&& streq(changes
[i
].path
, p
))
275 else if (q
&& streq(changes
[i
].path
, q
))
278 assert_not_reached("wut?");
281 unit_file_changes_free(changes
, n_changes
);
282 changes
= NULL
; n_changes
= 0;
284 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "linked.service", NULL
) == -ENOENT
);
286 assert_se(unit_file_enable(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("linked2.service"), &changes
, &n_changes
) >= 0);
287 assert_se(n_changes
== 2);
288 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/multi-user.target.wants/linked2.service");
289 q
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/linked2.service");
290 for (i
= 0 ; i
< n_changes
; i
++) {
291 assert_se(changes
[i
].type
== UNIT_FILE_SYMLINK
);
292 assert_se(streq(changes
[i
].source
, "/opt/linked2.service"));
294 if (p
&& streq(changes
[i
].path
, p
))
296 else if (q
&& streq(changes
[i
].path
, q
))
299 assert_not_reached("wut?");
302 unit_file_changes_free(changes
, n_changes
);
303 changes
= NULL
; n_changes
= 0;
305 assert_se(unit_file_enable(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("linked3.service"), &changes
, &n_changes
) >= 0);
306 assert_se(n_changes
== 1);
307 assert_se(changes
[0].type
== UNIT_FILE_SYMLINK
);
308 assert_se(startswith(changes
[0].path
, root
));
309 assert_se(endswith(changes
[0].path
, "linked3.service"));
310 assert_se(streq(changes
[0].source
, "/opt/linked3.service"));
311 unit_file_changes_free(changes
, n_changes
);
312 changes
= NULL
; n_changes
= 0;
315 static void test_default(const char *root
) {
316 _cleanup_free_
char *def
= NULL
;
317 UnitFileChange
*changes
= NULL
;
318 unsigned n_changes
= 0;
321 p
= strjoina(root
, "/usr/lib/systemd/system/test-default-real.target");
322 assert_se(write_string_file(p
, "# pretty much empty", WRITE_STRING_FILE_CREATE
) >= 0);
324 p
= strjoina(root
, "/usr/lib/systemd/system/test-default.target");
325 assert_se(symlink("test-default-real.target", p
) >= 0);
327 assert_se(unit_file_get_default(UNIT_FILE_SYSTEM
, root
, &def
) == -ENOENT
);
329 assert_se(unit_file_set_default(UNIT_FILE_SYSTEM
, 0, root
, "idontexist.target", &changes
, &n_changes
) == -ENOENT
);
330 assert_se(n_changes
== 1);
331 assert_se(changes
[0].type
== -ENOENT
);
332 assert_se(streq_ptr(changes
[0].path
, "idontexist.target"));
333 unit_file_changes_free(changes
, n_changes
);
334 changes
= NULL
; n_changes
= 0;
336 assert_se(unit_file_get_default(UNIT_FILE_SYSTEM
, root
, &def
) == -ENOENT
);
338 assert_se(unit_file_set_default(UNIT_FILE_SYSTEM
, 0, root
, "test-default.target", &changes
, &n_changes
) >= 0);
339 assert_se(n_changes
== 1);
340 assert_se(changes
[0].type
== UNIT_FILE_SYMLINK
);
341 assert_se(streq(changes
[0].source
, "/usr/lib/systemd/system/test-default-real.target"));
342 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/" SPECIAL_DEFAULT_TARGET
);
343 assert_se(streq(changes
[0].path
, p
));
344 unit_file_changes_free(changes
, n_changes
);
345 changes
= NULL
; n_changes
= 0;
347 assert_se(unit_file_get_default(UNIT_FILE_SYSTEM
, root
, &def
) >= 0);
348 assert_se(streq_ptr(def
, "test-default-real.target"));
351 static void test_add_dependency(const char *root
) {
352 UnitFileChange
*changes
= NULL
;
353 unsigned n_changes
= 0;
356 p
= strjoina(root
, "/usr/lib/systemd/system/real-add-dependency-test-target.target");
357 assert_se(write_string_file(p
, "# pretty much empty", WRITE_STRING_FILE_CREATE
) >= 0);
359 p
= strjoina(root
, "/usr/lib/systemd/system/add-dependency-test-target.target");
360 assert_se(symlink("real-add-dependency-test-target.target", p
) >= 0);
362 p
= strjoina(root
, "/usr/lib/systemd/system/real-add-dependency-test-service.service");
363 assert_se(write_string_file(p
, "# pretty much empty", WRITE_STRING_FILE_CREATE
) >= 0);
365 p
= strjoina(root
, "/usr/lib/systemd/system/add-dependency-test-service.service");
366 assert_se(symlink("real-add-dependency-test-service.service", p
) >= 0);
368 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);
369 assert_se(n_changes
== 1);
370 assert_se(changes
[0].type
== UNIT_FILE_SYMLINK
);
371 assert_se(streq(changes
[0].source
, "/usr/lib/systemd/system/real-add-dependency-test-service.service"));
372 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/real-add-dependency-test-target.target.wants/real-add-dependency-test-service.service");
373 assert_se(streq(changes
[0].path
, p
));
374 unit_file_changes_free(changes
, n_changes
);
375 changes
= NULL
; n_changes
= 0;
378 static void test_template_enable(const char *root
) {
379 UnitFileChange
*changes
= NULL
;
380 unsigned n_changes
= 0;
384 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template@.service", &state
) == -ENOENT
);
385 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template@def.service", &state
) == -ENOENT
);
386 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template@foo.service", &state
) == -ENOENT
);
387 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template-symlink@foo.service", &state
) == -ENOENT
);
389 p
= strjoina(root
, "/usr/lib/systemd/system/template@.service");
390 assert_se(write_string_file(p
,
392 "DefaultInstance=def\n"
393 "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE
) >= 0);
395 p
= strjoina(root
, "/usr/lib/systemd/system/template-symlink@.service");
396 assert_se(symlink("template@.service", p
) >= 0);
398 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template@.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
399 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template@def.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
400 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template@foo.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
401 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template-symlink@.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
402 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template-symlink@def.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
403 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template-symlink@foo.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
405 assert_se(unit_file_enable(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("template@.service"), &changes
, &n_changes
) >= 0);
406 assert_se(n_changes
== 1);
407 assert_se(changes
[0].type
== UNIT_FILE_SYMLINK
);
408 assert_se(streq(changes
[0].source
, "/usr/lib/systemd/system/template@.service"));
409 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/multi-user.target.wants/template@def.service");
410 assert_se(streq(changes
[0].path
, p
));
411 unit_file_changes_free(changes
, n_changes
);
412 changes
= NULL
; n_changes
= 0;
414 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template@.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
415 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template@def.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
416 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template@foo.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
417 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template-symlink@.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
418 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template-symlink@def.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
419 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template-symlink@foo.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
421 assert_se(unit_file_disable(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("template@.service"), &changes
, &n_changes
) >= 0);
422 assert_se(n_changes
== 1);
423 assert_se(changes
[0].type
== UNIT_FILE_UNLINK
);
424 assert_se(streq(changes
[0].path
, p
));
425 unit_file_changes_free(changes
, n_changes
);
426 changes
= NULL
; n_changes
= 0;
428 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template@.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
429 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template@def.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
430 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template@foo.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
431 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template-symlink@.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
432 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template-symlink@def.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
433 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template-symlink@foo.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
435 assert_se(unit_file_enable(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("template@foo.service"), &changes
, &n_changes
) >= 0);
436 assert_se(changes
[0].type
== UNIT_FILE_SYMLINK
);
437 assert_se(streq(changes
[0].source
, "/usr/lib/systemd/system/template@.service"));
438 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/multi-user.target.wants/template@foo.service");
439 assert_se(streq(changes
[0].path
, p
));
440 unit_file_changes_free(changes
, n_changes
);
441 changes
= NULL
; n_changes
= 0;
443 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template@.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
444 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template@def.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
445 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template@foo.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
446 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template-symlink@foo.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
447 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template-symlink@def.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
448 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template-symlink@foo.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
450 assert_se(unit_file_disable(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("template@foo.service"), &changes
, &n_changes
) >= 0);
451 assert_se(n_changes
== 1);
452 assert_se(changes
[0].type
== UNIT_FILE_UNLINK
);
453 assert_se(streq(changes
[0].path
, p
));
454 unit_file_changes_free(changes
, n_changes
);
455 changes
= NULL
; n_changes
= 0;
457 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template@.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
458 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template@def.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
459 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template@foo.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
460 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template@quux.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
461 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template-symlink@.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
462 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template-symlink@def.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
463 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template-symlink@foo.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
464 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template-symlink@quux.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
466 assert_se(unit_file_enable(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("template-symlink@quux.service"), &changes
, &n_changes
) >= 0);
467 assert_se(changes
[0].type
== UNIT_FILE_SYMLINK
);
468 assert_se(streq(changes
[0].source
, "/usr/lib/systemd/system/template@.service"));
469 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/multi-user.target.wants/template@quux.service");
470 assert_se(streq(changes
[0].path
, p
));
471 unit_file_changes_free(changes
, n_changes
);
472 changes
= NULL
; n_changes
= 0;
474 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template@.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
475 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template@def.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
476 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template@foo.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
477 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template@quux.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
478 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template-symlink@.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
479 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template-symlink@def.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
480 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template-symlink@foo.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
481 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "template-symlink@quux.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
484 static void test_indirect(const char *root
) {
485 UnitFileChange
*changes
= NULL
;
486 unsigned n_changes
= 0;
490 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "indirecta.service", &state
) == -ENOENT
);
491 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "indirectb.service", &state
) == -ENOENT
);
492 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "indirectc.service", &state
) == -ENOENT
);
494 p
= strjoina(root
, "/usr/lib/systemd/system/indirecta.service");
495 assert_se(write_string_file(p
,
497 "Also=indirectb.service\n", WRITE_STRING_FILE_CREATE
) >= 0);
499 p
= strjoina(root
, "/usr/lib/systemd/system/indirectb.service");
500 assert_se(write_string_file(p
,
502 "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE
) >= 0);
504 p
= strjoina(root
, "/usr/lib/systemd/system/indirectc.service");
505 assert_se(symlink("indirecta.service", p
) >= 0);
507 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "indirecta.service", &state
) >= 0 && state
== UNIT_FILE_INDIRECT
);
508 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "indirectb.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
509 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "indirectc.service", &state
) >= 0 && state
== UNIT_FILE_INDIRECT
);
511 assert_se(unit_file_enable(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("indirectc.service"), &changes
, &n_changes
) >= 0);
512 assert_se(n_changes
== 1);
513 assert_se(changes
[0].type
== UNIT_FILE_SYMLINK
);
514 assert_se(streq(changes
[0].source
, "/usr/lib/systemd/system/indirectb.service"));
515 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/multi-user.target.wants/indirectb.service");
516 assert_se(streq(changes
[0].path
, p
));
517 unit_file_changes_free(changes
, n_changes
);
518 changes
= NULL
; n_changes
= 0;
520 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "indirecta.service", &state
) >= 0 && state
== UNIT_FILE_INDIRECT
);
521 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "indirectb.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
522 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "indirectc.service", &state
) >= 0 && state
== UNIT_FILE_INDIRECT
);
524 assert_se(unit_file_disable(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("indirectc.service"), &changes
, &n_changes
) >= 0);
525 assert_se(n_changes
== 1);
526 assert_se(changes
[0].type
== UNIT_FILE_UNLINK
);
527 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/multi-user.target.wants/indirectb.service");
528 assert_se(streq(changes
[0].path
, p
));
529 unit_file_changes_free(changes
, n_changes
);
530 changes
= NULL
; n_changes
= 0;
533 static void test_preset_and_list(const char *root
) {
534 UnitFileChange
*changes
= NULL
;
535 unsigned n_changes
= 0, i
;
538 bool got_yes
= false, got_no
= false;
543 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "preset-yes.service", &state
) == -ENOENT
);
544 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "preset-no.service", &state
) == -ENOENT
);
546 p
= strjoina(root
, "/usr/lib/systemd/system/preset-yes.service");
547 assert_se(write_string_file(p
,
549 "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE
) >= 0);
551 p
= strjoina(root
, "/usr/lib/systemd/system/preset-no.service");
552 assert_se(write_string_file(p
,
554 "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE
) >= 0);
556 p
= strjoina(root
, "/usr/lib/systemd/system-preset/test.preset");
557 assert_se(write_string_file(p
,
559 "disable *\n", WRITE_STRING_FILE_CREATE
) >= 0);
561 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "preset-yes.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
562 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "preset-no.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
564 assert_se(unit_file_preset(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("preset-yes.service"), UNIT_FILE_PRESET_FULL
, &changes
, &n_changes
) >= 0);
565 assert_se(n_changes
== 1);
566 assert_se(changes
[0].type
== UNIT_FILE_SYMLINK
);
567 assert_se(streq(changes
[0].source
, "/usr/lib/systemd/system/preset-yes.service"));
568 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/multi-user.target.wants/preset-yes.service");
569 assert_se(streq(changes
[0].path
, p
));
570 unit_file_changes_free(changes
, n_changes
);
571 changes
= NULL
; n_changes
= 0;
573 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "preset-yes.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
574 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "preset-no.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
576 assert_se(unit_file_disable(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("preset-yes.service"), &changes
, &n_changes
) >= 0);
577 assert_se(n_changes
== 1);
578 assert_se(changes
[0].type
== UNIT_FILE_UNLINK
);
579 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/multi-user.target.wants/preset-yes.service");
580 assert_se(streq(changes
[0].path
, p
));
581 unit_file_changes_free(changes
, n_changes
);
582 changes
= NULL
; n_changes
= 0;
584 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "preset-yes.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
585 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "preset-no.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
587 assert_se(unit_file_preset(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("preset-no.service"), UNIT_FILE_PRESET_FULL
, &changes
, &n_changes
) >= 0);
588 assert_se(n_changes
== 0);
589 unit_file_changes_free(changes
, n_changes
);
590 changes
= NULL
; n_changes
= 0;
592 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "preset-yes.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
593 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "preset-no.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
595 assert_se(unit_file_preset_all(UNIT_FILE_SYSTEM
, 0, root
, UNIT_FILE_PRESET_FULL
, &changes
, &n_changes
) >= 0);
597 assert_se(n_changes
> 0);
599 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/multi-user.target.wants/preset-yes.service");
601 for (i
= 0; i
< n_changes
; i
++) {
603 if (changes
[i
].type
== UNIT_FILE_SYMLINK
) {
604 assert_se(streq(changes
[i
].source
, "/usr/lib/systemd/system/preset-yes.service"));
605 assert_se(streq(changes
[i
].path
, p
));
607 assert_se(changes
[i
].type
== UNIT_FILE_UNLINK
);
610 unit_file_changes_free(changes
, n_changes
);
611 changes
= NULL
; n_changes
= 0;
613 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "preset-yes.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
614 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "preset-no.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
616 assert_se(h
= hashmap_new(&string_hash_ops
));
617 assert_se(unit_file_get_list(UNIT_FILE_SYSTEM
, root
, h
, NULL
, NULL
) >= 0);
619 p
= strjoina(root
, "/usr/lib/systemd/system/preset-yes.service");
620 q
= strjoina(root
, "/usr/lib/systemd/system/preset-no.service");
622 HASHMAP_FOREACH(fl
, h
, j
) {
623 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, basename(fl
->path
), &state
) >= 0);
624 assert_se(fl
->state
== state
);
626 if (streq(fl
->path
, p
)) {
628 assert_se(fl
->state
== UNIT_FILE_ENABLED
);
629 } else if (streq(fl
->path
, q
)) {
631 assert_se(fl
->state
== UNIT_FILE_DISABLED
);
633 assert_se(IN_SET(fl
->state
, UNIT_FILE_DISABLED
, UNIT_FILE_STATIC
, UNIT_FILE_INDIRECT
));
636 unit_file_list_free(h
);
638 assert_se(got_yes
&& got_no
);
641 static void test_revert(const char *root
) {
644 UnitFileChange
*changes
= NULL
;
645 unsigned n_changes
= 0;
649 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "xx.service", NULL
) == -ENOENT
);
650 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "yy.service", NULL
) == -ENOENT
);
652 p
= strjoina(root
, "/usr/lib/systemd/system/xx.service");
653 assert_se(write_string_file(p
, "# Empty\n", WRITE_STRING_FILE_CREATE
) >= 0);
655 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "xx.service", NULL
) >= 0);
656 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "xx.service", &state
) >= 0 && state
== UNIT_FILE_STATIC
);
658 /* Initially there's nothing to revert */
659 assert_se(unit_file_revert(UNIT_FILE_SYSTEM
, root
, STRV_MAKE("xx.service"), &changes
, &n_changes
) >= 0);
660 assert_se(n_changes
== 0);
661 unit_file_changes_free(changes
, n_changes
);
662 changes
= NULL
; n_changes
= 0;
664 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/xx.service");
665 assert_se(write_string_file(p
, "# Empty override\n", WRITE_STRING_FILE_CREATE
) >= 0);
667 /* Revert the override file */
668 assert_se(unit_file_revert(UNIT_FILE_SYSTEM
, root
, STRV_MAKE("xx.service"), &changes
, &n_changes
) >= 0);
669 assert_se(n_changes
== 1);
670 assert_se(changes
[0].type
== UNIT_FILE_UNLINK
);
671 assert_se(streq(changes
[0].path
, p
));
672 unit_file_changes_free(changes
, n_changes
);
673 changes
= NULL
; n_changes
= 0;
675 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/xx.service.d/dropin.conf");
676 assert_se(mkdir_parents(p
, 0755) >= 0);
677 assert_se(write_string_file(p
, "# Empty dropin\n", WRITE_STRING_FILE_CREATE
) >= 0);
679 /* Revert the dropin file */
680 assert_se(unit_file_revert(UNIT_FILE_SYSTEM
, root
, STRV_MAKE("xx.service"), &changes
, &n_changes
) >= 0);
681 assert_se(n_changes
== 2);
682 assert_se(changes
[0].type
== UNIT_FILE_UNLINK
);
683 assert_se(streq(changes
[0].path
, p
));
685 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/xx.service.d");
686 assert_se(changes
[1].type
== UNIT_FILE_UNLINK
);
687 assert_se(streq(changes
[1].path
, p
));
688 unit_file_changes_free(changes
, n_changes
);
689 changes
= NULL
; n_changes
= 0;
692 static void test_preset_order(const char *root
) {
693 UnitFileChange
*changes
= NULL
;
694 unsigned n_changes
= 0;
698 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "prefix-1.service", &state
) == -ENOENT
);
699 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "prefix-2.service", &state
) == -ENOENT
);
701 p
= strjoina(root
, "/usr/lib/systemd/system/prefix-1.service");
702 assert_se(write_string_file(p
,
704 "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE
) >= 0);
706 p
= strjoina(root
, "/usr/lib/systemd/system/prefix-2.service");
707 assert_se(write_string_file(p
,
709 "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE
) >= 0);
711 p
= strjoina(root
, "/usr/lib/systemd/system-preset/test.preset");
712 assert_se(write_string_file(p
,
713 "enable prefix-1.service\n"
714 "disable prefix-*.service\n"
715 "enable prefix-2.service\n", WRITE_STRING_FILE_CREATE
) >= 0);
717 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "prefix-1.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
718 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "prefix-2.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
720 assert_se(unit_file_preset(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("prefix-1.service"), UNIT_FILE_PRESET_FULL
, &changes
, &n_changes
) >= 0);
721 assert_se(n_changes
== 1);
722 assert_se(changes
[0].type
== UNIT_FILE_SYMLINK
);
723 assert_se(streq(changes
[0].source
, "/usr/lib/systemd/system/prefix-1.service"));
724 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/multi-user.target.wants/prefix-1.service");
725 assert_se(streq(changes
[0].path
, p
));
726 unit_file_changes_free(changes
, n_changes
);
727 changes
= NULL
; 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
);
732 assert_se(unit_file_preset(UNIT_FILE_SYSTEM
, 0, root
, STRV_MAKE("prefix-2.service"), UNIT_FILE_PRESET_FULL
, &changes
, &n_changes
) >= 0);
733 assert_se(n_changes
== 0);
735 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "prefix-1.service", &state
) >= 0 && state
== UNIT_FILE_ENABLED
);
736 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "prefix-2.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
739 static void test_static_instance(const char *root
) {
743 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "static-instance@.service", &state
) == -ENOENT
);
744 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "static-instance@foo.service", &state
) == -ENOENT
);
746 p
= strjoina(root
, "/usr/lib/systemd/system/static-instance@.service");
747 assert_se(write_string_file(p
,
749 "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE
) >= 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_DISABLED
);
754 p
= strjoina(root
, "/usr/lib/systemd/system/static-instance@foo.service");
755 assert_se(symlink("static-instance@.service", p
) >= 0);
757 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "static-instance@.service", &state
) >= 0 && state
== UNIT_FILE_DISABLED
);
758 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM
, root
, "static-instance@foo.service", &state
) >= 0 && state
== UNIT_FILE_STATIC
);
761 int main(int argc
, char *argv
[]) {
762 char root
[] = "/tmp/rootXXXXXX";
765 assert_se(mkdtemp(root
));
767 p
= strjoina(root
, "/usr/lib/systemd/system/");
768 assert_se(mkdir_p(p
, 0755) >= 0);
770 p
= strjoina(root
, SYSTEM_CONFIG_UNIT_PATH
"/");
771 assert_se(mkdir_p(p
, 0755) >= 0);
773 p
= strjoina(root
, "/run/systemd/system/");
774 assert_se(mkdir_p(p
, 0755) >= 0);
776 p
= strjoina(root
, "/opt/");
777 assert_se(mkdir_p(p
, 0755) >= 0);
779 p
= strjoina(root
, "/usr/lib/systemd/system-preset/");
780 assert_se(mkdir_p(p
, 0755) >= 0);
782 test_basic_mask_and_enable(root
);
783 test_linked_units(root
);
785 test_add_dependency(root
);
786 test_template_enable(root
);
788 test_preset_and_list(root
);
789 test_preset_order(root
);
791 test_static_instance(root
);
793 assert_se(rm_rf(root
, REMOVE_ROOT
|REMOVE_PHYSICAL
) >= 0);