]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/test/test-unit-file.c
Fix several small typos
[thirdparty/systemd.git] / src / test / test-unit-file.c
CommitLineData
b5b46d59
LP
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2012 Lennart Poettering
b9893505 7 Copyright 2013 Zbigniew Jędrzejewski-Szmek
b5b46d59
LP
8
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.
13
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.
18
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/>.
21***/
22
23#include <assert.h>
24#include <stdio.h>
25#include <stddef.h>
26#include <string.h>
b9893505 27#include <unistd.h>
2d5bdf5b 28#include <fcntl.h>
b5b46d59
LP
29
30#include "install.h"
7742f7e9
ZJS
31#include "install-printf.h"
32#include "specifier.h"
b5b46d59
LP
33#include "util.h"
34#include "macro.h"
35#include "hashmap.h"
2c5417ad 36#include "load-fragment.h"
b9893505 37#include "strv.h"
a5c32cff 38#include "fileio.h"
143bfdaf 39#include "test-helper.h"
b5b46d59 40
751e7576 41static int test_unit_file_get_set(void) {
b5b46d59
LP
42 int r;
43 Hashmap *h;
44 Iterator i;
45 UnitFileList *p;
46
47 h = hashmap_new(string_hash_func, string_compare_func);
48 assert(h);
49
50 r = unit_file_get_list(UNIT_FILE_SYSTEM, NULL, h);
751e7576
CH
51 log_full(r == 0 ? LOG_INFO : LOG_ERR,
52 "unit_file_get_list: %s", strerror(-r));
53 if (r < 0)
54 return EXIT_FAILURE;
b5b46d59
LP
55
56 HASHMAP_FOREACH(p, h, i)
57 printf("%s = %s\n", p->path, unit_file_state_to_string(p->state));
58
59 unit_file_list_free(h);
751e7576
CH
60
61 return 0;
2c5417ad
ZJS
62}
63
64static void check_execcommand(ExecCommand *c,
65 const char* path,
66 const char* argv0,
67 const char* argv1,
68 bool ignore) {
69 assert_se(c);
70 log_info("%s %s %s %s",
71 c->path, c->argv[0], c->argv[1], c->argv[2]);
72 assert_se(streq(c->path, path));
73 assert_se(streq(c->argv[0], argv0));
74 assert_se(streq(c->argv[1], argv1));
75 assert_se(c->argv[2] == NULL);
76 assert_se(c->ignore == ignore);
77}
78
79static void test_config_parse_exec(void) {
80 /* int config_parse_exec( */
81 /* const char *filename, */
82 /* unsigned line, */
83 /* const char *section, */
71a61510 84 /* unsigned section_line, */
2c5417ad
ZJS
85 /* const char *lvalue, */
86 /* int ltype, */
87 /* const char *rvalue, */
88 /* void *data, */
89 /* void *userdata) */
90 int r;
91
92 ExecCommand *c = NULL, *c1;
93
94 /* basic test */
71a61510 95 r = config_parse_exec(NULL, "fake", 1, "section", 1,
2c5417ad
ZJS
96 "LValue", 0, "/RValue r1",
97 &c, NULL);
98 assert_se(r >= 0);
99 check_execcommand(c, "/RValue", "/RValue", "r1", false);
100
71a61510 101 r = config_parse_exec(NULL, "fake", 2, "section", 1,
2c5417ad
ZJS
102 "LValue", 0, "/RValue///slashes/// r1",
103 &c, NULL);
104 /* test slashes */
105 assert_se(r >= 0);
106 c1 = c->command_next;
107 check_execcommand(c1, "/RValue/slashes", "/RValue///slashes///",
108 "r1", false);
109
110 /* honour_argv0 */
71a61510 111 r = config_parse_exec(NULL, "fake", 3, "section", 1,
2c5417ad
ZJS
112 "LValue", 0, "@/RValue///slashes2/// argv0 r1",
113 &c, NULL);
114 assert_se(r >= 0);
115 c1 = c1->command_next;
116 check_execcommand(c1, "/RValue/slashes2", "argv0", "r1", false);
117
118 /* ignore && honour_argv0 */
71a61510 119 r = config_parse_exec(NULL, "fake", 4, "section", 1,
2c5417ad
ZJS
120 "LValue", 0, "-@/RValue///slashes3/// argv0a r1",
121 &c, NULL);
122 assert_se(r >= 0);
123 c1 = c1->command_next;
124 check_execcommand(c1,
125 "/RValue/slashes3", "argv0a", "r1", true);
126
0f67f1ef 127 /* ignore && honour_argv0 */
71a61510 128 r = config_parse_exec(NULL, "fake", 4, "section", 1,
0f67f1ef
ZJS
129 "LValue", 0, "@-/RValue///slashes4/// argv0b r1",
130 &c, NULL);
131 assert_se(r >= 0);
132 c1 = c1->command_next;
133 check_execcommand(c1,
134 "/RValue/slashes4", "argv0b", "r1", true);
135
136 /* ignore && ignore */
71a61510 137 r = config_parse_exec(NULL, "fake", 4, "section", 1,
0f67f1ef
ZJS
138 "LValue", 0, "--/RValue argv0 r1",
139 &c, NULL);
140 assert_se(r == 0);
141 assert_se(c1->command_next == NULL);
142
143 /* ignore && ignore */
71a61510 144 r = config_parse_exec(NULL, "fake", 4, "section", 1,
0f67f1ef
ZJS
145 "LValue", 0, "-@-/RValue argv0 r1",
146 &c, NULL);
147 assert_se(r == 0);
148 assert_se(c1->command_next == NULL);
149
2c5417ad 150 /* semicolon */
71a61510 151 r = config_parse_exec(NULL, "fake", 5, "section", 1,
2c5417ad
ZJS
152 "LValue", 0,
153 "-@/RValue argv0 r1 ; "
154 "/goo/goo boo",
155 &c, NULL);
156 assert_se(r >= 0);
157 c1 = c1->command_next;
158 check_execcommand(c1,
159 "/RValue", "argv0", "r1", true);
160
161 c1 = c1->command_next;
162 check_execcommand(c1,
163 "/goo/goo", "/goo/goo", "boo", false);
164
165 /* trailing semicolon */
71a61510 166 r = config_parse_exec(NULL, "fake", 5, "section", 1,
2c5417ad
ZJS
167 "LValue", 0,
168 "-@/RValue argv0 r1 ; ",
169 &c, NULL);
170 assert_se(r >= 0);
171 c1 = c1->command_next;
172 check_execcommand(c1,
173 "/RValue", "argv0", "r1", true);
174
175 assert_se(c1->command_next == NULL);
176
7e1a84f5 177 /* escaped semicolon */
71a61510 178 r = config_parse_exec(NULL, "fake", 5, "section", 1,
7e1a84f5
OS
179 "LValue", 0,
180 "/usr/bin/find \\;",
181 &c, NULL);
182 assert_se(r >= 0);
183 c1 = c1->command_next;
184 check_execcommand(c1,
185 "/usr/bin/find", "/usr/bin/find", ";", false);
186
2c5417ad
ZJS
187 exec_command_free_list(c);
188}
189
f73141d7
LP
190#define env_file_1 \
191 "a=a\n" \
192 "b=b\\\n" \
193 "c\n" \
194 "d=d\\\n" \
195 "e\\\n" \
196 "f\n" \
197 "g=g\\ \n" \
198 "h=h\n" \
199 "i=i\\"
200
201#define env_file_2 \
202 "a=a\\\n"
b9893505 203
a3aa7ee6
ZJS
204#define env_file_3 \
205 "#SPAMD_ARGS=\"-d --socketpath=/var/lib/bulwark/spamd \\\n" \
206 "#--nouser-config \\\n" \
207 "normal=line"
208
d3b6d0c2
ZJS
209#define env_file_4 \
210 "# Generated\n" \
211 "\n" \
212 "HWMON_MODULES=\"coretemp f71882fg\"\n" \
213 "\n" \
214 "# For compatibility reasons\n" \
215 "\n" \
216 "MODULE_0=coretemp\n" \
217 "MODULE_1=f71882fg"
218
219
b9893505 220static void test_load_env_file_1(void) {
7fd1b19b 221 _cleanup_strv_free_ char **data = NULL;
b9893505
ZJS
222 int r;
223
224 char name[] = "/tmp/test-load-env-file.XXXXXX";
2d5bdf5b
LP
225 _cleanup_close_ int fd;
226
227 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
b9893505
ZJS
228 assert(fd >= 0);
229 assert_se(write(fd, env_file_1, sizeof(env_file_1)) == sizeof(env_file_1));
230
f73141d7 231 r = load_env_file(name, NULL, &data);
b9893505 232 assert(r == 0);
f73141d7
LP
233 assert(streq(data[0], "a=a"));
234 assert(streq(data[1], "b=bc"));
235 assert(streq(data[2], "d=def"));
236 assert(streq(data[3], "g=g "));
237 assert(streq(data[4], "h=h"));
238 assert(streq(data[5], "i=i"));
b9893505
ZJS
239 assert(data[6] == NULL);
240 unlink(name);
241}
242
243static void test_load_env_file_2(void) {
7fd1b19b 244 _cleanup_strv_free_ char **data = NULL;
b9893505
ZJS
245 int r;
246
247 char name[] = "/tmp/test-load-env-file.XXXXXX";
2d5bdf5b
LP
248 _cleanup_close_ int fd;
249
250 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
b9893505
ZJS
251 assert(fd >= 0);
252 assert_se(write(fd, env_file_2, sizeof(env_file_2)) == sizeof(env_file_2));
253
f73141d7 254 r = load_env_file(name, NULL, &data);
b9893505 255 assert(r == 0);
f73141d7 256 assert(streq(data[0], "a=a"));
b9893505
ZJS
257 assert(data[1] == NULL);
258 unlink(name);
259}
260
a3aa7ee6 261static void test_load_env_file_3(void) {
7fd1b19b 262 _cleanup_strv_free_ char **data = NULL;
a3aa7ee6
ZJS
263 int r;
264
265 char name[] = "/tmp/test-load-env-file.XXXXXX";
2d5bdf5b
LP
266 _cleanup_close_ int fd;
267
268 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
a3aa7ee6
ZJS
269 assert(fd >= 0);
270 assert_se(write(fd, env_file_3, sizeof(env_file_3)) == sizeof(env_file_3));
271
f73141d7 272 r = load_env_file(name, NULL, &data);
a3aa7ee6
ZJS
273 assert(r == 0);
274 assert(data == NULL);
275 unlink(name);
276}
277
d3b6d0c2 278static void test_load_env_file_4(void) {
7fd1b19b 279 _cleanup_strv_free_ char **data = NULL;
2d5bdf5b
LP
280 char name[] = "/tmp/test-load-env-file.XXXXXX";
281 _cleanup_close_ int fd;
d3b6d0c2
ZJS
282 int r;
283
2d5bdf5b 284 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
d3b6d0c2
ZJS
285 assert(fd >= 0);
286 assert_se(write(fd, env_file_4, sizeof(env_file_4)) == sizeof(env_file_4));
287
288 r = load_env_file(name, NULL, &data);
289 assert(r == 0);
290 assert(streq(data[0], "HWMON_MODULES=coretemp f71882fg"));
291 assert(streq(data[1], "MODULE_0=coretemp"));
292 assert(streq(data[2], "MODULE_1=f71882fg"));
293 assert(data[3] == NULL);
294 unlink(name);
295}
296
297
7742f7e9
ZJS
298static void test_install_printf(void) {
299 char name[] = "name.service",
ad88e758 300 path[] = "/run/systemd/system/name.service",
7742f7e9
ZJS
301 user[] = "xxxx-no-such-user";
302 InstallInfo i = {name, path, user};
303 InstallInfo i2 = {name, path, NULL};
304 char name3[] = "name@inst.service",
ad88e758 305 path3[] = "/run/systemd/system/name.service";
7742f7e9
ZJS
306 InstallInfo i3 = {name3, path3, user};
307 InstallInfo i4 = {name3, path3, NULL};
308
7fd1b19b 309 _cleanup_free_ char *mid, *bid, *host;
7742f7e9 310
19f6d710
LP
311 assert_se(specifier_machine_id('m', NULL, NULL, &mid) >= 0 && mid);
312 assert_se(specifier_boot_id('b', NULL, NULL, &bid) >= 0 && bid);
7742f7e9
ZJS
313 assert_se((host = gethostname_malloc()));
314
315#define expect(src, pattern, result) \
f73141d7 316 do { \
19f6d710 317 _cleanup_free_ char *t = NULL; \
7fd1b19b 318 _cleanup_free_ char \
7742f7e9
ZJS
319 *d1 = strdup(i.name), \
320 *d2 = strdup(i.path), \
321 *d3 = strdup(i.user); \
19f6d710 322 assert_se(install_full_printf(&src, pattern, &t) >= 0 || !result); \
7742f7e9
ZJS
323 memzero(i.name, strlen(i.name)); \
324 memzero(i.path, strlen(i.path)); \
325 memzero(i.user, strlen(i.user)); \
326 assert(d1 && d2 && d3); \
327 if (result) { \
328 printf("%s\n", t); \
329 assert(streq(t, result)); \
330 } else assert(t == NULL); \
331 strcpy(i.name, d1); \
332 strcpy(i.path, d2); \
333 strcpy(i.user, d3); \
f73141d7 334 } while(false)
7742f7e9
ZJS
335
336 assert_se(setenv("USER", "root", 1) == 0);
337
338 expect(i, "%n", "name.service");
339 expect(i, "%N", "name");
340 expect(i, "%p", "name");
341 expect(i, "%i", "");
342 expect(i, "%u", "xxxx-no-such-user");
8fca4e30
LP
343
344 DISABLE_WARNING_NONNULL;
7742f7e9 345 expect(i, "%U", NULL);
8fca4e30
LP
346 REENABLE_WARNING;
347
7742f7e9
ZJS
348 expect(i, "%m", mid);
349 expect(i, "%b", bid);
350 expect(i, "%H", host);
351
352 expect(i2, "%u", "root");
353 expect(i2, "%U", "0");
354
355 expect(i3, "%n", "name@inst.service");
356 expect(i3, "%N", "name@inst");
357 expect(i3, "%p", "name");
358 expect(i3, "%u", "xxxx-no-such-user");
8fca4e30
LP
359
360 DISABLE_WARNING_NONNULL;
7742f7e9 361 expect(i3, "%U", NULL);
8fca4e30
LP
362 REENABLE_WARNING;
363
7742f7e9
ZJS
364 expect(i3, "%m", mid);
365 expect(i3, "%b", bid);
366 expect(i3, "%H", host);
367
368 expect(i4, "%u", "root");
369 expect(i4, "%U", "0");
370}
b9893505 371
2c5417ad 372int main(int argc, char *argv[]) {
751e7576 373 int r;
2c5417ad 374
c1b6628d
ZJS
375 log_parse_environment();
376 log_open();
377
751e7576 378 r = test_unit_file_get_set();
2c5417ad 379 test_config_parse_exec();
b9893505
ZJS
380 test_load_env_file_1();
381 test_load_env_file_2();
a3aa7ee6 382 test_load_env_file_3();
d3b6d0c2 383 test_load_env_file_4();
143bfdaf 384 TEST_REQ_RUNNING_SYSTEMD(test_install_printf());
b5b46d59 385
751e7576 386 return r;
b5b46d59 387}