1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2012 Lennart Poettering
7 Copyright 2013 Zbigniew Jędrzejewski-Szmek
9 systemd is free software; you can redistribute it and/or modify it
10 under the terms of the GNU Lesser General Public License as published by
11 the Free Software Foundation; either version 2.1 of the License, or
12 (at your option) any later version.
14 systemd is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
19 You should have received a copy of the GNU Lesser General Public License
20 along with systemd; If not, see <http://www.gnu.org/licenses/>.
31 #include "install-printf.h"
32 #include "specifier.h"
36 #include "load-fragment.h"
39 #include "test-helper.h"
41 static int test_unit_file_get_set(void) {
47 h = hashmap_new(&string_hash_ops);
50 r = unit_file_get_list(UNIT_FILE_SYSTEM, NULL, h);
52 if (r == -EPERM || r == -EACCES) {
53 printf("Skipping test: unit_file_get_list: %s", strerror(-r));
54 return EXIT_TEST_SKIP;
57 log_full(r == 0 ? LOG_INFO : LOG_ERR,
58 "unit_file_get_list: %s", strerror(-r));
62 HASHMAP_FOREACH(p, h, i)
63 printf("%s = %s\n", p->path, unit_file_state_to_string(p->state));
65 unit_file_list_free(h);
70 static void check_execcommand(ExecCommand *c,
77 log_info("%s %s %s %s",
78 c->path, c->argv[0], c->argv[1], c->argv[2]);
79 assert_se(streq(c->path, path));
80 assert_se(streq(c->argv[0], argv0));
81 assert_se(streq(c->argv[1], argv1));
82 assert_se(streq_ptr(c->argv[2], argv2));
83 assert_se(c->ignore == ignore);
86 static void test_config_parse_exec(void) {
87 /* int config_parse_exec( */
88 /* const char *filename, */
90 /* const char *section, */
91 /* unsigned section_line, */
92 /* const char *lvalue, */
94 /* const char *rvalue, */
99 ExecCommand *c = NULL, *c1;
102 r = config_parse_exec(NULL, "fake", 1, "section", 1,
103 "LValue", 0, "/RValue r1",
106 check_execcommand(c, "/RValue", "/RValue", "r1", NULL, false);
108 r = config_parse_exec(NULL, "fake", 2, "section", 1,
109 "LValue", 0, "/RValue///slashes/// r1",
113 c1 = c->command_next;
114 check_execcommand(c1, "/RValue/slashes", "/RValue///slashes///", "r1", NULL, false);
117 r = config_parse_exec(NULL, "fake", 3, "section", 1,
118 "LValue", 0, "@/RValue///slashes2/// argv0 r1",
121 c1 = c1->command_next;
122 check_execcommand(c1, "/RValue/slashes2", "argv0", "r1", NULL, false);
124 /* ignore && honour_argv0 */
125 r = config_parse_exec(NULL, "fake", 4, "section", 1,
126 "LValue", 0, "-@/RValue///slashes3/// argv0a r1",
129 c1 = c1->command_next;
130 check_execcommand(c1, "/RValue/slashes3", "argv0a", "r1", NULL, true);
132 /* ignore && honour_argv0 */
133 r = config_parse_exec(NULL, "fake", 4, "section", 1,
134 "LValue", 0, "@-/RValue///slashes4/// argv0b r1",
137 c1 = c1->command_next;
138 check_execcommand(c1, "/RValue/slashes4", "argv0b", "r1", NULL, true);
140 /* ignore && ignore */
141 r = config_parse_exec(NULL, "fake", 4, "section", 1,
142 "LValue", 0, "--/RValue argv0 r1",
145 assert_se(c1->command_next == NULL);
147 /* ignore && ignore */
148 r = config_parse_exec(NULL, "fake", 4, "section", 1,
149 "LValue", 0, "-@-/RValue argv0 r1",
152 assert_se(c1->command_next == NULL);
155 r = config_parse_exec(NULL, "fake", 5, "section", 1,
157 "-@/RValue argv0 r1 ; "
161 c1 = c1->command_next;
162 check_execcommand(c1, "/RValue", "argv0", "r1", NULL, true);
164 c1 = c1->command_next;
165 check_execcommand(c1, "/goo/goo", "/goo/goo", "boo", NULL, false);
167 /* trailing semicolon */
168 r = config_parse_exec(NULL, "fake", 5, "section", 1,
170 "-@/RValue argv0 r1 ; ",
173 c1 = c1->command_next;
174 check_execcommand(c1, "/RValue", "argv0", "r1", NULL, true);
176 assert_se(c1->command_next == NULL);
178 /* escaped semicolon */
179 r = config_parse_exec(NULL, "fake", 5, "section", 1,
184 c1 = c1->command_next;
185 check_execcommand(c1, "/bin/find", "/bin/find", ";", NULL, false);
187 /* escaped semicolon with following arg */
188 r = config_parse_exec(NULL, "fake", 5, "section", 1,
193 c1 = c1->command_next;
194 check_execcommand(c1,
195 "/sbin/find", "/sbin/find", ";", "x", false);
197 exec_command_free_list(c);
215 "#SPAMD_ARGS=\"-d --socketpath=/var/lib/bulwark/spamd \\\n" \
216 "#--nouser-config \\\n" \
222 "HWMON_MODULES=\"coretemp f71882fg\"\n" \
224 "# For compatibility reasons\n" \
226 "MODULE_0=coretemp\n" \
233 static void test_load_env_file_1(void) {
234 _cleanup_strv_free_ char **data = NULL;
237 char name[] = "/tmp/test-load-env-file.XXXXXX";
238 _cleanup_close_ int fd;
240 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
242 assert_se(write(fd, env_file_1, sizeof(env_file_1)) == sizeof(env_file_1));
244 r = load_env_file(NULL, name, NULL, &data);
246 assert_se(streq(data[0], "a=a"));
247 assert_se(streq(data[1], "b=bc"));
248 assert_se(streq(data[2], "d=def"));
249 assert_se(streq(data[3], "g=g "));
250 assert_se(streq(data[4], "h=h"));
251 assert_se(streq(data[5], "i=i"));
252 assert_se(data[6] == NULL);
256 static void test_load_env_file_2(void) {
257 _cleanup_strv_free_ char **data = NULL;
260 char name[] = "/tmp/test-load-env-file.XXXXXX";
261 _cleanup_close_ int fd;
263 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
265 assert_se(write(fd, env_file_2, sizeof(env_file_2)) == sizeof(env_file_2));
267 r = load_env_file(NULL, name, NULL, &data);
269 assert_se(streq(data[0], "a=a"));
270 assert_se(data[1] == NULL);
274 static void test_load_env_file_3(void) {
275 _cleanup_strv_free_ char **data = NULL;
278 char name[] = "/tmp/test-load-env-file.XXXXXX";
279 _cleanup_close_ int fd;
281 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
283 assert_se(write(fd, env_file_3, sizeof(env_file_3)) == sizeof(env_file_3));
285 r = load_env_file(NULL, name, NULL, &data);
287 assert_se(data == NULL);
291 static void test_load_env_file_4(void) {
292 _cleanup_strv_free_ char **data = NULL;
293 char name[] = "/tmp/test-load-env-file.XXXXXX";
294 _cleanup_close_ int fd;
297 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
299 assert_se(write(fd, env_file_4, sizeof(env_file_4)) == sizeof(env_file_4));
301 r = load_env_file(NULL, name, NULL, &data);
303 assert_se(streq(data[0], "HWMON_MODULES=coretemp f71882fg"));
304 assert_se(streq(data[1], "MODULE_0=coretemp"));
305 assert_se(streq(data[2], "MODULE_1=f71882fg"));
306 assert_se(data[3] == NULL);
310 static void test_load_env_file_5(void) {
311 _cleanup_strv_free_ char **data = NULL;
314 char name[] = "/tmp/test-load-env-file.XXXXXX";
315 _cleanup_close_ int fd;
317 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
319 assert_se(write(fd, env_file_5, sizeof(env_file_5)) == sizeof(env_file_5));
321 r = load_env_file(NULL, name, NULL, &data);
323 assert_se(streq(data[0], "a="));
324 assert_se(streq(data[1], "b="));
325 assert_se(data[2] == NULL);
329 static void test_install_printf(void) {
330 char name[] = "name.service",
331 path[] = "/run/systemd/system/name.service",
332 user[] = "xxxx-no-such-user";
333 InstallInfo i = {name, path, user};
334 InstallInfo i2 = {name, path, NULL};
335 char name3[] = "name@inst.service",
336 path3[] = "/run/systemd/system/name.service";
337 InstallInfo i3 = {name3, path3, user};
338 InstallInfo i4 = {name3, path3, NULL};
340 _cleanup_free_ char *mid, *bid, *host;
342 assert_se(specifier_machine_id('m', NULL, NULL, &mid) >= 0 && mid);
343 assert_se(specifier_boot_id('b', NULL, NULL, &bid) >= 0 && bid);
344 assert_se((host = gethostname_malloc()));
346 #define expect(src, pattern, result) \
348 _cleanup_free_ char *t = NULL; \
349 _cleanup_free_ char \
350 *d1 = strdup(i.name), \
351 *d2 = strdup(i.path), \
352 *d3 = strdup(i.user); \
353 assert_se(install_full_printf(&src, pattern, &t) >= 0 || !result); \
354 memzero(i.name, strlen(i.name)); \
355 memzero(i.path, strlen(i.path)); \
356 memzero(i.user, strlen(i.user)); \
357 assert_se(d1 && d2 && d3); \
360 assert_se(streq(t, result)); \
361 } else assert_se(t == NULL); \
362 strcpy(i.name, d1); \
363 strcpy(i.path, d2); \
364 strcpy(i.user, d3); \
367 assert_se(setenv("USER", "root", 1) == 0);
369 expect(i, "%n", "name.service");
370 expect(i, "%N", "name");
371 expect(i, "%p", "name");
373 expect(i, "%u", "xxxx-no-such-user");
375 DISABLE_WARNING_NONNULL;
376 expect(i, "%U", NULL);
379 expect(i, "%m", mid);
380 expect(i, "%b", bid);
381 expect(i, "%H", host);
383 expect(i2, "%u", "root");
384 expect(i2, "%U", "0");
386 expect(i3, "%n", "name@inst.service");
387 expect(i3, "%N", "name@inst");
388 expect(i3, "%p", "name");
389 expect(i3, "%u", "xxxx-no-such-user");
391 DISABLE_WARNING_NONNULL;
392 expect(i3, "%U", NULL);
395 expect(i3, "%m", mid);
396 expect(i3, "%b", bid);
397 expect(i3, "%H", host);
399 expect(i4, "%u", "root");
400 expect(i4, "%U", "0");
403 int main(int argc, char *argv[]) {
406 log_parse_environment();
409 r = test_unit_file_get_set();
410 test_config_parse_exec();
411 test_load_env_file_1();
412 test_load_env_file_2();
413 test_load_env_file_3();
414 test_load_env_file_4();
415 test_load_env_file_5();
416 TEST_REQ_RUNNING_SYSTEMD(test_install_printf());