Skip to content

Commit

Permalink
lib-test: enable naming of tests, such that only a subset is run
Browse files Browse the repository at this point in the history
How to use these will become clear in a subsequent patch. Even if you
don't want to name tests, the macros can reduce redundancy in the code,
as the list of test function prototypes and the list of test functions
to call become the same lists, expanded through 2 different macros.

Signed-off-by: Phil Carmody <phil@dovecot.fi>
  • Loading branch information
Phil Carmody authored and sirainen committed Sep 9, 2016
1 parent 8154226 commit 7d43648
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 0 deletions.
35 changes: 35 additions & 0 deletions src/lib-test/test-common.c
Expand Up @@ -365,6 +365,16 @@ static void test_run_funcs(void (*test_functions[])(void))
} T_END;
}
}
static void test_run_named_funcs(struct named_test tests[], const char *match)
{
unsigned int i;

for (i = 0; tests[i].func != NULL; i++) {
if (strstr(tests[i].name, match) != NULL) T_BEGIN {
tests[i].func();
} T_END;
}
}

static void run_one_fatal(enum fatal_test_state (*fatal_function)(int))
{
Expand Down Expand Up @@ -407,13 +417,29 @@ static void test_run_fatals(enum fatal_test_state (*fatal_functions[])(int index
} T_END;
}
}
static void test_run_named_fatals(const struct named_fatal fatals[], const char *match)
{
unsigned int i;

for (i = 0; fatals[i].func != NULL; i++) {
if (strstr(fatals[i].name, match) != NULL) T_BEGIN {
run_one_fatal(fatals[i].func);
} T_END;
}
}

int test_run(void (*test_functions[])(void))
{
test_init();
test_run_funcs(test_functions);
return test_deinit();
}
int test_run_named(struct named_test tests[], const char *match)
{
test_init();
test_run_named_funcs(tests, match);
return test_deinit();
}
int test_run_with_fatals(void (*test_functions[])(void),
enum fatal_test_state (*fatal_functions[])(int))
{
Expand All @@ -423,3 +449,12 @@ int test_run_with_fatals(void (*test_functions[])(void),
test_run_fatals(fatal_functions);
return test_deinit();
}
int test_run_named_with_fatals(const char *match, struct named_test tests[],
struct named_fatal fatals[])
{
test_init();
test_run_named_funcs(tests, match);
i_set_fatal_handler(test_fatal_handler);
test_run_named_fatals(fatals, match);
return test_deinit();
}
19 changes: 19 additions & 0 deletions src/lib-test/test-common.h
Expand Up @@ -45,13 +45,32 @@ void test_out_reason(const char *name, bool success, const char *reason)
ATTR_NULL(3);

int test_run(void (*test_functions[])(void));
struct named_test {
const char *name;
void (*func)(void);
};
int test_run_named(struct named_test tests[], const char *match);

#define TEST_DECL(x) void x(void);
#define TEST_NAMELESS(x) x, /* Were you to want to use the X trick but not name the tests */
#define TEST_NAMED(x) { .name = #x , .func = x },

enum fatal_test_state {
FATAL_TEST_FINISHED, /* no more test stages, don't call again */
FATAL_TEST_FAILURE, /* single stage has failed, continue */
FATAL_TEST_ABORT, /* something's gone horrifically wrong */
};
struct named_fatal {
const char *name;
enum fatal_test_state (*func)(int);
};
int test_run_with_fatals(void (*test_functions[])(void),
enum fatal_test_state (*fatal_functions[])(int));
int test_run_named_with_fatals(const char *match, struct named_test tests[],
struct named_fatal fatals[]);

#define FATAL_DECL(x) enum fatal_test_state x(int);
#define FATAL_NAMELESS(x) x, /* Were you to want to use the X trick but not name the tests */
#define FATAL_NAMED(x) { .name = #x , .func = x },

#endif

0 comments on commit 7d43648

Please sign in to comment.