]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/test/test-unit-file.c
2 This file is part of systemd.
4 Copyright 2012 Lennart Poettering
5 Copyright 2013 Zbigniew Jędrzejewski-Szmek
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.
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.
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/>.
25 #include <sys/capability.h>
28 #include "alloc-util.h"
29 #include "capability-util.h"
33 #include "hostname-util.h"
34 #include "install-printf.h"
36 #include "load-fragment.h"
38 #include "specifier.h"
39 #include "string-util.h"
41 #include "test-helper.h"
42 #include "user-util.h"
45 static int test_unit_file_get_set(void) {
51 h
= hashmap_new(&string_hash_ops
);
54 r
= unit_file_get_list(UNIT_FILE_SYSTEM
, NULL
, h
);
56 if (r
== -EPERM
|| r
== -EACCES
) {
57 printf("Skipping test: unit_file_get_list: %s", strerror(-r
));
58 return EXIT_TEST_SKIP
;
61 log_full(r
== 0 ? LOG_INFO
: LOG_ERR
,
62 "unit_file_get_list: %s", strerror(-r
));
66 HASHMAP_FOREACH(p
, h
, i
)
67 printf("%s = %s\n", p
->path
, unit_file_state_to_string(p
->state
));
69 unit_file_list_free(h
);
74 static void check_execcommand(ExecCommand
*c
,
83 log_info("expect: \"%s\" [\"%s\" \"%s\" \"%s\"]",
84 path
, argv0
?: path
, argv1
, argv2
);
85 n
= strv_length(c
->argv
);
86 log_info("actual: \"%s\" [\"%s\" \"%s\" \"%s\"]",
87 c
->path
, c
->argv
[0], n
> 0 ? c
->argv
[1] : NULL
, n
> 1 ? c
->argv
[2] : NULL
);
88 assert_se(streq(c
->path
, path
));
89 assert_se(streq(c
->argv
[0], argv0
?: path
));
91 assert_se(streq_ptr(c
->argv
[1], argv1
));
93 assert_se(streq_ptr(c
->argv
[2], argv2
));
94 assert_se(c
->ignore
== ignore
);
97 static void test_config_parse_exec(void) {
98 /* int config_parse_exec(
100 const char *filename,
103 unsigned section_line,
111 ExecCommand
*c
= NULL
, *c1
;
116 r
= manager_new(MANAGER_USER
, true, &m
);
117 if (MANAGER_SKIP_TEST(r
)) {
118 printf("Skipping test: manager_new: %s\n", strerror(-r
));
123 assert_se(manager_startup(m
, NULL
, NULL
) >= 0);
125 assert_se(u
= unit_new(m
, sizeof(Service
)));
127 log_info("/* basic test */");
128 r
= config_parse_exec(NULL
, "fake", 1, "section", 1,
129 "LValue", 0, "/RValue r1",
132 check_execcommand(c
, "/RValue", "/RValue", "r1", NULL
, false);
134 r
= config_parse_exec(NULL
, "fake", 2, "section", 1,
135 "LValue", 0, "/RValue///slashes r1///",
138 log_info("/* test slashes */");
140 c1
= c
->command_next
;
141 check_execcommand(c1
, "/RValue/slashes", "/RValue///slashes", "r1///", NULL
, false);
143 log_info("/* trailing slash */");
144 r
= config_parse_exec(NULL
, "fake", 4, "section", 1,
145 "LValue", 0, "/RValue/ argv0 r1",
148 assert_se(c1
->command_next
== NULL
);
150 log_info("/* honour_argv0 */");
151 r
= config_parse_exec(NULL
, "fake", 3, "section", 1,
152 "LValue", 0, "@/RValue///slashes2 ///argv0 r1",
155 c1
= c1
->command_next
;
156 check_execcommand(c1
, "/RValue/slashes2", "///argv0", "r1", NULL
, false);
158 log_info("/* honour_argv0, no args */");
159 r
= config_parse_exec(NULL
, "fake", 3, "section", 1,
160 "LValue", 0, "@/RValue",
163 assert_se(c1
->command_next
== NULL
);
165 log_info("/* no command, whitespace only, reset */");
166 r
= config_parse_exec(NULL
, "fake", 3, "section", 1,
170 assert_se(c
== NULL
);
172 log_info("/* ignore && honour_argv0 */");
173 r
= config_parse_exec(NULL
, "fake", 4, "section", 1,
174 "LValue", 0, "-@/RValue///slashes3 argv0a r1",
178 check_execcommand(c1
, "/RValue/slashes3", "argv0a", "r1", NULL
, true);
180 log_info("/* ignore && honour_argv0 */");
181 r
= config_parse_exec(NULL
, "fake", 4, "section", 1,
182 "LValue", 0, "@-/RValue///slashes4 argv0b r1",
185 c1
= c1
->command_next
;
186 check_execcommand(c1
, "/RValue/slashes4", "argv0b", "r1", NULL
, true);
188 log_info("/* ignore && ignore */");
189 r
= config_parse_exec(NULL
, "fake", 4, "section", 1,
190 "LValue", 0, "--/RValue argv0 r1",
193 assert_se(c1
->command_next
== NULL
);
195 log_info("/* ignore && ignore (2) */");
196 r
= config_parse_exec(NULL
, "fake", 4, "section", 1,
197 "LValue", 0, "-@-/RValue argv0 r1",
200 assert_se(c1
->command_next
== NULL
);
202 log_info("/* semicolon */");
203 r
= config_parse_exec(NULL
, "fake", 5, "section", 1,
205 "-@/RValue argv0 r1 ; "
209 c1
= c1
->command_next
;
210 check_execcommand(c1
, "/RValue", "argv0", "r1", NULL
, true);
212 c1
= c1
->command_next
;
213 check_execcommand(c1
, "/goo/goo", NULL
, "boo", NULL
, false);
215 log_info("/* two semicolons in a row */");
216 r
= config_parse_exec(NULL
, "fake", 5, "section", 1,
218 "-@/RValue argv0 r1 ; ; "
222 c1
= c1
->command_next
;
223 check_execcommand(c1
, "/RValue", "argv0", "r1", NULL
, true);
225 /* second command fails because the executable name is ";" */
226 assert_se(c1
->command_next
== NULL
);
228 log_info("/* trailing semicolon */");
229 r
= config_parse_exec(NULL
, "fake", 5, "section", 1,
231 "-@/RValue argv0 r1 ; ",
234 c1
= c1
->command_next
;
235 check_execcommand(c1
, "/RValue", "argv0", "r1", NULL
, true);
237 assert_se(c1
->command_next
== NULL
);
239 log_info("/* trailing semicolon, no whitespace */");
240 r
= config_parse_exec(NULL
, "fake", 5, "section", 1,
242 "-@/RValue argv0 r1 ;",
245 c1
= c1
->command_next
;
246 check_execcommand(c1
, "/RValue", "argv0", "r1", NULL
, true);
248 assert_se(c1
->command_next
== NULL
);
250 log_info("/* trailing semicolon in single quotes */");
251 r
= config_parse_exec(NULL
, "fake", 5, "section", 1,
253 "-@/RValue argv0 r1 ';'",
256 c1
= c1
->command_next
;
257 check_execcommand(c1
, "/RValue", "argv0", "r1", ";", true);
259 log_info("/* escaped semicolon */");
260 r
= config_parse_exec(NULL
, "fake", 5, "section", 1,
265 c1
= c1
->command_next
;
266 check_execcommand(c1
, "/bin/find", NULL
, ";", NULL
, false);
268 log_info("/* escaped semicolon with following arg */");
269 r
= config_parse_exec(NULL
, "fake", 5, "section", 1,
274 c1
= c1
->command_next
;
275 check_execcommand(c1
,
276 "/sbin/find", NULL
, ";", "/x", false);
278 log_info("/* escaped semicolon as part of an expression */");
279 r
= config_parse_exec(NULL
, "fake", 5, "section", 1,
284 c1
= c1
->command_next
;
285 check_execcommand(c1
,
286 "/sbin/find", NULL
, "\\;x", NULL
, false);
288 log_info("/* encoded semicolon */");
289 r
= config_parse_exec(NULL
, "fake", 5, "section", 1,
294 c1
= c1
->command_next
;
295 check_execcommand(c1
, "/bin/find", NULL
, ";", NULL
, false);
297 log_info("/* quoted semicolon */");
298 r
= config_parse_exec(NULL
, "fake", 5, "section", 1,
303 c1
= c1
->command_next
;
304 check_execcommand(c1
, "/bin/find", NULL
, ";", NULL
, false);
306 log_info("/* quoted semicolon with following arg */");
307 r
= config_parse_exec(NULL
, "fake", 5, "section", 1,
309 "/sbin/find \";\" /x",
312 c1
= c1
->command_next
;
313 check_execcommand(c1
,
314 "/sbin/find", NULL
, ";", "/x", false);
316 log_info("/* spaces in the filename */");
317 r
= config_parse_exec(NULL
, "fake", 5, "section", 1,
319 "\"/PATH WITH SPACES/daemon\" -1 -2",
322 c1
= c1
->command_next
;
323 check_execcommand(c1
,
324 "/PATH WITH SPACES/daemon", NULL
, "-1", "-2", false);
326 log_info("/* spaces in the filename, no args */");
327 r
= config_parse_exec(NULL
, "fake", 5, "section", 1,
329 "\"/PATH WITH SPACES/daemon -1 -2\"",
332 c1
= c1
->command_next
;
333 check_execcommand(c1
,
334 "/PATH WITH SPACES/daemon -1 -2", NULL
, NULL
, NULL
, false);
336 log_info("/* spaces in the filename, everything quoted */");
337 r
= config_parse_exec(NULL
, "fake", 5, "section", 1,
339 "\"/PATH WITH SPACES/daemon\" \"-1\" '-2'",
342 c1
= c1
->command_next
;
343 check_execcommand(c1
,
344 "/PATH WITH SPACES/daemon", NULL
, "-1", "-2", false);
346 log_info("/* escaped spaces in the filename */");
347 r
= config_parse_exec(NULL
, "fake", 5, "section", 1,
349 "\"/PATH\\sWITH\\sSPACES/daemon\" '-1 -2'",
352 c1
= c1
->command_next
;
353 check_execcommand(c1
,
354 "/PATH WITH SPACES/daemon", NULL
, "-1 -2", NULL
, false);
356 log_info("/* escaped spaces in the filename (2) */");
357 r
= config_parse_exec(NULL
, "fake", 5, "section", 1,
359 "\"/PATH\\x20WITH\\x20SPACES/daemon\" \"-1 -2\"",
362 c1
= c1
->command_next
;
363 check_execcommand(c1
,
364 "/PATH WITH SPACES/daemon", NULL
, "-1 -2", NULL
, false);
366 for (ccc
= "abfnrtv\\\'\"x"; *ccc
; ccc
++) {
367 /* \\x is an incomplete hexadecimal sequence, invalid because of the slash */
368 char path
[] = "/path\\X";
369 path
[sizeof(path
) - 2] = *ccc
;
371 log_info("/* invalid character: \\%c */", *ccc
);
372 r
= config_parse_exec(NULL
, "fake", 4, "section", 1,
376 assert_se(c1
->command_next
== NULL
);
379 log_info("/* valid character: \\s */");
380 r
= config_parse_exec(NULL
, "fake", 4, "section", 1,
381 "LValue", 0, "/path\\s",
384 c1
= c1
->command_next
;
385 check_execcommand(c1
, "/path ", NULL
, NULL
, NULL
, false);
387 log_info("/* quoted backslashes */");
388 r
= config_parse_exec(NULL
, "fake", 5, "section", 1,
390 "/bin/grep '\\w+\\K'",
393 c1
= c1
->command_next
;
394 check_execcommand(c1
, "/bin/grep", NULL
, "\\w+\\K", NULL
, false);
397 log_info("/* trailing backslash: \\ */");
398 /* backslash is invalid */
399 r
= config_parse_exec(NULL
, "fake", 4, "section", 1,
400 "LValue", 0, "/path\\",
403 assert_se(c1
->command_next
== NULL
);
405 log_info("/* missing ending ' */");
406 r
= config_parse_exec(NULL
, "fake", 4, "section", 1,
407 "LValue", 0, "/path 'foo",
410 assert_se(c1
->command_next
== NULL
);
412 log_info("/* missing ending ' with trailing backslash */");
413 r
= config_parse_exec(NULL
, "fake", 4, "section", 1,
414 "LValue", 0, "/path 'foo\\",
417 assert_se(c1
->command_next
== NULL
);
419 log_info("/* invalid space between modifiers */");
420 r
= config_parse_exec(NULL
, "fake", 4, "section", 1,
421 "LValue", 0, "- /path",
424 assert_se(c1
->command_next
== NULL
);
426 log_info("/* only modifiers, no path */");
427 r
= config_parse_exec(NULL
, "fake", 4, "section", 1,
431 assert_se(c1
->command_next
== NULL
);
433 log_info("/* empty argument, reset */");
434 r
= config_parse_exec(NULL
, "fake", 4, "section", 1,
438 assert_se(c
== NULL
);
440 exec_command_free_list(c
);
461 "#SPAMD_ARGS=\"-d --socketpath=/var/lib/bulwark/spamd \\\n" \
462 "#--nouser-config \\\n" \
468 "HWMON_MODULES=\"coretemp f71882fg\"\n" \
470 "# For compatibility reasons\n" \
472 "MODULE_0=coretemp\n" \
479 static void test_load_env_file_1(void) {
480 _cleanup_strv_free_
char **data
= NULL
;
483 char name
[] = "/tmp/test-load-env-file.XXXXXX";
484 _cleanup_close_
int fd
;
486 fd
= mkostemp_safe(name
, O_RDWR
|O_CLOEXEC
);
488 assert_se(write(fd
, env_file_1
, sizeof(env_file_1
)) == sizeof(env_file_1
));
490 r
= load_env_file(NULL
, name
, NULL
, &data
);
492 assert_se(streq(data
[0], "a=a"));
493 assert_se(streq(data
[1], "b=bc"));
494 assert_se(streq(data
[2], "d=def"));
495 assert_se(streq(data
[3], "g=g "));
496 assert_se(streq(data
[4], "h=h"));
497 assert_se(streq(data
[5], "i=i"));
498 assert_se(data
[6] == NULL
);
502 static void test_load_env_file_2(void) {
503 _cleanup_strv_free_
char **data
= NULL
;
506 char name
[] = "/tmp/test-load-env-file.XXXXXX";
507 _cleanup_close_
int fd
;
509 fd
= mkostemp_safe(name
, O_RDWR
|O_CLOEXEC
);
511 assert_se(write(fd
, env_file_2
, sizeof(env_file_2
)) == sizeof(env_file_2
));
513 r
= load_env_file(NULL
, name
, NULL
, &data
);
515 assert_se(streq(data
[0], "a=a"));
516 assert_se(data
[1] == NULL
);
520 static void test_load_env_file_3(void) {
521 _cleanup_strv_free_
char **data
= NULL
;
524 char name
[] = "/tmp/test-load-env-file.XXXXXX";
525 _cleanup_close_
int fd
;
527 fd
= mkostemp_safe(name
, O_RDWR
|O_CLOEXEC
);
529 assert_se(write(fd
, env_file_3
, sizeof(env_file_3
)) == sizeof(env_file_3
));
531 r
= load_env_file(NULL
, name
, NULL
, &data
);
533 assert_se(data
== NULL
);
537 static void test_load_env_file_4(void) {
538 _cleanup_strv_free_
char **data
= NULL
;
539 char name
[] = "/tmp/test-load-env-file.XXXXXX";
540 _cleanup_close_
int fd
;
543 fd
= mkostemp_safe(name
, O_RDWR
|O_CLOEXEC
);
545 assert_se(write(fd
, env_file_4
, sizeof(env_file_4
)) == sizeof(env_file_4
));
547 r
= load_env_file(NULL
, name
, NULL
, &data
);
549 assert_se(streq(data
[0], "HWMON_MODULES=coretemp f71882fg"));
550 assert_se(streq(data
[1], "MODULE_0=coretemp"));
551 assert_se(streq(data
[2], "MODULE_1=f71882fg"));
552 assert_se(data
[3] == NULL
);
556 static void test_load_env_file_5(void) {
557 _cleanup_strv_free_
char **data
= NULL
;
560 char name
[] = "/tmp/test-load-env-file.XXXXXX";
561 _cleanup_close_
int fd
;
563 fd
= mkostemp_safe(name
, O_RDWR
|O_CLOEXEC
);
565 assert_se(write(fd
, env_file_5
, sizeof(env_file_5
)) == sizeof(env_file_5
));
567 r
= load_env_file(NULL
, name
, NULL
, &data
);
569 assert_se(streq(data
[0], "a="));
570 assert_se(streq(data
[1], "b="));
571 assert_se(data
[2] == NULL
);
575 static void test_install_printf(void) {
576 char name
[] = "name.service",
577 path
[] = "/run/systemd/system/name.service";
578 UnitFileInstallInfo i
= { .name
= name
, .path
= path
, };
579 UnitFileInstallInfo i2
= { .name
= name
, .path
= path
, };
580 char name3
[] = "name@inst.service",
581 path3
[] = "/run/systemd/system/name.service";
582 UnitFileInstallInfo i3
= { .name
= name3
, .path
= path3
, };
583 UnitFileInstallInfo i4
= { .name
= name3
, .path
= path3
, };
585 _cleanup_free_
char *mid
= NULL
, *bid
= NULL
, *host
= NULL
, *uid
= NULL
, *user
= NULL
;
587 assert_se(specifier_machine_id('m', NULL
, NULL
, &mid
) >= 0 && mid
);
588 assert_se(specifier_boot_id('b', NULL
, NULL
, &bid
) >= 0 && bid
);
589 assert_se((host
= gethostname_malloc()));
590 assert_se((user
= getusername_malloc()));
591 assert_se(asprintf(&uid
, UID_FMT
, getuid()) >= 0);
593 #define expect(src, pattern, result) \
595 _cleanup_free_ char *t = NULL; \
596 _cleanup_free_ char \
597 *d1 = strdup(i.name), \
598 *d2 = strdup(i.path); \
599 assert_se(install_full_printf(&src, pattern, &t) >= 0 || !result); \
600 memzero(i.name, strlen(i.name)); \
601 memzero(i.path, strlen(i.path)); \
602 assert_se(d1 && d2); \
605 assert_se(streq(t, result)); \
606 } else assert_se(t == NULL); \
607 strcpy(i.name, d1); \
608 strcpy(i.path, d2); \
611 expect(i
, "%n", "name.service");
612 expect(i
, "%N", "name");
613 expect(i
, "%p", "name");
615 expect(i
, "%u", user
);
616 expect(i
, "%U", uid
);
618 expect(i
, "%m", mid
);
619 expect(i
, "%b", bid
);
620 expect(i
, "%H", host
);
622 expect(i2
, "%u", user
);
623 expect(i2
, "%U", uid
);
625 expect(i3
, "%n", "name@inst.service");
626 expect(i3
, "%N", "name@inst");
627 expect(i3
, "%p", "name");
628 expect(i3
, "%u", user
);
629 expect(i3
, "%U", uid
);
631 expect(i3
, "%m", mid
);
632 expect(i3
, "%b", bid
);
633 expect(i3
, "%H", host
);
635 expect(i4
, "%u", user
);
636 expect(i4
, "%U", uid
);
639 static uint64_t make_cap(int cap
) {
640 return ((uint64_t) 1ULL << (uint64_t) cap
);
643 static void test_config_parse_capability_set(void) {
644 /* int config_parse_capability_set(
646 const char *filename,
649 unsigned section_line,
656 uint64_t capability_bounding_set
= 0;
658 r
= config_parse_capability_set(NULL
, "fake", 1, "section", 1,
659 "CapabilityBoundingSet", 0, "CAP_NET_RAW",
660 &capability_bounding_set
, NULL
);
662 assert_se(capability_bounding_set
== make_cap(CAP_NET_RAW
));
664 r
= config_parse_capability_set(NULL
, "fake", 1, "section", 1,
665 "CapabilityBoundingSet", 0, "CAP_NET_ADMIN",
666 &capability_bounding_set
, NULL
);
668 assert_se(capability_bounding_set
== (make_cap(CAP_NET_RAW
) | make_cap(CAP_NET_ADMIN
)));
670 r
= config_parse_capability_set(NULL
, "fake", 1, "section", 1,
671 "CapabilityBoundingSet", 0, "",
672 &capability_bounding_set
, NULL
);
674 assert_se(capability_bounding_set
== UINT64_C(0));
676 r
= config_parse_capability_set(NULL
, "fake", 1, "section", 1,
677 "CapabilityBoundingSet", 0, "~",
678 &capability_bounding_set
, NULL
);
680 assert_se(cap_test_all(capability_bounding_set
));
682 capability_bounding_set
= 0;
683 r
= config_parse_capability_set(NULL
, "fake", 1, "section", 1,
684 "CapabilityBoundingSet", 0, " 'CAP_NET_RAW' WAT_CAP??? CAP_NET_ADMIN CAP'_trailing_garbage",
685 &capability_bounding_set
, NULL
);
687 assert_se(capability_bounding_set
== (make_cap(CAP_NET_RAW
) | make_cap(CAP_NET_ADMIN
)));
690 static void test_config_parse_rlimit(void) {
691 struct rlimit
* rl
[_RLIMIT_MAX
] = {};
693 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE
, "55", rl
, NULL
) >= 0);
694 assert_se(rl
[RLIMIT_NOFILE
]);
695 assert_se(rl
[RLIMIT_NOFILE
]->rlim_cur
== 55);
696 assert_se(rl
[RLIMIT_NOFILE
]->rlim_cur
== rl
[RLIMIT_NOFILE
]->rlim_max
);
698 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE
, "55:66", rl
, NULL
) >= 0);
699 assert_se(rl
[RLIMIT_NOFILE
]);
700 assert_se(rl
[RLIMIT_NOFILE
]->rlim_cur
== 55);
701 assert_se(rl
[RLIMIT_NOFILE
]->rlim_max
== 66);
703 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE
, "infinity", rl
, NULL
) >= 0);
704 assert_se(rl
[RLIMIT_NOFILE
]);
705 assert_se(rl
[RLIMIT_NOFILE
]->rlim_cur
== RLIM_INFINITY
);
706 assert_se(rl
[RLIMIT_NOFILE
]->rlim_cur
== rl
[RLIMIT_NOFILE
]->rlim_max
);
708 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE
, "infinity:infinity", rl
, NULL
) >= 0);
709 assert_se(rl
[RLIMIT_NOFILE
]);
710 assert_se(rl
[RLIMIT_NOFILE
]->rlim_cur
== RLIM_INFINITY
);
711 assert_se(rl
[RLIMIT_NOFILE
]->rlim_cur
== rl
[RLIMIT_NOFILE
]->rlim_max
);
713 rl
[RLIMIT_NOFILE
]->rlim_cur
= 10;
714 rl
[RLIMIT_NOFILE
]->rlim_max
= 20;
716 /* Invalid values don't change rl */
717 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE
, "10:20:30", rl
, NULL
) >= 0);
718 assert_se(rl
[RLIMIT_NOFILE
]);
719 assert_se(rl
[RLIMIT_NOFILE
]->rlim_cur
== 10);
720 assert_se(rl
[RLIMIT_NOFILE
]->rlim_max
== 20);
722 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE
, "wat:wat", rl
, NULL
) >= 0);
723 assert_se(rl
[RLIMIT_NOFILE
]);
724 assert_se(rl
[RLIMIT_NOFILE
]->rlim_cur
== 10);
725 assert_se(rl
[RLIMIT_NOFILE
]->rlim_max
== 20);
727 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE
, "66:wat", rl
, NULL
) >= 0);
728 assert_se(rl
[RLIMIT_NOFILE
]);
729 assert_se(rl
[RLIMIT_NOFILE
]->rlim_cur
== 10);
730 assert_se(rl
[RLIMIT_NOFILE
]->rlim_max
== 20);
732 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE
, "200:100", rl
, NULL
) >= 0);
733 assert_se(rl
[RLIMIT_NOFILE
]);
734 assert_se(rl
[RLIMIT_NOFILE
]->rlim_cur
== 10);
735 assert_se(rl
[RLIMIT_NOFILE
]->rlim_max
== 20);
737 rl
[RLIMIT_NOFILE
] = mfree(rl
[RLIMIT_NOFILE
]);
739 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitCPU", RLIMIT_CPU
, "56", rl
, NULL
) >= 0);
740 assert_se(rl
[RLIMIT_CPU
]);
741 assert_se(rl
[RLIMIT_CPU
]->rlim_cur
== 56);
742 assert_se(rl
[RLIMIT_CPU
]->rlim_cur
== rl
[RLIMIT_CPU
]->rlim_max
);
744 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitCPU", RLIMIT_CPU
, "57s", rl
, NULL
) >= 0);
745 assert_se(rl
[RLIMIT_CPU
]);
746 assert_se(rl
[RLIMIT_CPU
]->rlim_cur
== 57);
747 assert_se(rl
[RLIMIT_CPU
]->rlim_cur
== rl
[RLIMIT_CPU
]->rlim_max
);
749 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitCPU", RLIMIT_CPU
, "40s:1m", rl
, NULL
) >= 0);
750 assert_se(rl
[RLIMIT_CPU
]);
751 assert_se(rl
[RLIMIT_CPU
]->rlim_cur
== 40);
752 assert_se(rl
[RLIMIT_CPU
]->rlim_max
== 60);
754 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitCPU", RLIMIT_CPU
, "infinity", rl
, NULL
) >= 0);
755 assert_se(rl
[RLIMIT_CPU
]);
756 assert_se(rl
[RLIMIT_CPU
]->rlim_cur
== RLIM_INFINITY
);
757 assert_se(rl
[RLIMIT_CPU
]->rlim_cur
== rl
[RLIMIT_CPU
]->rlim_max
);
759 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitCPU", RLIMIT_CPU
, "1234ms", rl
, NULL
) >= 0);
760 assert_se(rl
[RLIMIT_CPU
]);
761 assert_se(rl
[RLIMIT_CPU
]->rlim_cur
== 2);
762 assert_se(rl
[RLIMIT_CPU
]->rlim_cur
== rl
[RLIMIT_CPU
]->rlim_max
);
764 rl
[RLIMIT_CPU
] = mfree(rl
[RLIMIT_CPU
]);
766 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitRTTIME", RLIMIT_RTTIME
, "58", rl
, NULL
) >= 0);
767 assert_se(rl
[RLIMIT_RTTIME
]);
768 assert_se(rl
[RLIMIT_RTTIME
]->rlim_cur
== 58);
769 assert_se(rl
[RLIMIT_RTTIME
]->rlim_cur
== rl
[RLIMIT_RTTIME
]->rlim_max
);
771 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitRTTIME", RLIMIT_RTTIME
, "58:60", rl
, NULL
) >= 0);
772 assert_se(rl
[RLIMIT_RTTIME
]);
773 assert_se(rl
[RLIMIT_RTTIME
]->rlim_cur
== 58);
774 assert_se(rl
[RLIMIT_RTTIME
]->rlim_max
== 60);
776 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitRTTIME", RLIMIT_RTTIME
, "59s", rl
, NULL
) >= 0);
777 assert_se(rl
[RLIMIT_RTTIME
]);
778 assert_se(rl
[RLIMIT_RTTIME
]->rlim_cur
== 59 * USEC_PER_SEC
);
779 assert_se(rl
[RLIMIT_RTTIME
]->rlim_cur
== rl
[RLIMIT_RTTIME
]->rlim_max
);
781 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitRTTIME", RLIMIT_RTTIME
, "59s:123s", rl
, NULL
) >= 0);
782 assert_se(rl
[RLIMIT_RTTIME
]);
783 assert_se(rl
[RLIMIT_RTTIME
]->rlim_cur
== 59 * USEC_PER_SEC
);
784 assert_se(rl
[RLIMIT_RTTIME
]->rlim_max
== 123 * USEC_PER_SEC
);
786 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitRTTIME", RLIMIT_RTTIME
, "infinity", rl
, NULL
) >= 0);
787 assert_se(rl
[RLIMIT_RTTIME
]);
788 assert_se(rl
[RLIMIT_RTTIME
]->rlim_cur
== RLIM_INFINITY
);
789 assert_se(rl
[RLIMIT_RTTIME
]->rlim_cur
== rl
[RLIMIT_RTTIME
]->rlim_max
);
791 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitRTTIME", RLIMIT_RTTIME
, "infinity:infinity", rl
, NULL
) >= 0);
792 assert_se(rl
[RLIMIT_RTTIME
]);
793 assert_se(rl
[RLIMIT_RTTIME
]->rlim_cur
== RLIM_INFINITY
);
794 assert_se(rl
[RLIMIT_RTTIME
]->rlim_cur
== rl
[RLIMIT_RTTIME
]->rlim_max
);
796 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitRTTIME", RLIMIT_RTTIME
, "2345ms", rl
, NULL
) >= 0);
797 assert_se(rl
[RLIMIT_RTTIME
]);
798 assert_se(rl
[RLIMIT_RTTIME
]->rlim_cur
== 2345 * USEC_PER_MSEC
);
799 assert_se(rl
[RLIMIT_RTTIME
]->rlim_cur
== rl
[RLIMIT_RTTIME
]->rlim_max
);
801 rl
[RLIMIT_RTTIME
] = mfree(rl
[RLIMIT_RTTIME
]);
804 static void test_config_parse_pass_environ(void) {
805 /* int config_parse_pass_environ(
807 const char *filename,
810 unsigned section_line,
817 _cleanup_strv_free_
char **passenv
= NULL
;
819 r
= config_parse_pass_environ(NULL
, "fake", 1, "section", 1,
820 "PassEnvironment", 0, "A B",
823 assert_se(strv_length(passenv
) == 2);
824 assert_se(streq(passenv
[0], "A"));
825 assert_se(streq(passenv
[1], "B"));
827 r
= config_parse_pass_environ(NULL
, "fake", 1, "section", 1,
828 "PassEnvironment", 0, "",
831 assert_se(strv_isempty(passenv
));
833 r
= config_parse_pass_environ(NULL
, "fake", 1, "section", 1,
834 "PassEnvironment", 0, "'invalid name' 'normal_name' A=1 \\",
837 assert_se(strv_length(passenv
) == 1);
838 assert_se(streq(passenv
[0], "normal_name"));
842 int main(int argc
, char *argv
[]) {
845 log_parse_environment();
848 r
= test_unit_file_get_set();
849 test_config_parse_exec();
850 test_config_parse_capability_set();
851 test_config_parse_rlimit();
852 test_config_parse_pass_environ();
853 test_load_env_file_1();
854 test_load_env_file_2();
855 test_load_env_file_3();
856 test_load_env_file_4();
857 test_load_env_file_5();
858 TEST_REQ_RUNNING_SYSTEMD(test_install_printf());