chiark / gitweb /
bus: when dumping string property values escape the chars we use as end-of-line and...
[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) {
89         char *p;
90
91         assert_se(find_binary("/bin/sh", &p) == 0);
92         puts(p);
93         assert_se(streq(p, "/bin/sh"));
94         free(p);
95
96         assert_se(find_binary(self, &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", &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", &p) == -ENOENT);
109
110         assert_se(find_binary("/some/dir/xxxx-xxxx", &p) == -ENOENT);
111 }
112
113 static void test_prefixes(void) {
114         static const char* values[] = { "/a/b/c/d", "/a/b/c", "/a/b", "/a", "", NULL};
115         unsigned i;
116         char s[PATH_MAX];
117         bool b;
118
119         i = 0;
120         PATH_FOREACH_PREFIX_MORE(s, "/a/b/c/d") {
121                 log_error("---%s---", s);
122                 assert_se(streq(s, values[i++]));
123         }
124         assert_se(values[i] == NULL);
125
126         i = 1;
127         PATH_FOREACH_PREFIX(s, "/a/b/c/d") {
128                 log_error("---%s---", s);
129                 assert_se(streq(s, values[i++]));
130         }
131         assert_se(values[i] == NULL);
132
133         i = 0;
134         PATH_FOREACH_PREFIX_MORE(s, "////a////b////c///d///////")
135                 assert_se(streq(s, values[i++]));
136         assert_se(values[i] == NULL);
137
138         i = 1;
139         PATH_FOREACH_PREFIX(s, "////a////b////c///d///////")
140                 assert_se(streq(s, values[i++]));
141         assert_se(values[i] == NULL);
142
143         PATH_FOREACH_PREFIX(s, "////")
144                 assert_not_reached("Wut?");
145
146         b = false;
147         PATH_FOREACH_PREFIX_MORE(s, "////") {
148                 assert_se(!b);
149                 assert_se(streq(s, ""));
150                 b = true;
151         }
152         assert_se(b);
153
154         PATH_FOREACH_PREFIX(s, "")
155                 assert_not_reached("wut?");
156
157         b = false;
158         PATH_FOREACH_PREFIX_MORE(s, "") {
159                 assert_se(!b);
160                 assert_se(streq(s, ""));
161                 b = true;
162         }
163 }
164
165 static void test_path_join(void) {
166
167 #define test_join(root, path, rest, expected) {  \
168                 _cleanup_free_ char *z = NULL;   \
169                 z = path_join(root, path, rest); \
170                 assert_se(streq(z, expected));   \
171         }
172
173         test_join("/root", "/a/b", "/c", "/root/a/b/c");
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", "/", "c", "/root//c");
177         test_join("/root", "/", NULL, "/root/");
178
179         test_join(NULL, "/a/b", "/c", "/a/b/c");
180         test_join(NULL, "a/b", "c", "a/b/c");
181         test_join(NULL, "/a/b", "c", "/a/b/c");
182         test_join(NULL, "/", "c", "//c");
183         test_join(NULL, "/", NULL, "/");
184 }
185
186 static void test_fsck_exists(void) {
187         /* Ensure we use a sane default for PATH. */
188         unsetenv("PATH");
189
190         /* fsck.minix is provided by util-linux and will probably exist. */
191         assert_se(fsck_exists("minix") == 0);
192
193         assert_se(fsck_exists("AbCdE") == -ENOENT);
194 }
195
196 static void test_make_relative(void) {
197         char *result;
198
199         assert_se(path_make_relative("some/relative/path", "/some/path", &result) < 0);
200         assert_se(path_make_relative("/some/path", "some/relative/path", &result) < 0);
201
202 #define test(from_dir, to_path, expected) {                \
203                 _cleanup_free_ char *z = NULL;             \
204                 path_make_relative(from_dir, to_path, &z); \
205                 assert_se(streq(z, expected));             \
206         }
207
208         test("/", "/", ".");
209         test("/", "/some/path", "some/path");
210         test("/some/path", "/some/path", ".");
211         test("/some/path", "/some/path/in/subdir", "in/subdir");
212         test("/some/path", "/", "../..");
213         test("/some/path", "/some/other/path", "../other/path");
214         test("//extra/////slashes///won't////fool///anybody//", "////extra///slashes////are/just///fine///", "../../../are/just/fine");
215 }
216
217 static void test_strv_resolve(void) {
218         char tmp_dir[] = "/tmp/test-path-util-XXXXXX";
219         _cleanup_strv_free_ char **search_dirs = NULL;
220         _cleanup_strv_free_ char **absolute_dirs = NULL;
221         char **d;
222
223         assert_se(mkdtemp(tmp_dir) != NULL);
224
225         search_dirs = strv_new("/dir1", "/dir2", "/dir3", NULL);
226         assert_se(search_dirs);
227         STRV_FOREACH(d, search_dirs) {
228                 char *p = strappend(tmp_dir, *d);
229                 assert_se(p);
230                 assert_se(strv_push(&absolute_dirs, p) == 0);
231         }
232
233         assert_se(mkdir(absolute_dirs[0], 0700) == 0);
234         assert_se(mkdir(absolute_dirs[1], 0700) == 0);
235         assert_se(symlink("dir2", absolute_dirs[2]) == 0);
236
237         path_strv_resolve(search_dirs, tmp_dir);
238         assert_se(streq(search_dirs[0], "/dir1"));
239         assert_se(streq(search_dirs[1], "/dir2"));
240         assert_se(streq(search_dirs[2], "/dir2"));
241
242         assert_se(rm_rf_dangerous(tmp_dir, false, true, false) == 0);
243 }
244
245 static void test_path_startswith(void) {
246         assert_se(path_startswith("/foo/bar/barfoo/", "/foo"));
247         assert_se(path_startswith("/foo/bar/barfoo/", "/foo/"));
248         assert_se(path_startswith("/foo/bar/barfoo/", "/"));
249         assert_se(path_startswith("/foo/bar/barfoo/", "////"));
250         assert_se(path_startswith("/foo/bar/barfoo/", "/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
257         assert_se(!path_startswith("/foo/bar/barfoo/", "/foo/bar/barfooa/"));
258         assert_se(!path_startswith("/foo/bar/barfoo/", "/foo/bar/barfooa"));
259         assert_se(!path_startswith("/foo/bar/barfoo/", ""));
260         assert_se(!path_startswith("/foo/bar/barfoo/", "/bar/foo"));
261         assert_se(!path_startswith("/foo/bar/barfoo/", "/f/b/b/"));
262 }
263
264 int main(int argc, char **argv) {
265         test_path();
266         test_find_binary(argv[0]);
267         test_prefixes();
268         test_path_join();
269         test_fsck_exists();
270         test_make_relative();
271         test_strv_resolve();
272         test_path_startswith();
273
274         return 0;
275 }