]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-test: Add support for temporary test directories
authorStephan Bosch <stephan.bosch@open-xchange.com>
Sun, 26 Oct 2025 04:42:06 +0000 (05:42 +0100)
committertimo.sirainen <timo.sirainen@open-xchange.com>
Wed, 5 Nov 2025 10:17:48 +0000 (10:17 +0000)
.gitignore
Makefile.am
configure.ac
src/lib-test/Makefile.am
src/lib-test/test-common.c
src/lib-test/test-dir.c [new file with mode: 0644]
src/lib-test/test-dir.h [new file with mode: 0644]

index b174277dd0594d6ea6be57b1762db47487398da6..f012e838ff8d94adcbd02584d39f19bb4b0bd61b 100644 (file)
@@ -53,6 +53,7 @@ auth-token-secret.dat
 /.cache
 /.dir-locals.el
 /.ropeproject
+/.test
 
 /aclocal.m4
 /m4/libtool.m4
index 1d5ded142df3da0ff6b83eadfc82ecffa302b8f8..f1ab78b4b3f26aaf85dd57524a7b7ed9aa1ec3eb 100644 (file)
@@ -101,6 +101,11 @@ DISTCLEANFILES = \
        $(top_builddir)/dovecot-config \
        $(top_builddir)/run-test.sh
 
+check-local:
+       rm -rf $(top_builddir)/.test
+clean-local:
+       rm -rf $(top_builddir)/.test
+
 distcheck-hook:
        if which scan-build > /dev/null; then \
          cd $(distdir)/_build; \
index cf5857c836ed8657af44df9ac6238b92b0888c09..dce385e937840d19abcfe6d9e267e22878481cd1 100644 (file)
@@ -789,8 +789,9 @@ SETTING_LINKED_FILES=`echo $libdovecot_c_files | $SED -e s,$srcdir/src,./src,g -
 AC_SUBST(SETTING_FILES)
 AC_SUBST(SETTING_LINKED_FILES)
 
-AM_CFLAGS="$AM_CFLAGS $EXTRA_CFLAGS"
-AM_CXXFLAGS="$AM_CXXFLAGS $EXTRA_CFLAGS"
+TEST_CFLAGS="-DTEST_DIR=\\\"\$(abs_top_builddir)/.test\\\""
+AM_CFLAGS="$AM_CFLAGS $TEST_CFLAGS $EXTRA_CFLAGS"
+AM_CXXFLAGS="$AM_CXXFLAGS $TEST_CFLAGS $EXTRA_CFLAGS"
 AC_SUBST([AM_CFLAGS])
 AC_SUBST([AM_CXXFLAGS])
 BINARY_LDFLAGS="$PIE_LDFLAGS $RELRO_LDFLAGS"
index bc4515e9f3b40645af6c3d1bb35fb94bb01377ea..ef4320404300af4ff1b743ebb4c79386c5c08e3d 100644 (file)
@@ -8,6 +8,7 @@ libtest_la_SOURCES = \
        fuzzer.c \
        ostream-final-trickle.c \
        test-common.c \
+       test-dir.c \
        test-istream.c \
        test-ostream.c \
        test-subprocess.c
@@ -17,6 +18,7 @@ headers = \
        ostream-final-trickle.h \
        test-common.h \
        test-private.h \
+       test-dir.h \
        test-subprocess.h
 
 pkginc_libdir=$(pkgincludedir)
index d3604bde3a49a3a08bb4784aed6b3f433a8ca64b..3489e117e73562c63a94ce193c928e1bd8c02fd9 100644 (file)
@@ -379,6 +379,8 @@ static void test_cleanup(void)
        /* Perform any additional important cleanup specific to the test. */
        if (test_cleanup_callback != NULL)
                test_cleanup_callback();
+
+       test_dir_cleanup();
 }
 
 static void test_terminate(const siginfo_t *si, void *context ATTR_UNUSED)
@@ -456,6 +458,7 @@ static int test_deinit(void)
        i_assert(test_prefix == NULL);
        printf("%u / %u tests failed\n", failure_count, total_count);
 
+       test_dir_deinit();
        test_subprocesses_deinit();
 
        event_unref(&test_event);
@@ -469,6 +472,8 @@ static int test_deinit(void)
 
 void test_forked_deinit(void)
 {
+       test_dir_deinit_forked();
+
        event_unref(&test_event);
 }
 
diff --git a/src/lib-test/test-dir.c b/src/lib-test/test-dir.c
new file mode 100644 (file)
index 0000000..20e95fa
--- /dev/null
@@ -0,0 +1,86 @@
+/* Copyright (c) 2021 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "str.h"
+#include "safe-mkstemp.h"
+#include "unlink-directory.h"
+#include "test-private.h"
+#include "test-dir.h"
+
+#include <sys/stat.h>
+
+static char *test_dir = NULL;
+
+#undef test_dir_init
+void test_dir_init(const char *top_test_dir, const char *name)
+{
+       string_t *dir;
+       int ret;
+
+       i_assert(test_dir == NULL);
+
+       test_init();
+       test_init_signals();
+
+       ret = mkdir(top_test_dir, 0700);
+       if (ret < 0 && errno != EEXIST)
+               i_fatal("mkdir(%s) failed: %m", TEST_DIR);
+
+       dir = t_str_new(256);
+       str_append(dir, top_test_dir);
+       str_append_c(dir, '/');
+       str_append(dir, name);
+       str_append_c(dir, '-');
+
+       if (safe_mkstemp_dir_pid(dir, 0700) < 0)
+               i_fatal("safe_mkstemp_dir(%s) failed: %m", str_c(dir));
+
+       test_dir = i_strdup(str_c(dir));
+}
+
+void test_dir_cleanup(void)
+{
+       const char *error;
+
+       if (test_dir == NULL)
+               return;
+       if (lib_is_initialized()) {
+               if (unlink_directory(test_dir,
+                                    UNLINK_DIRECTORY_FLAG_RMDIR, &error) < 0) {
+                       i_error("unlink_directory(%s) failed: %s.",
+                               test_dir, error);
+               }
+       } else {
+               /* Not supposed to happen, but automake will drop the main test
+                  directory upon the next run, so this will eventually be
+                  fixed. */
+       }
+
+       i_free(test_dir);
+}
+
+void test_dir_deinit(void)
+{
+       test_dir_cleanup();
+}
+
+void test_dir_deinit_forked(void)
+{
+       i_free(test_dir);
+}
+
+const char *test_dir_get(void)
+{
+       return test_dir;
+}
+
+const char *test_dir_get_prefix(void)
+{
+       return t_strconcat(test_dir, "/", NULL);
+}
+
+const char *test_dir_prepend(const char *path)
+{
+       return t_strconcat(test_dir, "/", path, NULL);
+}
+
diff --git a/src/lib-test/test-dir.h b/src/lib-test/test-dir.h
new file mode 100644 (file)
index 0000000..57118d5
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef TEST_DIR_H
+#define TEST_DIR_H
+
+void test_dir_init(const char *top_test_dir, const char *name);
+#define test_dir_init(name) test_dir_init(TEST_DIR, name);
+
+const char *test_dir_get(void);
+const char *test_dir_get_prefix(void);
+const char *test_dir_prepend(const char *path);
+
+#endif