chiark / gitweb /
Support negated fstab options
[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         if (!local)
113                 free(p);
114 }
115
116 static void test_prefixes(void) {
117         static const char* values[] = { "/a/b/c/d", "/a/b/c", "/a/b", "/a", "", NULL};
118         unsigned i;
119         char s[PATH_MAX];
120         bool b;
121
122         i = 0;
123         PATH_FOREACH_PREFIX_MORE(s, "/a/b/c/d") {
124                 log_error("---%s---", s);
125                 assert_se(streq(s, values[i++]));
126         }
127         assert_se(values[i] == NULL);
128
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         }
134         assert_se(values[i] == NULL);
135
136         i = 0;
137         PATH_FOREACH_PREFIX_MORE(s, "////a////b////c///d///////")
138                 assert_se(streq(s, values[i++]));
139         assert_se(values[i] == NULL);
140
141         i = 1;
142         PATH_FOREACH_PREFIX(s, "////a////b////c///d///////")
143                 assert_se(streq(s, values[i++]));
144         assert_se(values[i] == NULL);
145
146         PATH_FOREACH_PREFIX(s, "////")
147                 assert_not_reached("Wut?");
148
149         b = false;
150         PATH_FOREACH_PREFIX_MORE(s, "////") {
151                 assert_se(!b);
152                 assert_se(streq(s, ""));
153                 b = true;
154         }
155         assert_se(b);
156
157         PATH_FOREACH_PREFIX(s, "")
158                 assert_not_reached("wut?");
159
160         b = false;
161         PATH_FOREACH_PREFIX_MORE(s, "") {
162                 assert_se(!b);
163                 assert_se(streq(s, ""));
164                 b = true;
165         }
166 }
167
168 static void test_path_join(void) {
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, "/");
187 }
188
189 static 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
199 static 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
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));             \
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
220 static 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
248 static 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
267 int main(int argc, char **argv) {
268         test_path();
269         test_find_binary(argv[0], true);
270         test_find_binary(argv[0], false);
271         test_prefixes();
272         test_path_join();
273         test_fsck_exists();
274         test_make_relative();
275         test_strv_resolve();
276         test_path_startswith();
277
278         return 0;
279 }