1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2012 Lennart Poettering
7 Copyright 2013 Zbigniew Jędrzejewski-Szmek
8 Copyright 2014 Ronny Chevalier
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.
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.
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/>.
27 #include <sys/types.h>
32 #include "unit-name.h"
33 #include "unit-printf.h"
35 #include "specifier.h"
38 #include "test-helper.h"
40 static void test_replacements(void) {
41 #define expect(pattern, repl, expected) \
43 _cleanup_free_ char *t = \
44 unit_name_replace_instance(pattern, repl); \
46 assert_se(streq(t, expected)); \
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");
58 puts("-------------------------------------------------");
60 #define expect(path, suffix, expected) \
62 _cleanup_free_ char *k, *t = \
63 unit_name_from_path(path, suffix); \
65 k = unit_name_to_path(t); \
67 assert_se(streq(k, expected ? expected : path)); \
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", "/");
76 puts("-------------------------------------------------");
78 #define expect(pattern, path, suffix, expected) \
80 _cleanup_free_ char *t = \
81 unit_name_from_path_instance(pattern, path, suffix); \
83 assert_se(streq(t, expected)); \
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");
91 puts("-------------------------------------------------");
93 #define expect(pattern) \
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)); \
99 assert_se(streq(t, k)); \
104 expect("üxknürz.service");
105 expect("foobar-meh...waldi.service");
106 expect("_____####----.....service");
107 expect("_____##@;;;,,,##----.....service");
108 expect("xxx@@@@/////\\\\\\\\\\yyy.service");
113 static int test_unit_printf(void) {
118 _cleanup_free_ char *mid, *bid, *host, *root_uid;
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()));
125 assert_se((root = getpwnam("root")));
126 assert_se(asprintf(&root_uid, "%d", (int) root->pw_uid) > 0);
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;
135 #define expect(unit, pattern, expected) \
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)); \
144 assert_se(streq(t, expected)); \
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);
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);
156 expect(u, "%%", "%");
157 expect(u, "%%s", "%s");
158 expect(u, "%", ""); // REALLY?
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");
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/*");
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);
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/*");
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"));
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"));
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"));
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"));
228 static void test_unit_name_change_suffix(void) {
231 r = unit_name_change_suffix("foo.bar", ".service");
233 assert_se(streq(r, "foo.service"));
236 r = unit_name_change_suffix("foo@stuff.bar", ".boo");
238 assert_se(streq(r, "foo@stuff.boo"));
242 static void test_unit_name_build(void) {
245 r = unit_name_build("foo", "bar", ".service");
247 assert_se(streq(r, "foo@bar.service"));
250 r = unit_name_build("fo0-stUff_b", "bar", ".mount");
252 assert_se(streq(r, "fo0-stUff_b@bar.mount"));
255 r = unit_name_build("foo", NULL, ".service");
257 assert_se(streq(r, "foo.service"));
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"));
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(""));
271 static void test_build_subslice(void) {
275 assert_se(build_subslice("-.slice", "foo", &a) >= 0);
276 assert_se(build_subslice(a, "bar", &b) >= 0);
278 assert_se(build_subslice(b, "barfoo", &a) >= 0);
280 assert_se(build_subslice(a, "foobar", &b) >= 0);
282 assert_se(streq(b, "foo-bar-barfoo-foobar.slice"));
285 assert_se(build_subslice("foo.service", "bar", &a) < 0);
286 assert_se(build_subslice("foo", "bar", &a) < 0);
289 static void test_unit_name_to_instance(void) {
293 r = unit_name_to_instance("foo@bar.service", &instance);
295 assert_se(streq(instance, "bar"));
298 r = unit_name_to_instance("foo@.service", &instance);
300 assert_se(streq(instance, ""));
303 r = unit_name_to_instance("fo0-stUff_b@b.e", &instance);
305 assert_se(streq(instance, "b"));
308 r = unit_name_to_instance("foo.bar", &instance);
310 assert_se(!instance);
312 r = unit_name_to_instance("fooj@unk", &instance);
315 r = unit_name_to_instance("foo@", &instance);
319 static void test_unit_name_escape(void) {
320 _cleanup_free_ char *r;
322 r = unit_name_escape("ab+-c.a/bc@foo.service");
324 assert_se(streq(r, "ab\\x2b\\x2dc.a-bc\\x40foo.service"));
327 static void test_unit_name_template(void) {
328 #define expect(name, expected) \
330 _cleanup_free_ char *f = NULL; \
331 f = unit_name_template(name); \
333 printf("got: %s, expected: %s\n", f, expected); \
334 assert_se(streq(f, expected)); \
336 expect("foo@bar.service", "foo@.service")
337 expect("foo.mount", "foo.mount")
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"));
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"));
350 int main(int argc, char* argv[]) {
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();