chiark / gitweb /
sd-rtnl: route - allow GETROUTE with AF_UNSPEC
[elogind.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 }