]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/test/test-install-root.c
Merge pull request #6367 from keszybz/enable-tpm
[thirdparty/systemd.git] / src / test / test-install-root.c
1 /***
2 This file is part of systemd.
3
4 Copyright 2011 Lennart Poettering
5
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.
10
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.
15
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/>.
18 ***/
19
20 #include "alloc-util.h"
21 #include "fileio.h"
22 #include "install.h"
23 #include "mkdir.h"
24 #include "rm-rf.h"
25 #include "special.h"
26 #include "string-util.h"
27
28 static void test_basic_mask_and_enable(const char *root) {
29 const char *p;
30 UnitFileState state;
31 UnitFileChange *changes = NULL;
32 unsigned n_changes = 0;
33
34 log_set_max_level(LOG_DEBUG);
35
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);
40
41 p = strjoina(root, "/usr/lib/systemd/system/a.service");
42 assert_se(write_string_file(p,
43 "[Install]\n"
44 "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0);
45
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);
48
49 p = strjoina(root, "/usr/lib/systemd/system/b.service");
50 assert_se(symlink("a.service", p) >= 0);
51
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);
54
55 p = strjoina(root, "/usr/lib/systemd/system/c.service");
56 assert_se(symlink("/usr/lib/systemd/system/a.service", p) >= 0);
57
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);
60
61 p = strjoina(root, "/usr/lib/systemd/system/d.service");
62 assert_se(symlink("c.service", p) >= 0);
63
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);
67
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));
74
75 unit_file_changes_free(changes, n_changes);
76 changes = NULL; n_changes = 0;
77
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);
82
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;
87
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;
95
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;
104
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);
109
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;
115
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;
123
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);
128
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;
134
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;
144
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);
149
150 /* Let's try to reenable */
151
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;
162
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);
167 }
168
169 static void test_linked_units(const char *root) {
170 const char *p, *q;
171 UnitFileState state;
172 UnitFileChange *changes = NULL;
173 unsigned n_changes = 0, i;
174
175 /*
176 * We'll test three cases here:
177 *
178 * a) a unit file in /opt, that we use "systemctl link" and
179 * "systemctl enable" on to make it available to the system
180 *
181 * b) a unit file in /opt, that is statically linked into
182 * /usr/lib/systemd/system, that "enable" should work on
183 * correctly.
184 *
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.
189 */
190
191 p = strjoina(root, "/opt/linked.service");
192 assert_se(write_string_file(p,
193 "[Install]\n"
194 "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0);
195
196 p = strjoina(root, "/opt/linked2.service");
197 assert_se(write_string_file(p,
198 "[Install]\n"
199 "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0);
200
201 p = strjoina(root, "/opt/linked3.service");
202 assert_se(write_string_file(p,
203 "[Install]\n"
204 "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0);
205
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);
209
210 p = strjoina(root, "/usr/lib/systemd/system/linked2.service");
211 assert_se(symlink("/opt/linked2.service", p) >= 0);
212
213 p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/linked3.service");
214 assert_se(symlink("/opt/linked3.service", p) >= 0);
215
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);
219
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;
229
230 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "linked.service", &state) >= 0 && state == UNIT_FILE_LINKED);
231
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;
240
241 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "linked.service", NULL) == -ENOENT);
242
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"));
251
252 if (p && streq(changes[i].path, p))
253 p = NULL;
254 else if (q && streq(changes[i].path, q))
255 q = NULL;
256 else
257 assert_not_reached("wut?");
258 }
259 assert(!p && !q);
260 unit_file_changes_free(changes, n_changes);
261 changes = NULL; n_changes = 0;
262
263 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "linked.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
264
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);
272
273 if (p && streq(changes[i].path, p))
274 p = NULL;
275 else if (q && streq(changes[i].path, q))
276 q = NULL;
277 else
278 assert_not_reached("wut?");
279 }
280 assert(!p && !q);
281 unit_file_changes_free(changes, n_changes);
282 changes = NULL; n_changes = 0;
283
284 assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "linked.service", NULL) == -ENOENT);
285
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"));
293
294 if (p && streq(changes[i].path, p))
295 p = NULL;
296 else if (q && streq(changes[i].path, q))
297 q = NULL;
298 else
299 assert_not_reached("wut?");
300 }
301 assert(!p && !q);
302 unit_file_changes_free(changes, n_changes);
303 changes = NULL; n_changes = 0;
304
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;
313 }
314
315 static void test_default(const char *root) {
316 _cleanup_free_ char *def = NULL;
317 UnitFileChange *changes = NULL;
318 unsigned n_changes = 0;
319 const char *p;
320
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);
323
324 p = strjoina(root, "/usr/lib/systemd/system/test-default.target");
325 assert_se(symlink("test-default-real.target", p) >= 0);
326
327 assert_se(unit_file_get_default(UNIT_FILE_SYSTEM, root, &def) == -ENOENT);
328
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;
335
336 assert_se(unit_file_get_default(UNIT_FILE_SYSTEM, root, &def) == -ENOENT);
337
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;
346
347 assert_se(unit_file_get_default(UNIT_FILE_SYSTEM, root, &def) >= 0);
348 assert_se(streq_ptr(def, "test-default-real.target"));
349 }
350
351 static void test_add_dependency(const char *root) {
352 UnitFileChange *changes = NULL;
353 unsigned n_changes = 0;
354 const char *p;
355
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);
358
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);
361
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);
364
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);
367
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;
376 }
377
378 static void test_template_enable(const char *root) {
379 UnitFileChange *changes = NULL;
380 unsigned n_changes = 0;
381 UnitFileState state;
382 const char *p;
383
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);
388
389 p = strjoina(root, "/usr/lib/systemd/system/template@.service");
390 assert_se(write_string_file(p,
391 "[Install]\n"
392 "DefaultInstance=def\n"
393 "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0);
394
395 p = strjoina(root, "/usr/lib/systemd/system/template-symlink@.service");
396 assert_se(symlink("template@.service", p) >= 0);
397
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);
404
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;
413
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);
420
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;
427
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);
434
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;
442
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);
449
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;
456
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);
465
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;
473
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);
482 }
483
484 static void test_indirect(const char *root) {
485 UnitFileChange *changes = NULL;
486 unsigned n_changes = 0;
487 UnitFileState state;
488 const char *p;
489
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);
493
494 p = strjoina(root, "/usr/lib/systemd/system/indirecta.service");
495 assert_se(write_string_file(p,
496 "[Install]\n"
497 "Also=indirectb.service\n", WRITE_STRING_FILE_CREATE) >= 0);
498
499 p = strjoina(root, "/usr/lib/systemd/system/indirectb.service");
500 assert_se(write_string_file(p,
501 "[Install]\n"
502 "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0);
503
504 p = strjoina(root, "/usr/lib/systemd/system/indirectc.service");
505 assert_se(symlink("indirecta.service", p) >= 0);
506
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);
510
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;
519
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);
523
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;
531 }
532
533 static void test_preset_and_list(const char *root) {
534 UnitFileChange *changes = NULL;
535 unsigned n_changes = 0, i;
536 const char *p, *q;
537 UnitFileState state;
538 bool got_yes = false, got_no = false;
539 Iterator j;
540 UnitFileList *fl;
541 Hashmap *h;
542
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);
545
546 p = strjoina(root, "/usr/lib/systemd/system/preset-yes.service");
547 assert_se(write_string_file(p,
548 "[Install]\n"
549 "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0);
550
551 p = strjoina(root, "/usr/lib/systemd/system/preset-no.service");
552 assert_se(write_string_file(p,
553 "[Install]\n"
554 "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0);
555
556 p = strjoina(root, "/usr/lib/systemd/system-preset/test.preset");
557 assert_se(write_string_file(p,
558 "enable *-yes.*\n"
559 "disable *\n", WRITE_STRING_FILE_CREATE) >= 0);
560
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);
563
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;
572
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);
575
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;
583
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);
586
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;
591
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);
594
595 assert_se(unit_file_preset_all(UNIT_FILE_SYSTEM, 0, root, UNIT_FILE_PRESET_FULL, &changes, &n_changes) >= 0);
596
597 assert_se(n_changes > 0);
598
599 p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/preset-yes.service");
600
601 for (i = 0; i < n_changes; i++) {
602
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));
606 } else
607 assert_se(changes[i].type == UNIT_FILE_UNLINK);
608 }
609
610 unit_file_changes_free(changes, n_changes);
611 changes = NULL; n_changes = 0;
612
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);
615
616 assert_se(h = hashmap_new(&string_hash_ops));
617 assert_se(unit_file_get_list(UNIT_FILE_SYSTEM, root, h, NULL, NULL) >= 0);
618
619 p = strjoina(root, "/usr/lib/systemd/system/preset-yes.service");
620 q = strjoina(root, "/usr/lib/systemd/system/preset-no.service");
621
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);
625
626 if (streq(fl->path, p)) {
627 got_yes = true;
628 assert_se(fl->state == UNIT_FILE_ENABLED);
629 } else if (streq(fl->path, q)) {
630 got_no = true;
631 assert_se(fl->state == UNIT_FILE_DISABLED);
632 } else
633 assert_se(IN_SET(fl->state, UNIT_FILE_DISABLED, UNIT_FILE_STATIC, UNIT_FILE_INDIRECT));
634 }
635
636 unit_file_list_free(h);
637
638 assert_se(got_yes && got_no);
639 }
640
641 static void test_revert(const char *root) {
642 const char *p;
643 UnitFileState state;
644 UnitFileChange *changes = NULL;
645 unsigned n_changes = 0;
646
647 assert(root);
648
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);
651
652 p = strjoina(root, "/usr/lib/systemd/system/xx.service");
653 assert_se(write_string_file(p, "# Empty\n", WRITE_STRING_FILE_CREATE) >= 0);
654
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);
657
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;
663
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);
666
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;
674
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);
678
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));
684
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;
690 }
691
692 static void test_preset_order(const char *root) {
693 UnitFileChange *changes = NULL;
694 unsigned n_changes = 0;
695 const char *p;
696 UnitFileState state;
697
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);
700
701 p = strjoina(root, "/usr/lib/systemd/system/prefix-1.service");
702 assert_se(write_string_file(p,
703 "[Install]\n"
704 "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0);
705
706 p = strjoina(root, "/usr/lib/systemd/system/prefix-2.service");
707 assert_se(write_string_file(p,
708 "[Install]\n"
709 "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0);
710
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);
716
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);
719
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;
728
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);
731
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);
734
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);
737 }
738
739 static void test_static_instance(const char *root) {
740 UnitFileState state;
741 const char *p;
742
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);
745
746 p = strjoina(root, "/usr/lib/systemd/system/static-instance@.service");
747 assert_se(write_string_file(p,
748 "[Install]\n"
749 "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0);
750
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);
753
754 p = strjoina(root, "/usr/lib/systemd/system/static-instance@foo.service");
755 assert_se(symlink("static-instance@.service", p) >= 0);
756
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);
759 }
760
761 int main(int argc, char *argv[]) {
762 char root[] = "/tmp/rootXXXXXX";
763 const char *p;
764
765 assert_se(mkdtemp(root));
766
767 p = strjoina(root, "/usr/lib/systemd/system/");
768 assert_se(mkdir_p(p, 0755) >= 0);
769
770 p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/");
771 assert_se(mkdir_p(p, 0755) >= 0);
772
773 p = strjoina(root, "/run/systemd/system/");
774 assert_se(mkdir_p(p, 0755) >= 0);
775
776 p = strjoina(root, "/opt/");
777 assert_se(mkdir_p(p, 0755) >= 0);
778
779 p = strjoina(root, "/usr/lib/systemd/system-preset/");
780 assert_se(mkdir_p(p, 0755) >= 0);
781
782 test_basic_mask_and_enable(root);
783 test_linked_units(root);
784 test_default(root);
785 test_add_dependency(root);
786 test_template_enable(root);
787 test_indirect(root);
788 test_preset_and_list(root);
789 test_preset_order(root);
790 test_revert(root);
791 test_static_instance(root);
792
793 assert_se(rm_rf(root, REMOVE_ROOT|REMOVE_PHYSICAL) >= 0);
794
795 return 0;
796 }