]>
Commit | Line | Data |
---|---|---|
53e1b683 | 1 | /* SPDX-License-Identifier: LGPL-2.1+ */ |
0ec0deaa | 2 | |
ca78ad1d ZJS |
3 | #include <unistd.h> |
4 | ||
0ec0deaa LP |
5 | #include "alloc-util.h" |
6 | #include "fileio.h" | |
7 | #include "install.h" | |
8 | #include "mkdir.h" | |
9 | #include "rm-rf.h" | |
075dafd2 | 10 | #include "special.h" |
0ec0deaa | 11 | #include "string-util.h" |
6d7c4033 | 12 | #include "tests.h" |
0ec0deaa LP |
13 | |
14 | static void test_basic_mask_and_enable(const char *root) { | |
15 | const char *p; | |
16 | UnitFileState state; | |
17 | UnitFileChange *changes = NULL; | |
da6053d0 | 18 | size_t n_changes = 0; |
0ec0deaa | 19 | |
6d7c4033 | 20 | test_setup_logging(LOG_DEBUG); |
198402d3 | 21 | |
0ec0deaa LP |
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); | |
26 | ||
27 | p = strjoina(root, "/usr/lib/systemd/system/a.service"); | |
28 | assert_se(write_string_file(p, | |
29 | "[Install]\n" | |
30 | "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0); | |
31 | ||
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); | |
34 | ||
35 | p = strjoina(root, "/usr/lib/systemd/system/b.service"); | |
36 | assert_se(symlink("a.service", p) >= 0); | |
37 | ||
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); | |
40 | ||
41 | p = strjoina(root, "/usr/lib/systemd/system/c.service"); | |
42 | assert_se(symlink("/usr/lib/systemd/system/a.service", p) >= 0); | |
43 | ||
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); | |
46 | ||
47 | p = strjoina(root, "/usr/lib/systemd/system/d.service"); | |
48 | assert_se(symlink("c.service", p) >= 0); | |
49 | ||
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); | |
53 | ||
b3796dd8 | 54 | assert_se(unit_file_mask(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("a.service"), &changes, &n_changes) >= 0); |
0ec0deaa LP |
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)); | |
60 | ||
61 | unit_file_changes_free(changes, n_changes); | |
62 | changes = NULL; n_changes = 0; | |
63 | ||
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); | |
68 | ||
69 | /* Enabling a masked unit should fail! */ | |
b3796dd8 | 70 | assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("a.service"), &changes, &n_changes) == -ERFKILL); |
0ec0deaa LP |
71 | unit_file_changes_free(changes, n_changes); |
72 | changes = NULL; n_changes = 0; | |
73 | ||
b3796dd8 | 74 | assert_se(unit_file_unmask(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("a.service"), &changes, &n_changes) >= 0); |
0ec0deaa LP |
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; | |
81 | ||
b3796dd8 | 82 | assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("a.service"), &changes, &n_changes) == 1); |
0ec0deaa LP |
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; | |
90 | ||
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); | |
95 | ||
96 | /* Enabling it again should succeed but be a NOP */ | |
b3796dd8 | 97 | assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("a.service"), &changes, &n_changes) >= 0); |
0ec0deaa LP |
98 | assert_se(n_changes == 0); |
99 | unit_file_changes_free(changes, n_changes); | |
100 | changes = NULL; n_changes = 0; | |
101 | ||
b3796dd8 | 102 | assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("a.service"), &changes, &n_changes) >= 0); |
0ec0deaa LP |
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; | |
109 | ||
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); | |
114 | ||
5238e957 | 115 | /* Disabling a disabled unit must succeed but be a NOP */ |
b3796dd8 | 116 | assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("a.service"), &changes, &n_changes) >= 0); |
0ec0deaa LP |
117 | assert_se(n_changes == 0); |
118 | unit_file_changes_free(changes, n_changes); | |
119 | changes = NULL; n_changes = 0; | |
120 | ||
121 | /* Let's enable this indirectly via a symlink */ | |
b3796dd8 | 122 | assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("d.service"), &changes, &n_changes) >= 0); |
0ec0deaa LP |
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; | |
130 | ||
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); | |
135 | ||
136 | /* Let's try to reenable */ | |
137 | ||
b3796dd8 | 138 | assert_se(unit_file_reenable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("b.service"), &changes, &n_changes) >= 0); |
0ec0deaa LP |
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; | |
148 | ||
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); | |
153 | } | |
154 | ||
155 | static void test_linked_units(const char *root) { | |
156 | const char *p, *q; | |
157 | UnitFileState state; | |
158 | UnitFileChange *changes = NULL; | |
da6053d0 | 159 | size_t n_changes = 0, i; |
0ec0deaa LP |
160 | |
161 | /* | |
162 | * We'll test three cases here: | |
163 | * | |
164 | * a) a unit file in /opt, that we use "systemctl link" and | |
165 | * "systemctl enable" on to make it available to the system | |
166 | * | |
167 | * b) a unit file in /opt, that is statically linked into | |
168 | * /usr/lib/systemd/system, that "enable" should work on | |
169 | * correctly. | |
170 | * | |
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. | |
175 | */ | |
176 | ||
177 | p = strjoina(root, "/opt/linked.service"); | |
178 | assert_se(write_string_file(p, | |
179 | "[Install]\n" | |
180 | "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0); | |
181 | ||
182 | p = strjoina(root, "/opt/linked2.service"); | |
183 | assert_se(write_string_file(p, | |
184 | "[Install]\n" | |
185 | "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0); | |
186 | ||
187 | p = strjoina(root, "/opt/linked3.service"); | |
188 | assert_se(write_string_file(p, | |
189 | "[Install]\n" | |
190 | "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0); | |
191 | ||
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); | |
195 | ||
196 | p = strjoina(root, "/usr/lib/systemd/system/linked2.service"); | |
197 | assert_se(symlink("/opt/linked2.service", p) >= 0); | |
198 | ||
199 | p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/linked3.service"); | |
200 | assert_se(symlink("/opt/linked3.service", p) >= 0); | |
201 | ||
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); | |
205 | ||
206 | /* First, let's link the unit into the search path */ | |
b3796dd8 | 207 | assert_se(unit_file_link(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("/opt/linked.service"), &changes, &n_changes) >= 0); |
0ec0deaa LP |
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; | |
215 | ||
216 | assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "linked.service", &state) >= 0 && state == UNIT_FILE_LINKED); | |
217 | ||
218 | /* Let's unlink it from the search path again */ | |
b3796dd8 | 219 | assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("linked.service"), &changes, &n_changes) >= 0); |
0ec0deaa LP |
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; | |
226 | ||
227 | assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "linked.service", NULL) == -ENOENT); | |
228 | ||
229 | /* Now, let's not just link it, but also enable it */ | |
b3796dd8 | 230 | assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("/opt/linked.service"), &changes, &n_changes) >= 0); |
0ec0deaa LP |
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")); | |
237 | ||
238 | if (p && streq(changes[i].path, p)) | |
239 | p = NULL; | |
240 | else if (q && streq(changes[i].path, q)) | |
241 | q = NULL; | |
242 | else | |
243 | assert_not_reached("wut?"); | |
244 | } | |
245 | assert(!p && !q); | |
246 | unit_file_changes_free(changes, n_changes); | |
247 | changes = NULL; n_changes = 0; | |
248 | ||
249 | assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "linked.service", &state) >= 0 && state == UNIT_FILE_ENABLED); | |
250 | ||
251 | /* And let's unlink it again */ | |
b3796dd8 | 252 | assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("linked.service"), &changes, &n_changes) >= 0); |
0ec0deaa LP |
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); | |
258 | ||
259 | if (p && streq(changes[i].path, p)) | |
260 | p = NULL; | |
261 | else if (q && streq(changes[i].path, q)) | |
262 | q = NULL; | |
263 | else | |
264 | assert_not_reached("wut?"); | |
265 | } | |
266 | assert(!p && !q); | |
267 | unit_file_changes_free(changes, n_changes); | |
268 | changes = NULL; n_changes = 0; | |
269 | ||
270 | assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "linked.service", NULL) == -ENOENT); | |
271 | ||
b3796dd8 | 272 | assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("linked2.service"), &changes, &n_changes) >= 0); |
0ec0deaa LP |
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")); | |
279 | ||
280 | if (p && streq(changes[i].path, p)) | |
281 | p = NULL; | |
282 | else if (q && streq(changes[i].path, q)) | |
283 | q = NULL; | |
284 | else | |
285 | assert_not_reached("wut?"); | |
286 | } | |
287 | assert(!p && !q); | |
288 | unit_file_changes_free(changes, n_changes); | |
289 | changes = NULL; n_changes = 0; | |
290 | ||
b3796dd8 | 291 | assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("linked3.service"), &changes, &n_changes) >= 0); |
f777b434 ZJS |
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")); | |
0ec0deaa LP |
297 | unit_file_changes_free(changes, n_changes); |
298 | changes = NULL; n_changes = 0; | |
299 | } | |
300 | ||
301 | static void test_default(const char *root) { | |
302 | _cleanup_free_ char *def = NULL; | |
303 | UnitFileChange *changes = NULL; | |
da6053d0 | 304 | size_t n_changes = 0; |
0ec0deaa LP |
305 | const char *p; |
306 | ||
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); | |
309 | ||
310 | p = strjoina(root, "/usr/lib/systemd/system/test-default.target"); | |
311 | assert_se(symlink("test-default-real.target", p) >= 0); | |
312 | ||
313 | assert_se(unit_file_get_default(UNIT_FILE_SYSTEM, root, &def) == -ENOENT); | |
314 | ||
b3796dd8 | 315 | assert_se(unit_file_set_default(UNIT_FILE_SYSTEM, 0, root, "idontexist.target", &changes, &n_changes) == -ENOENT); |
59108fbe ZJS |
316 | assert_se(n_changes == 1); |
317 | assert_se(changes[0].type == -ENOENT); | |
318 | assert_se(streq_ptr(changes[0].path, "idontexist.target")); | |
0ec0deaa LP |
319 | unit_file_changes_free(changes, n_changes); |
320 | changes = NULL; n_changes = 0; | |
321 | ||
322 | assert_se(unit_file_get_default(UNIT_FILE_SYSTEM, root, &def) == -ENOENT); | |
323 | ||
b3796dd8 | 324 | assert_se(unit_file_set_default(UNIT_FILE_SYSTEM, 0, root, "test-default.target", &changes, &n_changes) >= 0); |
0ec0deaa LP |
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")); | |
075dafd2 | 328 | p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH "/" SPECIAL_DEFAULT_TARGET); |
0ec0deaa LP |
329 | assert_se(streq(changes[0].path, p)); |
330 | unit_file_changes_free(changes, n_changes); | |
331 | changes = NULL; n_changes = 0; | |
332 | ||
333 | assert_se(unit_file_get_default(UNIT_FILE_SYSTEM, root, &def) >= 0); | |
334 | assert_se(streq_ptr(def, "test-default-real.target")); | |
335 | } | |
336 | ||
337 | static void test_add_dependency(const char *root) { | |
338 | UnitFileChange *changes = NULL; | |
da6053d0 | 339 | size_t n_changes = 0; |
0ec0deaa LP |
340 | const char *p; |
341 | ||
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); | |
344 | ||
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); | |
347 | ||
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); | |
350 | ||
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); | |
353 | ||
b3796dd8 | 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); |
0ec0deaa LP |
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; | |
362 | } | |
363 | ||
364 | static void test_template_enable(const char *root) { | |
365 | UnitFileChange *changes = NULL; | |
da6053d0 | 366 | size_t n_changes = 0; |
0ec0deaa LP |
367 | UnitFileState state; |
368 | const char *p; | |
369 | ||
5cd8ae31 ZJS |
370 | log_info("== %s ==", __func__); |
371 | ||
0ec0deaa LP |
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); | |
376 | ||
377 | p = strjoina(root, "/usr/lib/systemd/system/template@.service"); | |
378 | assert_se(write_string_file(p, | |
379 | "[Install]\n" | |
380 | "DefaultInstance=def\n" | |
381 | "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0); | |
382 | ||
383 | p = strjoina(root, "/usr/lib/systemd/system/template-symlink@.service"); | |
384 | assert_se(symlink("template@.service", p) >= 0); | |
385 | ||
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); | |
392 | ||
5cd8ae31 ZJS |
393 | log_info("== %s with template@.service enabled ==", __func__); |
394 | ||
b3796dd8 | 395 | assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("template@.service"), &changes, &n_changes) >= 0); |
0ec0deaa LP |
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; | |
403 | ||
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); | |
410 | ||
b3796dd8 | 411 | assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("template@.service"), &changes, &n_changes) >= 0); |
0ec0deaa LP |
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; | |
417 | ||
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); | |
424 | ||
5cd8ae31 ZJS |
425 | log_info("== %s with template@foo.service enabled ==", __func__); |
426 | ||
b3796dd8 | 427 | assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("template@foo.service"), &changes, &n_changes) >= 0); |
0ec0deaa LP |
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; | |
434 | ||
d9b4b48f | 435 | assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@.service", &state) >= 0 && state == UNIT_FILE_INDIRECT); |
0ec0deaa LP |
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); | |
441 | ||
b3796dd8 | 442 | assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("template@foo.service"), &changes, &n_changes) >= 0); |
0ec0deaa LP |
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; | |
448 | ||
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); | |
457 | ||
5cd8ae31 ZJS |
458 | log_info("== %s with template-symlink@quux.service enabled ==", __func__); |
459 | ||
b3796dd8 | 460 | assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("template-symlink@quux.service"), &changes, &n_changes) >= 0); |
0ec0deaa LP |
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; | |
467 | ||
d9b4b48f | 468 | assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@.service", &state) >= 0 && state == UNIT_FILE_INDIRECT); |
0ec0deaa LP |
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); | |
d9b4b48f | 472 | assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@.service", &state) >= 0 && state == UNIT_FILE_INDIRECT); |
0ec0deaa LP |
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); | |
476 | } | |
477 | ||
478 | static void test_indirect(const char *root) { | |
479 | UnitFileChange *changes = NULL; | |
da6053d0 | 480 | size_t n_changes = 0; |
0ec0deaa LP |
481 | UnitFileState state; |
482 | const char *p; | |
483 | ||
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); | |
487 | ||
488 | p = strjoina(root, "/usr/lib/systemd/system/indirecta.service"); | |
489 | assert_se(write_string_file(p, | |
490 | "[Install]\n" | |
491 | "Also=indirectb.service\n", WRITE_STRING_FILE_CREATE) >= 0); | |
492 | ||
493 | p = strjoina(root, "/usr/lib/systemd/system/indirectb.service"); | |
494 | assert_se(write_string_file(p, | |
495 | "[Install]\n" | |
496 | "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0); | |
497 | ||
498 | p = strjoina(root, "/usr/lib/systemd/system/indirectc.service"); | |
499 | assert_se(symlink("indirecta.service", p) >= 0); | |
500 | ||
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); | |
504 | ||
b3796dd8 | 505 | assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("indirectc.service"), &changes, &n_changes) >= 0); |
0ec0deaa LP |
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; | |
513 | ||
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); | |
517 | ||
b3796dd8 | 518 | assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("indirectc.service"), &changes, &n_changes) >= 0); |
0ec0deaa LP |
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; | |
525 | } | |
526 | ||
527 | static void test_preset_and_list(const char *root) { | |
528 | UnitFileChange *changes = NULL; | |
da6053d0 | 529 | size_t n_changes = 0, i; |
0ec0deaa LP |
530 | const char *p, *q; |
531 | UnitFileState state; | |
532 | bool got_yes = false, got_no = false; | |
533 | Iterator j; | |
534 | UnitFileList *fl; | |
535 | Hashmap *h; | |
536 | ||
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); | |
539 | ||
540 | p = strjoina(root, "/usr/lib/systemd/system/preset-yes.service"); | |
541 | assert_se(write_string_file(p, | |
542 | "[Install]\n" | |
543 | "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0); | |
544 | ||
545 | p = strjoina(root, "/usr/lib/systemd/system/preset-no.service"); | |
546 | assert_se(write_string_file(p, | |
547 | "[Install]\n" | |
548 | "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0); | |
549 | ||
550 | p = strjoina(root, "/usr/lib/systemd/system-preset/test.preset"); | |
551 | assert_se(write_string_file(p, | |
552 | "enable *-yes.*\n" | |
553 | "disable *\n", WRITE_STRING_FILE_CREATE) >= 0); | |
554 | ||
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); | |
557 | ||
b3796dd8 | 558 | assert_se(unit_file_preset(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("preset-yes.service"), UNIT_FILE_PRESET_FULL, &changes, &n_changes) >= 0); |
0ec0deaa LP |
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; | |
566 | ||
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); | |
569 | ||
b3796dd8 | 570 | assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("preset-yes.service"), &changes, &n_changes) >= 0); |
0ec0deaa LP |
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; | |
577 | ||
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); | |
580 | ||
b3796dd8 | 581 | assert_se(unit_file_preset(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("preset-no.service"), UNIT_FILE_PRESET_FULL, &changes, &n_changes) >= 0); |
0ec0deaa LP |
582 | assert_se(n_changes == 0); |
583 | unit_file_changes_free(changes, n_changes); | |
584 | changes = NULL; n_changes = 0; | |
585 | ||
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); | |
588 | ||
b3796dd8 | 589 | assert_se(unit_file_preset_all(UNIT_FILE_SYSTEM, 0, root, UNIT_FILE_PRESET_FULL, &changes, &n_changes) >= 0); |
0ec0deaa LP |
590 | |
591 | assert_se(n_changes > 0); | |
592 | ||
593 | p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/preset-yes.service"); | |
594 | ||
595 | for (i = 0; i < n_changes; i++) { | |
596 | ||
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)); | |
600 | } else | |
601 | assert_se(changes[i].type == UNIT_FILE_UNLINK); | |
602 | } | |
603 | ||
604 | unit_file_changes_free(changes, n_changes); | |
605 | changes = NULL; n_changes = 0; | |
606 | ||
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); | |
609 | ||
610 | assert_se(h = hashmap_new(&string_hash_ops)); | |
313fe66f | 611 | assert_se(unit_file_get_list(UNIT_FILE_SYSTEM, root, h, NULL, NULL) >= 0); |
0ec0deaa LP |
612 | |
613 | p = strjoina(root, "/usr/lib/systemd/system/preset-yes.service"); | |
614 | q = strjoina(root, "/usr/lib/systemd/system/preset-no.service"); | |
615 | ||
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); | |
619 | ||
620 | if (streq(fl->path, p)) { | |
621 | got_yes = true; | |
622 | assert_se(fl->state == UNIT_FILE_ENABLED); | |
623 | } else if (streq(fl->path, q)) { | |
624 | got_no = true; | |
625 | assert_se(fl->state == UNIT_FILE_DISABLED); | |
626 | } else | |
627 | assert_se(IN_SET(fl->state, UNIT_FILE_DISABLED, UNIT_FILE_STATIC, UNIT_FILE_INDIRECT)); | |
628 | } | |
629 | ||
630 | unit_file_list_free(h); | |
631 | ||
632 | assert_se(got_yes && got_no); | |
633 | } | |
634 | ||
344ca755 LP |
635 | static void test_revert(const char *root) { |
636 | const char *p; | |
637 | UnitFileState state; | |
638 | UnitFileChange *changes = NULL; | |
da6053d0 | 639 | size_t n_changes = 0; |
344ca755 LP |
640 | |
641 | assert(root); | |
642 | ||
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); | |
645 | ||
646 | p = strjoina(root, "/usr/lib/systemd/system/xx.service"); | |
647 | assert_se(write_string_file(p, "# Empty\n", WRITE_STRING_FILE_CREATE) >= 0); | |
648 | ||
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); | |
651 | ||
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; | |
657 | ||
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); | |
660 | ||
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; | |
668 | ||
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); | |
672 | ||
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)); | |
678 | ||
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; | |
684 | } | |
685 | ||
622d3705 AC |
686 | static void test_preset_order(const char *root) { |
687 | UnitFileChange *changes = NULL; | |
da6053d0 | 688 | size_t n_changes = 0; |
622d3705 AC |
689 | const char *p; |
690 | UnitFileState state; | |
691 | ||
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); | |
694 | ||
695 | p = strjoina(root, "/usr/lib/systemd/system/prefix-1.service"); | |
696 | assert_se(write_string_file(p, | |
697 | "[Install]\n" | |
698 | "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0); | |
699 | ||
700 | p = strjoina(root, "/usr/lib/systemd/system/prefix-2.service"); | |
701 | assert_se(write_string_file(p, | |
702 | "[Install]\n" | |
703 | "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0); | |
704 | ||
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); | |
710 | ||
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); | |
713 | ||
b3796dd8 | 714 | assert_se(unit_file_preset(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("prefix-1.service"), UNIT_FILE_PRESET_FULL, &changes, &n_changes) >= 0); |
622d3705 AC |
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; | |
722 | ||
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); | |
725 | ||
b3796dd8 | 726 | assert_se(unit_file_preset(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("prefix-2.service"), UNIT_FILE_PRESET_FULL, &changes, &n_changes) >= 0); |
622d3705 AC |
727 | assert_se(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 | ||
dfead90d LP |
733 | static void test_static_instance(const char *root) { |
734 | UnitFileState state; | |
735 | const char *p; | |
736 | ||
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); | |
739 | ||
740 | p = strjoina(root, "/usr/lib/systemd/system/static-instance@.service"); | |
741 | assert_se(write_string_file(p, | |
742 | "[Install]\n" | |
743 | "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0); | |
744 | ||
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); | |
747 | ||
748 | p = strjoina(root, "/usr/lib/systemd/system/static-instance@foo.service"); | |
749 | assert_se(symlink("static-instance@.service", p) >= 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_STATIC); | |
753 | } | |
754 | ||
142468d8 JL |
755 | static void test_with_dropin(const char *root) { |
756 | const char *p; | |
757 | UnitFileState state; | |
758 | UnitFileChange *changes = NULL; | |
da6053d0 | 759 | size_t n_changes = 0; |
142468d8 JL |
760 | |
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); | |
766 | ||
767 | p = strjoina(root, "/usr/lib/systemd/system/with-dropin-1.service"); | |
768 | assert_se(write_string_file(p, | |
769 | "[Install]\n" | |
770 | "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0); | |
771 | ||
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, | |
775 | "[Install]\n" | |
776 | "WantedBy=graphical.target\n", WRITE_STRING_FILE_CREATE) >= 0); | |
777 | ||
778 | assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-1.service", &state) >= 0 && state == UNIT_FILE_DISABLED); | |
779 | ||
780 | p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/with-dropin-2.service"); | |
781 | assert_se(write_string_file(p, | |
782 | "[Install]\n" | |
783 | "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0); | |
784 | ||
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, | |
788 | "[Install]\n" | |
789 | "WantedBy=graphical.target\n", WRITE_STRING_FILE_CREATE) >= 0); | |
790 | ||
791 | assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-2.service", &state) >= 0 && state == UNIT_FILE_DISABLED); | |
792 | ||
793 | p = strjoina(root, "/usr/lib/systemd/system/with-dropin-3.service"); | |
794 | assert_se(write_string_file(p, | |
795 | "[Install]\n" | |
796 | "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0); | |
797 | ||
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, | |
801 | "[Install]\n" | |
802 | "WantedBy=graphical.target\n", WRITE_STRING_FILE_CREATE) >= 0); | |
803 | ||
804 | assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-3.service", &state) >= 0 && state == UNIT_FILE_DISABLED); | |
805 | ||
806 | p = strjoina(root, "/usr/lib/systemd/system/with-dropin-4a.service"); | |
807 | assert_se(write_string_file(p, | |
808 | "[Install]\n" | |
809 | "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0); | |
810 | ||
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, | |
814 | "[Install]\n" | |
815 | "Also=with-dropin-4b.service\n", WRITE_STRING_FILE_CREATE) >= 0); | |
816 | ||
817 | assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-4a.service", &state) >= 0 && state == UNIT_FILE_DISABLED); | |
818 | ||
819 | p = strjoina(root, "/usr/lib/systemd/system/with-dropin-4b.service"); | |
820 | assert_se(write_string_file(p, | |
821 | "[Install]\n" | |
822 | "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0); | |
823 | ||
824 | assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-4b.service", &state) >= 0 && state == UNIT_FILE_DISABLED); | |
825 | ||
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; | |
838 | ||
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; | |
852 | ||
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; | |
866 | ||
459500a3 | 867 | assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("with-dropin-4a.service"), &changes, &n_changes) == 2); |
142468d8 JL |
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; | |
880 | ||
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); | |
886 | } | |
887 | ||
888 | static void test_with_dropin_template(const char *root) { | |
889 | const char *p; | |
890 | UnitFileState state; | |
891 | UnitFileChange *changes = NULL; | |
da6053d0 | 892 | size_t n_changes = 0; |
142468d8 JL |
893 | |
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); | |
897 | ||
898 | p = strjoina(root, "/usr/lib/systemd/system/with-dropin-1@.service"); | |
899 | assert_se(write_string_file(p, | |
900 | "[Install]\n" | |
901 | "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0); | |
902 | ||
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, | |
906 | "[Install]\n" | |
907 | "WantedBy=graphical.target\n", WRITE_STRING_FILE_CREATE) >= 0); | |
908 | ||
909 | assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-1@.service", &state) >= 0 && state == UNIT_FILE_DISABLED); | |
910 | ||
911 | p = strjoina(root, "/usr/lib/systemd/system/with-dropin-2@.service"); | |
912 | assert_se(write_string_file(p, | |
913 | "[Install]\n" | |
914 | "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0); | |
915 | ||
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, | |
919 | "[Install]\n" | |
920 | "WantedBy=graphical.target\n", WRITE_STRING_FILE_CREATE) >= 0); | |
921 | ||
922 | assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-2@.service", &state) >= 0 && state == UNIT_FILE_DISABLED); | |
923 | ||
924 | p = strjoina(root, "/usr/lib/systemd/system/with-dropin-3@.service"); | |
925 | assert_se(write_string_file(p, | |
926 | "[Install]\n" | |
927 | "DefaultInstance=instance-1\n" | |
928 | "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0); | |
929 | ||
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, | |
933 | "[Install]\n" | |
934 | "DefaultInstance=instance-2\n", WRITE_STRING_FILE_CREATE) >= 0); | |
935 | ||
936 | assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-3@.service", &state) >= 0 && state == UNIT_FILE_DISABLED); | |
937 | ||
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; | |
950 | ||
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; | |
963 | ||
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; | |
972 | ||
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; | |
981 | ||
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); | |
987 | } | |
988 | ||
4c9565ee RB |
989 | static void test_preset_multiple_instances(const char *root) { |
990 | UnitFileChange *changes = NULL; | |
991 | size_t n_changes = 0; | |
992 | const char *p; | |
993 | UnitFileState state; | |
994 | ||
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, | |
998 | "[Install]\n" | |
999 | "DefaultInstance=def\n" | |
1000 | "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0); | |
1001 | ||
1002 | assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "foo@.service", &state) >= 0 && state == UNIT_FILE_DISABLED); | |
1003 | ||
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); | |
1009 | ||
1010 | assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "foo@bar0.service", &state) >= 0 && state == UNIT_FILE_DISABLED); | |
1011 | ||
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; | |
1021 | ||
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; | |
1029 | ||
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); | |
1034 | ||
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); | |
1037 | ||
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); | |
1042 | ||
efa14636 | 1043 | unit_file_changes_free(changes, n_changes); |
4c9565ee RB |
1044 | } |
1045 | ||
0ec0deaa LP |
1046 | int main(int argc, char *argv[]) { |
1047 | char root[] = "/tmp/rootXXXXXX"; | |
1048 | const char *p; | |
1049 | ||
1050 | assert_se(mkdtemp(root)); | |
1051 | ||
1052 | p = strjoina(root, "/usr/lib/systemd/system/"); | |
1053 | assert_se(mkdir_p(p, 0755) >= 0); | |
1054 | ||
1055 | p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/"); | |
1056 | assert_se(mkdir_p(p, 0755) >= 0); | |
1057 | ||
1058 | p = strjoina(root, "/run/systemd/system/"); | |
1059 | assert_se(mkdir_p(p, 0755) >= 0); | |
1060 | ||
1061 | p = strjoina(root, "/opt/"); | |
1062 | assert_se(mkdir_p(p, 0755) >= 0); | |
1063 | ||
1064 | p = strjoina(root, "/usr/lib/systemd/system-preset/"); | |
1065 | assert_se(mkdir_p(p, 0755) >= 0); | |
1066 | ||
1067 | test_basic_mask_and_enable(root); | |
1068 | test_linked_units(root); | |
1069 | test_default(root); | |
1070 | test_add_dependency(root); | |
1071 | test_template_enable(root); | |
1072 | test_indirect(root); | |
1073 | test_preset_and_list(root); | |
622d3705 | 1074 | test_preset_order(root); |
4c9565ee | 1075 | test_preset_multiple_instances(root); |
344ca755 | 1076 | test_revert(root); |
dfead90d | 1077 | test_static_instance(root); |
142468d8 JL |
1078 | test_with_dropin(root); |
1079 | test_with_dropin_template(root); | |
0ec0deaa LP |
1080 | |
1081 | assert_se(rm_rf(root, REMOVE_ROOT|REMOVE_PHYSICAL) >= 0); | |
1082 | ||
1083 | return 0; | |
1084 | } |