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