Added report hooks draft

This commit is contained in:
Snaipe 2015-02-01 18:14:36 +01:00
parent f605f26001
commit b25ad2001b
9 changed files with 121 additions and 21 deletions

View file

@ -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

7
include/common.h Normal file
View file

@ -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_ */

View file

@ -25,6 +25,7 @@
# define CRITERION_H_
#include <stddef.h>
#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) \

31
include/hooks.h Normal file
View file

@ -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_ */

View file

@ -1,6 +1,7 @@
#include <stdio.h>
#include <stdlib.h>
#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");

35
src/report.c Normal file
View file

@ -0,0 +1,35 @@
#include <stdio.h>
#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) {}

18
src/report.h Normal file
View file

@ -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_ */

View file

@ -25,11 +25,11 @@
#include <unistd.h>
#include <sys/wait.h>
#include <stdio.h>
#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);
}
}

View file

@ -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;