]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib: Add tests for path-util
authorMartti Rannanjärvi <martti.rannanjarvi@dovecot.fi>
Tue, 29 Nov 2016 18:50:28 +0000 (20:50 +0200)
committerGitLab <gitlab@git.dovecot.net>
Mon, 30 Jan 2017 16:48:15 +0000 (18:48 +0200)
src/lib/Makefile.am
src/lib/test-lib.inc
src/lib/test-path-util.c [new file with mode: 0644]

index 45d6c9674a6995e632425008285021ef68ef67eb..54308b28cfc5a89a5accfdc4d0d5ffe01e3f306f 100644 (file)
@@ -357,6 +357,7 @@ test_lib_SOURCES = \
        test-ostream-escaped.c \
        test-ostream-failure-at.c \
        test-ostream-file.c \
+       test-path-util.c \
        test-primes.c \
        test-printf-format-fix.c \
        test-priorityq.c \
index 77712f94ac5ea229a6a2858ef5278962eb6407b4..571a74a402b4fa7335ad6262ca3c66fc6377b024 100644 (file)
@@ -50,6 +50,7 @@ TEST(test_numpack)
 TEST(test_ostream_escaped)
 TEST(test_ostream_failure_at)
 TEST(test_ostream_file)
+TEST(test_path_util)
 TEST(test_pkcs5_pbkdf2)
 TEST(test_primes)
 TEST(test_printf_format_fix)
diff --git a/src/lib/test-path-util.c b/src/lib/test-path-util.c
new file mode 100644 (file)
index 0000000..2fada8f
--- /dev/null
@@ -0,0 +1,159 @@
+/* Copyright (c) 2016 Dovecot authors, see the included COPYING file */
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <libgen.h>
+
+#include "test-lib.h"
+#include "path-util.h"
+
+static char tmpdir[64];
+static const char *cwd;
+static const char *link1;
+static const char *link2;
+static const char *link3;
+
+static void test_local_path() {
+       const char *expected = t_strconcat(cwd, "/README.md", NULL);
+       const char *npath = NULL, *error = NULL;
+       test_assert(t_normpath_to("README.md", cwd, &npath, &error) == 0);
+       test_assert_strcmp(npath, expected);
+}
+
+static void test_absolute_path_no_change(void) {
+       const char *npath = NULL, *error = NULL;
+       test_assert(t_normpath_to("/", "/", &npath, &error) == 0);
+       test_assert_strcmp(npath, "/");
+
+       test_assert(t_normpath_to(cwd, cwd, &npath, &error) == 0);
+       test_assert_strcmp(npath, cwd);
+}
+
+static int path_height(const char* p) {
+       int n;
+       for (n = 0; *p != '\0'; ++p)
+               n += *p == '/';
+       return n;
+}
+
+static void test_travel_to_root(void) {
+       int l = path_height(cwd);
+       const char *npath = cwd;
+       for (npath = cwd; l--;) {
+               const char *error;
+               test_assert_idx(t_normpath_to("../", npath, &npath, &error) == 0, l);
+       }
+       test_assert_strcmp(npath, "/");
+}
+
+static void test_extra_slashes(void) {
+       const char *npath = NULL, *error = NULL;
+       test_assert(t_normpath_to(".", cwd, &npath, &error) == 0);
+       test_assert_strcmp(npath, cwd);
+
+       test_assert(t_normpath_to("./", cwd, &npath, &error) == 0);
+       test_assert_strcmp(npath, cwd);
+
+       test_assert(t_normpath_to(".////", cwd, &npath, &error) == 0);
+       test_assert_strcmp(npath, cwd);
+}
+
+static void test_nonexistent_path(void) {
+       const char *npath = NULL, *error = NULL;
+       const char *expected = t_strconcat(cwd, "/nonexistent", NULL);
+       test_assert(t_normpath_to("nonexistent", cwd, &npath, &error) == 0);
+       test_assert_strcmp(npath, expected);
+       test_assert(t_realpath_to("nonexistent", cwd, &npath, &error) == -1);
+       test_assert(error != NULL);
+}
+
+static void test_relative_dotdot() {
+       const char *rel_path = t_strconcat("../", basename(tmpdir), NULL);
+       const char *npath = NULL, *error = NULL;
+       test_assert(t_normpath_to(rel_path, tmpdir, &npath, &error) == 0);
+       test_assert_strcmp(npath, tmpdir);
+
+       test_assert(t_normpath_to("..", tmpdir, &npath, &error) == 0);
+       test_assert_strcmp(npath, "/tmp");
+
+       test_assert(t_normpath_to("../", tmpdir, &npath, &error) == 0);
+       test_assert_strcmp(npath, "/tmp");
+
+       test_assert(t_normpath_to("../.", tmpdir, &npath, &error) == 0);
+       test_assert_strcmp(npath, "/tmp");
+}
+
+static void test_link1() {
+       const char *npath = NULL, *error = NULL;
+       test_assert(t_realpath_to(link1, "/", &npath, &error) == 0);
+       test_assert_strcmp(npath, tmpdir);
+}
+
+static void test_link_loop() {
+       const char *npath = NULL, *error = NULL;
+       errno = 0;
+       test_assert(t_realpath_to(link2, "/", &npath, &error) == -1);
+       test_assert(errno == ELOOP);
+       test_assert(error != NULL);
+}
+
+static void test_abspath_vs_normpath() {
+       const char *abs = t_abspath_to("../../bin", "/usr/lib/");
+       test_assert_strcmp(abs, "/usr/lib//../../bin");
+
+       const char *norm = NULL, *error = NULL;
+       test_assert(t_normpath_to("../../bin", "/usr///lib/", &norm, &error) == 0);
+       test_assert_strcmp(norm, "/bin");
+}
+
+static void test_init(void) {
+       const char *error;
+       test_assert(t_get_working_dir(&cwd, &error) == 0);
+       strcpy(tmpdir, "/tmp/tmpdir.XXXXXX");
+       if (mkdtemp(tmpdir) == NULL) {
+               i_fatal("mkdtemp: %m");
+       }
+
+       link1 = t_strconcat(tmpdir, "/link1", NULL);
+       if (symlink(tmpdir, link1) < 0) {
+               i_fatal("symlink: %m");
+       }
+
+       /* link2 and link3 point to each other to create a loop */
+       link2 = t_strconcat(tmpdir, "/link2", NULL);
+       link3 = t_strconcat(tmpdir, "/link3", NULL);
+       if (symlink(link3, link2) < 0) {
+               i_fatal("symlink: %m");
+       }
+       if (symlink(link2, link3) < 0) {
+               i_fatal("symlink: %m");
+       }
+}
+
+static void test_deinit(void) {
+       if (unlink(link1) < 0) {
+               i_fatal("unlink: %m");
+       } if (unlink(link2) < 0) {
+               i_fatal("unlink: %m");
+       } if (unlink(link3) < 0) {
+               i_fatal("unlink: %m");
+       } if (rmdir(tmpdir) < 0) {
+               i_fatal("rmdir: %m");
+       }
+}
+
+void test_path_util(void) {
+       test_begin("test_path_util");
+       test_init();
+       test_local_path();
+       test_absolute_path_no_change();
+       test_travel_to_root();
+       test_extra_slashes();
+       test_nonexistent_path();
+       test_relative_dotdot();
+       test_link1();
+       test_link_loop();
+       test_abspath_vs_normpath();
+       test_deinit();
+       test_end();
+}