chiark / gitweb /
4ee33a9543f46302b16a733acd5a5a244d8c176e
[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                 char _cleanup_free_ *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(path_equal(path_kill_slashes(p1), "aaa/bbb/ccc"));
83                 assert(path_equal(path_kill_slashes(p2), "/aaa/./ccc"));
84                 assert(path_equal(path_kill_slashes(p3), "/./"));
85         }
86 }
87
88 static void test_find_binary(const char *self) {
89         char *p;
90
91         assert(find_binary("/bin/sh", &p) == 0);
92         puts(p);
93         assert(streq(p, "/bin/sh"));
94         free(p);
95
96         assert(find_binary(self, &p) == 0);
97         puts(p);
98         assert(endswith(p, "/test-path-util"));
99         assert(path_is_absolute(p));
100         free(p);
101
102         assert(find_binary("sh", &p) == 0);
103         puts(p);
104         assert(endswith(p, "/sh"));
105         assert(path_is_absolute(p));
106         free(p);
107
108         assert(find_binary("xxxx-xxxx", &p) == -ENOENT);
109
110         assert(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(!b);
160                 assert(streq(s, ""));
161                 b = true;
162         }
163 }
164
165 static void test_fsck_exists(void) {
166         /* Ensure we use a sane default for PATH. */
167         unsetenv("PATH");
168
169         /* fsck.minix is provided by util-linux and will probably exist. */
170         assert_se(fsck_exists("minix") == 0);
171
172         assert_se(fsck_exists("AbCdE") == -ENOENT);
173 }
174
175 static void test_make_relative(void) {
176         char *result;
177
178         assert_se(path_make_relative("some/relative/path", "/some/path", &result) < 0);
179         assert_se(path_make_relative("/some/path", "some/relative/path", &result) < 0);
180
181 #define test(from_dir, to_path, expected) {                     \
182                 path_make_relative(from_dir, to_path, &result); \
183                 assert_se(streq(result, expected));             \
184                 free(result);                                   \
185         }
186
187         test("/", "/", ".");
188         test("/", "/some/path", "some/path");
189         test("/some/path", "/some/path", ".");
190         test("/some/path", "/some/path/in/subdir", "in/subdir");
191         test("/some/path", "/", "../..");
192         test("/some/path", "/some/other/path", "../other/path");
193         test("//extra/////slashes///won't////fool///anybody//", "////extra///slashes////are/just///fine///", "../../../are/just/fine");
194 }
195
196 static void test_strv_resolve(void) {
197         char tmp_dir[] = "/tmp/test-path-util-XXXXXX";
198         _cleanup_strv_free_ char **search_dirs = NULL;
199         _cleanup_strv_free_ char **absolute_dirs = NULL;
200         char **d;
201
202         assert_se(mkdtemp(tmp_dir) != NULL);
203
204         search_dirs = strv_new("/dir1", "/dir2", "/dir3", NULL);
205         assert_se(search_dirs);
206         STRV_FOREACH(d, search_dirs) {
207                 char *p = strappend(tmp_dir, *d);
208                 assert_se(p);
209                 assert_se(strv_push(&absolute_dirs, p) == 0);
210         }
211
212         assert_se(mkdir(absolute_dirs[0], 0700) == 0);
213         assert_se(mkdir(absolute_dirs[1], 0700) == 0);
214         assert_se(symlink("dir2", absolute_dirs[2]) == 0);
215
216         path_strv_resolve(search_dirs, tmp_dir);
217         assert_se(streq(search_dirs[0], "/dir1"));
218         assert_se(streq(search_dirs[1], "/dir2"));
219         assert_se(streq(search_dirs[2], "/dir2"));
220
221         assert_se(rm_rf_dangerous(tmp_dir, false, true, false) == 0);
222 }
223
224 int main(int argc, char **argv) {
225         test_path();
226         test_find_binary(argv[0]);
227         test_prefixes();
228         test_fsck_exists();
229         test_make_relative();
230         test_strv_resolve();
231         return 0;
232 }