]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/test/test-execute.c
Add SPDX license identifiers to source files under the LGPL
[thirdparty/systemd.git] / src / test / test-execute.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
281e05b6
RC
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
cc7fa4fb
RC
21#include <grp.h>
22#include <pwd.h>
ff4ca461 23#include <stdio.h>
70d7aea5 24#include <sys/prctl.h>
ff4ca461 25#include <sys/types.h>
281e05b6 26
b4891260 27#include "errno-list.h"
03bd70dd 28#include "fileio.h"
f4f15635 29#include "fs-util.h"
281e05b6 30#include "macro.h"
f4f15635 31#include "manager.h"
281e05b6 32#include "mkdir.h"
ff4ca461 33#include "path-util.h"
c6878637 34#include "rm-rf.h"
349cc4a5 35#if HAVE_SECCOMP
83f12b27
FS
36#include "seccomp-util.h"
37#endif
34b86909 38#include "stat-util.h"
8b3aa503 39#include "test-helper.h"
cc100a5a 40#include "tests.h"
f4f15635
LP
41#include "unit.h"
42#include "util.h"
4dd4cb8f 43#include "virt.h"
281e05b6
RC
44
45typedef void (*test_function_t)(Manager *m);
46
47static void check(Manager *m, Unit *unit, int status_expected, int code_expected) {
48 Service *service = NULL;
49 usec_t ts;
8adb3d63 50 usec_t timeout = 2 * USEC_PER_MINUTE;
281e05b6
RC
51
52 assert_se(m);
53 assert_se(unit);
54
55 service = SERVICE(unit);
56 printf("%s\n", unit->id);
57 exec_context_dump(&service->exec_context, stdout, "\t");
58 ts = now(CLOCK_MONOTONIC);
ec2ce0c5 59 while (!IN_SET(service->state, SERVICE_DEAD, SERVICE_FAILED)) {
281e05b6
RC
60 int r;
61 usec_t n;
62
63 r = sd_event_run(m->event, 100 * USEC_PER_MSEC);
64 assert_se(r >= 0);
65
66 n = now(CLOCK_MONOTONIC);
67 if (ts + timeout < n) {
68 log_error("Test timeout when testing %s", unit->id);
69 exit(EXIT_FAILURE);
70 }
71 }
72 exec_status_dump(&service->main_exec_status, stdout, "\t");
73 assert_se(service->main_exec_status.status == status_expected);
74 assert_se(service->main_exec_status.code == code_expected);
75}
76
6086d2da
DP
77static bool is_inaccessible_available(void) {
78 char *p;
79
80 FOREACH_STRING(p,
81 "/run/systemd/inaccessible/reg",
82 "/run/systemd/inaccessible/dir",
83 "/run/systemd/inaccessible/chr",
84 "/run/systemd/inaccessible/blk",
85 "/run/systemd/inaccessible/fifo",
86 "/run/systemd/inaccessible/sock"
87 ) {
88 if (access(p, F_OK) < 0)
89 return false;
90 }
91
92 return true;
93}
94
281e05b6
RC
95static void test(Manager *m, const char *unit_name, int status_expected, int code_expected) {
96 Unit *unit;
97
98 assert_se(unit_name);
99
100 assert_se(manager_load_unit(m, unit_name, NULL, NULL, &unit) >= 0);
101 assert_se(UNIT_VTABLE(unit)->start(unit) >= 0);
102 check(m, unit, status_expected, code_expected);
103}
104
d053b72b
YW
105static void test_exec_bind_paths(Manager *m) {
106 assert_se(mkdir_p("/tmp/test-exec_bind_paths", 0755) >= 0);
107 assert_se(mkdir_p("/tmp/test-exec_bind_readonly_paths", 0755) >= 0);
108
109 test(m, "exec-bind-paths.service", 0, CLD_EXITED);
110
111 (void) rm_rf("/tmp/test-exec_bind_paths", REMOVE_ROOT|REMOVE_PHYSICAL);
112 (void) rm_rf("/tmp/test-exec_bind_readonly_paths", REMOVE_ROOT|REMOVE_PHYSICAL);
113}
114
281e05b6
RC
115static void test_exec_workingdirectory(Manager *m) {
116 assert_se(mkdir_p("/tmp/test-exec_workingdirectory", 0755) >= 0);
117
118 test(m, "exec-workingdirectory.service", 0, CLD_EXITED);
119
c6878637 120 (void) rm_rf("/tmp/test-exec_workingdirectory", REMOVE_ROOT|REMOVE_PHYSICAL);
281e05b6
RC
121}
122
123static void test_exec_personality(Manager *m) {
281e05b6
RC
124#if defined(__x86_64__)
125 test(m, "exec-personality-x86-64.service", 0, CLD_EXITED);
7517f51e
HB
126
127#elif defined(__s390__)
128 test(m, "exec-personality-s390.service", 0, CLD_EXITED);
129
12591863
JS
130#elif defined(__powerpc64__)
131# if __BYTE_ORDER == __BIG_ENDIAN
132 test(m, "exec-personality-ppc64.service", 0, CLD_EXITED);
133# else
134 test(m, "exec-personality-ppc64le.service", 0, CLD_EXITED);
135# endif
136
137#elif defined(__aarch64__)
138 test(m, "exec-personality-aarch64.service", 0, CLD_EXITED);
139
5798eb4c 140#elif defined(__i386__)
7517f51e 141 test(m, "exec-personality-x86.service", 0, CLD_EXITED);
281e05b6
RC
142#endif
143}
144
145static void test_exec_ignoresigpipe(Manager *m) {
146 test(m, "exec-ignoresigpipe-yes.service", 0, CLD_EXITED);
147 test(m, "exec-ignoresigpipe-no.service", SIGPIPE, CLD_KILLED);
148}
149
150static void test_exec_privatetmp(Manager *m) {
151 assert_se(touch("/tmp/test-exec_privatetmp") >= 0);
152
153 test(m, "exec-privatetmp-yes.service", 0, CLD_EXITED);
154 test(m, "exec-privatetmp-no.service", 0, CLD_EXITED);
155
156 unlink("/tmp/test-exec_privatetmp");
157}
158
159static void test_exec_privatedevices(Manager *m) {
4dd4cb8f 160 if (detect_container() > 0) {
303c0bf8 161 log_notice("testing in container, skipping %s", __func__);
4dd4cb8f
SM
162 return;
163 }
6086d2da 164 if (!is_inaccessible_available()) {
303c0bf8 165 log_notice("testing without inaccessible, skipping %s", __func__);
6086d2da
DP
166 return;
167 }
168
281e05b6
RC
169 test(m, "exec-privatedevices-yes.service", 0, CLD_EXITED);
170 test(m, "exec-privatedevices-no.service", 0, CLD_EXITED);
171}
172
615a1f4b 173static void test_exec_privatedevices_capabilities(Manager *m) {
0608ba98
ZJS
174 int r;
175
615a1f4b 176 if (detect_container() > 0) {
303c0bf8 177 log_notice("testing in container, skipping %s", __func__);
615a1f4b
DH
178 return;
179 }
6086d2da 180 if (!is_inaccessible_available()) {
303c0bf8 181 log_notice("testing without inaccessible, skipping %s", __func__);
6086d2da
DP
182 return;
183 }
184
0608ba98
ZJS
185 /* We use capsh to test if the capabilities are
186 * properly set, so be sure that it exists */
187 r = find_binary("capsh", NULL);
188 if (r < 0) {
189 log_error_errno(r, "Skipping %s, could not find capsh binary: %m", __func__);
6086d2da
DP
190 return;
191 }
192
615a1f4b
DH
193 test(m, "exec-privatedevices-yes-capability-mknod.service", 0, CLD_EXITED);
194 test(m, "exec-privatedevices-no-capability-mknod.service", 0, CLD_EXITED);
625d8769
DH
195 test(m, "exec-privatedevices-yes-capability-sys-rawio.service", 0, CLD_EXITED);
196 test(m, "exec-privatedevices-no-capability-sys-rawio.service", 0, CLD_EXITED);
615a1f4b
DH
197}
198
4982dbcc 199static void test_exec_protectkernelmodules(Manager *m) {
0608ba98
ZJS
200 int r;
201
3ae33295 202 if (detect_container() > 0) {
303c0bf8 203 log_notice("testing in container, skipping %s", __func__);
3ae33295
DH
204 return;
205 }
6086d2da 206 if (!is_inaccessible_available()) {
303c0bf8 207 log_notice("testing without inaccessible, skipping %s", __func__);
6086d2da
DP
208 return;
209 }
3ae33295 210
0608ba98
ZJS
211 r = find_binary("capsh", NULL);
212 if (r < 0) {
213 log_error_errno(r, "Skipping %s, could not find capsh binary: %m", __func__);
214 return;
215 }
216
217
3ae33295
DH
218 test(m, "exec-protectkernelmodules-no-capabilities.service", 0, CLD_EXITED);
219 test(m, "exec-protectkernelmodules-yes-capabilities.service", 0, CLD_EXITED);
4982dbcc 220 test(m, "exec-protectkernelmodules-yes-mount-propagation.service", 0, CLD_EXITED);
3ae33295
DH
221}
222
f78b36f0 223static void test_exec_readonlypaths(Manager *m) {
34b86909
LP
224
225 if (path_is_read_only_fs("/var") > 0)
226 return;
227
f78b36f0 228 test(m, "exec-readonlypaths.service", 0, CLD_EXITED);
cdfbd1fb 229 test(m, "exec-readonlypaths-mount-propagation.service", 0, CLD_EXITED);
23fd04e9 230 test(m, "exec-readonlypaths-with-bindpaths.service", 0, CLD_EXITED);
cdfbd1fb
DH
231}
232
233static void test_exec_readwritepaths(Manager *m) {
34b86909
LP
234
235 if (path_is_read_only_fs("/") > 0)
236 return;
237
cdfbd1fb
DH
238 test(m, "exec-readwritepaths-mount-propagation.service", 0, CLD_EXITED);
239}
240
241static void test_exec_inaccessiblepaths(Manager *m) {
34b86909
LP
242
243 if (path_is_read_only_fs("/") > 0)
244 return;
245
cdfbd1fb 246 test(m, "exec-inaccessiblepaths-mount-propagation.service", 0, CLD_EXITED);
f78b36f0
DH
247}
248
c090d74d 249static void test_exec_inaccessiblepaths_proc(Manager *m) {
af4af186
EV
250 if (!is_inaccessible_available()) {
251 log_notice("testing without inaccessible, skipping %s", __func__);
252 return;
253 }
254
c090d74d
TR
255 test(m, "exec-inaccessiblepaths-proc.service", 0, CLD_EXITED);
256}
257
281e05b6 258static void test_exec_systemcallfilter(Manager *m) {
349cc4a5 259#if HAVE_SECCOMP
83f12b27
FS
260 if (!is_seccomp_available())
261 return;
281e05b6
RC
262 test(m, "exec-systemcallfilter-not-failing.service", 0, CLD_EXITED);
263 test(m, "exec-systemcallfilter-not-failing2.service", 0, CLD_EXITED);
264 test(m, "exec-systemcallfilter-failing.service", SIGSYS, CLD_KILLED);
265 test(m, "exec-systemcallfilter-failing2.service", SIGSYS, CLD_KILLED);
b4891260
YW
266 test(m, "exec-systemcallfilter-with-errno-name.service", errno_from_name("EILSEQ"), CLD_EXITED);
267 test(m, "exec-systemcallfilter-with-errno-number.service", 255, CLD_EXITED);
83f12b27 268
281e05b6
RC
269#endif
270}
271
272static void test_exec_systemcallerrornumber(Manager *m) {
349cc4a5 273#if HAVE_SECCOMP
7a18854f
YW
274 if (!is_seccomp_available())
275 return;
276 test(m, "exec-systemcallerrornumber-name.service", errno_from_name("EACCES"), CLD_EXITED);
277 test(m, "exec-systemcallerrornumber-number.service", 255, CLD_EXITED);
281e05b6
RC
278#endif
279}
280
97e60383 281static void test_exec_restrict_namespaces(Manager *m) {
349cc4a5 282#if HAVE_SECCOMP
97e60383
DH
283 if (!is_seccomp_available())
284 return;
285
286 test(m, "exec-restrict-namespaces-no.service", 0, CLD_EXITED);
287 test(m, "exec-restrict-namespaces-yes.service", 1, CLD_EXITED);
288 test(m, "exec-restrict-namespaces-mnt.service", 0, CLD_EXITED);
289 test(m, "exec-restrict-namespaces-mnt-blacklist.service", 1, CLD_EXITED);
290#endif
291}
292
19c0b0b9 293static void test_exec_systemcall_system_mode_with_user(Manager *m) {
349cc4a5 294#if HAVE_SECCOMP
83f12b27
FS
295 if (!is_seccomp_available())
296 return;
19c0b0b9
RC
297 if (getpwnam("nobody"))
298 test(m, "exec-systemcallfilter-system-user.service", 0, CLD_EXITED);
50f130c2
RC
299 else if (getpwnam("nfsnobody"))
300 test(m, "exec-systemcallfilter-system-user-nfsnobody.service", 0, CLD_EXITED);
19c0b0b9 301 else
303c0bf8 302 log_error_errno(errno, "Skipping %s, could not find nobody/nfsnobody user: %m", __func__);
19c0b0b9
RC
303#endif
304}
305
281e05b6 306static void test_exec_user(Manager *m) {
cc7fa4fb
RC
307 if (getpwnam("nobody"))
308 test(m, "exec-user.service", 0, CLD_EXITED);
50f130c2
RC
309 else if (getpwnam("nfsnobody"))
310 test(m, "exec-user-nfsnobody.service", 0, CLD_EXITED);
ff4ca461 311 else
303c0bf8 312 log_error_errno(errno, "Skipping %s, could not find nobody/nfsnobody user: %m", __func__);
281e05b6
RC
313}
314
315static void test_exec_group(Manager *m) {
cc7fa4fb
RC
316 if (getgrnam("nobody"))
317 test(m, "exec-group.service", 0, CLD_EXITED);
50f130c2
RC
318 else if (getgrnam("nfsnobody"))
319 test(m, "exec-group-nfsnobody.service", 0, CLD_EXITED);
ff4ca461 320 else
303c0bf8 321 log_error_errno(errno, "Skipping %s, could not find nobody/nfsnobody group: %m", __func__);
281e05b6
RC
322}
323
86b838ea
DH
324static void test_exec_supplementary_groups(Manager *m) {
325 test(m, "exec-supplementarygroups.service", 0, CLD_EXITED);
bf9ace96
DH
326 test(m, "exec-supplementarygroups-single-group.service", 0, CLD_EXITED);
327 test(m, "exec-supplementarygroups-single-group-user.service", 0, CLD_EXITED);
50ca7a35
DH
328 test(m, "exec-supplementarygroups-multiple-groups-default-group-user.service", 0, CLD_EXITED);
329 test(m, "exec-supplementarygroups-multiple-groups-withgid.service", 0, CLD_EXITED);
330 test(m, "exec-supplementarygroups-multiple-groups-withuid.service", 0, CLD_EXITED);
86b838ea
DH
331}
332
2b9ac11e
DH
333static void test_exec_dynamic_user(Manager *m) {
334 test(m, "exec-dynamicuser-fixeduser.service", 0, CLD_EXITED);
335 test(m, "exec-dynamicuser-fixeduser-one-supplementarygroup.service", 0, CLD_EXITED);
5c67067f 336 test(m, "exec-dynamicuser-supplementarygroups.service", 0, CLD_EXITED);
8adb3d63 337 test(m, "exec-dynamicuser-state-dir.service", 0, CLD_EXITED);
2b9ac11e
DH
338}
339
281e05b6
RC
340static void test_exec_environment(Manager *m) {
341 test(m, "exec-environment.service", 0, CLD_EXITED);
342 test(m, "exec-environment-multiple.service", 0, CLD_EXITED);
343 test(m, "exec-environment-empty.service", 0, CLD_EXITED);
344}
345
03bd70dd
RC
346static void test_exec_environmentfile(Manager *m) {
347 static const char e[] =
348 "VAR1='word1 word2'\n"
349 "VAR2=word3 \n"
350 "# comment1\n"
351 "\n"
352 "; comment2\n"
353 " ; # comment3\n"
354 "line without an equal\n"
355 "VAR3='$word 5 6'\n";
356 int r;
357
358 r = write_string_file("/tmp/test-exec_environmentfile.conf", e, WRITE_STRING_FILE_CREATE);
359 assert_se(r == 0);
360
361 test(m, "exec-environmentfile.service", 0, CLD_EXITED);
362
363 unlink("/tmp/test-exec_environmentfile.conf");
364}
365
4c80d201 366static void test_exec_passenvironment(Manager *m) {
e1abca2e
FB
367 /* test-execute runs under MANAGER_USER which, by default, forwards all
368 * variables present in the environment, but only those that are
369 * present _at the time it is created_!
370 *
371 * So these PassEnvironment checks are still expected to work, since we
372 * are ensuring the variables are not present at manager creation (they
373 * are unset explicitly in main) and are only set here.
374 *
375 * This is still a good approximation of how a test for MANAGER_SYSTEM
376 * would work.
377 */
4c80d201
FB
378 assert_se(setenv("VAR1", "word1 word2", 1) == 0);
379 assert_se(setenv("VAR2", "word3", 1) == 0);
380 assert_se(setenv("VAR3", "$word 5 6", 1) == 0);
381 test(m, "exec-passenvironment.service", 0, CLD_EXITED);
382 test(m, "exec-passenvironment-repeated.service", 0, CLD_EXITED);
383 test(m, "exec-passenvironment-empty.service", 0, CLD_EXITED);
384 assert_se(unsetenv("VAR1") == 0);
385 assert_se(unsetenv("VAR2") == 0);
386 assert_se(unsetenv("VAR3") == 0);
387 test(m, "exec-passenvironment-absent.service", 0, CLD_EXITED);
388}
389
27c5347c
RC
390static void test_exec_umask(Manager *m) {
391 test(m, "exec-umask-default.service", 0, CLD_EXITED);
392 test(m, "exec-umask-0177.service", 0, CLD_EXITED);
393}
394
cc3ddc85
RC
395static void test_exec_runtimedirectory(Manager *m) {
396 test(m, "exec-runtimedirectory.service", 0, CLD_EXITED);
397 test(m, "exec-runtimedirectory-mode.service", 0, CLD_EXITED);
cc7fa4fb
RC
398 if (getgrnam("nobody"))
399 test(m, "exec-runtimedirectory-owner.service", 0, CLD_EXITED);
50f130c2
RC
400 else if (getgrnam("nfsnobody"))
401 test(m, "exec-runtimedirectory-owner-nfsnobody.service", 0, CLD_EXITED);
ff4ca461 402 else
303c0bf8 403 log_error_errno(errno, "Skipping %s, could not find nobody/nfsnobody group: %m", __func__);
ff4ca461
RC
404}
405
406static void test_exec_capabilityboundingset(Manager *m) {
407 int r;
408
ff4ca461
RC
409 r = find_binary("capsh", NULL);
410 if (r < 0) {
0608ba98 411 log_error_errno(r, "Skipping %s, could not find capsh binary: %m", __func__);
ff4ca461
RC
412 return;
413 }
414
415 test(m, "exec-capabilityboundingset-simple.service", 0, CLD_EXITED);
416 test(m, "exec-capabilityboundingset-reset.service", 0, CLD_EXITED);
417 test(m, "exec-capabilityboundingset-merge.service", 0, CLD_EXITED);
418 test(m, "exec-capabilityboundingset-invert.service", 0, CLD_EXITED);
cc3ddc85
RC
419}
420
70d7aea5
IP
421static void test_exec_capabilityambientset(Manager *m) {
422 int r;
423
424 /* Check if the kernel has support for ambient capabilities. Run
425 * the tests only if that's the case. Clearing all ambient
426 * capabilities is fine, since we are expecting them to be unset
427 * in the first place for the tests. */
428 r = prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_CLEAR_ALL, 0, 0, 0);
429 if (r >= 0 || errno != EINVAL) {
50f130c2 430 if (getpwnam("nobody")) {
50f130c2
RC
431 test(m, "exec-capabilityambientset.service", 0, CLD_EXITED);
432 test(m, "exec-capabilityambientset-merge.service", 0, CLD_EXITED);
34f5ff46
RC
433 } else if (getpwnam("nfsnobody")) {
434 test(m, "exec-capabilityambientset-nfsnobody.service", 0, CLD_EXITED);
435 test(m, "exec-capabilityambientset-merge-nfsnobody.service", 0, CLD_EXITED);
50f130c2 436 } else
303c0bf8 437 log_error_errno(errno, "Skipping %s, could not find nobody/nfsnobody user: %m", __func__);
50f130c2 438 } else
303c0bf8 439 log_error_errno(errno, "Skipping %s, the kernel does not support ambient capabilities: %m", __func__);
70d7aea5
IP
440}
441
63447f11
RC
442static void test_exec_privatenetwork(Manager *m) {
443 int r;
444
445 r = find_binary("ip", NULL);
446 if (r < 0) {
303c0bf8 447 log_error_errno(r, "Skipping %s, could not find ip binary: %m", __func__);
63447f11
RC
448 return;
449 }
450
451 test(m, "exec-privatenetwork-yes.service", 0, CLD_EXITED);
452}
453
c388dfea
RC
454static void test_exec_oomscoreadjust(Manager *m) {
455 test(m, "exec-oomscoreadjust-positive.service", 0, CLD_EXITED);
456 test(m, "exec-oomscoreadjust-negative.service", 0, CLD_EXITED);
457}
458
a6226758
RC
459static void test_exec_ioschedulingclass(Manager *m) {
460 test(m, "exec-ioschedulingclass-none.service", 0, CLD_EXITED);
461 test(m, "exec-ioschedulingclass-idle.service", 0, CLD_EXITED);
462 test(m, "exec-ioschedulingclass-realtime.service", 0, CLD_EXITED);
463 test(m, "exec-ioschedulingclass-best-effort.service", 0, CLD_EXITED);
464}
465
25254999
EV
466static void test_exec_spec_interpolation(Manager *m) {
467 test(m, "exec-spec-interpolation.service", 0, CLD_EXITED);
468}
469
6818c54c
LP
470static void test_exec_read_only_path_suceed(Manager *m) {
471 test(m, "exec-read-only-path-succeed.service", 0, CLD_EXITED);
472}
473
42cc99d5
LP
474static void test_exec_unset_environment(Manager *m) {
475 test(m, "exec-unset-environment.service", 0, CLD_EXITED);
476}
477
9672b583
LP
478static void test_exec_specifier(Manager *m) {
479 test(m, "exec-specifier.service", 0, CLD_EXITED);
480}
481
ea9cfad1
LP
482static int run_tests(UnitFileScope scope, const test_function_t *tests) {
483 const test_function_t *test = NULL;
19c0b0b9
RC
484 Manager *m = NULL;
485 int r;
486
487 assert_se(tests);
488
e0a3da1f 489 r = manager_new(scope, MANAGER_TEST_RUN_MINIMAL, &m);
19c0b0b9 490 if (MANAGER_SKIP_TEST(r)) {
2179fd10 491 log_notice_errno(r, "Skipping test: manager_new: %m");
19c0b0b9
RC
492 return EXIT_TEST_SKIP;
493 }
494 assert_se(r >= 0);
495 assert_se(manager_startup(m, NULL, NULL) >= 0);
496
497 for (test = tests; test && *test; test++)
498 (*test)(m);
499
500 manager_free(m);
501
502 return 0;
503}
504
281e05b6 505int main(int argc, char *argv[]) {
ea9cfad1 506 static const test_function_t user_tests[] = {
d053b72b 507 test_exec_bind_paths,
281e05b6
RC
508 test_exec_workingdirectory,
509 test_exec_personality,
510 test_exec_ignoresigpipe,
511 test_exec_privatetmp,
512 test_exec_privatedevices,
615a1f4b 513 test_exec_privatedevices_capabilities,
4982dbcc 514 test_exec_protectkernelmodules,
f78b36f0 515 test_exec_readonlypaths,
cdfbd1fb
DH
516 test_exec_readwritepaths,
517 test_exec_inaccessiblepaths,
c090d74d 518 test_exec_inaccessiblepaths_proc,
63447f11 519 test_exec_privatenetwork,
281e05b6
RC
520 test_exec_systemcallfilter,
521 test_exec_systemcallerrornumber,
97e60383 522 test_exec_restrict_namespaces,
281e05b6
RC
523 test_exec_user,
524 test_exec_group,
86b838ea 525 test_exec_supplementary_groups,
281e05b6 526 test_exec_environment,
03bd70dd 527 test_exec_environmentfile,
4c80d201 528 test_exec_passenvironment,
27c5347c 529 test_exec_umask,
cc3ddc85 530 test_exec_runtimedirectory,
ff4ca461 531 test_exec_capabilityboundingset,
70d7aea5 532 test_exec_capabilityambientset,
c388dfea 533 test_exec_oomscoreadjust,
a6226758 534 test_exec_ioschedulingclass,
25254999 535 test_exec_spec_interpolation,
6818c54c 536 test_exec_read_only_path_suceed,
42cc99d5 537 test_exec_unset_environment,
281e05b6
RC
538 NULL,
539 };
ea9cfad1 540 static const test_function_t system_tests[] = {
19c0b0b9 541 test_exec_systemcall_system_mode_with_user,
8adb3d63 542 test_exec_dynamic_user,
9672b583 543 test_exec_specifier,
19c0b0b9
RC
544 NULL,
545 };
281e05b6
RC
546 int r;
547
469830d1 548 log_set_max_level(LOG_DEBUG);
281e05b6
RC
549 log_parse_environment();
550 log_open();
551
607ff5f9
DH
552 /* It is needed otherwise cgroup creation fails */
553 if (getuid() != 0) {
651d47d1 554 puts("Skipping test: not root");
607ff5f9
DH
555 return EXIT_TEST_SKIP;
556 }
557
651d47d1
ZJS
558 r = enter_cgroup_subroot();
559 if (r == -ENOMEDIUM) {
560 puts("Skipping test: cgroupfs not available");
561 return EXIT_TEST_SKIP;
562 }
8c759b33 563
cc3ddc85 564 assert_se(setenv("XDG_RUNTIME_DIR", "/tmp/", 1) == 0);
cc100a5a 565 assert_se(set_unit_path(get_testdata_dir("/test-execute")) >= 0);
281e05b6 566
e1abca2e
FB
567 /* Unset VAR1, VAR2 and VAR3 which are used in the PassEnvironment test
568 * cases, otherwise (and if they are present in the environment),
569 * `manager_default_environment` will copy them into the default
570 * environment which is passed to each created job, which will make the
571 * tests that expect those not to be present to fail.
572 */
573 assert_se(unsetenv("VAR1") == 0);
574 assert_se(unsetenv("VAR2") == 0);
575 assert_se(unsetenv("VAR3") == 0);
576
463d0d15 577 r = run_tests(UNIT_FILE_USER, user_tests);
19c0b0b9
RC
578 if (r != 0)
579 return r;
281e05b6 580
463d0d15 581 return run_tests(UNIT_FILE_SYSTEM, system_tests);
281e05b6 582}