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