]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/test/test-path-util.c
hwdb: fix typo - "sort by by..." -> "sort by..."
[thirdparty/systemd.git] / src / test / test-path-util.c
CommitLineData
76877b46
ZJS
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2013 Zbigniew Jędrzejewski-Szmek
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
a696dbef 22#include <stdio.h>
3e8a78c8 23#include <unistd.h>
a696dbef 24
76877b46
ZJS
25#include "path-util.h"
26#include "util.h"
27#include "macro.h"
3e8a78c8 28#include "strv.h"
c6878637 29#include "rm-rf.h"
76877b46 30
2230852b
MS
31#define test_path_compare(a, b, result) { \
32 assert_se(path_compare(a, b) == result); \
33 assert_se(path_compare(b, a) == -result); \
34 assert_se(path_equal(a, b) == !result); \
35 assert_se(path_equal(b, a) == !result); \
36 }
76877b46
ZJS
37
38static void test_path(void) {
2230852b
MS
39 test_path_compare("/goo", "/goo", 0);
40 test_path_compare("/goo", "/goo", 0);
41 test_path_compare("//goo", "/goo", 0);
42 test_path_compare("//goo/////", "/goo", 0);
43 test_path_compare("goo/////", "goo", 0);
76877b46 44
2230852b
MS
45 test_path_compare("/goo/boo", "/goo//boo", 0);
46 test_path_compare("//goo/boo", "/goo/boo//", 0);
76877b46 47
2230852b 48 test_path_compare("/", "///", 0);
76877b46 49
2230852b
MS
50 test_path_compare("/x", "x/", 1);
51 test_path_compare("x/", "/", -1);
76877b46 52
2230852b
MS
53 test_path_compare("/x/./y", "x/y", 1);
54 test_path_compare("x/.y", "x/y", -1);
55
56 test_path_compare("foo", "/foo", -1);
57 test_path_compare("/foo", "/foo/bar", -1);
58 test_path_compare("/foo/aaa", "/foo/b", -1);
59 test_path_compare("/foo/aaa", "/foo/b/a", -1);
60 test_path_compare("/foo/a", "/foo/aaa", -1);
61 test_path_compare("/foo/a/b", "/foo/aaa", -1);
76877b46
ZJS
62
63 assert_se(path_is_absolute("/"));
64 assert_se(!path_is_absolute("./"));
65
66 assert_se(is_path("/dir"));
67 assert_se(is_path("a/b"));
68 assert_se(!is_path("."));
69
2b6bf07d
ZJS
70 assert_se(streq(basename("./aa/bb/../file.da."), "file.da."));
71 assert_se(streq(basename("/aa///.file"), ".file"));
72 assert_se(streq(basename("/aa///file..."), "file..."));
73 assert_se(streq(basename("file.../"), ""));
76877b46 74
a696dbef 75#define test_parent(x, y) { \
c8b32e11 76 _cleanup_free_ char *z = NULL; \
a696dbef
ZJS
77 int r = path_get_parent(x, &z); \
78 printf("expected: %s\n", y ? y : "error"); \
79 printf("actual: %s\n", r<0 ? "error" : z); \
80 assert_se((y==NULL) ^ (r==0)); \
81 assert_se(y==NULL || path_equal(z, y)); \
76877b46
ZJS
82 }
83
84 test_parent("./aa/bb/../file.da.", "./aa/bb/..");
85 test_parent("/aa///.file", "/aa///");
86 test_parent("/aa///file...", "/aa///");
a696dbef 87 test_parent("file.../", NULL);
76877b46 88
da00518b
LP
89 assert_se(path_is_mount_point("/", true) > 0);
90 assert_se(path_is_mount_point("/", false) > 0);
91
92 assert_se(path_is_mount_point("/proc", true) > 0);
93 assert_se(path_is_mount_point("/proc", false) > 0);
94
95 assert_se(path_is_mount_point("/sys", true) > 0);
96 assert_se(path_is_mount_point("/sys", false) > 0);
76877b46
ZJS
97
98 {
99 char p1[] = "aaa/bbb////ccc";
100 char p2[] = "//aaa/.////ccc";
101 char p3[] = "/./";
102
8d95631e
FB
103 assert_se(path_equal(path_kill_slashes(p1), "aaa/bbb/ccc"));
104 assert_se(path_equal(path_kill_slashes(p2), "/aaa/./ccc"));
105 assert_se(path_equal(path_kill_slashes(p3), "/./"));
76877b46
ZJS
106 }
107}
108
b63bd109 109static void test_find_binary(const char *self, bool local) {
c9d954b2
ZJS
110 char *p;
111
b63bd109 112 assert_se(find_binary("/bin/sh", local, &p) == 0);
c9d954b2 113 puts(p);
8d95631e 114 assert_se(streq(p, "/bin/sh"));
c9d954b2
ZJS
115 free(p);
116
b63bd109 117 assert_se(find_binary(self, local, &p) == 0);
c9d954b2 118 puts(p);
8d95631e
FB
119 assert_se(endswith(p, "/test-path-util"));
120 assert_se(path_is_absolute(p));
c9d954b2
ZJS
121 free(p);
122
b63bd109 123 assert_se(find_binary("sh", local, &p) == 0);
c9d954b2 124 puts(p);
8d95631e
FB
125 assert_se(endswith(p, "/sh"));
126 assert_se(path_is_absolute(p));
c9d954b2
ZJS
127 free(p);
128
b63bd109 129 assert_se(find_binary("xxxx-xxxx", local, &p) == -ENOENT);
b972115c 130
b63bd109
ZJS
131 assert_se(find_binary("/some/dir/xxxx-xxxx", local, &p) ==
132 (local ? -ENOENT : 0));
f08c4c08
TA
133 if (!local)
134 free(p);
c9d954b2
ZJS
135}
136
fecffe5d 137static void test_prefixes(void) {
e203f7c3
LP
138 static const char* values[] = { "/a/b/c/d", "/a/b/c", "/a/b", "/a", "", NULL};
139 unsigned i;
fecffe5d 140 char s[PATH_MAX];
e203f7c3 141 bool b;
fecffe5d 142
e203f7c3
LP
143 i = 0;
144 PATH_FOREACH_PREFIX_MORE(s, "/a/b/c/d") {
fecffe5d
LP
145 log_error("---%s---", s);
146 assert_se(streq(s, values[i++]));
147 }
e203f7c3 148 assert_se(values[i] == NULL);
fecffe5d 149
e203f7c3
LP
150 i = 1;
151 PATH_FOREACH_PREFIX(s, "/a/b/c/d") {
152 log_error("---%s---", s);
153 assert_se(streq(s, values[i++]));
154 }
fecffe5d
LP
155 assert_se(values[i] == NULL);
156
157 i = 0;
e203f7c3 158 PATH_FOREACH_PREFIX_MORE(s, "////a////b////c///d///////")
fecffe5d 159 assert_se(streq(s, values[i++]));
e203f7c3 160 assert_se(values[i] == NULL);
fecffe5d 161
e203f7c3
LP
162 i = 1;
163 PATH_FOREACH_PREFIX(s, "////a////b////c///d///////")
164 assert_se(streq(s, values[i++]));
fecffe5d
LP
165 assert_se(values[i] == NULL);
166
167 PATH_FOREACH_PREFIX(s, "////")
e203f7c3
LP
168 assert_not_reached("Wut?");
169
170 b = false;
171 PATH_FOREACH_PREFIX_MORE(s, "////") {
172 assert_se(!b);
fecffe5d 173 assert_se(streq(s, ""));
e203f7c3
LP
174 b = true;
175 }
176 assert_se(b);
fecffe5d
LP
177
178 PATH_FOREACH_PREFIX(s, "")
179 assert_not_reached("wut?");
180
e203f7c3
LP
181 b = false;
182 PATH_FOREACH_PREFIX_MORE(s, "") {
8d95631e
FB
183 assert_se(!b);
184 assert_se(streq(s, ""));
e203f7c3
LP
185 b = true;
186 }
fecffe5d
LP
187}
188
0c6ea3a4 189static void test_path_join(void) {
59ae3a95
TA
190
191#define test_join(root, path, rest, expected) { \
192 _cleanup_free_ char *z = NULL; \
193 z = path_join(root, path, rest); \
194 assert_se(streq(z, expected)); \
195 }
196
197 test_join("/root", "/a/b", "/c", "/root/a/b/c");
198 test_join("/root", "a/b", "c", "/root/a/b/c");
199 test_join("/root", "/a/b", "c", "/root/a/b/c");
bc854dc7 200 test_join("/root", "/", "c", "/root/c");
59ae3a95
TA
201 test_join("/root", "/", NULL, "/root/");
202
203 test_join(NULL, "/a/b", "/c", "/a/b/c");
204 test_join(NULL, "a/b", "c", "a/b/c");
205 test_join(NULL, "/a/b", "c", "/a/b/c");
bc854dc7 206 test_join(NULL, "/", "c", "/c");
59ae3a95 207 test_join(NULL, "/", NULL, "/");
0c6ea3a4
ZJS
208}
209
eb66db55
MG
210static void test_fsck_exists(void) {
211 /* Ensure we use a sane default for PATH. */
212 unsetenv("PATH");
213
214 /* fsck.minix is provided by util-linux and will probably exist. */
215 assert_se(fsck_exists("minix") == 0);
216
217 assert_se(fsck_exists("AbCdE") == -ENOENT);
218}
219
6b56a651
TK
220static void test_make_relative(void) {
221 char *result;
222
223 assert_se(path_make_relative("some/relative/path", "/some/path", &result) < 0);
224 assert_se(path_make_relative("/some/path", "some/relative/path", &result) < 0);
225
59ae3a95
TA
226#define test(from_dir, to_path, expected) { \
227 _cleanup_free_ char *z = NULL; \
228 path_make_relative(from_dir, to_path, &z); \
229 assert_se(streq(z, expected)); \
6b56a651
TK
230 }
231
232 test("/", "/", ".");
233 test("/", "/some/path", "some/path");
234 test("/some/path", "/some/path", ".");
235 test("/some/path", "/some/path/in/subdir", "in/subdir");
236 test("/some/path", "/", "../..");
237 test("/some/path", "/some/other/path", "../other/path");
238 test("//extra/////slashes///won't////fool///anybody//", "////extra///slashes////are/just///fine///", "../../../are/just/fine");
239}
240
3e8a78c8
MM
241static void test_strv_resolve(void) {
242 char tmp_dir[] = "/tmp/test-path-util-XXXXXX";
243 _cleanup_strv_free_ char **search_dirs = NULL;
244 _cleanup_strv_free_ char **absolute_dirs = NULL;
245 char **d;
246
247 assert_se(mkdtemp(tmp_dir) != NULL);
248
249 search_dirs = strv_new("/dir1", "/dir2", "/dir3", NULL);
250 assert_se(search_dirs);
251 STRV_FOREACH(d, search_dirs) {
252 char *p = strappend(tmp_dir, *d);
253 assert_se(p);
254 assert_se(strv_push(&absolute_dirs, p) == 0);
255 }
256
257 assert_se(mkdir(absolute_dirs[0], 0700) == 0);
258 assert_se(mkdir(absolute_dirs[1], 0700) == 0);
259 assert_se(symlink("dir2", absolute_dirs[2]) == 0);
260
261 path_strv_resolve(search_dirs, tmp_dir);
262 assert_se(streq(search_dirs[0], "/dir1"));
263 assert_se(streq(search_dirs[1], "/dir2"));
264 assert_se(streq(search_dirs[2], "/dir2"));
265
c6878637 266 assert_se(rm_rf(tmp_dir, REMOVE_ROOT|REMOVE_PHYSICAL) == 0);
3e8a78c8
MM
267}
268
5895b62f
RC
269static void test_path_startswith(void) {
270 assert_se(path_startswith("/foo/bar/barfoo/", "/foo"));
271 assert_se(path_startswith("/foo/bar/barfoo/", "/foo/"));
272 assert_se(path_startswith("/foo/bar/barfoo/", "/"));
273 assert_se(path_startswith("/foo/bar/barfoo/", "////"));
274 assert_se(path_startswith("/foo/bar/barfoo/", "/foo//bar/////barfoo///"));
275 assert_se(path_startswith("/foo/bar/barfoo/", "/foo/bar/barfoo////"));
276 assert_se(path_startswith("/foo/bar/barfoo/", "/foo/bar///barfoo/"));
277 assert_se(path_startswith("/foo/bar/barfoo/", "/foo////bar/barfoo/"));
278 assert_se(path_startswith("/foo/bar/barfoo/", "////foo/bar/barfoo/"));
279 assert_se(path_startswith("/foo/bar/barfoo/", "/foo/bar/barfoo"));
280
281 assert_se(!path_startswith("/foo/bar/barfoo/", "/foo/bar/barfooa/"));
282 assert_se(!path_startswith("/foo/bar/barfoo/", "/foo/bar/barfooa"));
283 assert_se(!path_startswith("/foo/bar/barfoo/", ""));
284 assert_se(!path_startswith("/foo/bar/barfoo/", "/bar/foo"));
285 assert_se(!path_startswith("/foo/bar/barfoo/", "/f/b/b/"));
286}
287
7f076504 288int main(int argc, char **argv) {
76877b46 289 test_path();
b63bd109
ZJS
290 test_find_binary(argv[0], true);
291 test_find_binary(argv[0], false);
fecffe5d 292 test_prefixes();
0c6ea3a4 293 test_path_join();
eb66db55 294 test_fsck_exists();
6b56a651 295 test_make_relative();
3e8a78c8 296 test_strv_resolve();
5895b62f
RC
297 test_path_startswith();
298
76877b46
ZJS
299 return 0;
300}