]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/test/test-path-util.c
treewide: use log_*_errno whenever %m is in the format string
[thirdparty/systemd.git] / src / test / test-path-util.c
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
22 #include <stdio.h>
23 #include <unistd.h>
24
25 #include "path-util.h"
26 #include "util.h"
27 #include "macro.h"
28 #include "strv.h"
29
30
31 static 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
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.../"), ""));
59
60 #define test_parent(x, y) { \
61 _cleanup_free_ char *z = NULL; \
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)); \
67 }
68
69 test_parent("./aa/bb/../file.da.", "./aa/bb/..");
70 test_parent("/aa///.file", "/aa///");
71 test_parent("/aa///file...", "/aa///");
72 test_parent("file.../", NULL);
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
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), "/./"));
85 }
86 }
87
88 static void test_find_binary(const char *self, bool local) {
89 char *p;
90
91 assert_se(find_binary("/bin/sh", local, &p) == 0);
92 puts(p);
93 assert_se(streq(p, "/bin/sh"));
94 free(p);
95
96 assert_se(find_binary(self, local, &p) == 0);
97 puts(p);
98 assert_se(endswith(p, "/test-path-util"));
99 assert_se(path_is_absolute(p));
100 free(p);
101
102 assert_se(find_binary("sh", local, &p) == 0);
103 puts(p);
104 assert_se(endswith(p, "/sh"));
105 assert_se(path_is_absolute(p));
106 free(p);
107
108 assert_se(find_binary("xxxx-xxxx", local, &p) == -ENOENT);
109
110 assert_se(find_binary("/some/dir/xxxx-xxxx", local, &p) ==
111 (local ? -ENOENT : 0));
112 }
113
114 static void test_prefixes(void) {
115 static const char* values[] = { "/a/b/c/d", "/a/b/c", "/a/b", "/a", "", NULL};
116 unsigned i;
117 char s[PATH_MAX];
118 bool b;
119
120 i = 0;
121 PATH_FOREACH_PREFIX_MORE(s, "/a/b/c/d") {
122 log_error("---%s---", s);
123 assert_se(streq(s, values[i++]));
124 }
125 assert_se(values[i] == NULL);
126
127 i = 1;
128 PATH_FOREACH_PREFIX(s, "/a/b/c/d") {
129 log_error("---%s---", s);
130 assert_se(streq(s, values[i++]));
131 }
132 assert_se(values[i] == NULL);
133
134 i = 0;
135 PATH_FOREACH_PREFIX_MORE(s, "////a////b////c///d///////")
136 assert_se(streq(s, values[i++]));
137 assert_se(values[i] == NULL);
138
139 i = 1;
140 PATH_FOREACH_PREFIX(s, "////a////b////c///d///////")
141 assert_se(streq(s, values[i++]));
142 assert_se(values[i] == NULL);
143
144 PATH_FOREACH_PREFIX(s, "////")
145 assert_not_reached("Wut?");
146
147 b = false;
148 PATH_FOREACH_PREFIX_MORE(s, "////") {
149 assert_se(!b);
150 assert_se(streq(s, ""));
151 b = true;
152 }
153 assert_se(b);
154
155 PATH_FOREACH_PREFIX(s, "")
156 assert_not_reached("wut?");
157
158 b = false;
159 PATH_FOREACH_PREFIX_MORE(s, "") {
160 assert_se(!b);
161 assert_se(streq(s, ""));
162 b = true;
163 }
164 }
165
166 static void test_path_join(void) {
167
168 #define test_join(root, path, rest, expected) { \
169 _cleanup_free_ char *z = NULL; \
170 z = path_join(root, path, rest); \
171 assert_se(streq(z, expected)); \
172 }
173
174 test_join("/root", "/a/b", "/c", "/root/a/b/c");
175 test_join("/root", "a/b", "c", "/root/a/b/c");
176 test_join("/root", "/a/b", "c", "/root/a/b/c");
177 test_join("/root", "/", "c", "/root//c");
178 test_join("/root", "/", NULL, "/root/");
179
180 test_join(NULL, "/a/b", "/c", "/a/b/c");
181 test_join(NULL, "a/b", "c", "a/b/c");
182 test_join(NULL, "/a/b", "c", "/a/b/c");
183 test_join(NULL, "/", "c", "//c");
184 test_join(NULL, "/", NULL, "/");
185 }
186
187 static void test_fsck_exists(void) {
188 /* Ensure we use a sane default for PATH. */
189 unsetenv("PATH");
190
191 /* fsck.minix is provided by util-linux and will probably exist. */
192 assert_se(fsck_exists("minix") == 0);
193
194 assert_se(fsck_exists("AbCdE") == -ENOENT);
195 }
196
197 static void test_make_relative(void) {
198 char *result;
199
200 assert_se(path_make_relative("some/relative/path", "/some/path", &result) < 0);
201 assert_se(path_make_relative("/some/path", "some/relative/path", &result) < 0);
202
203 #define test(from_dir, to_path, expected) { \
204 _cleanup_free_ char *z = NULL; \
205 path_make_relative(from_dir, to_path, &z); \
206 assert_se(streq(z, expected)); \
207 }
208
209 test("/", "/", ".");
210 test("/", "/some/path", "some/path");
211 test("/some/path", "/some/path", ".");
212 test("/some/path", "/some/path/in/subdir", "in/subdir");
213 test("/some/path", "/", "../..");
214 test("/some/path", "/some/other/path", "../other/path");
215 test("//extra/////slashes///won't////fool///anybody//", "////extra///slashes////are/just///fine///", "../../../are/just/fine");
216 }
217
218 static void test_strv_resolve(void) {
219 char tmp_dir[] = "/tmp/test-path-util-XXXXXX";
220 _cleanup_strv_free_ char **search_dirs = NULL;
221 _cleanup_strv_free_ char **absolute_dirs = NULL;
222 char **d;
223
224 assert_se(mkdtemp(tmp_dir) != NULL);
225
226 search_dirs = strv_new("/dir1", "/dir2", "/dir3", NULL);
227 assert_se(search_dirs);
228 STRV_FOREACH(d, search_dirs) {
229 char *p = strappend(tmp_dir, *d);
230 assert_se(p);
231 assert_se(strv_push(&absolute_dirs, p) == 0);
232 }
233
234 assert_se(mkdir(absolute_dirs[0], 0700) == 0);
235 assert_se(mkdir(absolute_dirs[1], 0700) == 0);
236 assert_se(symlink("dir2", absolute_dirs[2]) == 0);
237
238 path_strv_resolve(search_dirs, tmp_dir);
239 assert_se(streq(search_dirs[0], "/dir1"));
240 assert_se(streq(search_dirs[1], "/dir2"));
241 assert_se(streq(search_dirs[2], "/dir2"));
242
243 assert_se(rm_rf_dangerous(tmp_dir, false, true, false) == 0);
244 }
245
246 static void test_path_startswith(void) {
247 assert_se(path_startswith("/foo/bar/barfoo/", "/foo"));
248 assert_se(path_startswith("/foo/bar/barfoo/", "/foo/"));
249 assert_se(path_startswith("/foo/bar/barfoo/", "/"));
250 assert_se(path_startswith("/foo/bar/barfoo/", "////"));
251 assert_se(path_startswith("/foo/bar/barfoo/", "/foo//bar/////barfoo///"));
252 assert_se(path_startswith("/foo/bar/barfoo/", "/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
258 assert_se(!path_startswith("/foo/bar/barfoo/", "/foo/bar/barfooa/"));
259 assert_se(!path_startswith("/foo/bar/barfoo/", "/foo/bar/barfooa"));
260 assert_se(!path_startswith("/foo/bar/barfoo/", ""));
261 assert_se(!path_startswith("/foo/bar/barfoo/", "/bar/foo"));
262 assert_se(!path_startswith("/foo/bar/barfoo/", "/f/b/b/"));
263 }
264
265 int main(int argc, char **argv) {
266 test_path();
267 test_find_binary(argv[0], true);
268 test_find_binary(argv[0], false);
269 test_prefixes();
270 test_path_join();
271 test_fsck_exists();
272 test_make_relative();
273 test_strv_resolve();
274 test_path_startswith();
275
276 return 0;
277 }