chiark / gitweb /
tests: more tests
[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
38 static void test_unit_file_get_set(void) {
39         int r;
40         Hashmap *h;
41         Iterator i;
42         UnitFileList *p;
43
44         h = hashmap_new(string_hash_func, string_compare_func);
45         assert(h);
46
47         r = unit_file_get_list(UNIT_FILE_SYSTEM, NULL, h);
48         log_info("unit_file_get_list: %s", strerror(-r));
49         assert(r >= 0);
50
51         HASHMAP_FOREACH(p, h, i)
52                 printf("%s = %s\n", p->path, unit_file_state_to_string(p->state));
53
54         unit_file_list_free(h);
55 }
56
57 static void check_execcommand(ExecCommand *c,
58                               const char* path,
59                               const char* argv0,
60                               const char* argv1,
61                               bool ignore) {
62         assert_se(c);
63         log_info("%s %s %s %s",
64                  c->path, c->argv[0], c->argv[1], c->argv[2]);
65         assert_se(streq(c->path, path));
66         assert_se(streq(c->argv[0], argv0));
67         assert_se(streq(c->argv[1], argv1));
68         assert_se(c->argv[2] == NULL);
69         assert_se(c->ignore == ignore);
70 }
71
72 static void test_config_parse_exec(void) {
73         /* int config_parse_exec( */
74         /*         const char *filename, */
75         /*         unsigned line, */
76         /*         const char *section, */
77         /*         const char *lvalue, */
78         /*         int ltype, */
79         /*         const char *rvalue, */
80         /*         void *data, */
81         /*         void *userdata) */
82         int r;
83
84         ExecCommand *c = NULL, *c1;
85
86         /* basic test */
87         r = config_parse_exec("fake", 1, "section",
88                               "LValue", 0, "/RValue r1",
89                               &c, NULL);
90         assert_se(r >= 0);
91         check_execcommand(c, "/RValue", "/RValue", "r1", false);
92
93         r = config_parse_exec("fake", 2, "section",
94                               "LValue", 0, "/RValue///slashes/// r1",
95                               &c, NULL);
96        /* test slashes */
97         assert_se(r >= 0);
98         c1 = c->command_next;
99         check_execcommand(c1, "/RValue/slashes", "/RValue///slashes///",
100                           "r1", false);
101
102         /* honour_argv0 */
103         r = config_parse_exec("fake", 3, "section",
104                               "LValue", 0, "@/RValue///slashes2/// argv0 r1",
105                               &c, NULL);
106         assert_se(r >= 0);
107         c1 = c1->command_next;
108         check_execcommand(c1, "/RValue/slashes2", "argv0", "r1", false);
109
110         /* ignore && honour_argv0 */
111         r = config_parse_exec("fake", 4, "section",
112                               "LValue", 0, "-@/RValue///slashes3/// argv0a r1",
113                               &c, NULL);
114         assert_se(r >= 0);
115         c1 = c1->command_next;
116         check_execcommand(c1,
117                           "/RValue/slashes3", "argv0a", "r1", true);
118
119         /* ignore && honour_argv0 */
120         r = config_parse_exec("fake", 4, "section",
121                               "LValue", 0, "@-/RValue///slashes4/// argv0b r1",
122                               &c, NULL);
123         assert_se(r >= 0);
124         c1 = c1->command_next;
125         check_execcommand(c1,
126                           "/RValue/slashes4", "argv0b", "r1", true);
127
128         /* ignore && ignore */
129         r = config_parse_exec("fake", 4, "section",
130                               "LValue", 0, "--/RValue argv0 r1",
131                               &c, NULL);
132         assert_se(r == 0);
133         assert_se(c1->command_next == NULL);
134
135         /* ignore && ignore */
136         r = config_parse_exec("fake", 4, "section",
137                               "LValue", 0, "-@-/RValue argv0 r1",
138                               &c, NULL);
139         assert_se(r == 0);
140         assert_se(c1->command_next == NULL);
141
142         /* semicolon */
143         r = config_parse_exec("fake", 5, "section",
144                               "LValue", 0,
145                               "-@/RValue argv0 r1 ; "
146                               "/goo/goo boo",
147                               &c, NULL);
148         assert_se(r >= 0);
149         c1 = c1->command_next;
150         check_execcommand(c1,
151                           "/RValue", "argv0", "r1", true);
152
153         c1 = c1->command_next;
154         check_execcommand(c1,
155                           "/goo/goo", "/goo/goo", "boo", false);
156
157         /* trailing semicolon */
158         r = config_parse_exec("fake", 5, "section",
159                               "LValue", 0,
160                               "-@/RValue argv0 r1 ; ",
161                               &c, NULL);
162         assert_se(r >= 0);
163         c1 = c1->command_next;
164         check_execcommand(c1,
165                           "/RValue", "argv0", "r1", true);
166
167         assert_se(c1->command_next == NULL);
168
169         /* escaped semicolon */
170         r = config_parse_exec("fake", 5, "section",
171                               "LValue", 0,
172                               "/usr/bin/find \\;",
173                               &c, NULL);
174         assert_se(r >= 0);
175         c1 = c1->command_next;
176         check_execcommand(c1,
177                           "/usr/bin/find", "/usr/bin/find", ";", false);
178
179         exec_command_free_list(c);
180 }
181
182 #define env_file_1 \
183         "a\n"      \
184         "b\\\n"    \
185         "c\n"      \
186         "d\\\n"    \
187         "e\\\n"    \
188         "f\n"      \
189         "g\\ \n"   \
190         "h\n"      \
191         "i\\"
192
193 #define env_file_2 \
194         "a\\\n"
195
196 static void test_load_env_file_1(void) {
197         char _cleanup_strv_free_ **data = NULL;
198         int r;
199
200         char name[] = "/tmp/test-load-env-file.XXXXXX";
201         int _cleanup_close_ fd = mkstemp(name);
202         assert(fd >= 0);
203         assert_se(write(fd, env_file_1, sizeof(env_file_1)) == sizeof(env_file_1));
204
205         r = load_env_file(name, &data);
206         assert(r == 0);
207         assert(streq(data[0], "a"));
208         assert(streq(data[1], "bc"));
209         assert(streq(data[2], "def"));
210         assert(streq(data[3], "g\\"));
211         assert(streq(data[4], "h"));
212         assert(streq(data[5], "i\\"));
213         assert(data[6] == NULL);
214         unlink(name);
215 }
216
217 static void test_load_env_file_2(void) {
218         char _cleanup_strv_free_ **data = NULL;
219         int r;
220
221         char name[] = "/tmp/test-load-env-file.XXXXXX";
222         int _cleanup_close_ fd = mkstemp(name);
223         assert(fd >= 0);
224         assert_se(write(fd, env_file_2, sizeof(env_file_2)) == sizeof(env_file_2));
225
226         r = load_env_file(name, &data);
227         assert(r == 0);
228         assert(streq(data[0], "a"));
229         assert(data[1] == NULL);
230         unlink(name);
231 }
232
233 #pragma GCC diagnostic push
234 #pragma GCC diagnostic ignored "-Wnonnull"
235
236 static void test_install_printf(void) {
237         char    name[] = "name.service",
238                 path[] = "/run/systemd/systemd/name.service",
239                 user[] = "xxxx-no-such-user";
240         InstallInfo i = {name, path, user};
241         InstallInfo i2 = {name, path, NULL};
242         char    name3[] = "name@inst.service",
243                 path3[] = "/run/systemd/systemd/name.service";
244         InstallInfo i3 = {name3, path3, user};
245         InstallInfo i4 = {name3, path3, NULL};
246
247         char _cleanup_free_ *mid, *bid, *host;
248
249         assert_se((mid = specifier_machine_id('m', NULL, NULL)));
250         assert_se((bid = specifier_boot_id('b', NULL, NULL)));
251         assert_se((host = gethostname_malloc()));
252
253 #define expect(src, pattern, result)                                    \
254         {                                                               \
255                 char _cleanup_free_ *t = install_full_printf(&src, pattern); \
256                 char _cleanup_free_                                     \
257                         *d1 = strdup(i.name),                           \
258                         *d2 = strdup(i.path),                           \
259                         *d3 = strdup(i.user);                           \
260                 memzero(i.name, strlen(i.name));                        \
261                 memzero(i.path, strlen(i.path));                        \
262                 memzero(i.user, strlen(i.user));                        \
263                 assert(d1 && d2 && d3);                                 \
264                 if (result) {                                           \
265                         printf("%s\n", t);                              \
266                         assert(streq(t, result));                       \
267                 } else assert(t == NULL);                               \
268                 strcpy(i.name, d1);                                     \
269                 strcpy(i.path, d2);                                     \
270                 strcpy(i.user, d3);                                     \
271         }
272
273         assert_se(setenv("USER", "root", 1) == 0);
274
275         expect(i, "%n", "name.service");
276         expect(i, "%N", "name");
277         expect(i, "%p", "name");
278         expect(i, "%i", "");
279         expect(i, "%u", "xxxx-no-such-user");
280         expect(i, "%U", NULL);
281         expect(i, "%m", mid);
282         expect(i, "%b", bid);
283         expect(i, "%H", host);
284
285         expect(i2, "%u", "root");
286         expect(i2, "%U", "0");
287
288         expect(i3, "%n", "name@inst.service");
289         expect(i3, "%N", "name@inst");
290         expect(i3, "%p", "name");
291         expect(i3, "%u", "xxxx-no-such-user");
292         expect(i3, "%U", NULL);
293         expect(i3, "%m", mid);
294         expect(i3, "%b", bid);
295         expect(i3, "%H", host);
296
297         expect(i4, "%u", "root");
298         expect(i4, "%U", "0");
299 }
300 #pragma GCC diagnostic pop
301
302 int main(int argc, char *argv[]) {
303
304         test_unit_file_get_set();
305         test_config_parse_exec();
306         test_load_env_file_1();
307         test_load_env_file_2();
308         test_install_printf();
309
310         return 0;
311 }