LCOV - code coverage report
Current view: top level - test - test-path-util.c (source / functions) Hit Total Coverage
Test: main_coverage.info Lines: 471 473 99.6 %
Date: 2019-08-22 15:41:25 Functions: 24 24 100.0 %

          Line data    Source code
       1             : /* SPDX-License-Identifier: LGPL-2.1+ */
       2             : 
       3             : #include <stdio.h>
       4             : #include <unistd.h>
       5             : 
       6             : #include "alloc-util.h"
       7             : #include "fd-util.h"
       8             : #include "macro.h"
       9             : #include "mountpoint-util.h"
      10             : #include "path-util.h"
      11             : #include "rm-rf.h"
      12             : #include "stat-util.h"
      13             : #include "string-util.h"
      14             : #include "strv.h"
      15             : #include "tests.h"
      16             : #include "util.h"
      17             : 
      18             : #define test_path_compare(a, b, result) {                 \
      19             :                 assert_se(path_compare(a, b) == result);  \
      20             :                 assert_se(path_compare(b, a) == -result); \
      21             :                 assert_se(path_equal(a, b) == !result);   \
      22             :                 assert_se(path_equal(b, a) == !result);   \
      23             :         }
      24             : 
      25          14 : static void test_path_simplify(const char *in, const char *out, const char *out_dot) {
      26             :         char *p;
      27             : 
      28          14 :         log_info("/* %s */", __func__);
      29             : 
      30          14 :         p = strdupa(in);
      31          14 :         assert_se(streq(path_simplify(p, false), out));
      32             : 
      33          14 :         p = strdupa(in);
      34          14 :         assert_se(streq(path_simplify(p, true), out_dot));
      35          14 : }
      36             : 
      37           1 : static void test_path(void) {
      38           1 :         _cleanup_close_ int fd = -1;
      39             : 
      40           1 :         log_info("/* %s */", __func__);
      41             : 
      42           1 :         test_path_compare("/goo", "/goo", 0);
      43           1 :         test_path_compare("/goo", "/goo", 0);
      44           1 :         test_path_compare("//goo", "/goo", 0);
      45           1 :         test_path_compare("//goo/////", "/goo", 0);
      46           1 :         test_path_compare("goo/////", "goo", 0);
      47             : 
      48           1 :         test_path_compare("/goo/boo", "/goo//boo", 0);
      49           1 :         test_path_compare("//goo/boo", "/goo/boo//", 0);
      50             : 
      51           1 :         test_path_compare("/", "///", 0);
      52             : 
      53           1 :         test_path_compare("/x", "x/", 1);
      54           1 :         test_path_compare("x/", "/", -1);
      55             : 
      56           1 :         test_path_compare("/x/./y", "x/y", 1);
      57           1 :         test_path_compare("x/.y", "x/y", -1);
      58             : 
      59           1 :         test_path_compare("foo", "/foo", -1);
      60           1 :         test_path_compare("/foo", "/foo/bar", -1);
      61           1 :         test_path_compare("/foo/aaa", "/foo/b", -1);
      62           1 :         test_path_compare("/foo/aaa", "/foo/b/a", -1);
      63           1 :         test_path_compare("/foo/a", "/foo/aaa", -1);
      64           1 :         test_path_compare("/foo/a/b", "/foo/aaa", -1);
      65             : 
      66           1 :         assert_se(path_is_absolute("/"));
      67           1 :         assert_se(!path_is_absolute("./"));
      68             : 
      69           1 :         assert_se(is_path("/dir"));
      70           1 :         assert_se(is_path("a/b"));
      71           1 :         assert_se(!is_path("."));
      72             : 
      73           1 :         assert_se(streq(basename("./aa/bb/../file.da."), "file.da."));
      74           1 :         assert_se(streq(basename("/aa///.file"), ".file"));
      75           1 :         assert_se(streq(basename("/aa///file..."), "file..."));
      76           1 :         assert_se(streq(basename("file.../"), ""));
      77             : 
      78           1 :         fd = open("/", O_RDONLY|O_CLOEXEC|O_DIRECTORY|O_NOCTTY);
      79           1 :         assert_se(fd >= 0);
      80           1 :         assert_se(fd_is_mount_point(fd, "/", 0) > 0);
      81             : 
      82           1 :         test_path_simplify("aaa/bbb////ccc", "aaa/bbb/ccc", "aaa/bbb/ccc");
      83           1 :         test_path_simplify("//aaa/.////ccc", "/aaa/./ccc", "/aaa/ccc");
      84           1 :         test_path_simplify("///", "/", "/");
      85           1 :         test_path_simplify("///.//", "/.", "/");
      86           1 :         test_path_simplify("///.//.///", "/./.", "/");
      87           1 :         test_path_simplify("////.././///../.", "/.././../.", "/../..");
      88           1 :         test_path_simplify(".", ".", ".");
      89           1 :         test_path_simplify("./", ".", ".");
      90           1 :         test_path_simplify(".///.//./.", "./././.", ".");
      91           1 :         test_path_simplify(".///.//././/", "./././.", ".");
      92           1 :         test_path_simplify("//./aaa///.//./.bbb/..///c.//d.dd///..eeee/.",
      93             :                            "/./aaa/././.bbb/../c./d.dd/..eeee/.",
      94             :                            "/aaa/.bbb/../c./d.dd/..eeee");
      95           1 :         test_path_simplify("//./aaa///.//./.bbb/..///c.//d.dd///..eeee/..",
      96             :                            "/./aaa/././.bbb/../c./d.dd/..eeee/..",
      97             :                            "/aaa/.bbb/../c./d.dd/..eeee/..");
      98           1 :         test_path_simplify(".//./aaa///.//./.bbb/..///c.//d.dd///..eeee/..",
      99             :                            "././aaa/././.bbb/../c./d.dd/..eeee/..",
     100             :                            "aaa/.bbb/../c./d.dd/..eeee/..");
     101           1 :         test_path_simplify("..//./aaa///.//./.bbb/..///c.//d.dd///..eeee/..",
     102             :                            ".././aaa/././.bbb/../c./d.dd/..eeee/..",
     103             :                            "../aaa/.bbb/../c./d.dd/..eeee/..");
     104             : 
     105           2 :         assert_se(PATH_IN_SET("/bin", "/", "/bin", "/foo"));
     106           1 :         assert_se(PATH_IN_SET("/bin", "/bin"));
     107           2 :         assert_se(PATH_IN_SET("/bin", "/foo/bar", "/bin"));
     108           1 :         assert_se(PATH_IN_SET("/", "/", "/", "/foo/bar"));
     109           3 :         assert_se(!PATH_IN_SET("/", "/abc", "/def"));
     110             : 
     111           1 :         assert_se(path_equal_ptr(NULL, NULL));
     112           1 :         assert_se(path_equal_ptr("/a", "/a"));
     113           1 :         assert_se(!path_equal_ptr("/a", "/b"));
     114           1 :         assert_se(!path_equal_ptr("/a", NULL));
     115           1 :         assert_se(!path_equal_ptr(NULL, "/a"));
     116           1 : }
     117             : 
     118           1 : static void test_path_equal_root(void) {
     119             :         /* Nail down the details of how path_equal("/", ...) works. */
     120             : 
     121           1 :         log_info("/* %s */", __func__);
     122             : 
     123           1 :         assert_se(path_equal("/", "/"));
     124           1 :         assert_se(path_equal("/", "//"));
     125             : 
     126           1 :         assert_se(!path_equal("/", "/./"));
     127           1 :         assert_se(!path_equal("/", "/../"));
     128             : 
     129           1 :         assert_se(!path_equal("/", "/.../"));
     130             : 
     131             :         /* Make sure that files_same works as expected. */
     132             : 
     133           1 :         assert_se(files_same("/", "/", 0) > 0);
     134           1 :         assert_se(files_same("/", "/", AT_SYMLINK_NOFOLLOW) > 0);
     135           1 :         assert_se(files_same("/", "//", 0) > 0);
     136           1 :         assert_se(files_same("/", "//", AT_SYMLINK_NOFOLLOW) > 0);
     137             : 
     138           1 :         assert_se(files_same("/", "/./", 0) > 0);
     139           1 :         assert_se(files_same("/", "/./", AT_SYMLINK_NOFOLLOW) > 0);
     140           1 :         assert_se(files_same("/", "/../", 0) > 0);
     141           1 :         assert_se(files_same("/", "/../", AT_SYMLINK_NOFOLLOW) > 0);
     142             : 
     143           1 :         assert_se(files_same("/", "/.../", 0) == -ENOENT);
     144           1 :         assert_se(files_same("/", "/.../", AT_SYMLINK_NOFOLLOW) == -ENOENT);
     145             : 
     146             :         /* The same for path_equal_or_files_same. */
     147             : 
     148           1 :         assert_se(path_equal_or_files_same("/", "/", 0));
     149           1 :         assert_se(path_equal_or_files_same("/", "/", AT_SYMLINK_NOFOLLOW));
     150           1 :         assert_se(path_equal_or_files_same("/", "//", 0));
     151           1 :         assert_se(path_equal_or_files_same("/", "//", AT_SYMLINK_NOFOLLOW));
     152             : 
     153           1 :         assert_se(path_equal_or_files_same("/", "/./", 0));
     154           1 :         assert_se(path_equal_or_files_same("/", "/./", AT_SYMLINK_NOFOLLOW));
     155           1 :         assert_se(path_equal_or_files_same("/", "/../", 0));
     156           1 :         assert_se(path_equal_or_files_same("/", "/../", AT_SYMLINK_NOFOLLOW));
     157             : 
     158           1 :         assert_se(!path_equal_or_files_same("/", "/.../", 0));
     159           1 :         assert_se(!path_equal_or_files_same("/", "/.../", AT_SYMLINK_NOFOLLOW));
     160           1 : }
     161             : 
     162           1 : static void test_find_binary(const char *self) {
     163             :         char *p;
     164             : 
     165           1 :         log_info("/* %s */", __func__);
     166             : 
     167           1 :         assert_se(find_binary("/bin/sh", &p) == 0);
     168           1 :         puts(p);
     169           1 :         assert_se(path_equal(p, "/bin/sh"));
     170           1 :         free(p);
     171             : 
     172           1 :         assert_se(find_binary(self, &p) == 0);
     173           1 :         puts(p);
     174             :         /* libtool might prefix the binary name with "lt-" */
     175           1 :         assert_se(endswith(p, "/lt-test-path-util") || endswith(p, "/test-path-util"));
     176           1 :         assert_se(path_is_absolute(p));
     177           1 :         free(p);
     178             : 
     179           1 :         assert_se(find_binary("sh", &p) == 0);
     180           1 :         puts(p);
     181           1 :         assert_se(endswith(p, "/sh"));
     182           1 :         assert_se(path_is_absolute(p));
     183           1 :         free(p);
     184             : 
     185           1 :         assert_se(find_binary("xxxx-xxxx", &p) == -ENOENT);
     186           1 :         assert_se(find_binary("/some/dir/xxxx-xxxx", &p) == -ENOENT);
     187           1 : }
     188             : 
     189           1 : static void test_prefixes(void) {
     190             :         static const char* const values[] = {
     191             :                 "/a/b/c/d",
     192             :                 "/a/b/c",
     193             :                 "/a/b",
     194             :                 "/a",
     195             :                 "",
     196             :                 NULL
     197             :         };
     198             :         unsigned i;
     199             :         char s[PATH_MAX];
     200             :         bool b;
     201             : 
     202           1 :         log_info("/* %s */", __func__);
     203             : 
     204           1 :         i = 0;
     205           6 :         PATH_FOREACH_PREFIX_MORE(s, "/a/b/c/d") {
     206           5 :                 log_error("---%s---", s);
     207           5 :                 assert_se(streq(s, values[i++]));
     208             :         }
     209           1 :         assert_se(values[i] == NULL);
     210             : 
     211           1 :         i = 1;
     212           5 :         PATH_FOREACH_PREFIX(s, "/a/b/c/d") {
     213           4 :                 log_error("---%s---", s);
     214           4 :                 assert_se(streq(s, values[i++]));
     215             :         }
     216           1 :         assert_se(values[i] == NULL);
     217             : 
     218           1 :         i = 0;
     219           6 :         PATH_FOREACH_PREFIX_MORE(s, "////a////b////c///d///////")
     220           5 :                 assert_se(streq(s, values[i++]));
     221           1 :         assert_se(values[i] == NULL);
     222             : 
     223           1 :         i = 1;
     224           5 :         PATH_FOREACH_PREFIX(s, "////a////b////c///d///////")
     225           4 :                 assert_se(streq(s, values[i++]));
     226           1 :         assert_se(values[i] == NULL);
     227             : 
     228           1 :         PATH_FOREACH_PREFIX(s, "////")
     229           0 :                 assert_not_reached("Wut?");
     230             : 
     231           1 :         b = false;
     232           2 :         PATH_FOREACH_PREFIX_MORE(s, "////") {
     233           1 :                 assert_se(!b);
     234           1 :                 assert_se(streq(s, ""));
     235           1 :                 b = true;
     236             :         }
     237           1 :         assert_se(b);
     238             : 
     239           1 :         PATH_FOREACH_PREFIX(s, "")
     240           0 :                 assert_not_reached("wut?");
     241             : 
     242           1 :         b = false;
     243           2 :         PATH_FOREACH_PREFIX_MORE(s, "") {
     244           1 :                 assert_se(!b);
     245           1 :                 assert_se(streq(s, ""));
     246           1 :                 b = true;
     247             :         }
     248           1 : }
     249             : 
     250           1 : static void test_path_join(void) {
     251           1 :         log_info("/* %s */", __func__);
     252             : 
     253             : #define test_join(expected, ...) {        \
     254             :                 _cleanup_free_ char *z = NULL;   \
     255             :                 z = path_join(__VA_ARGS__); \
     256             :                 log_debug("got \"%s\", expected \"%s\"", z, expected); \
     257             :                 assert_se(streq(z, expected));   \
     258             :         }
     259             : 
     260           1 :         test_join("/root/a/b/c", "/root", "/a/b", "/c");
     261           1 :         test_join("/root/a/b/c", "/root", "a/b", "c");
     262           1 :         test_join("/root/a/b/c", "/root", "/a/b", "c");
     263           1 :         test_join("/root/c",     "/root", "/", "c");
     264           1 :         test_join("/root/",      "/root", "/", NULL);
     265             : 
     266           1 :         test_join("/a/b/c", "", "/a/b", "/c");
     267           1 :         test_join("a/b/c",  "", "a/b", "c");
     268           1 :         test_join("/a/b/c", "", "/a/b", "c");
     269           1 :         test_join("/c",     "", "/", "c");
     270           1 :         test_join("/",      "", "/", NULL);
     271             : 
     272           1 :         test_join("/a/b/c", NULL, "/a/b", "/c");
     273           1 :         test_join("a/b/c",  NULL, "a/b", "c");
     274           1 :         test_join("/a/b/c", NULL, "/a/b", "c");
     275           1 :         test_join("/c",     NULL, "/", "c");
     276           1 :         test_join("/",      NULL, "/", NULL);
     277             : 
     278           1 :         test_join("", "", NULL);
     279           1 :         test_join("", NULL, "");
     280           1 :         test_join("", NULL, NULL);
     281             : 
     282           1 :         test_join("foo/bar", "foo", "bar");
     283           1 :         test_join("foo/bar", "", "foo", "bar");
     284           1 :         test_join("foo/bar", NULL, "foo", NULL, "bar");
     285           1 :         test_join("foo/bar", "", "foo", "", "bar", "");
     286           1 :         test_join("foo/bar", "", "", "", "", "foo", "", "", "", "bar", "", "", "");
     287             : 
     288           1 :         test_join("//foo///bar//",         "", "/", "", "/foo/", "", "/", "", "/bar/", "", "/", "");
     289           1 :         test_join("/foo/bar/",             "/", "foo", "/", "bar", "/");
     290           1 :         test_join("foo/bar/baz",           "foo", "bar", "baz");
     291           1 :         test_join("foo/bar/baz",           "foo/", "bar", "/baz");
     292           1 :         test_join("foo//bar//baz",         "foo/", "/bar/", "/baz");
     293           1 :         test_join("//foo////bar////baz//", "//foo/", "///bar/", "///baz//");
     294           1 : }
     295             : 
     296           1 : static void test_fsck_exists(void) {
     297           1 :         log_info("/* %s */", __func__);
     298             : 
     299             :         /* Ensure we use a sane default for PATH. */
     300           1 :         unsetenv("PATH");
     301             : 
     302             :         /* fsck.minix is provided by util-linux and will probably exist. */
     303           1 :         assert_se(fsck_exists("minix") == 1);
     304             : 
     305           1 :         assert_se(fsck_exists("AbCdE") == 0);
     306           1 :         assert_se(fsck_exists("/../bin/") == 0);
     307           1 : }
     308             : 
     309           1 : static void test_make_relative(void) {
     310             :         char *result;
     311             : 
     312           1 :         log_info("/* %s */", __func__);
     313             : 
     314           1 :         assert_se(path_make_relative("some/relative/path", "/some/path", &result) < 0);
     315           1 :         assert_se(path_make_relative("/some/path", "some/relative/path", &result) < 0);
     316           1 :         assert_se(path_make_relative("/some/dotdot/../path", "/some/path", &result) < 0);
     317             : 
     318             : #define test(from_dir, to_path, expected) {                \
     319             :                 _cleanup_free_ char *z = NULL;             \
     320             :                 path_make_relative(from_dir, to_path, &z); \
     321             :                 assert_se(streq(z, expected));             \
     322             :         }
     323             : 
     324           1 :         test("/", "/", ".");
     325           1 :         test("/", "/some/path", "some/path");
     326           1 :         test("/some/path", "/some/path", ".");
     327           1 :         test("/some/path", "/some/path/in/subdir", "in/subdir");
     328           1 :         test("/some/path", "/", "../..");
     329           1 :         test("/some/path", "/some/other/path", "../other/path");
     330           1 :         test("/some/path/./dot", "/some/further/path", "../../further/path");
     331           1 :         test("//extra.//.//./.slashes//./won't////fo.ol///anybody//", "/././/extra././/.slashes////ar.e/.just/././.fine///", "../../../ar.e/.just/.fine");
     332           1 : }
     333             : 
     334           1 : static void test_strv_resolve(void) {
     335           1 :         char tmp_dir[] = "/tmp/test-path-util-XXXXXX";
     336           1 :         _cleanup_strv_free_ char **search_dirs = NULL;
     337           1 :         _cleanup_strv_free_ char **absolute_dirs = NULL;
     338             :         char **d;
     339             : 
     340           1 :         assert_se(mkdtemp(tmp_dir) != NULL);
     341             : 
     342           1 :         search_dirs = strv_new("/dir1", "/dir2", "/dir3");
     343           1 :         assert_se(search_dirs);
     344           4 :         STRV_FOREACH(d, search_dirs) {
     345           3 :                 char *p = path_join(tmp_dir, *d);
     346           3 :                 assert_se(p);
     347           3 :                 assert_se(strv_push(&absolute_dirs, p) == 0);
     348             :         }
     349             : 
     350           1 :         assert_se(mkdir(absolute_dirs[0], 0700) == 0);
     351           1 :         assert_se(mkdir(absolute_dirs[1], 0700) == 0);
     352           1 :         assert_se(symlink("dir2", absolute_dirs[2]) == 0);
     353             : 
     354           1 :         path_strv_resolve(search_dirs, tmp_dir);
     355           1 :         assert_se(streq(search_dirs[0], "/dir1"));
     356           1 :         assert_se(streq(search_dirs[1], "/dir2"));
     357           1 :         assert_se(streq(search_dirs[2], "/dir2"));
     358             : 
     359           1 :         assert_se(rm_rf(tmp_dir, REMOVE_ROOT|REMOVE_PHYSICAL) == 0);
     360           1 : }
     361             : 
     362           1 : static void test_path_startswith(void) {
     363             :         const char *p;
     364             : 
     365           1 :         log_info("/* %s */", __func__);
     366             : 
     367           1 :         p = path_startswith("/foo/bar/barfoo/", "/foo");
     368           1 :         assert_se(streq_ptr(p, "bar/barfoo/"));
     369             : 
     370           1 :         p = path_startswith("/foo/bar/barfoo/", "/foo/");
     371           1 :         assert_se(streq_ptr(p, "bar/barfoo/"));
     372             : 
     373           1 :         p = path_startswith("/foo/bar/barfoo/", "/");
     374           1 :         assert_se(streq_ptr(p, "foo/bar/barfoo/"));
     375             : 
     376           1 :         p = path_startswith("/foo/bar/barfoo/", "////");
     377           1 :         assert_se(streq_ptr(p, "foo/bar/barfoo/"));
     378             : 
     379           1 :         p = path_startswith("/foo/bar/barfoo/", "/foo//bar/////barfoo///");
     380           1 :         assert_se(streq_ptr(p, ""));
     381             : 
     382           1 :         p = path_startswith("/foo/bar/barfoo/", "/foo/bar/barfoo////");
     383           1 :         assert_se(streq_ptr(p, ""));
     384             : 
     385           1 :         p = path_startswith("/foo/bar/barfoo/", "/foo/bar///barfoo/");
     386           1 :         assert_se(streq_ptr(p, ""));
     387             : 
     388           1 :         p = path_startswith("/foo/bar/barfoo/", "/foo////bar/barfoo/");
     389           1 :         assert_se(streq_ptr(p, ""));
     390             : 
     391           1 :         p = path_startswith("/foo/bar/barfoo/", "////foo/bar/barfoo/");
     392           1 :         assert_se(streq_ptr(p, ""));
     393             : 
     394           1 :         p = path_startswith("/foo/bar/barfoo/", "/foo/bar/barfoo");
     395           1 :         assert_se(streq_ptr(p, ""));
     396             : 
     397           1 :         assert_se(!path_startswith("/foo/bar/barfoo/", "/foo/bar/barfooa/"));
     398           1 :         assert_se(!path_startswith("/foo/bar/barfoo/", "/foo/bar/barfooa"));
     399           1 :         assert_se(!path_startswith("/foo/bar/barfoo/", ""));
     400           1 :         assert_se(!path_startswith("/foo/bar/barfoo/", "/bar/foo"));
     401           1 :         assert_se(!path_startswith("/foo/bar/barfoo/", "/f/b/b/"));
     402           1 : }
     403             : 
     404          15 : static void test_prefix_root_one(const char *r, const char *p, const char *expected) {
     405          15 :         _cleanup_free_ char *s = NULL;
     406             :         const char *t;
     407             : 
     408          15 :         assert_se(s = path_join(r, p));
     409          15 :         assert_se(path_equal_ptr(s, expected));
     410             : 
     411          34 :         t = prefix_roota(r, p);
     412          15 :         assert_se(t);
     413          15 :         assert_se(path_equal_ptr(t, expected));
     414          15 : }
     415             : 
     416           1 : static void test_prefix_root(void) {
     417           1 :         log_info("/* %s */", __func__);
     418             : 
     419           1 :         test_prefix_root_one("/", "/foo", "/foo");
     420           1 :         test_prefix_root_one(NULL, "/foo", "/foo");
     421           1 :         test_prefix_root_one("", "/foo", "/foo");
     422           1 :         test_prefix_root_one("///", "/foo", "/foo");
     423           1 :         test_prefix_root_one("/", "////foo", "/foo");
     424           1 :         test_prefix_root_one(NULL, "////foo", "/foo");
     425           1 :         test_prefix_root_one("/", "foo", "/foo");
     426           1 :         test_prefix_root_one("", "foo", "foo");
     427           1 :         test_prefix_root_one(NULL, "foo", "foo");
     428             : 
     429           1 :         test_prefix_root_one("/foo", "/bar", "/foo/bar");
     430           1 :         test_prefix_root_one("/foo", "bar", "/foo/bar");
     431           1 :         test_prefix_root_one("foo", "bar", "foo/bar");
     432           1 :         test_prefix_root_one("/foo/", "/bar", "/foo/bar");
     433           1 :         test_prefix_root_one("/foo/", "//bar", "/foo/bar");
     434           1 :         test_prefix_root_one("/foo///", "//bar", "/foo/bar");
     435           1 : }
     436             : 
     437           1 : static void test_file_in_same_dir(void) {
     438             :         char *t;
     439             : 
     440           1 :         log_info("/* %s */", __func__);
     441             : 
     442           1 :         t = file_in_same_dir("/", "a");
     443           1 :         assert_se(streq(t, "/a"));
     444           1 :         free(t);
     445             : 
     446           1 :         t = file_in_same_dir("/", "/a");
     447           1 :         assert_se(streq(t, "/a"));
     448           1 :         free(t);
     449             : 
     450           1 :         t = file_in_same_dir("", "a");
     451           1 :         assert_se(streq(t, "a"));
     452           1 :         free(t);
     453             : 
     454           1 :         t = file_in_same_dir("a/", "a");
     455           1 :         assert_se(streq(t, "a/a"));
     456           1 :         free(t);
     457             : 
     458           1 :         t = file_in_same_dir("bar/foo", "bar");
     459           1 :         assert_se(streq(t, "bar/bar"));
     460           1 :         free(t);
     461           1 : }
     462             : 
     463           1 : static void test_last_path_component(void) {
     464           1 :         assert_se(last_path_component(NULL) == NULL);
     465           1 :         assert_se(streq(last_path_component("a/b/c"), "c"));
     466           1 :         assert_se(streq(last_path_component("a/b/c/"), "c/"));
     467           1 :         assert_se(streq(last_path_component("/"), "/"));
     468           1 :         assert_se(streq(last_path_component("//"), "/"));
     469           1 :         assert_se(streq(last_path_component("///"), "/"));
     470           1 :         assert_se(streq(last_path_component("."), "."));
     471           1 :         assert_se(streq(last_path_component("./."), "."));
     472           1 :         assert_se(streq(last_path_component("././"), "./"));
     473           1 :         assert_se(streq(last_path_component("././/"), ".//"));
     474           1 :         assert_se(streq(last_path_component("/foo/a"), "a"));
     475           1 :         assert_se(streq(last_path_component("/foo/a/"), "a/"));
     476           1 :         assert_se(streq(last_path_component(""), ""));
     477           1 :         assert_se(streq(last_path_component("a"), "a"));
     478           1 :         assert_se(streq(last_path_component("a/"), "a/"));
     479           1 :         assert_se(streq(last_path_component("/a"), "a"));
     480           1 :         assert_se(streq(last_path_component("/a/"), "a/"));
     481           1 : }
     482             : 
     483          26 : static void test_path_extract_filename_one(const char *input, const char *output, int ret) {
     484          26 :         _cleanup_free_ char *k = NULL;
     485             :         int r;
     486             : 
     487          26 :         r = path_extract_filename(input, &k);
     488          26 :         log_info("%s → %s/%s [expected: %s/%s]", strnull(input), strnull(k), strerror_safe(r), strnull(output), strerror_safe(ret));
     489          26 :         assert_se(streq_ptr(k, output));
     490          26 :         assert_se(r == ret);
     491          26 : }
     492             : 
     493           1 : static void test_path_extract_filename(void) {
     494           1 :         log_info("/* %s */", __func__);
     495             : 
     496           1 :         test_path_extract_filename_one(NULL, NULL, -EINVAL);
     497           1 :         test_path_extract_filename_one("a/b/c", "c", 0);
     498           1 :         test_path_extract_filename_one("a/b/c/", "c", 0);
     499           1 :         test_path_extract_filename_one("/", NULL, -EINVAL);
     500           1 :         test_path_extract_filename_one("//", NULL, -EINVAL);
     501           1 :         test_path_extract_filename_one("///", NULL, -EINVAL);
     502           1 :         test_path_extract_filename_one(".", NULL, -EINVAL);
     503           1 :         test_path_extract_filename_one("./.", NULL, -EINVAL);
     504           1 :         test_path_extract_filename_one("././", NULL, -EINVAL);
     505           1 :         test_path_extract_filename_one("././/", NULL, -EINVAL);
     506           1 :         test_path_extract_filename_one("/foo/a", "a", 0);
     507           1 :         test_path_extract_filename_one("/foo/a/", "a", 0);
     508           1 :         test_path_extract_filename_one("", NULL, -EINVAL);
     509           1 :         test_path_extract_filename_one("a", "a", 0);
     510           1 :         test_path_extract_filename_one("a/", "a", 0);
     511           1 :         test_path_extract_filename_one("/a", "a", 0);
     512           1 :         test_path_extract_filename_one("/a/", "a", 0);
     513           1 :         test_path_extract_filename_one("/////////////a/////////////", "a", 0);
     514           1 :         test_path_extract_filename_one("xx/.", NULL, -EINVAL);
     515           1 :         test_path_extract_filename_one("xx/..", NULL, -EINVAL);
     516           1 :         test_path_extract_filename_one("..", NULL, -EINVAL);
     517           1 :         test_path_extract_filename_one("/..", NULL, -EINVAL);
     518           1 :         test_path_extract_filename_one("../", NULL, -EINVAL);
     519           1 :         test_path_extract_filename_one(".", NULL, -EINVAL);
     520           1 :         test_path_extract_filename_one("/.", NULL, -EINVAL);
     521           1 :         test_path_extract_filename_one("./", NULL, -EINVAL);
     522           1 : }
     523             : 
     524           1 : static void test_filename_is_valid(void) {
     525             :         char foo[FILENAME_MAX+2];
     526             :         int i;
     527             : 
     528           1 :         log_info("/* %s */", __func__);
     529             : 
     530           1 :         assert_se(!filename_is_valid(""));
     531           1 :         assert_se(!filename_is_valid("/bar/foo"));
     532           1 :         assert_se(!filename_is_valid("/"));
     533           1 :         assert_se(!filename_is_valid("."));
     534           1 :         assert_se(!filename_is_valid(".."));
     535             : 
     536        4098 :         for (i=0; i<FILENAME_MAX+1; i++)
     537        4097 :                 foo[i] = 'a';
     538           1 :         foo[FILENAME_MAX+1] = '\0';
     539             : 
     540           1 :         assert_se(!filename_is_valid(foo));
     541             : 
     542           1 :         assert_se(filename_is_valid("foo_bar-333"));
     543           1 :         assert_se(filename_is_valid("o.o"));
     544           1 : }
     545             : 
     546           1 : static void test_hidden_or_backup_file(void) {
     547           1 :         log_info("/* %s */", __func__);
     548             : 
     549           1 :         assert_se(hidden_or_backup_file(".hidden"));
     550           1 :         assert_se(hidden_or_backup_file("..hidden"));
     551           1 :         assert_se(!hidden_or_backup_file("hidden."));
     552             : 
     553           1 :         assert_se(hidden_or_backup_file("backup~"));
     554           1 :         assert_se(hidden_or_backup_file(".backup~"));
     555             : 
     556           1 :         assert_se(hidden_or_backup_file("lost+found"));
     557           1 :         assert_se(hidden_or_backup_file("aquota.user"));
     558           1 :         assert_se(hidden_or_backup_file("aquota.group"));
     559             : 
     560           1 :         assert_se(hidden_or_backup_file("test.rpmnew"));
     561           1 :         assert_se(hidden_or_backup_file("test.dpkg-old"));
     562           1 :         assert_se(hidden_or_backup_file("test.dpkg-remove"));
     563           1 :         assert_se(hidden_or_backup_file("test.swp"));
     564             : 
     565           1 :         assert_se(!hidden_or_backup_file("test.rpmnew."));
     566           1 :         assert_se(!hidden_or_backup_file("test.dpkg-old.foo"));
     567           1 : }
     568             : 
     569           1 : static void test_systemd_installation_has_version(const char *path) {
     570             :         int r;
     571           1 :         const unsigned versions[] = {0, 231, PROJECT_VERSION, 999};
     572             :         unsigned i;
     573             : 
     574           1 :         log_info("/* %s */", __func__);
     575             : 
     576           5 :         for (i = 0; i < ELEMENTSOF(versions); i++) {
     577           4 :                 r = systemd_installation_has_version(path, versions[i]);
     578           4 :                 assert_se(r >= 0);
     579           4 :                 log_info("%s has systemd >= %u: %s",
     580             :                          path ?: "Current installation", versions[i], yes_no(r));
     581             :         }
     582           1 : }
     583             : 
     584           1 : static void test_skip_dev_prefix(void) {
     585           1 :         log_info("/* %s */", __func__);
     586             : 
     587           1 :         assert_se(streq(skip_dev_prefix("/"), "/"));
     588           1 :         assert_se(streq(skip_dev_prefix("/dev"), ""));
     589           1 :         assert_se(streq(skip_dev_prefix("/dev/"), ""));
     590           1 :         assert_se(streq(skip_dev_prefix("/dev/foo"), "foo"));
     591           1 :         assert_se(streq(skip_dev_prefix("/dev/foo/bar"), "foo/bar"));
     592           1 :         assert_se(streq(skip_dev_prefix("//dev"), ""));
     593           1 :         assert_se(streq(skip_dev_prefix("//dev//"), ""));
     594           1 :         assert_se(streq(skip_dev_prefix("/dev///foo"), "foo"));
     595           1 :         assert_se(streq(skip_dev_prefix("///dev///foo///bar"), "foo///bar"));
     596           1 :         assert_se(streq(skip_dev_prefix("//foo"), "//foo"));
     597           1 :         assert_se(streq(skip_dev_prefix("foo"), "foo"));
     598           1 : }
     599             : 
     600           1 : static void test_empty_or_root(void) {
     601           1 :         log_info("/* %s */", __func__);
     602             : 
     603           1 :         assert_se(empty_or_root(NULL));
     604           1 :         assert_se(empty_or_root(""));
     605           1 :         assert_se(empty_or_root("/"));
     606           1 :         assert_se(empty_or_root("//"));
     607           1 :         assert_se(empty_or_root("///"));
     608           1 :         assert_se(empty_or_root("/////////////////"));
     609           1 :         assert_se(!empty_or_root("xxx"));
     610           1 :         assert_se(!empty_or_root("/xxx"));
     611           1 :         assert_se(!empty_or_root("/xxx/"));
     612           1 :         assert_se(!empty_or_root("//yy//"));
     613           1 : }
     614             : 
     615           1 : static void test_path_startswith_set(void) {
     616           1 :         log_info("/* %s */", __func__);
     617             : 
     618           1 :         assert_se(streq_ptr(PATH_STARTSWITH_SET("/foo/bar", "/foo/quux", "/foo/bar", "/zzz"), ""));
     619           1 :         assert_se(streq_ptr(PATH_STARTSWITH_SET("/foo/bar", "/foo/quux", "/foo/", "/zzz"), "bar"));
     620           1 :         assert_se(streq_ptr(PATH_STARTSWITH_SET("/foo/bar", "/foo/quux", "/foo", "/zzz"), "bar"));
     621           1 :         assert_se(streq_ptr(PATH_STARTSWITH_SET("/foo/bar", "/foo/quux", "/", "/zzz"), "foo/bar"));
     622           1 :         assert_se(streq_ptr(PATH_STARTSWITH_SET("/foo/bar", "/foo/quux", "", "/zzz"), NULL));
     623             : 
     624           1 :         assert_se(streq_ptr(PATH_STARTSWITH_SET("/foo/bar2", "/foo/quux", "/foo/bar", "/zzz"), NULL));
     625           1 :         assert_se(streq_ptr(PATH_STARTSWITH_SET("/foo/bar2", "/foo/quux", "/foo/", "/zzz"), "bar2"));
     626           1 :         assert_se(streq_ptr(PATH_STARTSWITH_SET("/foo/bar2", "/foo/quux", "/foo", "/zzz"), "bar2"));
     627           1 :         assert_se(streq_ptr(PATH_STARTSWITH_SET("/foo/bar2", "/foo/quux", "/", "/zzz"), "foo/bar2"));
     628           1 :         assert_se(streq_ptr(PATH_STARTSWITH_SET("/foo/bar2", "/foo/quux", "", "/zzz"), NULL));
     629             : 
     630           1 :         assert_se(streq_ptr(PATH_STARTSWITH_SET("/foo2/bar", "/foo/quux", "/foo/bar", "/zzz"), NULL));
     631           1 :         assert_se(streq_ptr(PATH_STARTSWITH_SET("/foo2/bar", "/foo/quux", "/foo/", "/zzz"), NULL));
     632           1 :         assert_se(streq_ptr(PATH_STARTSWITH_SET("/foo2/bar", "/foo/quux", "/foo", "/zzz"), NULL));
     633           1 :         assert_se(streq_ptr(PATH_STARTSWITH_SET("/foo2/bar", "/foo/quux", "/", "/zzz"), "foo2/bar"));
     634           1 :         assert_se(streq_ptr(PATH_STARTSWITH_SET("/foo2/bar", "/foo/quux", "", "/zzz"), NULL));
     635           1 : }
     636             : 
     637           1 : static void test_path_startswith_strv(void) {
     638           1 :         log_info("/* %s */", __func__);
     639             : 
     640           1 :         assert_se(streq_ptr(path_startswith_strv("/foo/bar", STRV_MAKE("/foo/quux", "/foo/bar", "/zzz")), ""));
     641           1 :         assert_se(streq_ptr(path_startswith_strv("/foo/bar", STRV_MAKE("/foo/quux", "/foo/", "/zzz")), "bar"));
     642           1 :         assert_se(streq_ptr(path_startswith_strv("/foo/bar", STRV_MAKE("/foo/quux", "/foo", "/zzz")), "bar"));
     643           1 :         assert_se(streq_ptr(path_startswith_strv("/foo/bar", STRV_MAKE("/foo/quux", "/", "/zzz")), "foo/bar"));
     644           1 :         assert_se(streq_ptr(path_startswith_strv("/foo/bar", STRV_MAKE("/foo/quux", "", "/zzz")), NULL));
     645             : 
     646           1 :         assert_se(streq_ptr(path_startswith_strv("/foo/bar2", STRV_MAKE("/foo/quux", "/foo/bar", "/zzz")), NULL));
     647           1 :         assert_se(streq_ptr(path_startswith_strv("/foo/bar2", STRV_MAKE("/foo/quux", "/foo/", "/zzz")), "bar2"));
     648           1 :         assert_se(streq_ptr(path_startswith_strv("/foo/bar2", STRV_MAKE("/foo/quux", "/foo", "/zzz")), "bar2"));
     649           1 :         assert_se(streq_ptr(path_startswith_strv("/foo/bar2", STRV_MAKE("/foo/quux", "/", "/zzz")), "foo/bar2"));
     650           1 :         assert_se(streq_ptr(path_startswith_strv("/foo/bar2", STRV_MAKE("/foo/quux", "", "/zzz")), NULL));
     651             : 
     652           1 :         assert_se(streq_ptr(path_startswith_strv("/foo2/bar", STRV_MAKE("/foo/quux", "/foo/bar", "/zzz")), NULL));
     653           1 :         assert_se(streq_ptr(path_startswith_strv("/foo2/bar", STRV_MAKE("/foo/quux", "/foo/", "/zzz")), NULL));
     654           1 :         assert_se(streq_ptr(path_startswith_strv("/foo2/bar", STRV_MAKE("/foo/quux", "/foo", "/zzz")), NULL));
     655           1 :         assert_se(streq_ptr(path_startswith_strv("/foo2/bar", STRV_MAKE("/foo/quux", "/", "/zzz")), "foo2/bar"));
     656           1 :         assert_se(streq_ptr(path_startswith_strv("/foo2/bar", STRV_MAKE("/foo/quux", "", "/zzz")), NULL));
     657           1 : }
     658             : 
     659           1 : int main(int argc, char **argv) {
     660           1 :         test_setup_logging(LOG_DEBUG);
     661             : 
     662           1 :         test_path();
     663           1 :         test_path_equal_root();
     664           1 :         test_find_binary(argv[0]);
     665           1 :         test_prefixes();
     666           1 :         test_path_join();
     667           1 :         test_fsck_exists();
     668           1 :         test_make_relative();
     669           1 :         test_strv_resolve();
     670           1 :         test_path_startswith();
     671           1 :         test_prefix_root();
     672           1 :         test_file_in_same_dir();
     673           1 :         test_last_path_component();
     674           1 :         test_path_extract_filename();
     675           1 :         test_filename_is_valid();
     676           1 :         test_hidden_or_backup_file();
     677           1 :         test_skip_dev_prefix();
     678           1 :         test_empty_or_root();
     679           1 :         test_path_startswith_set();
     680           1 :         test_path_startswith_strv();
     681             : 
     682           1 :         test_systemd_installation_has_version(argv[1]); /* NULL is OK */
     683             : 
     684           1 :         return 0;
     685             : }

Generated by: LCOV version 1.14