From b25ad2001b88212c8f441c62bf8d342bb499fa2b Mon Sep 17 00:00:00 2001 From: Snaipe Date: Sun, 1 Feb 2015 18:14:36 +0100 Subject: [PATCH] Added report hooks draft --- Makefile | 6 +++--- include/common.h | 7 +++++++ include/criterion.h | 5 +---- include/hooks.h | 31 +++++++++++++++++++++++++++++++ samples/simple.c | 11 +++++++++-- src/report.c | 35 +++++++++++++++++++++++++++++++++++ src/report.h | 18 ++++++++++++++++++ src/runner.c | 27 +++++++++++++++------------ src/runner.h | 2 ++ 9 files changed, 121 insertions(+), 21 deletions(-) create mode 100644 include/common.h create mode 100644 include/hooks.h create mode 100644 src/report.c create mode 100644 src/report.h diff --git a/Makefile b/Makefile index 0360e8a..ad510a8 100644 --- a/Makefile +++ b/Makefile @@ -1,14 +1,14 @@ CC = gcc CFLAGS = -Wall -Wextra -std=gnu99 -Isrc/ -Iinclude/ -g -SRCS = runner.c +SRCS = runner.c report.c OBJS = $(addprefix src/,$(subst .c,.o,$(SRCS))) sample: samples/simple.o libcriterion.a - $(LINK.o) -o $@ $^ + $(LINK.o) -o $@ $< -L. -lcriterion libcriterion.a: $(OBJS) - $(AR) rcs $@ $^ + $(AR) cru $@ $^ clean: $(RM) $(OBJS) samples/simple.o diff --git a/include/common.h b/include/common.h new file mode 100644 index 0000000..22b5a05 --- /dev/null +++ b/include/common.h @@ -0,0 +1,7 @@ +#ifndef CRITERION_COMMON_H_ +# define CRITERION_COMMON_H_ + +# define SECTION_(Name) __attribute__((section(Name))) +# define UNUSED __attribute__((unused)) + +#endif /* !CRITERION_COMMON_H_ */ diff --git a/include/criterion.h b/include/criterion.h index dbbd369..c0a0d03 100644 --- a/include/criterion.h +++ b/include/criterion.h @@ -25,6 +25,7 @@ # define CRITERION_H_ #include +#include "common.h" struct criterion_test_extra_data { size_t sentinel_; @@ -39,10 +40,6 @@ struct criterion_test { const struct criterion_test_extra_data *data; }; -extern __attribute__ ((weak)) void criterion_init(void); -extern __attribute__ ((weak)) void criterion_fini(void); - -# define SECTION_(Name) __attribute__((section(Name))) # define IDENTIFIER_(Category, Name, Suffix) \ Category ## _ ## Name ## _ ## Suffix # define TEST_PROTOTYPE_(Category, Name) \ diff --git a/include/hooks.h b/include/hooks.h new file mode 100644 index 0000000..78754d9 --- /dev/null +++ b/include/hooks.h @@ -0,0 +1,31 @@ +#ifndef CRITERION_HOOKS_H_ +# define CRITERION_HOOKS_H_ + +#include "common.h" + +typedef enum { + PRE_INIT, + PRE_TEST, + POST_TEST, + POST_FINI, +} e_report_status; + +typedef void (*f_report_hook)(void *); + +# define HOOK_IDENTIFIER_(Suffix) HOOK_IDENTIFIER__(__LINE__, Suffix) +# define HOOK_IDENTIFIER__(Line, Suffix) HOOK_IDENTIFIER___(Line, Suffix) +# define HOOK_IDENTIFIER___(Line, Suffix) hook_l ## Line ## _ ## Suffix + +# define HOOK_PROTOTYPE_ \ + void HOOK_IDENTIFIER_(impl)(UNUSED void *data) + +# define ReportHook(Kind) \ + HOOK_PROTOTYPE_; \ + SECTION_("criterion_hooks_" #Kind) \ + const f_report_hook HOOK_IDENTIFIER_(func) = HOOK_IDENTIFIER_(impl); \ + HOOK_PROTOTYPE_ + +extern __attribute__ ((weak)) void criterion_init(void); +extern __attribute__ ((weak)) void criterion_fini(void); + +#endif /* !CRITERION_HOOKS_H_ */ diff --git a/samples/simple.c b/samples/simple.c index b63c89d..8df8fd8 100644 --- a/samples/simple.c +++ b/samples/simple.c @@ -1,6 +1,7 @@ #include #include #include "criterion.h" +#include "report.h" Test(misc, simple) { } @@ -9,9 +10,15 @@ Test(misc, failing) { exit(1); } -/*void criterion_init(void) { +ReportHook(PRE_INIT) { + struct criterion_test *test = data; + + printf("testing %s in category %s\n", test->name, test->category); +} + +void criterion_init(void) { puts("criterion_init"); -}*/ +} void criterion_fini(void) { puts("criterion_fini"); diff --git a/src/report.c b/src/report.c new file mode 100644 index 0000000..48ea375 --- /dev/null +++ b/src/report.c @@ -0,0 +1,35 @@ +#include +#include "criterion.h" +#include "report.h" + +#define IMPL_CALL_REPORT_HOOKS(Kind) \ + static f_report_hook * const g_##Kind##_section_start = \ + &__start_criterion_hooks_##Kind; \ + static f_report_hook * const g_##Kind##_section_end = \ + &__stop_criterion_hooks_##Kind; \ + void call_report_hooks_##Kind(void *data) { \ + for (f_report_hook *hook = g_##Kind##_section_start;\ + hook < g_##Kind##_section_end; \ + ++hook) { \ + (*hook)(data); \ + } \ + } + +IMPL_CALL_REPORT_HOOKS(PRE_INIT); +IMPL_CALL_REPORT_HOOKS(PRE_TEST); +IMPL_CALL_REPORT_HOOKS(POST_TEST); +IMPL_CALL_REPORT_HOOKS(POST_FINI); + +ReportHook(PRE_INIT) { + struct criterion_test *test = data; + + printf("%s::%s: ", test->category, test->name); + fflush(stdout); +} + +ReportHook(POST_TEST) { + +} + +ReportHook(PRE_TEST) {} +ReportHook(POST_FINI) {} diff --git a/src/report.h b/src/report.h new file mode 100644 index 0000000..10666e1 --- /dev/null +++ b/src/report.h @@ -0,0 +1,18 @@ +#ifndef REPORT_H_ +# define REPORT_H_ + +# include "hooks.h" + +# define report(Kind, Data) call_report_hooks_##Kind(Data) + +# define DECL_CALL_REPORT_HOOKS(Kind) \ + extern f_report_hook __start_criterion_hooks_##Kind; \ + extern f_report_hook __stop_criterion_hooks_##Kind; \ + void call_report_hooks_##Kind(void *data) + +DECL_CALL_REPORT_HOOKS(PRE_INIT); +DECL_CALL_REPORT_HOOKS(PRE_TEST); +DECL_CALL_REPORT_HOOKS(POST_TEST); +DECL_CALL_REPORT_HOOKS(POST_FINI); + +#endif /* !REPORT_H_ */ diff --git a/src/runner.c b/src/runner.c index 895f497..617b3b0 100644 --- a/src/runner.c +++ b/src/runner.c @@ -25,11 +25,11 @@ #include #include #include -#include "criterion.h" #include "runner.h" +#include "report.h" -struct criterion_test * const g_section_start = &__start_criterion_tests; -struct criterion_test * const g_section_end = &__stop_criterion_tests; +static struct criterion_test * const g_section_start = &__start_criterion_tests; +static struct criterion_test * const g_section_end = &__stop_criterion_tests; static void map_tests(void (*fun)(struct criterion_test *)) { for (struct criterion_test *test = g_section_start; test < g_section_end; ++test) { @@ -40,20 +40,23 @@ static void map_tests(void (*fun)(struct criterion_test *)) { __attribute__ ((always_inline)) static inline void nothing(void) {} +static void run_test_nofork(struct criterion_test *test) { + report(PRE_INIT, test); + (test->data->init ?: nothing)(); + report(PRE_TEST, test); + (test->test ?: nothing)(); + report(POST_TEST, test); + (test->data->fini ?: nothing)(); + report(POST_FINI, test); +} + static void run_test(struct criterion_test *test) { - printf("%s::%s: ", test->category, test->name); - fflush(stdout); pid_t pid; if (!(pid = fork())) { - (test->data->init ?: nothing)(); - (test->test ?: nothing)(); - (test->data->fini ?: nothing)(); + run_test_nofork(test); exit(0); } else { - int status; - waitpid(pid, &status, 0); - int success = WIFEXITED(status) && WEXITSTATUS(status) == 0; - printf("%s\n", success ? "SUCCESS" : "FAILURE"); + waitpid(pid, NULL, 0); } } diff --git a/src/runner.h b/src/runner.h index edcba9a..3d252f4 100644 --- a/src/runner.h +++ b/src/runner.h @@ -24,6 +24,8 @@ #ifndef CRITERION_RUNNER_H_ # define CRITERION_RUNNER_H_ +# include "criterion.h" + extern struct criterion_test __start_criterion_tests; extern struct criterion_test __stop_criterion_tests;