]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/test/test-path-util.c
util: rework rm_rf() logic
[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
ZJS
88
89 assert_se(path_is_mount_point("/", true));
90 assert_se(path_is_mount_point("/", false));
91
92 {
93 char p1[] = "aaa/bbb////ccc";
94 char p2[] = "//aaa/.////ccc";
95 char p3[] = "/./";
96
8d95631e
FB
97 assert_se(path_equal(path_kill_slashes(p1), "aaa/bbb/ccc"));
98 assert_se(path_equal(path_kill_slashes(p2), "/aaa/./ccc"));
99 assert_se(path_equal(path_kill_slashes(p3), "/./"));
76877b46
ZJS
100 }
101}
102
b63bd109 103static void test_find_binary(const char *self, bool local) {
c9d954b2
ZJS
104 char *p;
105
b63bd109 106 assert_se(find_binary("/bin/sh", local, &p) == 0);
c9d954b2 107 puts(p);
8d95631e 108 assert_se(streq(p, "/bin/sh"));
c9d954b2
ZJS
109 free(p);
110
b63bd109 111 assert_se(find_binary(self, local, &p) == 0);
c9d954b2 112 puts(p);
8d95631e
FB
113 assert_se(endswith(p, "/test-path-util"));
114 assert_se(path_is_absolute(p));
c9d954b2
ZJS
115 free(p);
116
b63bd109 117 assert_se(find_binary("sh", local, &p) == 0);
c9d954b2 118 puts(p);
8d95631e
FB
119 assert_se(endswith(p, "/sh"));
120 assert_se(path_is_absolute(p));
c9d954b2
ZJS
121 free(p);
122
b63bd109 123 assert_se(find_binary("xxxx-xxxx", local, &p) == -ENOENT);
b972115c 124
b63bd109
ZJS
125 assert_se(find_binary("/some/dir/xxxx-xxxx", local, &p) ==
126 (local ? -ENOENT : 0));
f08c4c08
TA
127 if (!local)
128 free(p);
c9d954b2
ZJS
129}
130
fecffe5d 131static void test_prefixes(void) {
e203f7c3
LP
132 static const char* values[] = { "/a/b/c/d", "/a/b/c", "/a/b", "/a", "", NULL};
133 unsigned i;
fecffe5d 134 char s[PATH_MAX];
e203f7c3 135 bool b;
fecffe5d 136
e203f7c3
LP
137 i = 0;
138 PATH_FOREACH_PREFIX_MORE(s, "/a/b/c/d") {
fecffe5d
LP
139 log_error("---%s---", s);
140 assert_se(streq(s, values[i++]));
141 }
e203f7c3 142 assert_se(values[i] == NULL);
fecffe5d 143
e203f7c3
LP
144 i = 1;
145 PATH_FOREACH_PREFIX(s, "/a/b/c/d") {
146 log_error("---%s---", s);
147 assert_se(streq(s, values[i++]));
148 }
fecffe5d
LP
149 assert_se(values[i] == NULL);
150
151 i = 0;
e203f7c3 152 PATH_FOREACH_PREFIX_MORE(s, "////a////b////c///d///////")
fecffe5d 153 assert_se(streq(s, values[i++]));
e203f7c3 154 assert_se(values[i] == NULL);
fecffe5d 155
e203f7c3
LP
156 i = 1;
157 PATH_FOREACH_PREFIX(s, "////a////b////c///d///////")
158 assert_se(streq(s, values[i++]));
fecffe5d
LP
159 assert_se(values[i] == NULL);
160
161 PATH_FOREACH_PREFIX(s, "////")
e203f7c3
LP
162 assert_not_reached("Wut?");
163
164 b = false;
165 PATH_FOREACH_PREFIX_MORE(s, "////") {
166 assert_se(!b);
fecffe5d 167 assert_se(streq(s, ""));
e203f7c3
LP
168 b = true;
169 }
170 assert_se(b);
fecffe5d
LP
171
172 PATH_FOREACH_PREFIX(s, "")
173 assert_not_reached("wut?");
174
e203f7c3
LP
175 b = false;
176 PATH_FOREACH_PREFIX_MORE(s, "") {
8d95631e
FB
177 assert_se(!b);
178 assert_se(streq(s, ""));
e203f7c3
LP
179 b = true;
180 }
fecffe5d
LP
181}
182
0c6ea3a4 183static void test_path_join(void) {
59ae3a95
TA
184
185#define test_join(root, path, rest, expected) { \
186 _cleanup_free_ char *z = NULL; \
187 z = path_join(root, path, rest); \
188 assert_se(streq(z, expected)); \
189 }
190
191 test_join("/root", "/a/b", "/c", "/root/a/b/c");
192 test_join("/root", "a/b", "c", "/root/a/b/c");
193 test_join("/root", "/a/b", "c", "/root/a/b/c");
bc854dc7 194 test_join("/root", "/", "c", "/root/c");
59ae3a95
TA
195 test_join("/root", "/", NULL, "/root/");
196
197 test_join(NULL, "/a/b", "/c", "/a/b/c");
198 test_join(NULL, "a/b", "c", "a/b/c");
199 test_join(NULL, "/a/b", "c", "/a/b/c");
bc854dc7 200 test_join(NULL, "/", "c", "/c");
59ae3a95 201 test_join(NULL, "/", NULL, "/");
0c6ea3a4
ZJS
202}
203
eb66db55
MG
204static void test_fsck_exists(void) {
205 /* Ensure we use a sane default for PATH. */
206 unsetenv("PATH");
207
208 /* fsck.minix is provided by util-linux and will probably exist. */
209 assert_se(fsck_exists("minix") == 0);
210
211 assert_se(fsck_exists("AbCdE") == -ENOENT);
212}
213
6b56a651
TK
214static void test_make_relative(void) {
215 char *result;
216
217 assert_se(path_make_relative("some/relative/path", "/some/path", &result) < 0);
218 assert_se(path_make_relative("/some/path", "some/relative/path", &result) < 0);
219
59ae3a95
TA
220#define test(from_dir, to_path, expected) { \
221 _cleanup_free_ char *z = NULL; \
222 path_make_relative(from_dir, to_path, &z); \
223 assert_se(streq(z, expected)); \
6b56a651
TK
224 }
225
226 test("/", "/", ".");
227 test("/", "/some/path", "some/path");
228 test("/some/path", "/some/path", ".");
229 test("/some/path", "/some/path/in/subdir", "in/subdir");
230 test("/some/path", "/", "../..");
231 test("/some/path", "/some/other/path", "../other/path");
232 test("//extra/////slashes///won't////fool///anybody//", "////extra///slashes////are/just///fine///", "../../../are/just/fine");
233}
234
3e8a78c8
MM
235static void test_strv_resolve(void) {
236 char tmp_dir[] = "/tmp/test-path-util-XXXXXX";
237 _cleanup_strv_free_ char **search_dirs = NULL;
238 _cleanup_strv_free_ char **absolute_dirs = NULL;
239 char **d;
240
241 assert_se(mkdtemp(tmp_dir) != NULL);
242
243 search_dirs = strv_new("/dir1", "/dir2", "/dir3", NULL);
244 assert_se(search_dirs);
245 STRV_FOREACH(d, search_dirs) {
246 char *p = strappend(tmp_dir, *d);
247 assert_se(p);
248 assert_se(strv_push(&absolute_dirs, p) == 0);
249 }
250
251 assert_se(mkdir(absolute_dirs[0], 0700) == 0);
252 assert_se(mkdir(absolute_dirs[1], 0700) == 0);
253 assert_se(symlink("dir2", absolute_dirs[2]) == 0);
254
255 path_strv_resolve(search_dirs, tmp_dir);
256 assert_se(streq(search_dirs[0], "/dir1"));
257 assert_se(streq(search_dirs[1], "/dir2"));
258 assert_se(streq(search_dirs[2], "/dir2"));
259
c6878637 260 assert_se(rm_rf(tmp_dir, REMOVE_ROOT|REMOVE_PHYSICAL) == 0);
3e8a78c8
MM
261}
262
5895b62f
RC
263static void test_path_startswith(void) {
264 assert_se(path_startswith("/foo/bar/barfoo/", "/foo"));
265 assert_se(path_startswith("/foo/bar/barfoo/", "/foo/"));
266 assert_se(path_startswith("/foo/bar/barfoo/", "/"));
267 assert_se(path_startswith("/foo/bar/barfoo/", "////"));
268 assert_se(path_startswith("/foo/bar/barfoo/", "/foo//bar/////barfoo///"));
269 assert_se(path_startswith("/foo/bar/barfoo/", "/foo/bar/barfoo////"));
270 assert_se(path_startswith("/foo/bar/barfoo/", "/foo/bar///barfoo/"));
271 assert_se(path_startswith("/foo/bar/barfoo/", "/foo////bar/barfoo/"));
272 assert_se(path_startswith("/foo/bar/barfoo/", "////foo/bar/barfoo/"));
273 assert_se(path_startswith("/foo/bar/barfoo/", "/foo/bar/barfoo"));
274
275 assert_se(!path_startswith("/foo/bar/barfoo/", "/foo/bar/barfooa/"));
276 assert_se(!path_startswith("/foo/bar/barfoo/", "/foo/bar/barfooa"));
277 assert_se(!path_startswith("/foo/bar/barfoo/", ""));
278 assert_se(!path_startswith("/foo/bar/barfoo/", "/bar/foo"));
279 assert_se(!path_startswith("/foo/bar/barfoo/", "/f/b/b/"));
280}
281
7f076504 282int main(int argc, char **argv) {
76877b46 283 test_path();
b63bd109
ZJS
284 test_find_binary(argv[0], true);
285 test_find_binary(argv[0], false);
fecffe5d 286 test_prefixes();
0c6ea3a4 287 test_path_join();
eb66db55 288 test_fsck_exists();
6b56a651 289 test_make_relative();
3e8a78c8 290 test_strv_resolve();
5895b62f
RC
291 test_path_startswith();
292
76877b46
ZJS
293 return 0;
294}