chiark / gitweb /
Revert "socket: add support for TCP fast Open"
[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(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(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(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(r == 0);
134
135 #define expect(unit, pattern, expected)                                 \
136         {                                                               \
137                 char *e;                                                \
138                 _cleanup_free_ char *t;                                 \
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(strncmp(t, e, e-expected));              \
143                 else                                                    \
144                         assert(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, "%N", "blah");
163         expect(u, "%p", "blah");
164         expect(u, "%P", "blah");
165         expect(u, "%i", "");
166         expect(u, "%u", root->pw_name);
167         expect(u, "%U", root_uid);
168         expect(u, "%h", root->pw_dir);
169         expect(u, "%m", mid);
170         expect(u, "%b", bid);
171         expect(u, "%H", host);
172         expect(u, "%t", "/run/user/*");
173
174         /* templated */
175         assert_se(u2 = unit_new(m, sizeof(Service)));
176         assert_se(unit_add_name(u2, "blah@foo-foo.service") == 0);
177         assert_se(unit_add_name(u2, "blah@foo-foo.service") == 0);
178
179         expect(u2, "%n", "blah@foo-foo.service");
180         expect(u2, "%N", "blah@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
195         return 0;
196 }
197
198 static void test_unit_instance_is_valid(void) {
199         assert_se(unit_instance_is_valid("fooBar"));
200         assert_se(unit_instance_is_valid("foo-bar"));
201         assert_se(unit_instance_is_valid("foo.stUff"));
202         assert_se(unit_instance_is_valid("fOo123.stuff"));
203         assert_se(unit_instance_is_valid("@f_oo123.Stuff"));
204
205         assert_se(!unit_instance_is_valid("$¢£"));
206         assert_se(!unit_instance_is_valid(""));
207         assert_se(!unit_instance_is_valid("foo bar"));
208         assert_se(!unit_instance_is_valid("foo/bar"));
209 }
210
211 static void test_unit_prefix_is_valid(void) {
212         assert_se(unit_prefix_is_valid("fooBar"));
213         assert_se(unit_prefix_is_valid("foo-bar"));
214         assert_se(unit_prefix_is_valid("foo.stUff"));
215         assert_se(unit_prefix_is_valid("fOo123.stuff"));
216         assert_se(unit_prefix_is_valid("foo123.Stuff"));
217
218         assert_se(!unit_prefix_is_valid("$¢£"));
219         assert_se(!unit_prefix_is_valid(""));
220         assert_se(!unit_prefix_is_valid("foo bar"));
221         assert_se(!unit_prefix_is_valid("foo/bar"));
222         assert_se(!unit_prefix_is_valid("@foo-bar"));
223 }
224
225 static void test_unit_name_change_suffix(void) {
226         char *r;
227
228         r = unit_name_change_suffix("foo.bar", ".service");
229         assert_se(r);
230         assert_se(streq(r, "foo.service"));
231         free(r);
232
233         r = unit_name_change_suffix("foo@stuff.bar", ".boo");
234         assert_se(r);
235         assert_se(streq(r, "foo@stuff.boo"));
236         free(r);
237 }
238
239 static void test_unit_name_build(void) {
240         char *r;
241
242         r = unit_name_build("foo", "bar", ".service");
243         assert_se(r);
244         assert_se(streq(r, "foo@bar.service"));
245         free(r);
246
247         r = unit_name_build("fo0-stUff_b", "bar", ".mount");
248         assert_se(r);
249         assert_se(streq(r, "fo0-stUff_b@bar.mount"));
250         free(r);
251
252         r = unit_name_build("foo", NULL, ".service");
253         assert_se(r);
254         assert_se(streq(r, "foo.service"));
255         free(r);
256 }
257
258 static void test_unit_name_is_instance(void) {
259         assert_se(unit_name_is_instance("a@b.service"));
260         assert_se(unit_name_is_instance("a-c_c01Aj@b05Dii_-oioi.service"));
261
262         assert_se(!unit_name_is_instance("a.service"));
263         assert_se(!unit_name_is_instance("junk"));
264         assert_se(!unit_name_is_instance(""));
265 }
266
267 static void test_build_subslice(void) {
268         char *a;
269         char *b;
270
271         assert_se(build_subslice("-.slice", "foo", &a) >= 0);
272         assert_se(build_subslice(a, "bar", &b) >= 0);
273         free(a);
274         assert_se(build_subslice(b, "barfoo", &a) >= 0);
275         free(b);
276         assert_se(build_subslice(a, "foobar", &b) >= 0);
277         free(a);
278         assert_se(streq(b, "foo-bar-barfoo-foobar.slice"));
279         free(b);
280
281         assert_se(build_subslice("foo.service", "bar", &a) < 0);
282         assert_se(build_subslice("foo", "bar", &a) < 0);
283 }
284
285 static void test_unit_name_to_instance(void) {
286         char *instance;
287         int r;
288
289         r = unit_name_to_instance("foo@bar.service", &instance);
290         assert_se(r >= 0);
291         assert_se(streq(instance, "bar"));
292         free(instance);
293
294         r = unit_name_to_instance("fo0-stUff_b@b.e", &instance);
295         assert_se(r >= 0);
296         assert_se(streq(instance, "b"));
297         free(instance);
298
299         r = unit_name_to_instance("foo.bar", &instance);
300         assert_se(r >= 0);
301         assert_se(!instance);
302
303         r = unit_name_to_instance("fooj@unk", &instance);
304         assert_se(r < 0);
305 }
306
307 static void test_unit_name_escape(void) {
308         _cleanup_free_ char *r;
309
310         r = unit_name_escape("ab+-c.a/bc@foo.service");
311         assert_se(r);
312         assert_se(streq(r, "ab\\x2b\\x2dc.a-bc\\x40foo.service"));
313 }
314
315 int main(int argc, char* argv[]) {
316         int rc = 0;
317         test_replacements();
318         TEST_REQ_RUNNING_SYSTEMD(rc = test_unit_printf());
319         test_unit_instance_is_valid();
320         test_unit_prefix_is_valid();
321         test_unit_name_change_suffix();
322         test_unit_name_build();
323         test_unit_name_is_instance();
324         test_build_subslice();
325         test_unit_name_to_instance();
326         test_unit_name_escape();
327
328         return rc;
329 }