]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/test/test-unit-file.c
tests: add test for install_full_printf()
[thirdparty/systemd.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 }