From 3c2e92d169c8e57d6bce3b0912f0f192f7498696 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 17 Oct 2024 08:29:22 +1000 Subject: [PATCH] test: add ability to collect test results from a nonforking test Use longjmp to try to get out of a test error. This will only work for errors triggered by our own test suite (i.e. not for SIGSEGV and friends) but that's good enough for most things. Part-of: --- test/litest-runner.c | 25 +++++++++++++++++++++++-- test/litest-runner.h | 8 ++++++++ test/litest.c | 14 +++++++------- 3 files changed, 38 insertions(+), 9 deletions(-) diff --git a/test/litest-runner.c b/test/litest-runner.c index f9f996b9..c5507a35 100644 --- a/test/litest-runner.c +++ b/test/litest-runner.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include "litest-runner.h" @@ -42,6 +43,9 @@ #include "util-list.h" #include "util-stringbuf.h" +static bool use_jmpbuf; /* only used for max_forks = 0 */ +static jmp_buf jmpbuf; + /* musl doesn't have this one but it's not that important */ #ifndef HAVE_SIGABBREV_NP #define sigabbrev_np(...) "???" @@ -587,10 +591,20 @@ litest_runner_test_update_errno(struct litest_runner_test *t, int error) } } +__attribute__((noreturn)) +void +litest_runner_abort(void) { + if (use_jmpbuf) { + longjmp(jmpbuf, SIGABRT); + } else { + abort(); + } +} + static int litest_runner_run_test(struct litest_runner *runner, struct litest_runner_test *t) { - int r = 0; + int r; t->result = LITEST_SYSTEM_ERROR; @@ -599,7 +613,12 @@ litest_runner_run_test(struct litest_runner *runner, struct litest_runner_test * t->times.start_millis = us2ms(now); if (runner->max_forks == 0) { - t->result = litest_runner_test_run(&t->desc); + if (use_jmpbuf && setjmp(jmpbuf) == 0) { + t->result = litest_runner_test_run(&t->desc); + } else { + t->result = LITEST_FAIL; + } + r = 0; /* -Wclobbered */ } else { r = litest_runner_fork_test(runner, t); if (r >= 0) @@ -845,6 +864,8 @@ litest_runner_run_tests(struct litest_runner *runner) if (runner->global.setup) runner->global.setup(runner->global.userdata); + use_jmpbuf = runner->max_forks == 0; + setup_sighandler(SIGINT); uint64_t now = 0; diff --git a/test/litest-runner.h b/test/litest-runner.h index c557e185..14f0a11d 100644 --- a/test/litest-runner.h +++ b/test/litest-runner.h @@ -92,3 +92,11 @@ litest_runner_set_setup_funcs(struct litest_runner *runner, void *userdata); void litest_runner_destroy(struct litest_runner *runner); + +/* + * Function to call abort(). Depending on the number of forks permitted, + * this function may simply abort() or it may longjmp back out to collect + * errors from non-forking tests. + */ +__attribute__((noreturn)) +void litest_runner_abort(void); diff --git a/test/litest.c b/test/litest.c index 858598e8..47a6a7e7 100644 --- a/test/litest.c +++ b/test/litest.c @@ -185,7 +185,7 @@ litest_fail_condition(const char *file, litest_log("in %s() (%s:%d)\n", func, file, line); litest_backtrace(); - abort(); + litest_runner_abort(); } __attribute__((noreturn)) @@ -203,7 +203,7 @@ litest_fail_comparison_int(const char *file, litest_log("Resolved to: %d %s %d\n", a, operator, b); litest_log("in %s() (%s:%d)\n", func, file, line); litest_backtrace(); - abort(); + litest_runner_abort(); } __attribute__((noreturn)) @@ -221,7 +221,7 @@ litest_fail_comparison_double(const char *file, litest_log("Resolved to: %.3f %s %.3f\n", a, operator, b); litest_log("in %s() (%s:%d)\n", func, file, line); litest_backtrace(); - abort(); + litest_runner_abort(); } __attribute__((noreturn)) @@ -234,7 +234,7 @@ litest_fail_comparison_ptr(const char *file, litest_log("FAILED COMPARISON: %s\n", comparison); litest_log("in %s() (%s:%d)\n", func, file, line); litest_backtrace(); - abort(); + litest_runner_abort(); } __attribute__((noreturn)) @@ -251,7 +251,7 @@ litest_fail_comparison_str(const char *file, litest_log("Resolved to: %s %s %s\n", astr, operator, bstr); litest_log("in %s() (%s:%d)\n", func, file, line); litest_backtrace(); - abort(); + litest_runner_abort(); } struct test { @@ -3257,7 +3257,7 @@ _litest_assert_event_type_is_one_of(struct libinput_event *event, ...) fprintf(stderr, "\nWrong event is: "); litest_print_event(event); litest_backtrace(); - abort(); + litest_runner_abort(); } void @@ -3298,7 +3298,7 @@ _litest_assert_event_type_not_one_of(struct libinput_event *event, ...) fprintf(stderr, "\nWrong event is: "); litest_print_event(event); litest_backtrace(); - abort(); + litest_runner_abort(); } void -- 2.34.1