Added report hooks draft
This commit is contained in:
parent
f605f26001
commit
b25ad2001b
9 changed files with 121 additions and 21 deletions
6
Makefile
6
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
|
||||
|
|
7
include/common.h
Normal file
7
include/common.h
Normal 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_ */
|
|
@ -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
31
include/hooks.h
Normal 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_ */
|
|
@ -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
35
src/report.c
Normal 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
18
src/report.h
Normal 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_ */
|
27
src/runner.c
27
src/runner.c
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue