Boyscouting

This commit is contained in:
Snaipe 2015-04-10 01:03:58 +02:00
parent fe65034ecd
commit 260b88c5d7
11 changed files with 112 additions and 48 deletions

View file

@ -26,10 +26,12 @@
# include "types.h"
typedef int (*f_criterion_cmp)(void *, void *);
struct criterion_ordered_set {
struct criterion_ordered_set_node *first;
size_t size;
int (*const cmp)(void *, void *);
f_criterion_cmp cmp;
void (*const dtor)(void *, void *);
};
@ -48,12 +50,16 @@ struct criterion_test_set {
size_t tests;
};
struct criterion_ordered_set *new_ordered_set(int (*cmp)(void *, void *), void (*dtor)(void *, void *));
void *insert_ordered_set(struct criterion_ordered_set *l, void *ptr, size_t size);
struct criterion_ordered_set *new_ordered_set(f_criterion_cmp cmp,
void (*dtor)(void *, void *));
# define FOREACH_SET(Elt, Set) \
for (struct criterion_ordered_set_node *n = Set->first; n; n = n->next) \
for (int cond = 1; cond;) \
void *insert_ordered_set(struct criterion_ordered_set *l,
void *ptr,
size_t size);
# define FOREACH_SET(Elt, Set) \
for (struct criterion_ordered_set_node *n = Set->first; n; n = n->next) \
for (int cond = 1; cond;) \
for (Elt = (void*) n->data; cond && (cond = 0, 1);)
#endif /* !CRITERION_ORDERED_SET_H_ */

View file

@ -48,14 +48,18 @@ struct event *read_event(FILE *f) {
if (fread(buf, assert_size, 1, f) == 0)
return NULL;
return unique_ptr(struct event, { .kind = kind, .data = buf }, destroy_event);
return unique_ptr(struct event,
.value = { .kind = kind, .data = buf },
.dtor = destroy_event);
}
case POST_TEST: {
double *elapsed_time = malloc(sizeof (double));
if (fread(elapsed_time, sizeof (double), 1, f) == 0)
return NULL;
return unique_ptr(struct event, { .kind = kind, .data = elapsed_time }, destroy_event);
return unique_ptr(struct event,
.value = { .kind = kind, .data = elapsed_time },
.dtor = destroy_event);
}
default:
return unique_ptr(struct event, { .kind = kind, .data = NULL });

View file

@ -9,7 +9,8 @@
# else
# include <libintl.h>
# define _(String) dgettext(PACKAGE, String)
# define _s(String, Plural, Quantity) dngettext(PACKAGE, String, Plural, (Quantity))
# define _s(String, Plural, Quantity) \
dngettext(PACKAGE, String, Plural, (Quantity))
# endif
#endif /* !I18N_H_ */

View file

@ -39,13 +39,18 @@ void normal_log_pre_all(UNUSED struct criterion_test_set *set) {
}
void normal_log_pre_init(struct criterion_test *test) {
criterion_pinfo(CRITERION_PREFIX_RUN, _("%1$s::%2$s\n"), test->category, test->name);
criterion_pinfo(CRITERION_PREFIX_RUN, _("%1$s::%2$s\n"),
test->category,
test->name);
if (test->data->description)
criterion_pinfo(CRITERION_PREFIX_RUN, _(" %s\n"), test->data->description);
criterion_pinfo(CRITERION_PREFIX_RUN, _(" %s\n"),
test->data->description);
}
void normal_log_post_test(struct criterion_test_stats *stats) {
const char *format = can_measure_time() ? "%1$s::%2$s: (%3$3.2fs)\n" : "%1$s::%2$s\n";
const char *format = can_measure_time() ? "%1$s::%2$s: (%3$3.2fs)\n"
: "%1$s::%2$s\n";
const enum criterion_logging_level level
= stats->failed ? CRITERION_IMPORTANT : CRITERION_INFO;
@ -59,7 +64,8 @@ void normal_log_post_test(struct criterion_test_stats *stats) {
}
__attribute__((always_inline))
static inline bool is_disabled(struct criterion_test *t, struct criterion_suite *s) {
static inline bool is_disabled(struct criterion_test *t,
struct criterion_suite *s) {
return t->data->disabled || (s->data && s->data->disabled);
}
@ -75,7 +81,8 @@ void normal_log_post_suite(struct criterion_suite_stats *stats) {
ts->test->name);
if (ts->test->data->description)
criterion_pinfo(CRITERION_PREFIX_DASHES, " %s\n", ts->test->data->description);
criterion_pinfo(CRITERION_PREFIX_DASHES, " %s\n",
ts->test->data->description);
}
}
}
@ -97,8 +104,10 @@ void normal_log_post_all(struct criterion_global_stats *stats) {
void normal_log_assert(struct criterion_assert_stats *stats) {
if (!stats->passed) {
char *dup = strdup(*stats->message ? stats->message : stats->condition), *saveptr = NULL;
char *line = strtok_r(dup, "\n", &saveptr);
char *dup = strdup(*stats->message ? stats->message
: stats->condition);
char *saveptr = NULL;
char *line = strtok_r(dup, "\n", &saveptr);
criterion_pimportant(CRITERION_PREFIX_DASHES,
_("%1$s%2$s%3$s:%4$s%5$d%6$s: Assertion failed: %7$s\n"),

View file

@ -23,4 +23,6 @@
*/
# include "criterion/options.h"
struct criterion_options criterion_options = { .logging_threshold = CRITERION_IMPORTANT };
struct criterion_options criterion_options = {
.logging_threshold = CRITERION_IMPORTANT,
};

View file

@ -39,12 +39,17 @@ static void destroy_ordered_set_node(void *ptr, void *meta) {
sfree(((struct criterion_ordered_set_node *) ptr)->next);
}
struct criterion_ordered_set *new_ordered_set(int (*cmp)(void *, void *), f_destructor dtor) {
struct criterion_ordered_set *new_ordered_set(f_criterion_cmp cmp,
f_destructor dtor) {
return unique_ptr(struct criterion_ordered_set,
{ .cmp = cmp, .dtor = dtor }, destroy_ordered_set);
.value = { .cmp = cmp, .dtor = dtor },
.dtor = destroy_ordered_set);
}
void *insert_ordered_set(struct criterion_ordered_set *l, void *ptr, size_t size) {
void *insert_ordered_set(struct criterion_ordered_set *l,
void *ptr,
size_t size) {
int cmp;
struct criterion_ordered_set_node *n, *prev = NULL;
for (n = l->first; n && (cmp = l->cmp(ptr, n->data)) > 0; n = n->next)

View file

@ -22,6 +22,9 @@
&(StartupInfo), \
&(Info))
# define WRITE_PROCESS_(Proc, What, Size) \
WriteProcessMemory(Proc, &What, &What, Size, NULL);
#else
# include <unistd.h>
# include <sys/wait.h>
@ -87,20 +90,26 @@ s_proc_handle *fork_process() {
child_suite = *g_worker_context.suite;
child_pipe = *g_worker_context.pipe;
g_worker_context = (struct worker_context) { &child_test, &child_suite, child_func, &child_pipe };
g_worker_context = (struct worker_context) {
&child_test,
&child_suite,
child_func,
&child_pipe
};
child_test.data = &child_test_data;
if (g_worker_context.suite->data) {
child_suite_data = *g_worker_context.suite->data;
child_suite.data = &child_suite_data;
WriteProcessMemory(info.hProcess, &child_suite_data, &child_suite_data, sizeof (child_suite_data), NULL);
WRITE_PROCESS_(info.hProcess, child_suite_data, sizeof (child_suite_data));
}
WriteProcessMemory(info.hProcess, &child_test, &child_test, sizeof (child_test), NULL);
WriteProcessMemory(info.hProcess, &child_test_data, &child_test_data, sizeof (child_test_data), NULL);
WriteProcessMemory(info.hProcess, &child_suite, &child_suite, sizeof (child_suite), NULL);
WriteProcessMemory(info.hProcess, &child_pipe, &child_pipe, sizeof (child_pipe), NULL);
WriteProcessMemory(info.hProcess, &g_worker_context, &g_worker_context, sizeof (struct worker_context), NULL);
WRITE_PROCESS_(info.hProcess, child_test, sizeof (child_test));
WRITE_PROCESS_(info.hProcess, child_test_data, sizeof (child_test_data));
WRITE_PROCESS_(info.hProcess, child_suite, sizeof (child_suite));
WRITE_PROCESS_(info.hProcess, child_pipe, sizeof (child_pipe));
WRITE_PROCESS_(info.hProcess, g_worker_context, sizeof (struct worker_context));
ResumeThread(info.hThread);
CloseHandle(info.hThread);
@ -167,7 +176,10 @@ FILE *pipe_out(s_pipe_handle *p) {
s_pipe_handle *stdpipe() {
#ifdef VANILLA_WIN32
HANDLE fhs[2];
SECURITY_ATTRIBUTES attr = { .nLength = sizeof (SECURITY_ATTRIBUTES), .bInheritHandle = TRUE };
SECURITY_ATTRIBUTES attr = {
.nLength = sizeof (SECURITY_ATTRIBUTES),
.bInheritHandle = TRUE
};
if (!CreatePipe(fhs, fhs + 1, &attr, 0))
return NULL;
return unique_ptr(s_pipe_handle, {{ fhs[0], fhs[1] }});

View file

@ -16,10 +16,10 @@
# endif
# ifdef VANILLA_WIN32
# define WEXITSTATUS(Status) (((Status) & 0xFF00) >> 8)
# define WTERMSIG(Status) ((Status) & 0x7F)
# define WIFEXITED(Status) (WTERMSIG(Status) == 0)
# define WIFSIGNALED(Status) (((signed char) (WTERMSIG(Status) + 1) >> 1) > 0)
# define WEXITSTATUS(Status) (((Status) & 0xFF00) >> 8)
# define WTERMSIG(Status) ((Status) & 0x7F)
# define WIFEXITED(Status) (WTERMSIG(Status) == 0)
# define WIFSIGNALED(Status) (((signed char) (WTERMSIG(Status) + 1) >> 1) > 0)
# else
# include <sys/wait.h>
# endif

View file

@ -94,7 +94,9 @@ struct process *spawn_test_worker(struct criterion_test *test,
return NULL;
}
return unique_ptr(struct process, { .proc = proc, .in = pipe_in(pipe) }, close_process);
return unique_ptr(struct process,
.value = { .proc = proc, .in = pipe_in(pipe) },
.dtor = close_process);
}
struct process_status wait_proc(struct process *proc) {
@ -102,10 +104,16 @@ struct process_status wait_proc(struct process *proc) {
wait_process(proc->proc, &status);
if (WIFEXITED(status))
return (struct process_status) { .kind = EXIT_STATUS, .status = WEXITSTATUS(status) };
return (struct process_status) {
.kind = EXIT_STATUS,
.status = WEXITSTATUS(status)
};
if (WIFSIGNALED(status))
return (struct process_status) { .kind = SIGNAL, .status = WTERMSIG(status) };
return (struct process_status) {
.kind = SIGNAL,
.status = WTERMSIG(status)
};
return (struct process_status) { .kind = STOPPED };
}

View file

@ -56,18 +56,24 @@
__attribute__((always_inline))
static inline void nothing() {}
#ifdef HAVE_FNMATCH
void disable_unmatching(struct criterion_test_set *set) {
FOREACH_SET(struct criterion_suite_set *s, set->suites) {
if ((s->suite.data && s->suite.data->disabled) || !s->tests)
continue;
FOREACH_SET(struct criterion_test *test, s->tests) {
if (fnmatch(criterion_options.pattern, test->data->identifier_, 0))
test->data->disabled = true;
}
}
}
#endif
IMPL_REPORT_HOOK(PRE_ALL)(struct criterion_test_set *set) {
#ifdef HAVE_FNMATCH
if (criterion_options.pattern) {
FOREACH_SET(struct criterion_suite_set *s, set->suites) {
if ((s->suite.data && s->suite.data->disabled) || !s->tests)
continue;
FOREACH_SET(struct criterion_test *test, s->tests) {
if (fnmatch(criterion_options.pattern, test->data->identifier_, 0))
test->data->disabled = true;
}
}
disable_unmatching(set);
}
#endif
log(pre_all, set);

View file

@ -38,6 +38,7 @@
IMPL_SECTION_LIMITS(struct criterion_test, criterion_tests);
IMPL_SECTION_LIMITS(struct criterion_suite, crit_suites);
// This is here to make the test suite section non-empty
TestSuite(default);
int cmp_suite(void *a, void *b) {
@ -95,7 +96,10 @@ typedef void (*f_test_run)(struct criterion_global_stats *,
struct criterion_test *,
struct criterion_suite *);
static void map_tests(struct criterion_test_set *set, struct criterion_global_stats *stats, f_test_run fun) {
static void map_tests(struct criterion_test_set *set,
struct criterion_global_stats *stats,
f_test_run fun) {
FOREACH_SET(struct criterion_suite_set *s, set->suites) {
if (!s->tests)
continue;
@ -122,7 +126,9 @@ static void map_tests(struct criterion_test_set *set, struct criterion_global_st
__attribute__ ((always_inline))
static inline void nothing() {}
static void run_test_child(struct criterion_test *test, struct criterion_suite *suite) {
static void run_test_child(struct criterion_test *test,
struct criterion_suite *suite) {
send_event(PRE_INIT, NULL, 0);
if (suite->data)
(suite->data->init ?: nothing)();
@ -144,7 +150,9 @@ static void run_test_child(struct criterion_test *test, struct criterion_suite *
}
__attribute__((always_inline))
static inline bool is_disabled(struct criterion_test *t, struct criterion_suite *s) {
static inline bool is_disabled(struct criterion_test *t,
struct criterion_suite *s) {
return t->data->disabled || (s->data && s->data->disabled);
}
@ -165,7 +173,10 @@ static void run_test(struct criterion_global_stats *stats,
smart struct criterion_test_stats *test_stats = test_stats_init(test);
if (is_disabled(test, suite)) {
stat_push_event(stats, suite_stats, test_stats, &(struct event) { .kind = PRE_TEST });
stat_push_event(stats,
suite_stats,
test_stats,
&(struct event) { .kind = PRE_TEST });
return;
}