diff --git a/src/libstrongswan/tests/test_suite.c b/src/libstrongswan/tests/test_suite.c index fb40b05c1..a636d6f7c 100644 --- a/src/libstrongswan/tests/test_suite.c +++ b/src/libstrongswan/tests/test_suite.c @@ -40,6 +40,11 @@ static int failure_line; */ static backtrace_t *failure_backtrace; +/** + * Flag to indicate if a worker thread failed + */ +static bool worker_failed; + /** * Longjump restore point when failing */ @@ -169,6 +174,17 @@ void test_fail_msg(const char *file, int line, char *fmt, ...) test_failure(); } +/** + * See header. + */ +void test_fail_if_worker_failed() +{ + if (pthread_self() == main_thread && worker_failed) + { + test_failure(); + } +} + /** * Signal handler catching critical and alarm signals */ @@ -180,8 +196,9 @@ static void test_sighandler(int signal) switch (signal) { case SIGUSR1: - /* a different thread failed, abort test */ - return test_failure(); + /* a different thread failed, abort test at the next opportunity */ + worker_failed = TRUE; + return; case SIGSEGV: signame = "SIGSEGV"; break; @@ -251,6 +268,8 @@ void test_setup_timeout(int s) sigaction(SIGUSR1, &action, NULL); alarm(s); + + worker_failed = FALSE; } /** diff --git a/src/libstrongswan/tests/test_suite.h b/src/libstrongswan/tests/test_suite.h index 2b1a64c2d..4bef6ff37 100644 --- a/src/libstrongswan/tests/test_suite.h +++ b/src/libstrongswan/tests/test_suite.h @@ -236,6 +236,12 @@ void test_fail_vmsg(const char *file, int line, char *fmt, va_list args); */ void test_fail_msg(const char *file, int line, char *fmt, ...); +/** + * Let a test fail if one of the worker threads has failed (only if called from + * the main thread). + */ +void test_fail_if_worker_failed(); + /** * Check if two integers equal, fail test if not * @@ -246,6 +252,7 @@ void test_fail_msg(const char *file, int line, char *fmt, ...); ({ \ typeof(a) _a = a; \ typeof(b) _b = b; \ + test_fail_if_worker_failed(); \ if (_a != _b) \ { \ test_fail_msg(__FILE__, __LINE__, #a " != " #b " (%d != %d)", _a, _b); \ @@ -262,6 +269,7 @@ void test_fail_msg(const char *file, int line, char *fmt, ...); ({ \ char* _a = (char*)a; \ char* _b = (char*)b; \ + test_fail_if_worker_failed(); \ if (!_a || !_b || !streq(_a, _b)) \ { \ test_fail_msg(__FILE__, __LINE__, \ @@ -279,6 +287,7 @@ void test_fail_msg(const char *file, int line, char *fmt, ...); ({ \ chunk_t _a = (chunk_t)a; \ chunk_t _b = (chunk_t)b; \ + test_fail_if_worker_failed(); \ if (_a.len != _b.len || !memeq(a.ptr, b.ptr, a.len)) \ { \ test_fail_msg(__FILE__, __LINE__, \ @@ -293,6 +302,7 @@ void test_fail_msg(const char *file, int line, char *fmt, ...); */ #define test_assert(x) \ ({ \ + test_fail_if_worker_failed(); \ if (!(x)) \ { \ test_fail_msg(__FILE__, __LINE__, #x); \ @@ -308,6 +318,7 @@ void test_fail_msg(const char *file, int line, char *fmt, ...); */ #define test_assert_msg(x, fmt, ...) \ ({ \ + test_fail_if_worker_failed(); \ if (!(x)) \ { \ test_fail_msg(__FILE__, __LINE__, #x ": " fmt, ##__VA_ARGS__); \ @@ -327,6 +338,7 @@ void test_fail_msg(const char *file, int line, char *fmt, ...); #define fail(fmt, ...) test_fail_msg(__FILE__, __LINE__, fmt, ##__VA_ARGS__) #define fail_if(x, fmt, ...) \ ({ \ + test_fail_if_worker_failed(); \ if (x) \ { \ test_fail_msg(__FILE__, __LINE__, #x ": " fmt, ##__VA_ARGS__); \ @@ -341,10 +353,10 @@ void test_fail_msg(const char *file, int line, char *fmt, ...); #define tcase_set_timeout test_case_set_timeout #define suite_add_tcase test_suite_add_case #define START_TEST(name) static void name (int _i) { -#define END_TEST } +#define END_TEST test_fail_if_worker_failed(); } #define START_SETUP(name) static void name() { -#define END_SETUP } +#define END_SETUP test_fail_if_worker_failed(); } #define START_TEARDOWN(name) static void name() { -#define END_TEARDOWN } +#define END_TEARDOWN test_fail_if_worker_failed(); } #endif /** TEST_SUITE_H_ @}*/