]>
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"
39 #include "specifier.h"
40 #include "string-util.h"
42 #include "test-helper.h"
44 #include "user-util.h"
47 static int test_unit_file_get_set(void) {
53 h
= hashmap_new(&string_hash_ops
);
56 r
= unit_file_get_list(UNIT_FILE_SYSTEM
, NULL
, h
, NULL
, NULL
);
58 if (r
== -EPERM
|| r
== -EACCES
) {
59 log_notice_errno(r
, "Skipping test: unit_file_get_list: %m");
60 return EXIT_TEST_SKIP
;
63 log_full_errno(r
== 0 ? LOG_INFO
: LOG_ERR
, r
,
64 "unit_file_get_list: %m");
68 HASHMAP_FOREACH(p
, h
, i
)
69 printf("%s = %s\n", p
->path
, unit_file_state_to_string(p
->state
));
71 unit_file_list_free(h
);
76 static void check_execcommand(ExecCommand
*c
,
85 log_info("expect: \"%s\" [\"%s\" \"%s\" \"%s\"]",
86 path
, argv0
?: path
, argv1
, argv2
);
87 n
= strv_length(c
->argv
);
88 log_info("actual: \"%s\" [\"%s\" \"%s\" \"%s\"]",
89 c
->path
, c
->argv
[0], n
> 0 ? c
->argv
[1] : NULL
, n
> 1 ? c
->argv
[2] : NULL
);
90 assert_se(streq(c
->path
, path
));
91 assert_se(streq(c
->argv
[0], argv0
?: path
));
93 assert_se(streq_ptr(c
->argv
[1], argv1
));
95 assert_se(streq_ptr(c
->argv
[2], argv2
));
96 assert_se(c
->ignore
== ignore
);
99 static void test_config_parse_exec(void) {
100 /* int config_parse_exec(
102 const char *filename,
105 unsigned section_line,
113 ExecCommand
*c
= NULL
, *c1
;
118 r
= manager_new(UNIT_FILE_USER
, true, &m
);
119 if (MANAGER_SKIP_TEST(r
)) {
120 log_notice_errno(r
, "Skipping test: manager_new: %m");
125 assert_se(manager_startup(m
, NULL
, NULL
) >= 0);
127 assert_se(u
= unit_new(m
, sizeof(Service
)));
129 log_info("/* basic test */");
130 r
= config_parse_exec(NULL
, "fake", 1, "section", 1,
131 "LValue", 0, "/RValue r1",
134 check_execcommand(c
, "/RValue", "/RValue", "r1", NULL
, false);
136 r
= config_parse_exec(NULL
, "fake", 2, "section", 1,
137 "LValue", 0, "/RValue///slashes r1///",
140 log_info("/* test slashes */");
142 c1
= c
->command_next
;
143 check_execcommand(c1
, "/RValue/slashes", "/RValue///slashes", "r1///", NULL
, false);
145 log_info("/* trailing slash */");
146 r
= config_parse_exec(NULL
, "fake", 4, "section", 1,
147 "LValue", 0, "/RValue/ argv0 r1",
150 assert_se(c1
->command_next
== NULL
);
152 log_info("/* honour_argv0 */");
153 r
= config_parse_exec(NULL
, "fake", 3, "section", 1,
154 "LValue", 0, "@/RValue///slashes2 ///argv0 r1",
157 c1
= c1
->command_next
;
158 check_execcommand(c1
, "/RValue/slashes2", "///argv0", "r1", NULL
, false);
160 log_info("/* honour_argv0, no args */");
161 r
= config_parse_exec(NULL
, "fake", 3, "section", 1,
162 "LValue", 0, "@/RValue",
165 assert_se(c1
->command_next
== NULL
);
167 log_info("/* no command, whitespace only, reset */");
168 r
= config_parse_exec(NULL
, "fake", 3, "section", 1,
172 assert_se(c
== NULL
);
174 log_info("/* ignore && honour_argv0 */");
175 r
= config_parse_exec(NULL
, "fake", 4, "section", 1,
176 "LValue", 0, "-@/RValue///slashes3 argv0a r1",
180 check_execcommand(c1
, "/RValue/slashes3", "argv0a", "r1", NULL
, true);
182 log_info("/* ignore && honour_argv0 */");
183 r
= config_parse_exec(NULL
, "fake", 4, "section", 1,
184 "LValue", 0, "@-/RValue///slashes4 argv0b r1",
187 c1
= c1
->command_next
;
188 check_execcommand(c1
, "/RValue/slashes4", "argv0b", "r1", NULL
, true);
190 log_info("/* ignore && ignore */");
191 r
= config_parse_exec(NULL
, "fake", 4, "section", 1,
192 "LValue", 0, "--/RValue argv0 r1",
195 assert_se(c1
->command_next
== NULL
);
197 log_info("/* ignore && ignore (2) */");
198 r
= config_parse_exec(NULL
, "fake", 4, "section", 1,
199 "LValue", 0, "-@-/RValue argv0 r1",
202 assert_se(c1
->command_next
== NULL
);
204 log_info("/* semicolon */");
205 r
= config_parse_exec(NULL
, "fake", 5, "section", 1,
207 "-@/RValue argv0 r1 ; "
211 c1
= c1
->command_next
;
212 check_execcommand(c1
, "/RValue", "argv0", "r1", NULL
, true);
214 c1
= c1
->command_next
;
215 check_execcommand(c1
, "/goo/goo", NULL
, "boo", NULL
, false);
217 log_info("/* two semicolons in a row */");
218 r
= config_parse_exec(NULL
, "fake", 5, "section", 1,
220 "-@/RValue argv0 r1 ; ; "
224 c1
= c1
->command_next
;
225 check_execcommand(c1
, "/RValue", "argv0", "r1", NULL
, true);
227 /* second command fails because the executable name is ";" */
228 assert_se(c1
->command_next
== NULL
);
230 log_info("/* trailing semicolon */");
231 r
= config_parse_exec(NULL
, "fake", 5, "section", 1,
233 "-@/RValue argv0 r1 ; ",
236 c1
= c1
->command_next
;
237 check_execcommand(c1
, "/RValue", "argv0", "r1", NULL
, true);
239 assert_se(c1
->command_next
== NULL
);
241 log_info("/* trailing semicolon, no whitespace */");
242 r
= config_parse_exec(NULL
, "fake", 5, "section", 1,
244 "-@/RValue argv0 r1 ;",
247 c1
= c1
->command_next
;
248 check_execcommand(c1
, "/RValue", "argv0", "r1", NULL
, true);
250 assert_se(c1
->command_next
== NULL
);
252 log_info("/* trailing semicolon in single quotes */");
253 r
= config_parse_exec(NULL
, "fake", 5, "section", 1,
255 "-@/RValue argv0 r1 ';'",
258 c1
= c1
->command_next
;
259 check_execcommand(c1
, "/RValue", "argv0", "r1", ";", true);
261 log_info("/* escaped semicolon */");
262 r
= config_parse_exec(NULL
, "fake", 5, "section", 1,
267 c1
= c1
->command_next
;
268 check_execcommand(c1
, "/bin/find", NULL
, ";", NULL
, false);
270 log_info("/* escaped semicolon with following arg */");
271 r
= config_parse_exec(NULL
, "fake", 5, "section", 1,
276 c1
= c1
->command_next
;
277 check_execcommand(c1
,
278 "/sbin/find", NULL
, ";", "/x", false);
280 log_info("/* escaped semicolon as part of an expression */");
281 r
= config_parse_exec(NULL
, "fake", 5, "section", 1,
286 c1
= c1
->command_next
;
287 check_execcommand(c1
,
288 "/sbin/find", NULL
, "\\;x", NULL
, false);
290 log_info("/* encoded semicolon */");
291 r
= config_parse_exec(NULL
, "fake", 5, "section", 1,
296 c1
= c1
->command_next
;
297 check_execcommand(c1
, "/bin/find", NULL
, ";", NULL
, false);
299 log_info("/* quoted semicolon */");
300 r
= config_parse_exec(NULL
, "fake", 5, "section", 1,
305 c1
= c1
->command_next
;
306 check_execcommand(c1
, "/bin/find", NULL
, ";", NULL
, false);
308 log_info("/* quoted semicolon with following arg */");
309 r
= config_parse_exec(NULL
, "fake", 5, "section", 1,
311 "/sbin/find \";\" /x",
314 c1
= c1
->command_next
;
315 check_execcommand(c1
,
316 "/sbin/find", NULL
, ";", "/x", false);
318 log_info("/* spaces in the filename */");
319 r
= config_parse_exec(NULL
, "fake", 5, "section", 1,
321 "\"/PATH WITH SPACES/daemon\" -1 -2",
324 c1
= c1
->command_next
;
325 check_execcommand(c1
,
326 "/PATH WITH SPACES/daemon", NULL
, "-1", "-2", false);
328 log_info("/* spaces in the filename, no args */");
329 r
= config_parse_exec(NULL
, "fake", 5, "section", 1,
331 "\"/PATH WITH SPACES/daemon -1 -2\"",
334 c1
= c1
->command_next
;
335 check_execcommand(c1
,
336 "/PATH WITH SPACES/daemon -1 -2", NULL
, NULL
, NULL
, false);
338 log_info("/* spaces in the filename, everything quoted */");
339 r
= config_parse_exec(NULL
, "fake", 5, "section", 1,
341 "\"/PATH WITH SPACES/daemon\" \"-1\" '-2'",
344 c1
= c1
->command_next
;
345 check_execcommand(c1
,
346 "/PATH WITH SPACES/daemon", NULL
, "-1", "-2", false);
348 log_info("/* escaped spaces in the filename */");
349 r
= config_parse_exec(NULL
, "fake", 5, "section", 1,
351 "\"/PATH\\sWITH\\sSPACES/daemon\" '-1 -2'",
354 c1
= c1
->command_next
;
355 check_execcommand(c1
,
356 "/PATH WITH SPACES/daemon", NULL
, "-1 -2", NULL
, false);
358 log_info("/* escaped spaces in the filename (2) */");
359 r
= config_parse_exec(NULL
, "fake", 5, "section", 1,
361 "\"/PATH\\x20WITH\\x20SPACES/daemon\" \"-1 -2\"",
364 c1
= c1
->command_next
;
365 check_execcommand(c1
,
366 "/PATH WITH SPACES/daemon", NULL
, "-1 -2", NULL
, false);
368 for (ccc
= "abfnrtv\\\'\"x"; *ccc
; ccc
++) {
369 /* \\x is an incomplete hexadecimal sequence, invalid because of the slash */
370 char path
[] = "/path\\X";
371 path
[sizeof(path
) - 2] = *ccc
;
373 log_info("/* invalid character: \\%c */", *ccc
);
374 r
= config_parse_exec(NULL
, "fake", 4, "section", 1,
378 assert_se(c1
->command_next
== NULL
);
381 log_info("/* valid character: \\s */");
382 r
= config_parse_exec(NULL
, "fake", 4, "section", 1,
383 "LValue", 0, "/path\\s",
386 c1
= c1
->command_next
;
387 check_execcommand(c1
, "/path ", NULL
, NULL
, NULL
, false);
389 log_info("/* quoted backslashes */");
390 r
= config_parse_exec(NULL
, "fake", 5, "section", 1,
392 "/bin/grep '\\w+\\K'",
395 c1
= c1
->command_next
;
396 check_execcommand(c1
, "/bin/grep", NULL
, "\\w+\\K", NULL
, false);
399 log_info("/* trailing backslash: \\ */");
400 /* backslash is invalid */
401 r
= config_parse_exec(NULL
, "fake", 4, "section", 1,
402 "LValue", 0, "/path\\",
405 assert_se(c1
->command_next
== NULL
);
407 log_info("/* missing ending ' */");
408 r
= config_parse_exec(NULL
, "fake", 4, "section", 1,
409 "LValue", 0, "/path 'foo",
412 assert_se(c1
->command_next
== NULL
);
414 log_info("/* missing ending ' with trailing backslash */");
415 r
= config_parse_exec(NULL
, "fake", 4, "section", 1,
416 "LValue", 0, "/path 'foo\\",
419 assert_se(c1
->command_next
== NULL
);
421 log_info("/* invalid space between modifiers */");
422 r
= config_parse_exec(NULL
, "fake", 4, "section", 1,
423 "LValue", 0, "- /path",
426 assert_se(c1
->command_next
== NULL
);
428 log_info("/* only modifiers, no path */");
429 r
= config_parse_exec(NULL
, "fake", 4, "section", 1,
433 assert_se(c1
->command_next
== NULL
);
435 log_info("/* empty argument, reset */");
436 r
= config_parse_exec(NULL
, "fake", 4, "section", 1,
440 assert_se(c
== NULL
);
442 exec_command_free_list(c
);
463 "#SPAMD_ARGS=\"-d --socketpath=/var/lib/bulwark/spamd \\\n" \
464 "#--nouser-config \\\n" \
470 "HWMON_MODULES=\"coretemp f71882fg\"\n" \
472 "# For compatibility reasons\n" \
474 "MODULE_0=coretemp\n" \
481 static void test_load_env_file_1(void) {
482 _cleanup_strv_free_
char **data
= NULL
;
485 char name
[] = "/tmp/test-load-env-file.XXXXXX";
486 _cleanup_close_
int fd
;
488 fd
= mkostemp_safe(name
);
490 assert_se(write(fd
, env_file_1
, sizeof(env_file_1
)) == sizeof(env_file_1
));
492 r
= load_env_file(NULL
, name
, NULL
, &data
);
494 assert_se(streq(data
[0], "a=a"));
495 assert_se(streq(data
[1], "b=bc"));
496 assert_se(streq(data
[2], "d=def"));
497 assert_se(streq(data
[3], "g=g "));
498 assert_se(streq(data
[4], "h=h"));
499 assert_se(streq(data
[5], "i=i"));
500 assert_se(data
[6] == NULL
);
504 static void test_load_env_file_2(void) {
505 _cleanup_strv_free_
char **data
= NULL
;
508 char name
[] = "/tmp/test-load-env-file.XXXXXX";
509 _cleanup_close_
int fd
;
511 fd
= mkostemp_safe(name
);
513 assert_se(write(fd
, env_file_2
, sizeof(env_file_2
)) == sizeof(env_file_2
));
515 r
= load_env_file(NULL
, name
, NULL
, &data
);
517 assert_se(streq(data
[0], "a=a"));
518 assert_se(data
[1] == NULL
);
522 static void test_load_env_file_3(void) {
523 _cleanup_strv_free_
char **data
= NULL
;
526 char name
[] = "/tmp/test-load-env-file.XXXXXX";
527 _cleanup_close_
int fd
;
529 fd
= mkostemp_safe(name
);
531 assert_se(write(fd
, env_file_3
, sizeof(env_file_3
)) == sizeof(env_file_3
));
533 r
= load_env_file(NULL
, name
, NULL
, &data
);
535 assert_se(data
== NULL
);
539 static void test_load_env_file_4(void) {
540 _cleanup_strv_free_
char **data
= NULL
;
541 char name
[] = "/tmp/test-load-env-file.XXXXXX";
542 _cleanup_close_
int fd
;
545 fd
= mkostemp_safe(name
);
547 assert_se(write(fd
, env_file_4
, sizeof(env_file_4
)) == sizeof(env_file_4
));
549 r
= load_env_file(NULL
, name
, NULL
, &data
);
551 assert_se(streq(data
[0], "HWMON_MODULES=coretemp f71882fg"));
552 assert_se(streq(data
[1], "MODULE_0=coretemp"));
553 assert_se(streq(data
[2], "MODULE_1=f71882fg"));
554 assert_se(data
[3] == NULL
);
558 static void test_load_env_file_5(void) {
559 _cleanup_strv_free_
char **data
= NULL
;
562 char name
[] = "/tmp/test-load-env-file.XXXXXX";
563 _cleanup_close_
int fd
;
565 fd
= mkostemp_safe(name
);
567 assert_se(write(fd
, env_file_5
, sizeof(env_file_5
)) == sizeof(env_file_5
));
569 r
= load_env_file(NULL
, name
, NULL
, &data
);
571 assert_se(streq(data
[0], "a="));
572 assert_se(streq(data
[1], "b="));
573 assert_se(data
[2] == NULL
);
577 static void test_install_printf(void) {
578 char name
[] = "name.service",
579 path
[] = "/run/systemd/system/name.service";
580 UnitFileInstallInfo i
= { .name
= name
, .path
= path
, };
581 UnitFileInstallInfo i2
= { .name
= name
, .path
= path
, };
582 char name3
[] = "name@inst.service",
583 path3
[] = "/run/systemd/system/name.service";
584 UnitFileInstallInfo i3
= { .name
= name3
, .path
= path3
, };
585 UnitFileInstallInfo i4
= { .name
= name3
, .path
= path3
, };
587 _cleanup_free_
char *mid
= NULL
, *bid
= NULL
, *host
= NULL
, *uid
= NULL
, *user
= NULL
;
589 assert_se(specifier_machine_id('m', NULL
, NULL
, &mid
) >= 0 && mid
);
590 assert_se(specifier_boot_id('b', NULL
, NULL
, &bid
) >= 0 && bid
);
591 assert_se((host
= gethostname_malloc()));
592 assert_se((user
= getusername_malloc()));
593 assert_se(asprintf(&uid
, UID_FMT
, getuid()) >= 0);
595 #define expect(src, pattern, result) \
597 _cleanup_free_ char *t = NULL; \
598 _cleanup_free_ char \
599 *d1 = strdup(i.name), \
600 *d2 = strdup(i.path); \
601 assert_se(install_full_printf(&src, pattern, &t) >= 0 || !result); \
602 memzero(i.name, strlen(i.name)); \
603 memzero(i.path, strlen(i.path)); \
604 assert_se(d1 && d2); \
607 assert_se(streq(t, result)); \
608 } else assert_se(t == NULL); \
609 strcpy(i.name, d1); \
610 strcpy(i.path, d2); \
613 expect(i
, "%n", "name.service");
614 expect(i
, "%N", "name");
615 expect(i
, "%p", "name");
617 expect(i
, "%u", user
);
618 expect(i
, "%U", uid
);
620 expect(i
, "%m", mid
);
621 expect(i
, "%b", bid
);
622 expect(i
, "%H", host
);
624 expect(i2
, "%u", user
);
625 expect(i2
, "%U", uid
);
627 expect(i3
, "%n", "name@inst.service");
628 expect(i3
, "%N", "name@inst");
629 expect(i3
, "%p", "name");
630 expect(i3
, "%u", user
);
631 expect(i3
, "%U", uid
);
633 expect(i3
, "%m", mid
);
634 expect(i3
, "%b", bid
);
635 expect(i3
, "%H", host
);
637 expect(i4
, "%u", user
);
638 expect(i4
, "%U", uid
);
641 static uint64_t make_cap(int cap
) {
642 return ((uint64_t) 1ULL << (uint64_t) cap
);
645 static void test_config_parse_capability_set(void) {
646 /* int config_parse_capability_set(
648 const char *filename,
651 unsigned section_line,
658 uint64_t capability_bounding_set
= 0;
660 r
= config_parse_capability_set(NULL
, "fake", 1, "section", 1,
661 "CapabilityBoundingSet", 0, "CAP_NET_RAW",
662 &capability_bounding_set
, NULL
);
664 assert_se(capability_bounding_set
== make_cap(CAP_NET_RAW
));
666 r
= config_parse_capability_set(NULL
, "fake", 1, "section", 1,
667 "CapabilityBoundingSet", 0, "CAP_NET_ADMIN",
668 &capability_bounding_set
, NULL
);
670 assert_se(capability_bounding_set
== (make_cap(CAP_NET_RAW
) | make_cap(CAP_NET_ADMIN
)));
672 r
= config_parse_capability_set(NULL
, "fake", 1, "section", 1,
673 "CapabilityBoundingSet", 0, "",
674 &capability_bounding_set
, NULL
);
676 assert_se(capability_bounding_set
== UINT64_C(0));
678 r
= config_parse_capability_set(NULL
, "fake", 1, "section", 1,
679 "CapabilityBoundingSet", 0, "~",
680 &capability_bounding_set
, NULL
);
682 assert_se(cap_test_all(capability_bounding_set
));
684 capability_bounding_set
= 0;
685 r
= config_parse_capability_set(NULL
, "fake", 1, "section", 1,
686 "CapabilityBoundingSet", 0, " 'CAP_NET_RAW' WAT_CAP??? CAP_NET_ADMIN CAP'_trailing_garbage",
687 &capability_bounding_set
, NULL
);
689 assert_se(capability_bounding_set
== (make_cap(CAP_NET_RAW
) | make_cap(CAP_NET_ADMIN
)));
692 static void test_config_parse_rlimit(void) {
693 struct rlimit
* rl
[_RLIMIT_MAX
] = {};
695 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE
, "55", rl
, NULL
) >= 0);
696 assert_se(rl
[RLIMIT_NOFILE
]);
697 assert_se(rl
[RLIMIT_NOFILE
]->rlim_cur
== 55);
698 assert_se(rl
[RLIMIT_NOFILE
]->rlim_cur
== rl
[RLIMIT_NOFILE
]->rlim_max
);
700 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE
, "55:66", rl
, NULL
) >= 0);
701 assert_se(rl
[RLIMIT_NOFILE
]);
702 assert_se(rl
[RLIMIT_NOFILE
]->rlim_cur
== 55);
703 assert_se(rl
[RLIMIT_NOFILE
]->rlim_max
== 66);
705 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE
, "infinity", rl
, NULL
) >= 0);
706 assert_se(rl
[RLIMIT_NOFILE
]);
707 assert_se(rl
[RLIMIT_NOFILE
]->rlim_cur
== RLIM_INFINITY
);
708 assert_se(rl
[RLIMIT_NOFILE
]->rlim_cur
== rl
[RLIMIT_NOFILE
]->rlim_max
);
710 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE
, "infinity:infinity", rl
, NULL
) >= 0);
711 assert_se(rl
[RLIMIT_NOFILE
]);
712 assert_se(rl
[RLIMIT_NOFILE
]->rlim_cur
== RLIM_INFINITY
);
713 assert_se(rl
[RLIMIT_NOFILE
]->rlim_cur
== rl
[RLIMIT_NOFILE
]->rlim_max
);
715 rl
[RLIMIT_NOFILE
]->rlim_cur
= 10;
716 rl
[RLIMIT_NOFILE
]->rlim_max
= 20;
718 /* Invalid values don't change rl */
719 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE
, "10:20:30", rl
, NULL
) >= 0);
720 assert_se(rl
[RLIMIT_NOFILE
]);
721 assert_se(rl
[RLIMIT_NOFILE
]->rlim_cur
== 10);
722 assert_se(rl
[RLIMIT_NOFILE
]->rlim_max
== 20);
724 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE
, "wat:wat", rl
, NULL
) >= 0);
725 assert_se(rl
[RLIMIT_NOFILE
]);
726 assert_se(rl
[RLIMIT_NOFILE
]->rlim_cur
== 10);
727 assert_se(rl
[RLIMIT_NOFILE
]->rlim_max
== 20);
729 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE
, "66:wat", rl
, NULL
) >= 0);
730 assert_se(rl
[RLIMIT_NOFILE
]);
731 assert_se(rl
[RLIMIT_NOFILE
]->rlim_cur
== 10);
732 assert_se(rl
[RLIMIT_NOFILE
]->rlim_max
== 20);
734 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE
, "200:100", rl
, NULL
) >= 0);
735 assert_se(rl
[RLIMIT_NOFILE
]);
736 assert_se(rl
[RLIMIT_NOFILE
]->rlim_cur
== 10);
737 assert_se(rl
[RLIMIT_NOFILE
]->rlim_max
== 20);
739 rl
[RLIMIT_NOFILE
] = mfree(rl
[RLIMIT_NOFILE
]);
741 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitCPU", RLIMIT_CPU
, "56", rl
, NULL
) >= 0);
742 assert_se(rl
[RLIMIT_CPU
]);
743 assert_se(rl
[RLIMIT_CPU
]->rlim_cur
== 56);
744 assert_se(rl
[RLIMIT_CPU
]->rlim_cur
== rl
[RLIMIT_CPU
]->rlim_max
);
746 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitCPU", RLIMIT_CPU
, "57s", rl
, NULL
) >= 0);
747 assert_se(rl
[RLIMIT_CPU
]);
748 assert_se(rl
[RLIMIT_CPU
]->rlim_cur
== 57);
749 assert_se(rl
[RLIMIT_CPU
]->rlim_cur
== rl
[RLIMIT_CPU
]->rlim_max
);
751 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitCPU", RLIMIT_CPU
, "40s:1m", rl
, NULL
) >= 0);
752 assert_se(rl
[RLIMIT_CPU
]);
753 assert_se(rl
[RLIMIT_CPU
]->rlim_cur
== 40);
754 assert_se(rl
[RLIMIT_CPU
]->rlim_max
== 60);
756 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitCPU", RLIMIT_CPU
, "infinity", rl
, NULL
) >= 0);
757 assert_se(rl
[RLIMIT_CPU
]);
758 assert_se(rl
[RLIMIT_CPU
]->rlim_cur
== RLIM_INFINITY
);
759 assert_se(rl
[RLIMIT_CPU
]->rlim_cur
== rl
[RLIMIT_CPU
]->rlim_max
);
761 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitCPU", RLIMIT_CPU
, "1234ms", rl
, NULL
) >= 0);
762 assert_se(rl
[RLIMIT_CPU
]);
763 assert_se(rl
[RLIMIT_CPU
]->rlim_cur
== 2);
764 assert_se(rl
[RLIMIT_CPU
]->rlim_cur
== rl
[RLIMIT_CPU
]->rlim_max
);
766 rl
[RLIMIT_CPU
] = mfree(rl
[RLIMIT_CPU
]);
768 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitRTTIME", RLIMIT_RTTIME
, "58", rl
, NULL
) >= 0);
769 assert_se(rl
[RLIMIT_RTTIME
]);
770 assert_se(rl
[RLIMIT_RTTIME
]->rlim_cur
== 58);
771 assert_se(rl
[RLIMIT_RTTIME
]->rlim_cur
== rl
[RLIMIT_RTTIME
]->rlim_max
);
773 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitRTTIME", RLIMIT_RTTIME
, "58:60", rl
, NULL
) >= 0);
774 assert_se(rl
[RLIMIT_RTTIME
]);
775 assert_se(rl
[RLIMIT_RTTIME
]->rlim_cur
== 58);
776 assert_se(rl
[RLIMIT_RTTIME
]->rlim_max
== 60);
778 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitRTTIME", RLIMIT_RTTIME
, "59s", rl
, NULL
) >= 0);
779 assert_se(rl
[RLIMIT_RTTIME
]);
780 assert_se(rl
[RLIMIT_RTTIME
]->rlim_cur
== 59 * USEC_PER_SEC
);
781 assert_se(rl
[RLIMIT_RTTIME
]->rlim_cur
== rl
[RLIMIT_RTTIME
]->rlim_max
);
783 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitRTTIME", RLIMIT_RTTIME
, "59s:123s", rl
, NULL
) >= 0);
784 assert_se(rl
[RLIMIT_RTTIME
]);
785 assert_se(rl
[RLIMIT_RTTIME
]->rlim_cur
== 59 * USEC_PER_SEC
);
786 assert_se(rl
[RLIMIT_RTTIME
]->rlim_max
== 123 * USEC_PER_SEC
);
788 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitRTTIME", RLIMIT_RTTIME
, "infinity", rl
, NULL
) >= 0);
789 assert_se(rl
[RLIMIT_RTTIME
]);
790 assert_se(rl
[RLIMIT_RTTIME
]->rlim_cur
== RLIM_INFINITY
);
791 assert_se(rl
[RLIMIT_RTTIME
]->rlim_cur
== rl
[RLIMIT_RTTIME
]->rlim_max
);
793 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitRTTIME", RLIMIT_RTTIME
, "infinity:infinity", rl
, NULL
) >= 0);
794 assert_se(rl
[RLIMIT_RTTIME
]);
795 assert_se(rl
[RLIMIT_RTTIME
]->rlim_cur
== RLIM_INFINITY
);
796 assert_se(rl
[RLIMIT_RTTIME
]->rlim_cur
== rl
[RLIMIT_RTTIME
]->rlim_max
);
798 assert_se(config_parse_limit(NULL
, "fake", 1, "section", 1, "LimitRTTIME", RLIMIT_RTTIME
, "2345ms", rl
, NULL
) >= 0);
799 assert_se(rl
[RLIMIT_RTTIME
]);
800 assert_se(rl
[RLIMIT_RTTIME
]->rlim_cur
== 2345 * USEC_PER_MSEC
);
801 assert_se(rl
[RLIMIT_RTTIME
]->rlim_cur
== rl
[RLIMIT_RTTIME
]->rlim_max
);
803 rl
[RLIMIT_RTTIME
] = mfree(rl
[RLIMIT_RTTIME
]);
806 static void test_config_parse_pass_environ(void) {
807 /* int config_parse_pass_environ(
809 const char *filename,
812 unsigned section_line,
819 _cleanup_strv_free_
char **passenv
= NULL
;
821 r
= config_parse_pass_environ(NULL
, "fake", 1, "section", 1,
822 "PassEnvironment", 0, "A B",
825 assert_se(strv_length(passenv
) == 2);
826 assert_se(streq(passenv
[0], "A"));
827 assert_se(streq(passenv
[1], "B"));
829 r
= config_parse_pass_environ(NULL
, "fake", 1, "section", 1,
830 "PassEnvironment", 0, "",
833 assert_se(strv_isempty(passenv
));
835 r
= config_parse_pass_environ(NULL
, "fake", 1, "section", 1,
836 "PassEnvironment", 0, "'invalid name' 'normal_name' A=1 \\",
839 assert_se(strv_length(passenv
) == 1);
840 assert_se(streq(passenv
[0], "normal_name"));
844 int main(int argc
, char *argv
[]) {
845 _cleanup_(rm_rf_physical_and_freep
) char *runtime_dir
= NULL
;
848 log_parse_environment();
851 assert_se(runtime_dir
= setup_fake_runtime_dir());
853 r
= test_unit_file_get_set();
854 test_config_parse_exec();
855 test_config_parse_capability_set();
856 test_config_parse_rlimit();
857 test_config_parse_pass_environ();
858 test_load_env_file_1();
859 test_load_env_file_2();
860 test_load_env_file_3();
861 test_load_env_file_4();
862 test_load_env_file_5();
863 TEST_REQ_RUNNING_SYSTEMD(test_install_printf());