]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/test/test-path-util.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd.
5 Copyright 2013 Zbigniew Jędrzejewski-Szmek
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
22 #include <sys/mount.h>
25 #include "alloc-util.h"
28 #include "mount-util.h"
29 #include "path-util.h"
31 #include "stat-util.h"
32 #include "string-util.h"
36 #define test_path_compare(a, b, result) { \
37 assert_se(path_compare(a, b) == result); \
38 assert_se(path_compare(b, a) == -result); \
39 assert_se(path_equal(a, b) == !result); \
40 assert_se(path_equal(b, a) == !result); \
43 static void test_path(void) {
44 _cleanup_close_
int fd
= -1;
46 test_path_compare("/goo", "/goo", 0);
47 test_path_compare("/goo", "/goo", 0);
48 test_path_compare("//goo", "/goo", 0);
49 test_path_compare("//goo/////", "/goo", 0);
50 test_path_compare("goo/////", "goo", 0);
52 test_path_compare("/goo/boo", "/goo//boo", 0);
53 test_path_compare("//goo/boo", "/goo/boo//", 0);
55 test_path_compare("/", "///", 0);
57 test_path_compare("/x", "x/", 1);
58 test_path_compare("x/", "/", -1);
60 test_path_compare("/x/./y", "x/y", 1);
61 test_path_compare("x/.y", "x/y", -1);
63 test_path_compare("foo", "/foo", -1);
64 test_path_compare("/foo", "/foo/bar", -1);
65 test_path_compare("/foo/aaa", "/foo/b", -1);
66 test_path_compare("/foo/aaa", "/foo/b/a", -1);
67 test_path_compare("/foo/a", "/foo/aaa", -1);
68 test_path_compare("/foo/a/b", "/foo/aaa", -1);
70 assert_se(path_is_absolute("/"));
71 assert_se(!path_is_absolute("./"));
73 assert_se(is_path("/dir"));
74 assert_se(is_path("a/b"));
75 assert_se(!is_path("."));
77 assert_se(streq(basename("./aa/bb/../file.da."), "file.da."));
78 assert_se(streq(basename("/aa///.file"), ".file"));
79 assert_se(streq(basename("/aa///file..."), "file..."));
80 assert_se(streq(basename("file.../"), ""));
82 fd
= open("/", O_RDONLY
|O_CLOEXEC
|O_DIRECTORY
|O_NOCTTY
);
84 assert_se(fd_is_mount_point(fd
, "/", 0) > 0);
87 char p1
[] = "aaa/bbb////ccc";
88 char p2
[] = "//aaa/.////ccc";
91 assert_se(path_equal(path_kill_slashes(p1
), "aaa/bbb/ccc"));
92 assert_se(path_equal(path_kill_slashes(p2
), "/aaa/./ccc"));
93 assert_se(path_equal(path_kill_slashes(p3
), "/./"));
96 assert_se(PATH_IN_SET("/bin", "/", "/bin", "/foo"));
97 assert_se(PATH_IN_SET("/bin", "/bin"));
98 assert_se(PATH_IN_SET("/bin", "/foo/bar", "/bin"));
99 assert_se(PATH_IN_SET("/", "/", "/", "/foo/bar"));
100 assert_se(!PATH_IN_SET("/", "/abc", "/def"));
102 assert_se(path_equal_ptr(NULL
, NULL
));
103 assert_se(path_equal_ptr("/a", "/a"));
104 assert_se(!path_equal_ptr("/a", "/b"));
105 assert_se(!path_equal_ptr("/a", NULL
));
106 assert_se(!path_equal_ptr(NULL
, "/a"));
109 static void test_path_equal_root(void) {
110 /* Nail down the details of how path_equal("/", ...) works. */
112 assert_se(path_equal("/", "/"));
113 assert_se(path_equal("/", "//"));
115 assert_se(!path_equal("/", "/./"));
116 assert_se(!path_equal("/", "/../"));
118 assert_se(!path_equal("/", "/.../"));
120 /* Make sure that files_same works as expected. */
122 assert_se(files_same("/", "/", 0) > 0);
123 assert_se(files_same("/", "/", AT_SYMLINK_NOFOLLOW
) > 0);
124 assert_se(files_same("/", "//", 0) > 0);
125 assert_se(files_same("/", "//", AT_SYMLINK_NOFOLLOW
) > 0);
127 assert_se(files_same("/", "/./", 0) > 0);
128 assert_se(files_same("/", "/./", AT_SYMLINK_NOFOLLOW
) > 0);
129 assert_se(files_same("/", "/../", 0) > 0);
130 assert_se(files_same("/", "/../", AT_SYMLINK_NOFOLLOW
) > 0);
132 assert_se(files_same("/", "/.../", 0) == -ENOENT
);
133 assert_se(files_same("/", "/.../", AT_SYMLINK_NOFOLLOW
) == -ENOENT
);
135 /* The same for path_equal_or_files_same. */
137 assert_se(path_equal_or_files_same("/", "/", 0));
138 assert_se(path_equal_or_files_same("/", "/", AT_SYMLINK_NOFOLLOW
));
139 assert_se(path_equal_or_files_same("/", "//", 0));
140 assert_se(path_equal_or_files_same("/", "//", AT_SYMLINK_NOFOLLOW
));
142 assert_se(path_equal_or_files_same("/", "/./", 0));
143 assert_se(path_equal_or_files_same("/", "/./", AT_SYMLINK_NOFOLLOW
));
144 assert_se(path_equal_or_files_same("/", "/../", 0));
145 assert_se(path_equal_or_files_same("/", "/../", AT_SYMLINK_NOFOLLOW
));
147 assert_se(!path_equal_or_files_same("/", "/.../", 0));
148 assert_se(!path_equal_or_files_same("/", "/.../", AT_SYMLINK_NOFOLLOW
));
151 static void test_find_binary(const char *self
) {
154 assert_se(find_binary("/bin/sh", &p
) == 0);
156 assert_se(path_equal(p
, "/bin/sh"));
159 assert_se(find_binary(self
, &p
) == 0);
161 /* libtool might prefix the binary name with "lt-" */
162 assert_se(endswith(p
, "/lt-test-path-util") || endswith(p
, "/test-path-util"));
163 assert_se(path_is_absolute(p
));
166 assert_se(find_binary("sh", &p
) == 0);
168 assert_se(endswith(p
, "/sh"));
169 assert_se(path_is_absolute(p
));
172 assert_se(find_binary("xxxx-xxxx", &p
) == -ENOENT
);
173 assert_se(find_binary("/some/dir/xxxx-xxxx", &p
) == -ENOENT
);
176 static void test_prefixes(void) {
177 static const char* values
[] = { "/a/b/c/d", "/a/b/c", "/a/b", "/a", "", NULL
};
183 PATH_FOREACH_PREFIX_MORE(s
, "/a/b/c/d") {
184 log_error("---%s---", s
);
185 assert_se(streq(s
, values
[i
++]));
187 assert_se(values
[i
] == NULL
);
190 PATH_FOREACH_PREFIX(s
, "/a/b/c/d") {
191 log_error("---%s---", s
);
192 assert_se(streq(s
, values
[i
++]));
194 assert_se(values
[i
] == NULL
);
197 PATH_FOREACH_PREFIX_MORE(s
, "////a////b////c///d///////")
198 assert_se(streq(s
, values
[i
++]));
199 assert_se(values
[i
] == NULL
);
202 PATH_FOREACH_PREFIX(s
, "////a////b////c///d///////")
203 assert_se(streq(s
, values
[i
++]));
204 assert_se(values
[i
] == NULL
);
206 PATH_FOREACH_PREFIX(s
, "////")
207 assert_not_reached("Wut?");
210 PATH_FOREACH_PREFIX_MORE(s
, "////") {
212 assert_se(streq(s
, ""));
217 PATH_FOREACH_PREFIX(s
, "")
218 assert_not_reached("wut?");
221 PATH_FOREACH_PREFIX_MORE(s
, "") {
223 assert_se(streq(s
, ""));
228 static void test_path_join(void) {
230 #define test_join(root, path, rest, expected) { \
231 _cleanup_free_ char *z = NULL; \
232 z = path_join(root, path, rest); \
233 assert_se(streq(z, expected)); \
236 test_join("/root", "/a/b", "/c", "/root/a/b/c");
237 test_join("/root", "a/b", "c", "/root/a/b/c");
238 test_join("/root", "/a/b", "c", "/root/a/b/c");
239 test_join("/root", "/", "c", "/root/c");
240 test_join("/root", "/", NULL
, "/root/");
242 test_join(NULL
, "/a/b", "/c", "/a/b/c");
243 test_join(NULL
, "a/b", "c", "a/b/c");
244 test_join(NULL
, "/a/b", "c", "/a/b/c");
245 test_join(NULL
, "/", "c", "/c");
246 test_join(NULL
, "/", NULL
, "/");
249 static void test_fsck_exists(void) {
250 /* Ensure we use a sane default for PATH. */
253 /* fsck.minix is provided by util-linux and will probably exist. */
254 assert_se(fsck_exists("minix") == 1);
256 assert_se(fsck_exists("AbCdE") == 0);
257 assert_se(fsck_exists("/../bin/") == 0);
260 static void test_make_relative(void) {
263 assert_se(path_make_relative("some/relative/path", "/some/path", &result
) < 0);
264 assert_se(path_make_relative("/some/path", "some/relative/path", &result
) < 0);
265 assert_se(path_make_relative("/some/dotdot/../path", "/some/path", &result
) < 0);
267 #define test(from_dir, to_path, expected) { \
268 _cleanup_free_ char *z = NULL; \
269 path_make_relative(from_dir, to_path, &z); \
270 assert_se(streq(z, expected)); \
274 test("/", "/some/path", "some/path");
275 test("/some/path", "/some/path", ".");
276 test("/some/path", "/some/path/in/subdir", "in/subdir");
277 test("/some/path", "/", "../..");
278 test("/some/path", "/some/other/path", "../other/path");
279 test("/some/path/./dot", "/some/further/path", "../../further/path");
280 test("//extra/////slashes///won't////fool///anybody//", "////extra///slashes////are/just///fine///", "../../../are/just/fine");
283 static void test_strv_resolve(void) {
284 char tmp_dir
[] = "/tmp/test-path-util-XXXXXX";
285 _cleanup_strv_free_
char **search_dirs
= NULL
;
286 _cleanup_strv_free_
char **absolute_dirs
= NULL
;
289 assert_se(mkdtemp(tmp_dir
) != NULL
);
291 search_dirs
= strv_new("/dir1", "/dir2", "/dir3", NULL
);
292 assert_se(search_dirs
);
293 STRV_FOREACH(d
, search_dirs
) {
294 char *p
= strappend(tmp_dir
, *d
);
296 assert_se(strv_push(&absolute_dirs
, p
) == 0);
299 assert_se(mkdir(absolute_dirs
[0], 0700) == 0);
300 assert_se(mkdir(absolute_dirs
[1], 0700) == 0);
301 assert_se(symlink("dir2", absolute_dirs
[2]) == 0);
303 path_strv_resolve(search_dirs
, tmp_dir
);
304 assert_se(streq(search_dirs
[0], "/dir1"));
305 assert_se(streq(search_dirs
[1], "/dir2"));
306 assert_se(streq(search_dirs
[2], "/dir2"));
308 assert_se(rm_rf(tmp_dir
, REMOVE_ROOT
|REMOVE_PHYSICAL
) == 0);
311 static void test_path_startswith(void) {
314 p
= path_startswith("/foo/bar/barfoo/", "/foo");
315 assert_se(streq_ptr(p
, "bar/barfoo/"));
317 p
= path_startswith("/foo/bar/barfoo/", "/foo/");
318 assert_se(streq_ptr(p
, "bar/barfoo/"));
320 p
= path_startswith("/foo/bar/barfoo/", "/");
321 assert_se(streq_ptr(p
, "foo/bar/barfoo/"));
323 p
= path_startswith("/foo/bar/barfoo/", "////");
324 assert_se(streq_ptr(p
, "foo/bar/barfoo/"));
326 p
= path_startswith("/foo/bar/barfoo/", "/foo//bar/////barfoo///");
327 assert_se(streq_ptr(p
, ""));
329 p
= path_startswith("/foo/bar/barfoo/", "/foo/bar/barfoo////");
330 assert_se(streq_ptr(p
, ""));
332 p
= path_startswith("/foo/bar/barfoo/", "/foo/bar///barfoo/");
333 assert_se(streq_ptr(p
, ""));
335 p
= path_startswith("/foo/bar/barfoo/", "/foo////bar/barfoo/");
336 assert_se(streq_ptr(p
, ""));
338 p
= path_startswith("/foo/bar/barfoo/", "////foo/bar/barfoo/");
339 assert_se(streq_ptr(p
, ""));
341 p
= path_startswith("/foo/bar/barfoo/", "/foo/bar/barfoo");
342 assert_se(streq_ptr(p
, ""));
344 assert_se(!path_startswith("/foo/bar/barfoo/", "/foo/bar/barfooa/"));
345 assert_se(!path_startswith("/foo/bar/barfoo/", "/foo/bar/barfooa"));
346 assert_se(!path_startswith("/foo/bar/barfoo/", ""));
347 assert_se(!path_startswith("/foo/bar/barfoo/", "/bar/foo"));
348 assert_se(!path_startswith("/foo/bar/barfoo/", "/f/b/b/"));
351 static void test_prefix_root_one(const char *r
, const char *p
, const char *expected
) {
352 _cleanup_free_
char *s
= NULL
;
355 assert_se(s
= prefix_root(r
, p
));
356 assert_se(streq_ptr(s
, expected
));
358 t
= prefix_roota(r
, p
);
360 assert_se(streq_ptr(t
, expected
));
363 static void test_prefix_root(void) {
364 test_prefix_root_one("/", "/foo", "/foo");
365 test_prefix_root_one(NULL
, "/foo", "/foo");
366 test_prefix_root_one("", "/foo", "/foo");
367 test_prefix_root_one("///", "/foo", "/foo");
368 test_prefix_root_one("/", "////foo", "/foo");
369 test_prefix_root_one(NULL
, "////foo", "/foo");
371 test_prefix_root_one("/foo", "/bar", "/foo/bar");
372 test_prefix_root_one("/foo", "bar", "/foo/bar");
373 test_prefix_root_one("foo", "bar", "foo/bar");
374 test_prefix_root_one("/foo/", "/bar", "/foo/bar");
375 test_prefix_root_one("/foo/", "//bar", "/foo/bar");
376 test_prefix_root_one("/foo///", "//bar", "/foo/bar");
379 static void test_path_is_mount_point(void) {
381 char tmp_dir
[] = "/tmp/test-path-is-mount-point-XXXXXX";
382 _cleanup_free_
char *file1
= NULL
, *file2
= NULL
, *link1
= NULL
, *link2
= NULL
;
383 _cleanup_free_
char *dir1
= NULL
, *dir1file
= NULL
, *dirlink1
= NULL
, *dirlink1file
= NULL
;
384 _cleanup_free_
char *dir2
= NULL
, *dir2file
= NULL
;
386 assert_se(path_is_mount_point("/", NULL
, AT_SYMLINK_FOLLOW
) > 0);
387 assert_se(path_is_mount_point("/", NULL
, 0) > 0);
389 assert_se(path_is_mount_point("/proc", NULL
, AT_SYMLINK_FOLLOW
) > 0);
390 assert_se(path_is_mount_point("/proc", NULL
, 0) > 0);
392 assert_se(path_is_mount_point("/proc/1", NULL
, AT_SYMLINK_FOLLOW
) == 0);
393 assert_se(path_is_mount_point("/proc/1", NULL
, 0) == 0);
395 assert_se(path_is_mount_point("/sys", NULL
, AT_SYMLINK_FOLLOW
) > 0);
396 assert_se(path_is_mount_point("/sys", NULL
, 0) > 0);
398 /* we'll create a hierarchy of different kinds of dir/file/link
401 * <tmp>/file1, <tmp>/file2
402 * <tmp>/link1 -> file1, <tmp>/link2 -> file2
405 * <tmp>/dirlink1 -> dir1
406 * <tmp>/dirlink1file -> dirlink1/file
411 /* file mountpoints */
412 assert_se(mkdtemp(tmp_dir
) != NULL
);
413 file1
= path_join(NULL
, tmp_dir
, "file1");
415 file2
= path_join(NULL
, tmp_dir
, "file2");
417 fd
= open(file1
, O_WRONLY
|O_CREAT
|O_EXCL
|O_CLOEXEC
, 0664);
420 fd
= open(file2
, O_WRONLY
|O_CREAT
|O_EXCL
|O_CLOEXEC
, 0664);
423 link1
= path_join(NULL
, tmp_dir
, "link1");
425 assert_se(symlink("file1", link1
) == 0);
426 link2
= path_join(NULL
, tmp_dir
, "link2");
428 assert_se(symlink("file2", link2
) == 0);
430 assert_se(path_is_mount_point(file1
, NULL
, AT_SYMLINK_FOLLOW
) == 0);
431 assert_se(path_is_mount_point(file1
, NULL
, 0) == 0);
432 assert_se(path_is_mount_point(link1
, NULL
, AT_SYMLINK_FOLLOW
) == 0);
433 assert_se(path_is_mount_point(link1
, NULL
, 0) == 0);
435 /* directory mountpoints */
436 dir1
= path_join(NULL
, tmp_dir
, "dir1");
438 assert_se(mkdir(dir1
, 0755) == 0);
439 dirlink1
= path_join(NULL
, tmp_dir
, "dirlink1");
441 assert_se(symlink("dir1", dirlink1
) == 0);
442 dirlink1file
= path_join(NULL
, tmp_dir
, "dirlink1file");
443 assert_se(dirlink1file
);
444 assert_se(symlink("dirlink1/file", dirlink1file
) == 0);
445 dir2
= path_join(NULL
, tmp_dir
, "dir2");
447 assert_se(mkdir(dir2
, 0755) == 0);
449 assert_se(path_is_mount_point(dir1
, NULL
, AT_SYMLINK_FOLLOW
) == 0);
450 assert_se(path_is_mount_point(dir1
, NULL
, 0) == 0);
451 assert_se(path_is_mount_point(dirlink1
, NULL
, AT_SYMLINK_FOLLOW
) == 0);
452 assert_se(path_is_mount_point(dirlink1
, NULL
, 0) == 0);
454 /* file in subdirectory mountpoints */
455 dir1file
= path_join(NULL
, dir1
, "file");
457 fd
= open(dir1file
, O_WRONLY
|O_CREAT
|O_EXCL
|O_CLOEXEC
, 0664);
461 assert_se(path_is_mount_point(dir1file
, NULL
, AT_SYMLINK_FOLLOW
) == 0);
462 assert_se(path_is_mount_point(dir1file
, NULL
, 0) == 0);
463 assert_se(path_is_mount_point(dirlink1file
, NULL
, AT_SYMLINK_FOLLOW
) == 0);
464 assert_se(path_is_mount_point(dirlink1file
, NULL
, 0) == 0);
466 /* these tests will only work as root */
467 if (mount(file1
, file2
, NULL
, MS_BIND
, NULL
) >= 0) {
468 int rt
, rf
, rlt
, rlf
, rl1t
, rl1f
;
471 /* capture results in vars, to avoid dangling mounts on failure */
472 rf
= path_is_mount_point(file2
, NULL
, 0);
473 rt
= path_is_mount_point(file2
, NULL
, AT_SYMLINK_FOLLOW
);
474 rlf
= path_is_mount_point(link2
, NULL
, 0);
475 rlt
= path_is_mount_point(link2
, NULL
, AT_SYMLINK_FOLLOW
);
477 assert_se(umount(file2
) == 0);
485 dir2file
= path_join(NULL
, dir2
, "file");
487 fd
= open(dir2file
, O_WRONLY
|O_CREAT
|O_EXCL
|O_CLOEXEC
, 0664);
491 assert_se(mount(dir2
, dir1
, NULL
, MS_BIND
, NULL
) >= 0);
493 rf
= path_is_mount_point(dir1
, NULL
, 0);
494 rt
= path_is_mount_point(dir1
, NULL
, AT_SYMLINK_FOLLOW
);
495 rlf
= path_is_mount_point(dirlink1
, NULL
, 0);
496 rlt
= path_is_mount_point(dirlink1
, NULL
, AT_SYMLINK_FOLLOW
);
497 /* its parent is a mount point, but not /file itself */
498 rl1f
= path_is_mount_point(dirlink1file
, NULL
, 0);
499 rl1t
= path_is_mount_point(dirlink1file
, NULL
, AT_SYMLINK_FOLLOW
);
501 assert_se(umount(dir1
) == 0);
507 assert_se(rl1f
== 0);
508 assert_se(rl1t
== 0);
511 printf("Skipping bind mount file test: %m\n");
513 assert_se(rm_rf(tmp_dir
, REMOVE_ROOT
|REMOVE_PHYSICAL
) == 0);
516 static void test_file_in_same_dir(void) {
519 t
= file_in_same_dir("/", "a");
520 assert_se(streq(t
, "/a"));
523 t
= file_in_same_dir("/", "/a");
524 assert_se(streq(t
, "/a"));
527 t
= file_in_same_dir("", "a");
528 assert_se(streq(t
, "a"));
531 t
= file_in_same_dir("a/", "a");
532 assert_se(streq(t
, "a/a"));
535 t
= file_in_same_dir("bar/foo", "bar");
536 assert_se(streq(t
, "bar/bar"));
540 static void test_filename_is_valid(void) {
541 char foo
[FILENAME_MAX
+2];
544 assert_se(!filename_is_valid(""));
545 assert_se(!filename_is_valid("/bar/foo"));
546 assert_se(!filename_is_valid("/"));
547 assert_se(!filename_is_valid("."));
548 assert_se(!filename_is_valid(".."));
550 for (i
=0; i
<FILENAME_MAX
+1; i
++)
552 foo
[FILENAME_MAX
+1] = '\0';
554 assert_se(!filename_is_valid(foo
));
556 assert_se(filename_is_valid("foo_bar-333"));
557 assert_se(filename_is_valid("o.o"));
560 static void test_hidden_or_backup_file(void) {
561 assert_se(hidden_or_backup_file(".hidden"));
562 assert_se(hidden_or_backup_file("..hidden"));
563 assert_se(!hidden_or_backup_file("hidden."));
565 assert_se(hidden_or_backup_file("backup~"));
566 assert_se(hidden_or_backup_file(".backup~"));
568 assert_se(hidden_or_backup_file("lost+found"));
569 assert_se(hidden_or_backup_file("aquota.user"));
570 assert_se(hidden_or_backup_file("aquota.group"));
572 assert_se(hidden_or_backup_file("test.rpmnew"));
573 assert_se(hidden_or_backup_file("test.dpkg-old"));
574 assert_se(hidden_or_backup_file("test.dpkg-remove"));
575 assert_se(hidden_or_backup_file("test.swp"));
577 assert_se(!hidden_or_backup_file("test.rpmnew."));
578 assert_se(!hidden_or_backup_file("test.dpkg-old.foo"));
581 static void test_systemd_installation_has_version(const char *path
) {
583 const unsigned versions
[] = {0, 231, atoi(PACKAGE_VERSION
), 999};
586 for (i
= 0; i
< ELEMENTSOF(versions
); i
++) {
587 r
= systemd_installation_has_version(path
, versions
[i
]);
589 log_info("%s has systemd >= %u: %s",
590 path
?: "Current installation", versions
[i
], yes_no(r
));
594 static void test_skip_dev_prefix(void) {
596 assert_se(streq(skip_dev_prefix("/"), "/"));
597 assert_se(streq(skip_dev_prefix("/dev"), ""));
598 assert_se(streq(skip_dev_prefix("/dev/"), ""));
599 assert_se(streq(skip_dev_prefix("/dev/foo"), "foo"));
600 assert_se(streq(skip_dev_prefix("/dev/foo/bar"), "foo/bar"));
601 assert_se(streq(skip_dev_prefix("//dev"), ""));
602 assert_se(streq(skip_dev_prefix("//dev//"), ""));
603 assert_se(streq(skip_dev_prefix("/dev///foo"), "foo"));
604 assert_se(streq(skip_dev_prefix("///dev///foo///bar"), "foo///bar"));
605 assert_se(streq(skip_dev_prefix("//foo"), "//foo"));
606 assert_se(streq(skip_dev_prefix("foo"), "foo"));
609 int main(int argc
, char **argv
) {
610 log_set_max_level(LOG_DEBUG
);
611 log_parse_environment();
615 test_path_equal_root();
616 test_find_binary(argv
[0]);
620 test_make_relative();
622 test_path_startswith();
624 test_path_is_mount_point();
625 test_file_in_same_dir();
626 test_filename_is_valid();
627 test_hidden_or_backup_file();
628 test_skip_dev_prefix();
630 test_systemd_installation_has_version(argv
[1]); /* NULL is OK */