static unsigned int total_count;
static unsigned int expected_errors;
static char *expected_error_str, *expected_fatal_str;
+static test_fatal_callback_t *test_fatal_callback;
+static void *test_fatal_context;
void test_begin(const char *name)
{
expected_fatal_str = i_strdup(substr);
}
+#undef test_fatal_set_callback
+void test_fatal_set_callback(test_fatal_callback_t *callback, void *context)
+{
+ i_assert(test_fatal_callback == NULL);
+ test_fatal_callback = callback;
+ test_fatal_context = context;
+}
+
static void ATTR_FORMAT(2, 0) ATTR_NORETURN
test_fatal_handler(const struct failure_context *ctx,
const char *format, va_list args)
va_end(args);
if (suppress) {
+ if (test_fatal_callback != NULL) {
+ test_fatal_callback(test_fatal_context);
+ test_fatal_callback = NULL;
+ test_fatal_context = NULL;
+ }
+
i_set_fatal_handler(test_fatal_handler);
longjmp(fatal_jmpbuf, 1);
} else {
FATAL_TEST_FINISHED or FATAL_TEST_ABORT is returned. */
typedef enum fatal_test_state test_fatal_func_t(unsigned int stage);
+typedef void test_fatal_callback_t(void *context);
+
struct named_fatal {
const char *name;
test_fatal_func_t *func;
/* Require the Fatal/Panic string to match this or the fatal test fails. */
void test_expect_fatal_string(const char *substr);
+/* Call the specified callback when a fatal is being triggered. This is mainly
+ intended to allow freeing memory so valgrind won't complain about memory
+ leaks. */
+void test_fatal_set_callback(test_fatal_callback_t *callback, void *context);
+#define test_fatal_set_callback(callback, context) \
+ test_fatal_set_callback(1 ? (test_fatal_callback_t *)callback : \
+ CALLBACK_TYPECHECK(callback, void (*)(typeof(context))), \
+ context)
#define FATAL_DECL(x) enum fatal_test_state x(unsigned int);
#define FATAL_NAMELESS(x) x, /* Were you to want to use the X trick but not name the tests */