From: Stephan Bosch Date: Sun, 26 Oct 2025 04:42:06 +0000 (+0100) Subject: lib-test: Add support for temporary test directories X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=130afd37a81e8d5f9caf620999f6db0276c89eb9;p=thirdparty%2Fdovecot%2Fcore.git lib-test: Add support for temporary test directories --- diff --git a/.gitignore b/.gitignore index b174277dd0..f012e838ff 100644 --- a/.gitignore +++ b/.gitignore @@ -53,6 +53,7 @@ auth-token-secret.dat /.cache /.dir-locals.el /.ropeproject +/.test /aclocal.m4 /m4/libtool.m4 diff --git a/Makefile.am b/Makefile.am index 1d5ded142d..f1ab78b4b3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -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; \ diff --git a/configure.ac b/configure.ac index cf5857c836..dce385e937 100644 --- a/configure.ac +++ b/configure.ac @@ -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" diff --git a/src/lib-test/Makefile.am b/src/lib-test/Makefile.am index bc4515e9f3..ef43204043 100644 --- a/src/lib-test/Makefile.am +++ b/src/lib-test/Makefile.am @@ -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) diff --git a/src/lib-test/test-common.c b/src/lib-test/test-common.c index d3604bde3a..3489e117e7 100644 --- a/src/lib-test/test-common.c +++ b/src/lib-test/test-common.c @@ -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 index 0000000000..20e95fac70 --- /dev/null +++ b/src/lib-test/test-dir.c @@ -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 + +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 index 0000000000..57118d57a9 --- /dev/null +++ b/src/lib-test/test-dir.h @@ -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