]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/test/test-path-util.c
systemctl: share path lookup between 'cat' and 'edit'
[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"
76877b46
ZJS
29
30
31static void test_path(void) {
32 assert_se(path_equal("/goo", "/goo"));
33 assert_se(path_equal("//goo", "/goo"));
34 assert_se(path_equal("//goo/////", "/goo"));
35 assert_se(path_equal("goo/////", "goo"));
36
37 assert_se(path_equal("/goo/boo", "/goo//boo"));
38 assert_se(path_equal("//goo/boo", "/goo/boo//"));
39
40 assert_se(path_equal("/", "///"));
41
42 assert_se(!path_equal("/x", "x/"));
43 assert_se(!path_equal("x/", "/"));
44
45 assert_se(!path_equal("/x/./y", "x/y"));
46 assert_se(!path_equal("x/.y", "x/y"));
47
48 assert_se(path_is_absolute("/"));
49 assert_se(!path_is_absolute("./"));
50
51 assert_se(is_path("/dir"));
52 assert_se(is_path("a/b"));
53 assert_se(!is_path("."));
54
2b6bf07d
ZJS
55 assert_se(streq(basename("./aa/bb/../file.da."), "file.da."));
56 assert_se(streq(basename("/aa///.file"), ".file"));
57 assert_se(streq(basename("/aa///file..."), "file..."));
58 assert_se(streq(basename("file.../"), ""));
76877b46 59
a696dbef 60#define test_parent(x, y) { \
c8b32e11 61 _cleanup_free_ char *z = NULL; \
a696dbef
ZJS
62 int r = path_get_parent(x, &z); \
63 printf("expected: %s\n", y ? y : "error"); \
64 printf("actual: %s\n", r<0 ? "error" : z); \
65 assert_se((y==NULL) ^ (r==0)); \
66 assert_se(y==NULL || path_equal(z, y)); \
76877b46
ZJS
67 }
68
69 test_parent("./aa/bb/../file.da.", "./aa/bb/..");
70 test_parent("/aa///.file", "/aa///");
71 test_parent("/aa///file...", "/aa///");
a696dbef 72 test_parent("file.../", NULL);
76877b46
ZJS
73
74 assert_se(path_is_mount_point("/", true));
75 assert_se(path_is_mount_point("/", false));
76
77 {
78 char p1[] = "aaa/bbb////ccc";
79 char p2[] = "//aaa/.////ccc";
80 char p3[] = "/./";
81
8d95631e
FB
82 assert_se(path_equal(path_kill_slashes(p1), "aaa/bbb/ccc"));
83 assert_se(path_equal(path_kill_slashes(p2), "/aaa/./ccc"));
84 assert_se(path_equal(path_kill_slashes(p3), "/./"));
76877b46
ZJS
85 }
86}
87
b63bd109 88static void test_find_binary(const char *self, bool local) {
c9d954b2
ZJS
89 char *p;
90
b63bd109 91 assert_se(find_binary("/bin/sh", local, &p) == 0);
c9d954b2 92 puts(p);
8d95631e 93 assert_se(streq(p, "/bin/sh"));
c9d954b2
ZJS
94 free(p);
95
b63bd109 96 assert_se(find_binary(self, local, &p) == 0);
c9d954b2 97 puts(p);
8d95631e
FB
98 assert_se(endswith(p, "/test-path-util"));
99 assert_se(path_is_absolute(p));
c9d954b2
ZJS
100 free(p);
101
b63bd109 102 assert_se(find_binary("sh", local, &p) == 0);
c9d954b2 103 puts(p);
8d95631e
FB
104 assert_se(endswith(p, "/sh"));
105 assert_se(path_is_absolute(p));
c9d954b2
ZJS
106 free(p);
107
b63bd109 108 assert_se(find_binary("xxxx-xxxx", local, &p) == -ENOENT);
b972115c 109
b63bd109
ZJS
110 assert_se(find_binary("/some/dir/xxxx-xxxx", local, &p) ==
111 (local ? -ENOENT : 0));
f08c4c08
TA
112 if (!local)
113 free(p);
c9d954b2
ZJS
114}
115
fecffe5d 116static void test_prefixes(void) {
e203f7c3
LP
117 static const char* values[] = { "/a/b/c/d", "/a/b/c", "/a/b", "/a", "", NULL};
118 unsigned i;
fecffe5d 119 char s[PATH_MAX];
e203f7c3 120 bool b;
fecffe5d 121
e203f7c3
LP
122 i = 0;
123 PATH_FOREACH_PREFIX_MORE(s, "/a/b/c/d") {
fecffe5d
LP
124 log_error("---%s---", s);
125 assert_se(streq(s, values[i++]));
126 }
e203f7c3 127 assert_se(values[i] == NULL);
fecffe5d 128
e203f7c3
LP
129 i = 1;
130 PATH_FOREACH_PREFIX(s, "/a/b/c/d") {
131 log_error("---%s---", s);
132 assert_se(streq(s, values[i++]));
133 }
fecffe5d
LP
134 assert_se(values[i] == NULL);
135
136 i = 0;
e203f7c3 137 PATH_FOREACH_PREFIX_MORE(s, "////a////b////c///d///////")
fecffe5d 138 assert_se(streq(s, values[i++]));
e203f7c3 139 assert_se(values[i] == NULL);
fecffe5d 140
e203f7c3
LP
141 i = 1;
142 PATH_FOREACH_PREFIX(s, "////a////b////c///d///////")
143 assert_se(streq(s, values[i++]));
fecffe5d
LP
144 assert_se(values[i] == NULL);
145
146 PATH_FOREACH_PREFIX(s, "////")
e203f7c3
LP
147 assert_not_reached("Wut?");
148
149 b = false;
150 PATH_FOREACH_PREFIX_MORE(s, "////") {
151 assert_se(!b);
fecffe5d 152 assert_se(streq(s, ""));
e203f7c3
LP
153 b = true;
154 }
155 assert_se(b);
fecffe5d
LP
156
157 PATH_FOREACH_PREFIX(s, "")
158 assert_not_reached("wut?");
159
e203f7c3
LP
160 b = false;
161 PATH_FOREACH_PREFIX_MORE(s, "") {
8d95631e
FB
162 assert_se(!b);
163 assert_se(streq(s, ""));
e203f7c3
LP
164 b = true;
165 }
fecffe5d
LP
166}
167
0c6ea3a4 168static void test_path_join(void) {
59ae3a95
TA
169
170#define test_join(root, path, rest, expected) { \
171 _cleanup_free_ char *z = NULL; \
172 z = path_join(root, path, rest); \
173 assert_se(streq(z, expected)); \
174 }
175
176 test_join("/root", "/a/b", "/c", "/root/a/b/c");
177 test_join("/root", "a/b", "c", "/root/a/b/c");
178 test_join("/root", "/a/b", "c", "/root/a/b/c");
179 test_join("/root", "/", "c", "/root//c");
180 test_join("/root", "/", NULL, "/root/");
181
182 test_join(NULL, "/a/b", "/c", "/a/b/c");
183 test_join(NULL, "a/b", "c", "a/b/c");
184 test_join(NULL, "/a/b", "c", "/a/b/c");
185 test_join(NULL, "/", "c", "//c");
186 test_join(NULL, "/", NULL, "/");
0c6ea3a4
ZJS
187}
188
eb66db55
MG
189static void test_fsck_exists(void) {
190 /* Ensure we use a sane default for PATH. */
191 unsetenv("PATH");
192
193 /* fsck.minix is provided by util-linux and will probably exist. */
194 assert_se(fsck_exists("minix") == 0);
195
196 assert_se(fsck_exists("AbCdE") == -ENOENT);
197}
198
6b56a651
TK
199static void test_make_relative(void) {
200 char *result;
201
202 assert_se(path_make_relative("some/relative/path", "/some/path", &result) < 0);
203 assert_se(path_make_relative("/some/path", "some/relative/path", &result) < 0);
204
59ae3a95
TA
205#define test(from_dir, to_path, expected) { \
206 _cleanup_free_ char *z = NULL; \
207 path_make_relative(from_dir, to_path, &z); \
208 assert_se(streq(z, expected)); \
6b56a651
TK
209 }
210
211 test("/", "/", ".");
212 test("/", "/some/path", "some/path");
213 test("/some/path", "/some/path", ".");
214 test("/some/path", "/some/path/in/subdir", "in/subdir");
215 test("/some/path", "/", "../..");
216 test("/some/path", "/some/other/path", "../other/path");
217 test("//extra/////slashes///won't////fool///anybody//", "////extra///slashes////are/just///fine///", "../../../are/just/fine");
218}
219
3e8a78c8
MM
220static void test_strv_resolve(void) {
221 char tmp_dir[] = "/tmp/test-path-util-XXXXXX";
222 _cleanup_strv_free_ char **search_dirs = NULL;
223 _cleanup_strv_free_ char **absolute_dirs = NULL;
224 char **d;
225
226 assert_se(mkdtemp(tmp_dir) != NULL);
227
228 search_dirs = strv_new("/dir1", "/dir2", "/dir3", NULL);
229 assert_se(search_dirs);
230 STRV_FOREACH(d, search_dirs) {
231 char *p = strappend(tmp_dir, *d);
232 assert_se(p);
233 assert_se(strv_push(&absolute_dirs, p) == 0);
234 }
235
236 assert_se(mkdir(absolute_dirs[0], 0700) == 0);
237 assert_se(mkdir(absolute_dirs[1], 0700) == 0);
238 assert_se(symlink("dir2", absolute_dirs[2]) == 0);
239
240 path_strv_resolve(search_dirs, tmp_dir);
241 assert_se(streq(search_dirs[0], "/dir1"));
242 assert_se(streq(search_dirs[1], "/dir2"));
243 assert_se(streq(search_dirs[2], "/dir2"));
244
245 assert_se(rm_rf_dangerous(tmp_dir, false, true, false) == 0);
246}
247
5895b62f
RC
248static void test_path_startswith(void) {
249 assert_se(path_startswith("/foo/bar/barfoo/", "/foo"));
250 assert_se(path_startswith("/foo/bar/barfoo/", "/foo/"));
251 assert_se(path_startswith("/foo/bar/barfoo/", "/"));
252 assert_se(path_startswith("/foo/bar/barfoo/", "////"));
253 assert_se(path_startswith("/foo/bar/barfoo/", "/foo//bar/////barfoo///"));
254 assert_se(path_startswith("/foo/bar/barfoo/", "/foo/bar/barfoo////"));
255 assert_se(path_startswith("/foo/bar/barfoo/", "/foo/bar///barfoo/"));
256 assert_se(path_startswith("/foo/bar/barfoo/", "/foo////bar/barfoo/"));
257 assert_se(path_startswith("/foo/bar/barfoo/", "////foo/bar/barfoo/"));
258 assert_se(path_startswith("/foo/bar/barfoo/", "/foo/bar/barfoo"));
259
260 assert_se(!path_startswith("/foo/bar/barfoo/", "/foo/bar/barfooa/"));
261 assert_se(!path_startswith("/foo/bar/barfoo/", "/foo/bar/barfooa"));
262 assert_se(!path_startswith("/foo/bar/barfoo/", ""));
263 assert_se(!path_startswith("/foo/bar/barfoo/", "/bar/foo"));
264 assert_se(!path_startswith("/foo/bar/barfoo/", "/f/b/b/"));
265}
266
7f076504 267int main(int argc, char **argv) {
76877b46 268 test_path();
b63bd109
ZJS
269 test_find_binary(argv[0], true);
270 test_find_binary(argv[0], false);
fecffe5d 271 test_prefixes();
0c6ea3a4 272 test_path_join();
eb66db55 273 test_fsck_exists();
6b56a651 274 test_make_relative();
3e8a78c8 275 test_strv_resolve();
5895b62f
RC
276 test_path_startswith();
277
76877b46
ZJS
278 return 0;
279}