]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/test/test-execute.c
Merge pull request #7540 from fbuihuu/systemd-delta-tweaks
[thirdparty/systemd.git] / src / test / test-execute.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2 /***
3 This file is part of systemd.
4
5 Copyright 2014 Ronny Chevalier
6
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
11
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
19 ***/
20
21 #include <grp.h>
22 #include <pwd.h>
23 #include <stdio.h>
24 #include <sys/prctl.h>
25 #include <sys/types.h>
26
27 #include "cpu-set-util.h"
28 #include "errno-list.h"
29 #include "fileio.h"
30 #include "fs-util.h"
31 #include "macro.h"
32 #include "manager.h"
33 #include "mkdir.h"
34 #include "path-util.h"
35 #include "rm-rf.h"
36 #if HAVE_SECCOMP
37 #include "seccomp-util.h"
38 #endif
39 #include "stat-util.h"
40 #include "test-helper.h"
41 #include "tests.h"
42 #include "unit.h"
43 #include "util.h"
44 #include "virt.h"
45
46 typedef void (*test_function_t)(Manager *m);
47
48 static void check(Manager *m, Unit *unit, int status_expected, int code_expected) {
49 Service *service = NULL;
50 usec_t ts;
51 usec_t timeout = 2 * USEC_PER_MINUTE;
52
53 assert_se(m);
54 assert_se(unit);
55
56 service = SERVICE(unit);
57 printf("%s\n", unit->id);
58 exec_context_dump(&service->exec_context, stdout, "\t");
59 ts = now(CLOCK_MONOTONIC);
60 while (!IN_SET(service->state, SERVICE_DEAD, SERVICE_FAILED)) {
61 int r;
62 usec_t n;
63
64 r = sd_event_run(m->event, 100 * USEC_PER_MSEC);
65 assert_se(r >= 0);
66
67 n = now(CLOCK_MONOTONIC);
68 if (ts + timeout < n) {
69 log_error("Test timeout when testing %s", unit->id);
70 exit(EXIT_FAILURE);
71 }
72 }
73 exec_status_dump(&service->main_exec_status, stdout, "\t");
74 assert_se(service->main_exec_status.status == status_expected);
75 assert_se(service->main_exec_status.code == code_expected);
76 }
77
78 static bool is_inaccessible_available(void) {
79 char *p;
80
81 FOREACH_STRING(p,
82 "/run/systemd/inaccessible/reg",
83 "/run/systemd/inaccessible/dir",
84 "/run/systemd/inaccessible/chr",
85 "/run/systemd/inaccessible/blk",
86 "/run/systemd/inaccessible/fifo",
87 "/run/systemd/inaccessible/sock"
88 ) {
89 if (access(p, F_OK) < 0)
90 return false;
91 }
92
93 return true;
94 }
95
96 static void test(Manager *m, const char *unit_name, int status_expected, int code_expected) {
97 Unit *unit;
98
99 assert_se(unit_name);
100
101 assert_se(manager_load_unit(m, unit_name, NULL, NULL, &unit) >= 0);
102 assert_se(UNIT_VTABLE(unit)->start(unit) >= 0);
103 check(m, unit, status_expected, code_expected);
104 }
105
106 static void test_exec_bindpaths(Manager *m) {
107 assert_se(mkdir_p("/tmp/test-exec-bindpaths", 0755) >= 0);
108 assert_se(mkdir_p("/tmp/test-exec-bindreadonlypaths", 0755) >= 0);
109
110 test(m, "exec-bindpaths.service", 0, CLD_EXITED);
111
112 (void) rm_rf("/tmp/test-exec-bindpaths", REMOVE_ROOT|REMOVE_PHYSICAL);
113 (void) rm_rf("/tmp/test-exec-bindreadonlypaths", REMOVE_ROOT|REMOVE_PHYSICAL);
114 }
115
116 static void test_exec_cpuaffinity(Manager *m) {
117 _cleanup_cpu_free_ cpu_set_t *c = NULL;
118 unsigned n;
119
120 assert_se(c = cpu_set_malloc(&n));
121 assert_se(sched_getaffinity(0, CPU_ALLOC_SIZE(n), c) >= 0);
122
123 if (CPU_ISSET_S(0, CPU_ALLOC_SIZE(n), c) == 0) {
124 log_notice("Cannot use CPU 0, skipping %s", __func__);
125 return;
126 }
127
128 test(m, "exec-cpuaffinity1.service", 0, CLD_EXITED);
129 test(m, "exec-cpuaffinity2.service", 0, CLD_EXITED);
130
131 if (CPU_ISSET_S(1, CPU_ALLOC_SIZE(n), c) == 0 ||
132 CPU_ISSET_S(2, CPU_ALLOC_SIZE(n), c) == 0) {
133 log_notice("Cannot use CPU 1 or 2, skipping remaining tests in %s", __func__);
134 return;
135 }
136
137 test(m, "exec-cpuaffinity3.service", 0, CLD_EXITED);
138 }
139
140 static void test_exec_workingdirectory(Manager *m) {
141 assert_se(mkdir_p("/tmp/test-exec_workingdirectory", 0755) >= 0);
142
143 test(m, "exec-workingdirectory.service", 0, CLD_EXITED);
144
145 (void) rm_rf("/tmp/test-exec_workingdirectory", REMOVE_ROOT|REMOVE_PHYSICAL);
146 }
147
148 static void test_exec_personality(Manager *m) {
149 #if defined(__x86_64__)
150 test(m, "exec-personality-x86-64.service", 0, CLD_EXITED);
151
152 #elif defined(__s390__)
153 test(m, "exec-personality-s390.service", 0, CLD_EXITED);
154
155 #elif defined(__powerpc64__)
156 # if __BYTE_ORDER == __BIG_ENDIAN
157 test(m, "exec-personality-ppc64.service", 0, CLD_EXITED);
158 # else
159 test(m, "exec-personality-ppc64le.service", 0, CLD_EXITED);
160 # endif
161
162 #elif defined(__aarch64__)
163 test(m, "exec-personality-aarch64.service", 0, CLD_EXITED);
164
165 #elif defined(__i386__)
166 test(m, "exec-personality-x86.service", 0, CLD_EXITED);
167 #else
168 log_notice("Unknown personality, skipping %s", __func__);
169 #endif
170 }
171
172 static void test_exec_ignoresigpipe(Manager *m) {
173 test(m, "exec-ignoresigpipe-yes.service", 0, CLD_EXITED);
174 test(m, "exec-ignoresigpipe-no.service", SIGPIPE, CLD_KILLED);
175 }
176
177 static void test_exec_privatetmp(Manager *m) {
178 assert_se(touch("/tmp/test-exec_privatetmp") >= 0);
179
180 test(m, "exec-privatetmp-yes.service", 0, CLD_EXITED);
181 test(m, "exec-privatetmp-no.service", 0, CLD_EXITED);
182
183 unlink("/tmp/test-exec_privatetmp");
184 }
185
186 static void test_exec_privatedevices(Manager *m) {
187 int r;
188
189 if (detect_container() > 0) {
190 log_notice("Testing in container, skipping %s", __func__);
191 return;
192 }
193 if (!is_inaccessible_available()) {
194 log_notice("Testing without inaccessible, skipping %s", __func__);
195 return;
196 }
197
198 test(m, "exec-privatedevices-yes.service", 0, CLD_EXITED);
199 test(m, "exec-privatedevices-no.service", 0, CLD_EXITED);
200
201 /* We use capsh to test if the capabilities are
202 * properly set, so be sure that it exists */
203 r = find_binary("capsh", NULL);
204 if (r < 0) {
205 log_error_errno(r, "Could not find capsh binary, skipping remaining tests in %s: %m", __func__);
206 return;
207 }
208
209 test(m, "exec-privatedevices-yes-capability-mknod.service", 0, CLD_EXITED);
210 test(m, "exec-privatedevices-no-capability-mknod.service", 0, CLD_EXITED);
211 test(m, "exec-privatedevices-yes-capability-sys-rawio.service", 0, CLD_EXITED);
212 test(m, "exec-privatedevices-no-capability-sys-rawio.service", 0, CLD_EXITED);
213 }
214
215 static void test_exec_protectkernelmodules(Manager *m) {
216 int r;
217
218 if (detect_container() > 0) {
219 log_notice("Testing in container, skipping %s", __func__);
220 return;
221 }
222 if (!is_inaccessible_available()) {
223 log_notice("Testing without inaccessible, skipping %s", __func__);
224 return;
225 }
226
227 r = find_binary("capsh", NULL);
228 if (r < 0) {
229 log_error_errno(r, "Skipping %s, could not find capsh binary: %m", __func__);
230 return;
231 }
232
233 test(m, "exec-protectkernelmodules-no-capabilities.service", 0, CLD_EXITED);
234 test(m, "exec-protectkernelmodules-yes-capabilities.service", 0, CLD_EXITED);
235 test(m, "exec-protectkernelmodules-yes-mount-propagation.service", 0, CLD_EXITED);
236 }
237
238 static void test_exec_readonlypaths(Manager *m) {
239
240 test(m, "exec-readonlypaths-simple.service", 0, CLD_EXITED);
241
242 if (path_is_read_only_fs("/var") > 0) {
243 log_notice("Directory /var is readonly, skipping remaining tests in %s", __func__);
244 return;
245 }
246
247 test(m, "exec-readonlypaths.service", 0, CLD_EXITED);
248 test(m, "exec-readonlypaths-mount-propagation.service", 0, CLD_EXITED);
249 test(m, "exec-readonlypaths-with-bindpaths.service", 0, CLD_EXITED);
250 }
251
252 static void test_exec_readwritepaths(Manager *m) {
253
254 if (path_is_read_only_fs("/") > 0) {
255 log_notice("Root directory is readonly, skipping %s", __func__);
256 return;
257 }
258
259 test(m, "exec-readwritepaths-mount-propagation.service", 0, CLD_EXITED);
260 }
261
262 static void test_exec_inaccessiblepaths(Manager *m) {
263
264 if (!is_inaccessible_available()) {
265 log_notice("Testing without inaccessible, skipping %s", __func__);
266 return;
267 }
268
269 test(m, "exec-inaccessiblepaths-proc.service", 0, CLD_EXITED);
270
271 if (path_is_read_only_fs("/") > 0) {
272 log_notice("Root directory is readonly, skipping remaining tests in %s", __func__);
273 return;
274 }
275
276 test(m, "exec-inaccessiblepaths-mount-propagation.service", 0, CLD_EXITED);
277 }
278
279 static void test_exec_systemcallfilter(Manager *m) {
280 #if HAVE_SECCOMP
281 if (!is_seccomp_available()) {
282 log_notice("Seccomp not available, skipping %s", __func__);
283 return;
284 }
285
286 test(m, "exec-systemcallfilter-not-failing.service", 0, CLD_EXITED);
287 test(m, "exec-systemcallfilter-not-failing2.service", 0, CLD_EXITED);
288 test(m, "exec-systemcallfilter-failing.service", SIGSYS, CLD_KILLED);
289 test(m, "exec-systemcallfilter-failing2.service", SIGSYS, CLD_KILLED);
290 test(m, "exec-systemcallfilter-with-errno-name.service", errno_from_name("EILSEQ"), CLD_EXITED);
291 test(m, "exec-systemcallfilter-with-errno-number.service", 255, CLD_EXITED);
292 #endif
293 }
294
295 static void test_exec_systemcallerrornumber(Manager *m) {
296 #if HAVE_SECCOMP
297 if (!is_seccomp_available()) {
298 log_notice("Seccomp not available, skipping %s", __func__);
299 return;
300 }
301
302 test(m, "exec-systemcallerrornumber-name.service", errno_from_name("EACCES"), CLD_EXITED);
303 test(m, "exec-systemcallerrornumber-number.service", 255, CLD_EXITED);
304 #endif
305 }
306
307 static void test_exec_restrictnamespaces(Manager *m) {
308 #if HAVE_SECCOMP
309 if (!is_seccomp_available()) {
310 log_notice("Seccomp not available, skipping %s", __func__);
311 return;
312 }
313
314 test(m, "exec-restrictnamespaces-no.service", 0, CLD_EXITED);
315 test(m, "exec-restrictnamespaces-yes.service", 1, CLD_EXITED);
316 test(m, "exec-restrictnamespaces-mnt.service", 0, CLD_EXITED);
317 test(m, "exec-restrictnamespaces-mnt-blacklist.service", 1, CLD_EXITED);
318 #endif
319 }
320
321 static void test_exec_systemcallfilter_system(Manager *m) {
322 #if HAVE_SECCOMP
323 if (!is_seccomp_available()) {
324 log_notice("Seccomp not available, skipping %s", __func__);
325 return;
326 }
327 if (getpwnam("nobody"))
328 test(m, "exec-systemcallfilter-system-user.service", 0, CLD_EXITED);
329 else if (getpwnam("nfsnobody"))
330 test(m, "exec-systemcallfilter-system-user-nfsnobody.service", 0, CLD_EXITED);
331 else
332 log_error_errno(errno, "Skipping %s, could not find nobody/nfsnobody user: %m", __func__);
333 #endif
334 }
335
336 static void test_exec_user(Manager *m) {
337 if (getpwnam("nobody"))
338 test(m, "exec-user.service", 0, CLD_EXITED);
339 else if (getpwnam("nfsnobody"))
340 test(m, "exec-user-nfsnobody.service", 0, CLD_EXITED);
341 else
342 log_error_errno(errno, "Skipping %s, could not find nobody/nfsnobody user: %m", __func__);
343 }
344
345 static void test_exec_group(Manager *m) {
346 if (getgrnam("nobody"))
347 test(m, "exec-group.service", 0, CLD_EXITED);
348 else if (getgrnam("nfsnobody"))
349 test(m, "exec-group-nfsnobody.service", 0, CLD_EXITED);
350 else if (getgrnam("nogroup"))
351 test(m, "exec-group-nogroup.service", 0, CLD_EXITED);
352 else
353 log_error_errno(errno, "Skipping %s, could not find nobody/nfsnobody/nogroup group: %m", __func__);
354 }
355
356 static void test_exec_supplementarygroups(Manager *m) {
357 test(m, "exec-supplementarygroups.service", 0, CLD_EXITED);
358 test(m, "exec-supplementarygroups-single-group.service", 0, CLD_EXITED);
359 test(m, "exec-supplementarygroups-single-group-user.service", 0, CLD_EXITED);
360 test(m, "exec-supplementarygroups-multiple-groups-default-group-user.service", 0, CLD_EXITED);
361 test(m, "exec-supplementarygroups-multiple-groups-withgid.service", 0, CLD_EXITED);
362 test(m, "exec-supplementarygroups-multiple-groups-withuid.service", 0, CLD_EXITED);
363 }
364
365 static void test_exec_dynamicuser(Manager *m) {
366 test(m, "exec-dynamicuser-fixeduser.service", 0, CLD_EXITED);
367 test(m, "exec-dynamicuser-fixeduser-one-supplementarygroup.service", 0, CLD_EXITED);
368 test(m, "exec-dynamicuser-supplementarygroups.service", 0, CLD_EXITED);
369 test(m, "exec-dynamicuser-statedir.service", 0, CLD_EXITED);
370
371 test(m, "exec-dynamicuser-statedir-migrate-step1.service", 0, CLD_EXITED);
372 test(m, "exec-dynamicuser-statedir-migrate-step2.service", 0, CLD_EXITED);
373 (void) rm_rf("/var/lib/test-dynamicuser-migrate", REMOVE_ROOT|REMOVE_PHYSICAL);
374 (void) rm_rf("/var/lib/test-dynamicuser-migrate2", REMOVE_ROOT|REMOVE_PHYSICAL);
375 (void) rm_rf("/var/lib/private/test-dynamicuser-migrate", REMOVE_ROOT|REMOVE_PHYSICAL);
376 (void) rm_rf("/var/lib/private/test-dynamicuser-migrate2", REMOVE_ROOT|REMOVE_PHYSICAL);
377 }
378
379 static void test_exec_environment(Manager *m) {
380 test(m, "exec-environment.service", 0, CLD_EXITED);
381 test(m, "exec-environment-multiple.service", 0, CLD_EXITED);
382 test(m, "exec-environment-empty.service", 0, CLD_EXITED);
383 }
384
385 static void test_exec_environmentfile(Manager *m) {
386 static const char e[] =
387 "VAR1='word1 word2'\n"
388 "VAR2=word3 \n"
389 "# comment1\n"
390 "\n"
391 "; comment2\n"
392 " ; # comment3\n"
393 "line without an equal\n"
394 "VAR3='$word 5 6'\n";
395 int r;
396
397 r = write_string_file("/tmp/test-exec_environmentfile.conf", e, WRITE_STRING_FILE_CREATE);
398 assert_se(r == 0);
399
400 test(m, "exec-environmentfile.service", 0, CLD_EXITED);
401
402 (void) unlink("/tmp/test-exec_environmentfile.conf");
403 }
404
405 static void test_exec_passenvironment(Manager *m) {
406 /* test-execute runs under MANAGER_USER which, by default, forwards all
407 * variables present in the environment, but only those that are
408 * present _at the time it is created_!
409 *
410 * So these PassEnvironment checks are still expected to work, since we
411 * are ensuring the variables are not present at manager creation (they
412 * are unset explicitly in main) and are only set here.
413 *
414 * This is still a good approximation of how a test for MANAGER_SYSTEM
415 * would work.
416 */
417 assert_se(setenv("VAR1", "word1 word2", 1) == 0);
418 assert_se(setenv("VAR2", "word3", 1) == 0);
419 assert_se(setenv("VAR3", "$word 5 6", 1) == 0);
420 test(m, "exec-passenvironment.service", 0, CLD_EXITED);
421 test(m, "exec-passenvironment-repeated.service", 0, CLD_EXITED);
422 test(m, "exec-passenvironment-empty.service", 0, CLD_EXITED);
423 assert_se(unsetenv("VAR1") == 0);
424 assert_se(unsetenv("VAR2") == 0);
425 assert_se(unsetenv("VAR3") == 0);
426 test(m, "exec-passenvironment-absent.service", 0, CLD_EXITED);
427 }
428
429 static void test_exec_umask(Manager *m) {
430 test(m, "exec-umask-default.service", 0, CLD_EXITED);
431 test(m, "exec-umask-0177.service", 0, CLD_EXITED);
432 }
433
434 static void test_exec_runtimedirectory(Manager *m) {
435 test(m, "exec-runtimedirectory.service", 0, CLD_EXITED);
436 test(m, "exec-runtimedirectory-mode.service", 0, CLD_EXITED);
437 if (getgrnam("nobody"))
438 test(m, "exec-runtimedirectory-owner.service", 0, CLD_EXITED);
439 else if (getgrnam("nfsnobody"))
440 test(m, "exec-runtimedirectory-owner-nfsnobody.service", 0, CLD_EXITED);
441 else
442 log_error_errno(errno, "Skipping %s, could not find nobody/nfsnobody group: %m", __func__);
443 }
444
445 static void test_exec_capabilityboundingset(Manager *m) {
446 int r;
447
448 r = find_binary("capsh", NULL);
449 if (r < 0) {
450 log_error_errno(r, "Skipping %s, could not find capsh binary: %m", __func__);
451 return;
452 }
453
454 test(m, "exec-capabilityboundingset-simple.service", 0, CLD_EXITED);
455 test(m, "exec-capabilityboundingset-reset.service", 0, CLD_EXITED);
456 test(m, "exec-capabilityboundingset-merge.service", 0, CLD_EXITED);
457 test(m, "exec-capabilityboundingset-invert.service", 0, CLD_EXITED);
458 }
459
460 static void test_exec_capabilityambientset(Manager *m) {
461 int r;
462
463 /* Check if the kernel has support for ambient capabilities. Run
464 * the tests only if that's the case. Clearing all ambient
465 * capabilities is fine, since we are expecting them to be unset
466 * in the first place for the tests. */
467 r = prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_CLEAR_ALL, 0, 0, 0);
468 if (r < 0 && IN_SET(errno, EINVAL, EOPNOTSUPP, ENOSYS)) {
469 log_error("Skipping %s, the kernel does not support ambient capabilities", __func__);
470 return;
471 }
472
473 if (getpwnam("nobody")) {
474 test(m, "exec-capabilityambientset.service", 0, CLD_EXITED);
475 test(m, "exec-capabilityambientset-merge.service", 0, CLD_EXITED);
476 } else if (getpwnam("nfsnobody")) {
477 test(m, "exec-capabilityambientset-nfsnobody.service", 0, CLD_EXITED);
478 test(m, "exec-capabilityambientset-merge-nfsnobody.service", 0, CLD_EXITED);
479 } else
480 log_error_errno(errno, "Skipping %s, could not find nobody/nfsnobody user: %m", __func__);
481 }
482
483 static void test_exec_privatenetwork(Manager *m) {
484 int r;
485
486 r = find_binary("ip", NULL);
487 if (r < 0) {
488 log_error_errno(r, "Skipping %s, could not find ip binary: %m", __func__);
489 return;
490 }
491
492 test(m, "exec-privatenetwork-yes.service", 0, CLD_EXITED);
493 }
494
495 static void test_exec_oomscoreadjust(Manager *m) {
496 test(m, "exec-oomscoreadjust-positive.service", 0, CLD_EXITED);
497 test(m, "exec-oomscoreadjust-negative.service", 0, CLD_EXITED);
498 }
499
500 static void test_exec_ioschedulingclass(Manager *m) {
501 test(m, "exec-ioschedulingclass-none.service", 0, CLD_EXITED);
502 test(m, "exec-ioschedulingclass-idle.service", 0, CLD_EXITED);
503 test(m, "exec-ioschedulingclass-realtime.service", 0, CLD_EXITED);
504 test(m, "exec-ioschedulingclass-best-effort.service", 0, CLD_EXITED);
505 }
506
507 static void test_exec_unsetenvironment(Manager *m) {
508 test(m, "exec-unsetenvironment.service", 0, CLD_EXITED);
509 }
510
511 static void test_exec_specifier(Manager *m) {
512 test(m, "exec-specifier.service", 0, CLD_EXITED);
513 test(m, "exec-specifier@foo-bar.service", 0, CLD_EXITED);
514 test(m, "exec-specifier-interpolation.service", 0, CLD_EXITED);
515 }
516
517 static void test_exec_standardinput(Manager *m) {
518 test(m, "exec-standardinput-data.service", 0, CLD_EXITED);
519 test(m, "exec-standardinput-file.service", 0, CLD_EXITED);
520 }
521
522 static int run_tests(UnitFileScope scope, const test_function_t *tests) {
523 const test_function_t *test = NULL;
524 Manager *m = NULL;
525 int r;
526
527 assert_se(tests);
528
529 r = manager_new(scope, MANAGER_TEST_RUN_MINIMAL, &m);
530 if (MANAGER_SKIP_TEST(r)) {
531 log_notice_errno(r, "Skipping test: manager_new: %m");
532 return EXIT_TEST_SKIP;
533 }
534 assert_se(r >= 0);
535 assert_se(manager_startup(m, NULL, NULL) >= 0);
536
537 for (test = tests; test && *test; test++)
538 (*test)(m);
539
540 manager_free(m);
541
542 return 0;
543 }
544
545 int main(int argc, char *argv[]) {
546 static const test_function_t user_tests[] = {
547 test_exec_bindpaths,
548 test_exec_capabilityambientset,
549 test_exec_capabilityboundingset,
550 test_exec_cpuaffinity,
551 test_exec_environment,
552 test_exec_environmentfile,
553 test_exec_group,
554 test_exec_ignoresigpipe,
555 test_exec_inaccessiblepaths,
556 test_exec_ioschedulingclass,
557 test_exec_oomscoreadjust,
558 test_exec_passenvironment,
559 test_exec_personality,
560 test_exec_privatedevices,
561 test_exec_privatenetwork,
562 test_exec_privatetmp,
563 test_exec_protectkernelmodules,
564 test_exec_readonlypaths,
565 test_exec_readwritepaths,
566 test_exec_restrictnamespaces,
567 test_exec_runtimedirectory,
568 test_exec_standardinput,
569 test_exec_supplementarygroups,
570 test_exec_systemcallerrornumber,
571 test_exec_systemcallfilter,
572 test_exec_umask,
573 test_exec_unsetenvironment,
574 test_exec_user,
575 test_exec_workingdirectory,
576 NULL,
577 };
578 static const test_function_t system_tests[] = {
579 test_exec_dynamicuser,
580 test_exec_specifier,
581 test_exec_systemcallfilter_system,
582 NULL,
583 };
584 int r;
585
586 log_set_max_level(LOG_DEBUG);
587 log_parse_environment();
588 log_open();
589
590 (void) unsetenv("USER");
591 (void) unsetenv("LOGNAME");
592
593 /* It is needed otherwise cgroup creation fails */
594 if (getuid() != 0) {
595 puts("Skipping test: not root");
596 return EXIT_TEST_SKIP;
597 }
598
599 r = enter_cgroup_subroot();
600 if (r == -ENOMEDIUM) {
601 puts("Skipping test: cgroupfs not available");
602 return EXIT_TEST_SKIP;
603 }
604
605 assert_se(setenv("XDG_RUNTIME_DIR", "/tmp/", 1) == 0);
606 assert_se(set_unit_path(get_testdata_dir("/test-execute")) >= 0);
607
608 /* Unset VAR1, VAR2 and VAR3 which are used in the PassEnvironment test
609 * cases, otherwise (and if they are present in the environment),
610 * `manager_default_environment` will copy them into the default
611 * environment which is passed to each created job, which will make the
612 * tests that expect those not to be present to fail.
613 */
614 assert_se(unsetenv("VAR1") == 0);
615 assert_se(unsetenv("VAR2") == 0);
616 assert_se(unsetenv("VAR3") == 0);
617
618 r = run_tests(UNIT_FILE_USER, user_tests);
619 if (r != 0)
620 return r;
621
622 return run_tests(UNIT_FILE_SYSTEM, system_tests);
623 }