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(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(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(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; \
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)); \
144 assert(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, "%N", "blah");
163 expect(u, "%p", "blah");
164 expect(u, "%P", "blah");
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/*");
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);
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/*");
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"));
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"));
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"));
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"));
225 static void test_unit_name_change_suffix(void) {
228 r = unit_name_change_suffix("foo.bar", ".service");
230 assert_se(streq(r, "foo.service"));
233 r = unit_name_change_suffix("foo@stuff.bar", ".boo");
235 assert_se(streq(r, "foo@stuff.boo"));
239 static void test_unit_name_build(void) {
242 r = unit_name_build("foo", "bar", ".service");
244 assert_se(streq(r, "foo@bar.service"));
247 r = unit_name_build("fo0-stUff_b", "bar", ".mount");
249 assert_se(streq(r, "fo0-stUff_b@bar.mount"));
252 r = unit_name_build("foo", NULL, ".service");
254 assert_se(streq(r, "foo.service"));
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"));
262 assert_se(!unit_name_is_instance("a.service"));
263 assert_se(!unit_name_is_instance("junk"));
264 assert_se(!unit_name_is_instance(""));
267 static void test_build_subslice(void) {
271 assert_se(build_subslice("-.slice", "foo", &a) >= 0);
272 assert_se(build_subslice(a, "bar", &b) >= 0);
274 assert_se(build_subslice(b, "barfoo", &a) >= 0);
276 assert_se(build_subslice(a, "foobar", &b) >= 0);
278 assert_se(streq(b, "foo-bar-barfoo-foobar.slice"));
281 assert_se(build_subslice("foo.service", "bar", &a) < 0);
282 assert_se(build_subslice("foo", "bar", &a) < 0);
285 static void test_unit_name_to_instance(void) {
289 r = unit_name_to_instance("foo@bar.service", &instance);
291 assert_se(streq(instance, "bar"));
294 r = unit_name_to_instance("fo0-stUff_b@b.e", &instance);
296 assert_se(streq(instance, "b"));
299 r = unit_name_to_instance("foo.bar", &instance);
301 assert_se(!instance);
303 r = unit_name_to_instance("fooj@unk", &instance);
307 static void test_unit_name_escape(void) {
308 _cleanup_free_ char *r;
310 r = unit_name_escape("ab+-c.a/bc@foo.service");
312 assert_se(streq(r, "ab\\x2b\\x2dc.a-bc\\x40foo.service"));
315 int main(int argc, char* argv[]) {
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();