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/*");
200 static void test_unit_instance_is_valid(void) {
201 assert_se(unit_instance_is_valid("fooBar"));
202 assert_se(unit_instance_is_valid("foo-bar"));
203 assert_se(unit_instance_is_valid("foo.stUff"));
204 assert_se(unit_instance_is_valid("fOo123.stuff"));
205 assert_se(unit_instance_is_valid("@f_oo123.Stuff"));
207 assert_se(!unit_instance_is_valid("$¢£"));
208 assert_se(!unit_instance_is_valid(""));
209 assert_se(!unit_instance_is_valid("foo bar"));
210 assert_se(!unit_instance_is_valid("foo/bar"));
213 static void test_unit_prefix_is_valid(void) {
214 assert_se(unit_prefix_is_valid("fooBar"));
215 assert_se(unit_prefix_is_valid("foo-bar"));
216 assert_se(unit_prefix_is_valid("foo.stUff"));
217 assert_se(unit_prefix_is_valid("fOo123.stuff"));
218 assert_se(unit_prefix_is_valid("foo123.Stuff"));
220 assert_se(!unit_prefix_is_valid("$¢£"));
221 assert_se(!unit_prefix_is_valid(""));
222 assert_se(!unit_prefix_is_valid("foo bar"));
223 assert_se(!unit_prefix_is_valid("foo/bar"));
224 assert_se(!unit_prefix_is_valid("@foo-bar"));
227 static void test_unit_name_change_suffix(void) {
230 r = unit_name_change_suffix("foo.bar", ".service");
232 assert_se(streq(r, "foo.service"));
235 r = unit_name_change_suffix("foo@stuff.bar", ".boo");
237 assert_se(streq(r, "foo@stuff.boo"));
241 static void test_unit_name_build(void) {
244 r = unit_name_build("foo", "bar", ".service");
246 assert_se(streq(r, "foo@bar.service"));
249 r = unit_name_build("fo0-stUff_b", "bar", ".mount");
251 assert_se(streq(r, "fo0-stUff_b@bar.mount"));
254 r = unit_name_build("foo", NULL, ".service");
256 assert_se(streq(r, "foo.service"));
260 static void test_unit_name_is_instance(void) {
261 assert_se(unit_name_is_instance("a@b.service"));
262 assert_se(unit_name_is_instance("a-c_c01Aj@b05Dii_-oioi.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(""));
269 static void test_build_subslice(void) {
273 assert_se(build_subslice("-.slice", "foo", &a) >= 0);
274 assert_se(build_subslice(a, "bar", &b) >= 0);
276 assert_se(build_subslice(b, "barfoo", &a) >= 0);
278 assert_se(build_subslice(a, "foobar", &b) >= 0);
280 assert_se(streq(b, "foo-bar-barfoo-foobar.slice"));
283 assert_se(build_subslice("foo.service", "bar", &a) < 0);
284 assert_se(build_subslice("foo", "bar", &a) < 0);
287 static void test_unit_name_to_instance(void) {
291 r = unit_name_to_instance("foo@bar.service", &instance);
293 assert_se(streq(instance, "bar"));
296 r = unit_name_to_instance("fo0-stUff_b@b.e", &instance);
298 assert_se(streq(instance, "b"));
301 r = unit_name_to_instance("foo.bar", &instance);
303 assert_se(!instance);
305 r = unit_name_to_instance("fooj@unk", &instance);
309 static void test_unit_name_escape(void) {
310 _cleanup_free_ char *r;
312 r = unit_name_escape("ab+-c.a/bc@foo.service");
314 assert_se(streq(r, "ab\\x2b\\x2dc.a-bc\\x40foo.service"));
317 int main(int argc, char* argv[]) {
320 TEST_REQ_RUNNING_SYSTEMD(rc = test_unit_printf());
321 test_unit_instance_is_valid();
322 test_unit_prefix_is_valid();
323 test_unit_name_change_suffix();
324 test_unit_name_build();
325 test_unit_name_is_instance();
326 test_build_subslice();
327 test_unit_name_to_instance();
328 test_unit_name_escape();