chiark / gitweb /
importd: add new bus calls for importing local tar and raw images
[elogind.git] / src / test / test-unit-name.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   Copyright 2014 Ronny Chevalier
9
10   systemd is free software; you can redistribute it and/or modify it
11   under the terms of the GNU Lesser General Public License as published by
12   the Free Software Foundation; either version 2.1 of the License, or
13   (at your option) any later version.
14
15   systemd is distributed in the hope that it will be useful, but
16   WITHOUT ANY WARRANTY; without even the implied warranty of
17   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18   Lesser General Public License for more details.
19
20   You should have received a copy of the GNU Lesser General Public License
21   along with systemd; If not, see <http://www.gnu.org/licenses/>.
22 ***/
23
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <pwd.h>
28
29 #include "manager.h"
30 #include "unit.h"
31 #include "unit-name.h"
32 #include "unit-printf.h"
33 #include "specifier.h"
34 #include "util.h"
35 #include "macro.h"
36 #include "test-helper.h"
37
38 static void test_replacements(void) {
39 #define expect(pattern, repl, expected)                            \
40         {                                                          \
41                 _cleanup_free_ char *t =                           \
42                         unit_name_replace_instance(pattern, repl); \
43                 puts(t);                                           \
44                 assert_se(streq(t, expected));                        \
45         }
46
47         expect("foo@.service", "waldo", "foo@waldo.service");
48         expect("foo@xyz.service", "waldo", "foo@waldo.service");
49         expect("xyz", "waldo", "xyz");
50         expect("", "waldo", "");
51         expect("foo.service", "waldo", "foo.service");
52         expect(".service", "waldo", ".service");
53         expect("foo@", "waldo", "foo@waldo");
54         expect("@bar", "waldo", "@waldo");
55
56         puts("-------------------------------------------------");
57 #undef expect
58 #define expect(path, suffix, expected)                             \
59         {                                                          \
60                 _cleanup_free_ char *k, *t =                       \
61                         unit_name_from_path(path, suffix);         \
62                 puts(t);                                           \
63                 k = unit_name_to_path(t);                          \
64                 puts(k);                                           \
65                 assert_se(streq(k, expected ? expected : path));      \
66         }
67
68         expect("/waldo", ".mount", NULL);
69         expect("/waldo/quuix", ".mount", NULL);
70         expect("/waldo/quuix/", ".mount", "/waldo/quuix");
71         expect("/", ".mount", NULL);
72         expect("///", ".mount", "/");
73
74         puts("-------------------------------------------------");
75 #undef expect
76 #define expect(pattern, path, suffix, expected)                              \
77         {                                                                    \
78                 _cleanup_free_ char *t =                                     \
79                         unit_name_from_path_instance(pattern, path, suffix); \
80                 puts(t);                                                     \
81                 assert_se(streq(t, expected));                                  \
82         }
83
84         expect("waldo", "/waldo", ".mount", "waldo@waldo.mount");
85         expect("waldo", "/waldo////quuix////", ".mount", "waldo@waldo-quuix.mount");
86         expect("waldo", "/", ".mount", "waldo@-.mount");
87         expect("wa--ldo", "/--", ".mount", "wa--ldo@\\x2d\\x2d.mount");
88
89         puts("-------------------------------------------------");
90 #undef expect
91 #define expect(pattern)                                                     \
92         {                                                                   \
93                 _cleanup_free_ char *k, *t;                                 \
94                 assert_se(t = unit_name_mangle(pattern, MANGLE_NOGLOB));    \
95                 assert_se(k = unit_name_mangle(t, MANGLE_NOGLOB));          \
96                 puts(t);                                                    \
97                 assert_se(streq(t, k));                                     \
98         }
99
100         expect("/home");
101         expect("/dev/sda");
102         expect("üxknürz.service");
103         expect("foobar-meh...waldi.service");
104         expect("_____####----.....service");
105         expect("_____##@;;;,,,##----.....service");
106         expect("xxx@@@@/////\\\\\\\\\\yyy.service");
107
108 #undef expect
109 }
110
111 static int test_unit_printf(void) {
112         Manager *m = NULL;
113         Unit *u, *u2;
114         int r;
115
116         _cleanup_free_ char *mid, *bid, *host, *root_uid;
117         struct passwd *root;
118
119         assert_se(specifier_machine_id('m', NULL, NULL, &mid) >= 0 && mid);
120         assert_se(specifier_boot_id('b', NULL, NULL, &bid) >= 0 && bid);
121         assert_se((host = gethostname_malloc()));
122
123         assert_se((root = getpwnam("root")));
124         assert_se(asprintf(&root_uid, "%d", (int) root->pw_uid) > 0);
125
126         r = manager_new(SYSTEMD_USER, true, &m);
127         if (r == -EPERM || r == -EACCES || r == -EADDRINUSE) {
128                 puts("manager_new: Permission denied. Skipping test.");
129                 return EXIT_TEST_SKIP;
130         }
131         assert_se(r == 0);
132
133 #define expect(unit, pattern, expected)                                 \
134         {                                                               \
135                 char *e;                                                \
136                 _cleanup_free_ char *t = NULL;                          \
137                 assert_se(unit_full_printf(unit, pattern, &t) >= 0);    \
138                 printf("result: %s\nexpect: %s\n", t, expected);        \
139                 if ((e = endswith(expected, "*")))                      \
140                         assert_se(strncmp(t, e, e-expected));              \
141                 else                                                    \
142                         assert_se(streq(t, expected));                     \
143         }
144
145         assert_se(setenv("USER", "root", 1) == 0);
146         assert_se(setenv("HOME", "/root", 1) == 0);
147         assert_se(setenv("XDG_RUNTIME_DIR", "/run/user/1/", 1) == 0);
148
149         assert_se(u = unit_new(m, sizeof(Service)));
150         assert_se(unit_add_name(u, "blah.service") == 0);
151         assert_se(unit_add_name(u, "blah.service") == 0);
152
153         /* general tests */
154         expect(u, "%%", "%");
155         expect(u, "%%s", "%s");
156         expect(u, "%", "");    // REALLY?
157
158         /* normal unit */
159         expect(u, "%n", "blah.service");
160         expect(u, "%f", "/blah");
161         expect(u, "%N", "blah");
162         expect(u, "%p", "blah");
163         expect(u, "%P", "blah");
164         expect(u, "%i", "");
165         expect(u, "%u", root->pw_name);
166         expect(u, "%U", root_uid);
167         expect(u, "%h", root->pw_dir);
168         expect(u, "%m", mid);
169         expect(u, "%b", bid);
170         expect(u, "%H", host);
171         expect(u, "%t", "/run/user/*");
172
173         /* templated */
174         assert_se(u2 = unit_new(m, sizeof(Service)));
175         assert_se(unit_add_name(u2, "blah@foo-foo.service") == 0);
176         assert_se(unit_add_name(u2, "blah@foo-foo.service") == 0);
177
178         expect(u2, "%n", "blah@foo-foo.service");
179         expect(u2, "%N", "blah@foo-foo");
180         expect(u2, "%f", "/foo/foo");
181         expect(u2, "%p", "blah");
182         expect(u2, "%P", "blah");
183         expect(u2, "%i", "foo-foo");
184         expect(u2, "%I", "foo/foo");
185         expect(u2, "%u", root->pw_name);
186         expect(u2, "%U", root_uid);
187         expect(u2, "%h", root->pw_dir);
188         expect(u2, "%m", mid);
189         expect(u2, "%b", bid);
190         expect(u2, "%H", host);
191         expect(u2, "%t", "/run/user/*");
192
193         manager_free(m);
194 #undef expect
195
196         return 0;
197 }
198
199 static void test_unit_instance_is_valid(void) {
200         assert_se(unit_instance_is_valid("fooBar"));
201         assert_se(unit_instance_is_valid("foo-bar"));
202         assert_se(unit_instance_is_valid("foo.stUff"));
203         assert_se(unit_instance_is_valid("fOo123.stuff"));
204         assert_se(unit_instance_is_valid("@f_oo123.Stuff"));
205
206         assert_se(!unit_instance_is_valid("$¢£"));
207         assert_se(!unit_instance_is_valid(""));
208         assert_se(!unit_instance_is_valid("foo bar"));
209         assert_se(!unit_instance_is_valid("foo/bar"));
210 }
211
212 static void test_unit_prefix_is_valid(void) {
213         assert_se(unit_prefix_is_valid("fooBar"));
214         assert_se(unit_prefix_is_valid("foo-bar"));
215         assert_se(unit_prefix_is_valid("foo.stUff"));
216         assert_se(unit_prefix_is_valid("fOo123.stuff"));
217         assert_se(unit_prefix_is_valid("foo123.Stuff"));
218
219         assert_se(!unit_prefix_is_valid("$¢£"));
220         assert_se(!unit_prefix_is_valid(""));
221         assert_se(!unit_prefix_is_valid("foo bar"));
222         assert_se(!unit_prefix_is_valid("foo/bar"));
223         assert_se(!unit_prefix_is_valid("@foo-bar"));
224 }
225
226 static void test_unit_name_change_suffix(void) {
227         char *r;
228
229         r = unit_name_change_suffix("foo.bar", ".service");
230         assert_se(r);
231         assert_se(streq(r, "foo.service"));
232         free(r);
233
234         r = unit_name_change_suffix("foo@stuff.bar", ".boo");
235         assert_se(r);
236         assert_se(streq(r, "foo@stuff.boo"));
237         free(r);
238 }
239
240 static void test_unit_name_build(void) {
241         char *r;
242
243         r = unit_name_build("foo", "bar", ".service");
244         assert_se(r);
245         assert_se(streq(r, "foo@bar.service"));
246         free(r);
247
248         r = unit_name_build("fo0-stUff_b", "bar", ".mount");
249         assert_se(r);
250         assert_se(streq(r, "fo0-stUff_b@bar.mount"));
251         free(r);
252
253         r = unit_name_build("foo", NULL, ".service");
254         assert_se(r);
255         assert_se(streq(r, "foo.service"));
256         free(r);
257 }
258
259 static void test_unit_name_is_instance(void) {
260         assert_se(unit_name_is_instance("a@b.service"));
261         assert_se(unit_name_is_instance("a-c_c01Aj@b05Dii_-oioi.service"));
262
263         assert_se(!unit_name_is_instance("a.service"));
264         assert_se(!unit_name_is_instance("a@.service"));
265         assert_se(!unit_name_is_instance("junk"));
266         assert_se(!unit_name_is_instance(""));
267 }
268
269 static void test_build_subslice(void) {
270         char *a;
271         char *b;
272
273         assert_se(build_subslice("-.slice", "foo", &a) >= 0);
274         assert_se(build_subslice(a, "bar", &b) >= 0);
275         free(a);
276         assert_se(build_subslice(b, "barfoo", &a) >= 0);
277         free(b);
278         assert_se(build_subslice(a, "foobar", &b) >= 0);
279         free(a);
280         assert_se(streq(b, "foo-bar-barfoo-foobar.slice"));
281         free(b);
282
283         assert_se(build_subslice("foo.service", "bar", &a) < 0);
284         assert_se(build_subslice("foo", "bar", &a) < 0);
285 }
286
287 static void test_unit_name_to_instance(void) {
288         char *instance;
289         int r;
290
291         r = unit_name_to_instance("foo@bar.service", &instance);
292         assert_se(r >= 0);
293         assert_se(streq(instance, "bar"));
294         free(instance);
295
296         r = unit_name_to_instance("foo@.service", &instance);
297         assert_se(r >= 0);
298         assert_se(streq(instance, ""));
299         free(instance);
300
301         r = unit_name_to_instance("fo0-stUff_b@b.e", &instance);
302         assert_se(r >= 0);
303         assert_se(streq(instance, "b"));
304         free(instance);
305
306         r = unit_name_to_instance("foo.bar", &instance);
307         assert_se(r >= 0);
308         assert_se(!instance);
309
310         r = unit_name_to_instance("fooj@unk", &instance);
311         assert_se(r < 0);
312
313         r = unit_name_to_instance("foo@", &instance);
314         assert_se(r < 0);
315 }
316
317 static void test_unit_name_escape(void) {
318         _cleanup_free_ char *r;
319
320         r = unit_name_escape("ab+-c.a/bc@foo.service");
321         assert_se(r);
322         assert_se(streq(r, "ab\\x2b\\x2dc.a-bc\\x40foo.service"));
323 }
324
325 static void test_unit_name_template(void) {
326 #define expect(name, expected) \
327         { \
328                 _cleanup_free_ char *f = NULL; \
329                 f = unit_name_template(name); \
330                 assert_se(f); \
331                 printf("got: %s, expected: %s\n", f, expected); \
332                 assert_se(streq(f, expected)); \
333         }
334         expect("foo@bar.service", "foo@.service")
335         expect("foo.mount", "foo.mount")
336 #undef expect
337 }
338
339 static void test_unit_name_is_template(void) {
340         assert_se(unit_name_is_template("foo@.service"));
341         assert_se(unit_name_is_template("bar@.path"));
342
343         assert_se(!unit_name_is_template("bar@i.mount"));
344         assert_se(!unit_name_is_template("bar@foobbbb.service"));
345         assert_se(!unit_name_is_template("barfoo.service"));
346 }
347
348 int main(int argc, char* argv[]) {
349         int rc = 0;
350         test_replacements();
351         TEST_REQ_RUNNING_SYSTEMD(rc = test_unit_printf());
352         test_unit_instance_is_valid();
353         test_unit_prefix_is_valid();
354         test_unit_name_change_suffix();
355         test_unit_name_build();
356         test_unit_name_is_instance();
357         test_build_subslice();
358         test_unit_name_to_instance();
359         test_unit_name_escape();
360         test_unit_name_template();
361         test_unit_name_is_template();
362
363         return rc;
364 }