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