From b0ebd5cddece3bc62d893ae3e89e0ae0a0e5ecf8 Mon Sep 17 00:00:00 2001 From: Snaipe Date: Thu, 5 Feb 2015 20:35:17 +0100 Subject: [PATCH] Added visual reporting for failed asserts and crashes --- include/criterion/assert.h | 1 + include/criterion/criterion.h | 6 ++++-- include/criterion/event.h | 2 +- include/criterion/stats.h | 3 +++ samples/simple.c | 14 +++----------- src/event.c | 2 +- src/report.c | 17 +++++++++++++++++ src/report.h | 2 ++ src/runner.c | 14 ++++++++------ src/stats.c | 9 ++++++++- 10 files changed, 48 insertions(+), 22 deletions(-) diff --git a/include/criterion/assert.h b/include/criterion/assert.h index 015e330..b2a263e 100644 --- a/include/criterion/assert.h +++ b/include/criterion/assert.h @@ -42,6 +42,7 @@ enum criterion_assert_kind { .condition = #Condition, \ .message = "" __VA_ARGS__, \ .passed = passed, \ + .file = __FILE__, \ .line = __LINE__, \ }; \ send_event(ASSERT, &stat, sizeof (stat)); \ diff --git a/include/criterion/criterion.h b/include/criterion/criterion.h index 0379e57..b8dbf1b 100644 --- a/include/criterion/criterion.h +++ b/include/criterion/criterion.h @@ -30,7 +30,8 @@ # include "assert.h" struct criterion_test_extra_data { - size_t sentinel_; + const char *file_; + unsigned line_; void (*init)(void); void (*fini)(void); }; @@ -50,7 +51,8 @@ struct criterion_test { # define Test(Category, Name, Args...) \ TEST_PROTOTYPE_(Category, Name); \ struct criterion_test_extra_data IDENTIFIER_(Category, Name, extra) = { \ - .sentinel_ = 0, \ + .file_ = __FILE__, \ + .line_ = __LINE__, \ Args \ }; \ SECTION_("criterion_tests") \ diff --git a/include/criterion/event.h b/include/criterion/event.h index d509a8d..37080ee 100644 --- a/include/criterion/event.h +++ b/include/criterion/event.h @@ -24,7 +24,7 @@ #ifndef CRITERION_EVENT_H_ # define CRITERION_EVENT_H_ -extern const int EVENT_PIPE; +extern int EVENT_PIPE; void send_event(int kind, void *data, size_t size); diff --git a/include/criterion/stats.h b/include/criterion/stats.h index 03da1da..55df8c6 100644 --- a/include/criterion/stats.h +++ b/include/criterion/stats.h @@ -32,6 +32,7 @@ struct criterion_assert_stats { const char *message; bool passed; unsigned line; + const char *file; struct criterion_assert_stats *next; }; @@ -41,6 +42,8 @@ struct criterion_test_stats { struct criterion_assert_stats *asserts; int passed; int failed; + unsigned progress; + const char *file; struct criterion_test_stats *next; }; diff --git a/samples/simple.c b/samples/simple.c index 2f153df..fcb3a2b 100644 --- a/samples/simple.c +++ b/samples/simple.c @@ -14,17 +14,9 @@ Test(misc, simple) { expect(1); } -Test(aziezdcjn, simple) { - expect(1); -} -Test(aziezdcjn, abcd) { - expect(1); -} -Test(aziezdcjn, simplez) { - expect(1); -} -Test(aziezdcjn, simpl) { - expect(1); +Test(abcd, crash) { + int *i = NULL; + *i = 42; } ReportHook(PRE_INIT)(struct criterion_test *test) { diff --git a/src/event.c b/src/event.c index 7484f17..0e569d7 100644 --- a/src/event.c +++ b/src/event.c @@ -33,7 +33,7 @@ #include "criterion/hooks.h" #include "event.h" -const int EVENT_PIPE = 3; +int EVENT_PIPE = -1; void destroy_event(void *ptr, UNUSED void *meta) { struct event *ev = ptr; diff --git a/src/report.c b/src/report.c index 37e6ab0..3acf9ef 100644 --- a/src/report.c +++ b/src/report.c @@ -42,6 +42,8 @@ IMPL_CALL_REPORT_HOOKS(PRE_EVERYTHING); IMPL_CALL_REPORT_HOOKS(PRE_INIT); IMPL_CALL_REPORT_HOOKS(PRE_TEST); +IMPL_CALL_REPORT_HOOKS(ASSERT); +IMPL_CALL_REPORT_HOOKS(TEST_CRASH); IMPL_CALL_REPORT_HOOKS(POST_TEST); IMPL_CALL_REPORT_HOOKS(POST_FINI); IMPL_CALL_REPORT_HOOKS(POST_EVERYTHING); @@ -62,4 +64,19 @@ ReportHook(POST_FINI)() {} ReportHook(PRE_EVERYTHING)() {} ReportHook(POST_EVERYTHING)() {} +ReportHook(ASSERT)(struct criterion_assert_stats *stats) { + if (!stats->passed) { + fprintf(stderr, "\t%s:%d: Assertion failed: %s\n", + stats->file, + stats->line, + *stats->message ? stats->message : stats->condition); + } +} +ReportHook(TEST_CRASH)(struct criterion_test_stats *stats) { + fprintf(stderr, "\tUnexpected signal after %s:%u!\n%s::%s: FAILURE (CRASH!)\n", + stats->file, + stats->progress, + stats->test->category, + stats->test->name); +} diff --git a/src/report.h b/src/report.h index e0c1b44..4b02caa 100644 --- a/src/report.h +++ b/src/report.h @@ -36,6 +36,8 @@ DECL_CALL_REPORT_HOOKS(PRE_EVERYTHING); DECL_CALL_REPORT_HOOKS(PRE_INIT); DECL_CALL_REPORT_HOOKS(PRE_TEST); +DECL_CALL_REPORT_HOOKS(ASSERT); +DECL_CALL_REPORT_HOOKS(TEST_CRASH); DECL_CALL_REPORT_HOOKS(POST_TEST); DECL_CALL_REPORT_HOOKS(POST_FINI); DECL_CALL_REPORT_HOOKS(POST_EVERYTHING); diff --git a/src/runner.c b/src/runner.c index 211bf06..70163b3 100644 --- a/src/runner.c +++ b/src/runner.c @@ -111,8 +111,7 @@ struct pipefds { static void setup_child(struct pipefds *fds) { close(STDIN_FILENO); close(fds->in); - dup2(fds->out, EVENT_PIPE); - close(fds->out); + EVENT_PIPE = fds->out; } static void run_test(struct criterion_global_stats *stats, struct criterion_test *test) { @@ -136,13 +135,16 @@ static void run_test(struct criterion_global_stats *stats, struct criterion_test switch (ev->kind) { case PRE_INIT: report(PRE_INIT, test); break; case PRE_TEST: report(PRE_TEST, test); break; - case ASSERT: report(PRE_TEST, ev->data); break; + case ASSERT: report(ASSERT, ev->data); break; case POST_TEST: report(POST_TEST, test_stats); break; - case POST_FINI: report(POST_FINI, test); break; + case POST_FINI: report(POST_FINI, test_stats); break; } sfree(ev); } - waitpid(pid, NULL, 0); + int status; + waitpid(pid, &status, 0); + if (WIFSIGNALED(status)) + report(TEST_CRASH, test_stats); } } @@ -154,7 +156,7 @@ void run_all(void) { if (!set) abort(); map_tests(set, stats, run_test); - report(POST_EVERYTHING, NULL); + report(POST_EVERYTHING, stats); } int main(void) { diff --git a/src/stats.c b/src/stats.c index d83adcf..4ecda69 100644 --- a/src/stats.c +++ b/src/stats.c @@ -53,7 +53,11 @@ static void destroy_test_stats(void *ptr, UNUSED void *meta) { } s_test_stats *test_stats_init(struct criterion_test *t) { - return shared_ptr(s_test_stats, ({ .test = t }), destroy_test_stats); + return shared_ptr(s_test_stats, ({ + .test = t, + .progress = t->data->line_, + .file = t->data->file_ + }), destroy_test_stats); } void stat_push_event(s_glob_stats *stats, @@ -103,6 +107,9 @@ static void push_assert(s_glob_stats *stats, ++stats->asserts_failed; ++test->failed; } + + test->progress = dup->line; + test->file = dup->file; } static void push_post_test(s_glob_stats *stats,