]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/test/test-path-util.c
Add SPDX license identifiers to source files under the LGPL
[thirdparty/systemd.git] / src / test / test-path-util.c
index b53324b5e6de6bf16e0c65177c6966265bc65359..68fe941f151367e318f5b217fcc6acf6ca02bb74 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -27,6 +28,7 @@
 #include "mount-util.h"
 #include "path-util.h"
 #include "rm-rf.h"
+#include "stat-util.h"
 #include "string-util.h"
 #include "strv.h"
 #include "util.h"
@@ -104,6 +106,48 @@ static void test_path(void) {
         assert_se(!path_equal_ptr(NULL, "/a"));
 }
 
+static void test_path_equal_root(void) {
+        /* Nail down the details of how path_equal("/", ...) works. */
+
+        assert_se(path_equal("/", "/"));
+        assert_se(path_equal("/", "//"));
+
+        assert_se(!path_equal("/", "/./"));
+        assert_se(!path_equal("/", "/../"));
+
+        assert_se(!path_equal("/", "/.../"));
+
+        /* Make sure that files_same works as expected. */
+
+        assert_se(files_same("/", "/", 0) > 0);
+        assert_se(files_same("/", "/", AT_SYMLINK_NOFOLLOW) > 0);
+        assert_se(files_same("/", "//", 0) > 0);
+        assert_se(files_same("/", "//", AT_SYMLINK_NOFOLLOW) > 0);
+
+        assert_se(files_same("/", "/./", 0) > 0);
+        assert_se(files_same("/", "/./", AT_SYMLINK_NOFOLLOW) > 0);
+        assert_se(files_same("/", "/../", 0) > 0);
+        assert_se(files_same("/", "/../", AT_SYMLINK_NOFOLLOW) > 0);
+
+        assert_se(files_same("/", "/.../", 0) == -ENOENT);
+        assert_se(files_same("/", "/.../", AT_SYMLINK_NOFOLLOW) == -ENOENT);
+
+        /* The same for path_equal_or_files_same. */
+
+        assert_se(path_equal_or_files_same("/", "/", 0));
+        assert_se(path_equal_or_files_same("/", "/", AT_SYMLINK_NOFOLLOW));
+        assert_se(path_equal_or_files_same("/", "//", 0));
+        assert_se(path_equal_or_files_same("/", "//", AT_SYMLINK_NOFOLLOW));
+
+        assert_se(path_equal_or_files_same("/", "/./", 0));
+        assert_se(path_equal_or_files_same("/", "/./", AT_SYMLINK_NOFOLLOW));
+        assert_se(path_equal_or_files_same("/", "/../", 0));
+        assert_se(path_equal_or_files_same("/", "/../", AT_SYMLINK_NOFOLLOW));
+
+        assert_se(!path_equal_or_files_same("/", "/.../", 0));
+        assert_se(!path_equal_or_files_same("/", "/.../", AT_SYMLINK_NOFOLLOW));
+}
+
 static void test_find_binary(const char *self) {
         char *p;
 
@@ -114,7 +158,8 @@ static void test_find_binary(const char *self) {
 
         assert_se(find_binary(self, &p) == 0);
         puts(p);
-        assert_se(endswith(p, "/test-path-util"));
+        /* libtool might prefix the binary name with "lt-" */
+        assert_se(endswith(p, "/lt-test-path-util") || endswith(p, "/test-path-util"));
         assert_se(path_is_absolute(p));
         free(p);
 
@@ -217,6 +262,7 @@ static void test_make_relative(void) {
 
         assert_se(path_make_relative("some/relative/path", "/some/path", &result) < 0);
         assert_se(path_make_relative("/some/path", "some/relative/path", &result) < 0);
+        assert_se(path_make_relative("/some/dotdot/../path", "/some/path", &result) < 0);
 
 #define test(from_dir, to_path, expected) {                \
                 _cleanup_free_ char *z = NULL;             \
@@ -230,6 +276,7 @@ static void test_make_relative(void) {
         test("/some/path", "/some/path/in/subdir", "in/subdir");
         test("/some/path", "/", "../..");
         test("/some/path", "/some/other/path", "../other/path");
+        test("/some/path/./dot", "/some/further/path", "../../further/path");
         test("//extra/////slashes///won't////fool///anybody//", "////extra///slashes////are/just///fine///", "../../../are/just/fine");
 }
 
@@ -262,16 +309,37 @@ static void test_strv_resolve(void) {
 }
 
 static void test_path_startswith(void) {
-        assert_se(path_startswith("/foo/bar/barfoo/", "/foo"));
-        assert_se(path_startswith("/foo/bar/barfoo/", "/foo/"));
-        assert_se(path_startswith("/foo/bar/barfoo/", "/"));
-        assert_se(path_startswith("/foo/bar/barfoo/", "////"));
-        assert_se(path_startswith("/foo/bar/barfoo/", "/foo//bar/////barfoo///"));
-        assert_se(path_startswith("/foo/bar/barfoo/", "/foo/bar/barfoo////"));
-        assert_se(path_startswith("/foo/bar/barfoo/", "/foo/bar///barfoo/"));
-        assert_se(path_startswith("/foo/bar/barfoo/", "/foo////bar/barfoo/"));
-        assert_se(path_startswith("/foo/bar/barfoo/", "////foo/bar/barfoo/"));
-        assert_se(path_startswith("/foo/bar/barfoo/", "/foo/bar/barfoo"));
+        const char *p;
+
+        p = path_startswith("/foo/bar/barfoo/", "/foo");
+        assert_se(streq_ptr(p, "bar/barfoo/"));
+
+        p = path_startswith("/foo/bar/barfoo/", "/foo/");
+        assert_se(streq_ptr(p, "bar/barfoo/"));
+
+        p = path_startswith("/foo/bar/barfoo/", "/");
+        assert_se(streq_ptr(p, "foo/bar/barfoo/"));
+
+        p = path_startswith("/foo/bar/barfoo/", "////");
+        assert_se(streq_ptr(p, "foo/bar/barfoo/"));
+
+        p = path_startswith("/foo/bar/barfoo/", "/foo//bar/////barfoo///");
+        assert_se(streq_ptr(p, ""));
+
+        p = path_startswith("/foo/bar/barfoo/", "/foo/bar/barfoo////");
+        assert_se(streq_ptr(p, ""));
+
+        p = path_startswith("/foo/bar/barfoo/", "/foo/bar///barfoo/");
+        assert_se(streq_ptr(p, ""));
+
+        p = path_startswith("/foo/bar/barfoo/", "/foo////bar/barfoo/");
+        assert_se(streq_ptr(p, ""));
+
+        p = path_startswith("/foo/bar/barfoo/", "////foo/bar/barfoo/");
+        assert_se(streq_ptr(p, ""));
+
+        p = path_startswith("/foo/bar/barfoo/", "/foo/bar/barfoo");
+        assert_se(streq_ptr(p, ""));
 
         assert_se(!path_startswith("/foo/bar/barfoo/", "/foo/bar/barfooa/"));
         assert_se(!path_startswith("/foo/bar/barfoo/", "/foo/bar/barfooa"));
@@ -315,17 +383,17 @@ static void test_path_is_mount_point(void) {
         _cleanup_free_ char *dir1 = NULL, *dir1file = NULL, *dirlink1 = NULL, *dirlink1file = NULL;
         _cleanup_free_ char *dir2 = NULL, *dir2file = NULL;
 
-        assert_se(path_is_mount_point("/", AT_SYMLINK_FOLLOW) > 0);
-        assert_se(path_is_mount_point("/", 0) > 0);
+        assert_se(path_is_mount_point("/", NULL, AT_SYMLINK_FOLLOW) > 0);
+        assert_se(path_is_mount_point("/", NULL, 0) > 0);
 
-        assert_se(path_is_mount_point("/proc", AT_SYMLINK_FOLLOW) > 0);
-        assert_se(path_is_mount_point("/proc", 0) > 0);
+        assert_se(path_is_mount_point("/proc", NULL, AT_SYMLINK_FOLLOW) > 0);
+        assert_se(path_is_mount_point("/proc", NULL, 0) > 0);
 
-        assert_se(path_is_mount_point("/proc/1", AT_SYMLINK_FOLLOW) == 0);
-        assert_se(path_is_mount_point("/proc/1", 0) == 0);
+        assert_se(path_is_mount_point("/proc/1", NULL, AT_SYMLINK_FOLLOW) == 0);
+        assert_se(path_is_mount_point("/proc/1", NULL, 0) == 0);
 
-        assert_se(path_is_mount_point("/sys", AT_SYMLINK_FOLLOW) > 0);
-        assert_se(path_is_mount_point("/sys", 0) > 0);
+        assert_se(path_is_mount_point("/sys", NULL, AT_SYMLINK_FOLLOW) > 0);
+        assert_se(path_is_mount_point("/sys", NULL, 0) > 0);
 
         /* we'll create a hierarchy of different kinds of dir/file/link
          * layouts:
@@ -359,10 +427,10 @@ static void test_path_is_mount_point(void) {
         assert_se(link1);
         assert_se(symlink("file2", link2) == 0);
 
-        assert_se(path_is_mount_point(file1, AT_SYMLINK_FOLLOW) == 0);
-        assert_se(path_is_mount_point(file1, 0) == 0);
-        assert_se(path_is_mount_point(link1, AT_SYMLINK_FOLLOW) == 0);
-        assert_se(path_is_mount_point(link1, 0) == 0);
+        assert_se(path_is_mount_point(file1, NULL, AT_SYMLINK_FOLLOW) == 0);
+        assert_se(path_is_mount_point(file1, NULL, 0) == 0);
+        assert_se(path_is_mount_point(link1, NULL, AT_SYMLINK_FOLLOW) == 0);
+        assert_se(path_is_mount_point(link1, NULL, 0) == 0);
 
         /* directory mountpoints */
         dir1 = path_join(NULL, tmp_dir, "dir1");
@@ -378,10 +446,10 @@ static void test_path_is_mount_point(void) {
         assert_se(dir2);
         assert_se(mkdir(dir2, 0755) == 0);
 
-        assert_se(path_is_mount_point(dir1, AT_SYMLINK_FOLLOW) == 0);
-        assert_se(path_is_mount_point(dir1, 0) == 0);
-        assert_se(path_is_mount_point(dirlink1, AT_SYMLINK_FOLLOW) == 0);
-        assert_se(path_is_mount_point(dirlink1, 0) == 0);
+        assert_se(path_is_mount_point(dir1, NULL, AT_SYMLINK_FOLLOW) == 0);
+        assert_se(path_is_mount_point(dir1, NULL, 0) == 0);
+        assert_se(path_is_mount_point(dirlink1, NULL, AT_SYMLINK_FOLLOW) == 0);
+        assert_se(path_is_mount_point(dirlink1, NULL, 0) == 0);
 
         /* file in subdirectory mountpoints */
         dir1file = path_join(NULL, dir1, "file");
@@ -390,10 +458,10 @@ static void test_path_is_mount_point(void) {
         assert_se(fd > 0);
         close(fd);
 
-        assert_se(path_is_mount_point(dir1file, AT_SYMLINK_FOLLOW) == 0);
-        assert_se(path_is_mount_point(dir1file, 0) == 0);
-        assert_se(path_is_mount_point(dirlink1file, AT_SYMLINK_FOLLOW) == 0);
-        assert_se(path_is_mount_point(dirlink1file, 0) == 0);
+        assert_se(path_is_mount_point(dir1file, NULL, AT_SYMLINK_FOLLOW) == 0);
+        assert_se(path_is_mount_point(dir1file, NULL, 0) == 0);
+        assert_se(path_is_mount_point(dirlink1file, NULL, AT_SYMLINK_FOLLOW) == 0);
+        assert_se(path_is_mount_point(dirlink1file, NULL, 0) == 0);
 
         /* these tests will only work as root */
         if (mount(file1, file2, NULL, MS_BIND, NULL) >= 0) {
@@ -401,10 +469,10 @@ static void test_path_is_mount_point(void) {
 
                 /* files */
                 /* capture results in vars, to avoid dangling mounts on failure */
-                rf = path_is_mount_point(file2, 0);
-                rt = path_is_mount_point(file2, AT_SYMLINK_FOLLOW);
-                rlf = path_is_mount_point(link2, 0);
-                rlt = path_is_mount_point(link2, AT_SYMLINK_FOLLOW);
+                rf = path_is_mount_point(file2, NULL, 0);
+                rt = path_is_mount_point(file2, NULL, AT_SYMLINK_FOLLOW);
+                rlf = path_is_mount_point(link2, NULL, 0);
+                rlt = path_is_mount_point(link2, NULL, AT_SYMLINK_FOLLOW);
 
                 assert_se(umount(file2) == 0);
 
@@ -422,13 +490,13 @@ static void test_path_is_mount_point(void) {
 
                 assert_se(mount(dir2, dir1, NULL, MS_BIND, NULL) >= 0);
 
-                rf = path_is_mount_point(dir1, 0);
-                rt = path_is_mount_point(dir1, AT_SYMLINK_FOLLOW);
-                rlf = path_is_mount_point(dirlink1, 0);
-                rlt = path_is_mount_point(dirlink1, AT_SYMLINK_FOLLOW);
+                rf = path_is_mount_point(dir1, NULL, 0);
+                rt = path_is_mount_point(dir1, NULL, AT_SYMLINK_FOLLOW);
+                rlf = path_is_mount_point(dirlink1, NULL, 0);
+                rlt = path_is_mount_point(dirlink1, NULL, AT_SYMLINK_FOLLOW);
                 /* its parent is a mount point, but not /file itself */
-                rl1f = path_is_mount_point(dirlink1file, 0);
-                rl1t = path_is_mount_point(dirlink1file, AT_SYMLINK_FOLLOW);
+                rl1f = path_is_mount_point(dirlink1file, NULL, 0);
+                rl1t = path_is_mount_point(dirlink1file, NULL, AT_SYMLINK_FOLLOW);
 
                 assert_se(umount(dir1) == 0);
 
@@ -510,8 +578,41 @@ static void test_hidden_or_backup_file(void) {
         assert_se(!hidden_or_backup_file("test.dpkg-old.foo"));
 }
 
+static void test_systemd_installation_has_version(const char *path) {
+        int r;
+        const unsigned versions[] = {0, 231, atoi(PACKAGE_VERSION), 999};
+        unsigned i;
+
+        for (i = 0; i < ELEMENTSOF(versions); i++) {
+                r = systemd_installation_has_version(path, versions[i]);
+                assert_se(r >= 0);
+                log_info("%s has systemd >= %u: %s",
+                         path ?: "Current installation", versions[i], yes_no(r));
+        }
+}
+
+static void test_skip_dev_prefix(void) {
+
+        assert_se(streq(skip_dev_prefix("/"), "/"));
+        assert_se(streq(skip_dev_prefix("/dev"), ""));
+        assert_se(streq(skip_dev_prefix("/dev/"), ""));
+        assert_se(streq(skip_dev_prefix("/dev/foo"), "foo"));
+        assert_se(streq(skip_dev_prefix("/dev/foo/bar"), "foo/bar"));
+        assert_se(streq(skip_dev_prefix("//dev"), ""));
+        assert_se(streq(skip_dev_prefix("//dev//"), ""));
+        assert_se(streq(skip_dev_prefix("/dev///foo"), "foo"));
+        assert_se(streq(skip_dev_prefix("///dev///foo///bar"), "foo///bar"));
+        assert_se(streq(skip_dev_prefix("//foo"), "//foo"));
+        assert_se(streq(skip_dev_prefix("foo"), "foo"));
+}
+
 int main(int argc, char **argv) {
+        log_set_max_level(LOG_DEBUG);
+        log_parse_environment();
+        log_open();
+
         test_path();
+        test_path_equal_root();
         test_find_binary(argv[0]);
         test_prefixes();
         test_path_join();
@@ -524,6 +625,9 @@ int main(int argc, char **argv) {
         test_file_in_same_dir();
         test_filename_is_valid();
         test_hidden_or_backup_file();
+        test_skip_dev_prefix();
+
+        test_systemd_installation_has_version(argv[1]); /* NULL is OK */
 
         return 0;
 }