mirror of
https://github.com/cuberite/libevent.git
synced 2025-09-10 04:50:37 -04:00
Update to latest tinytest (911b4f0349377)
This commit is contained in:
parent
def3b83419
commit
ef7c4f7956
105
test/tinytest.c
105
test/tinytest.c
@ -67,6 +67,8 @@ static int opt_nofork = 0; /**< Suppress calls to fork() for debugging. */
|
|||||||
static int opt_verbosity = 1; /**< -==quiet,0==terse,1==normal,2==verbose */
|
static int opt_verbosity = 1; /**< -==quiet,0==terse,1==normal,2==verbose */
|
||||||
const char *verbosity_flag = "";
|
const char *verbosity_flag = "";
|
||||||
|
|
||||||
|
const struct testlist_alias_t *cfg_aliases=NULL;
|
||||||
|
|
||||||
enum outcome { SKIP=2, OK=1, FAIL=0 };
|
enum outcome { SKIP=2, OK=1, FAIL=0 };
|
||||||
static enum outcome cur_test_outcome = 0;
|
static enum outcome cur_test_outcome = 0;
|
||||||
const char *cur_test_prefix = NULL; /**< prefix of the current test group */
|
const char *cur_test_prefix = NULL; /**< prefix of the current test group */
|
||||||
@ -80,6 +82,7 @@ static char commandname[MAX_PATH+1];
|
|||||||
|
|
||||||
static void usage(struct testgroup_t *groups, int list_groups)
|
static void usage(struct testgroup_t *groups, int list_groups)
|
||||||
__attribute__((noreturn));
|
__attribute__((noreturn));
|
||||||
|
static int process_test_option(struct testgroup_t *groups, const char *test);
|
||||||
|
|
||||||
static enum outcome
|
static enum outcome
|
||||||
testcase_run_bare_(const struct testcase_t *testcase)
|
testcase_run_bare_(const struct testcase_t *testcase)
|
||||||
@ -214,10 +217,11 @@ testcase_run_one(const struct testgroup_t *group,
|
|||||||
{
|
{
|
||||||
enum outcome outcome;
|
enum outcome outcome;
|
||||||
|
|
||||||
if (testcase->flags & TT_SKIP) {
|
if (testcase->flags & (TT_SKIP|TT_OFF_BY_DEFAULT)) {
|
||||||
if (opt_verbosity>0)
|
if (opt_verbosity>0)
|
||||||
printf("%s%s: SKIPPED\n",
|
printf("%s%s: %s\n",
|
||||||
group->prefix, testcase->name);
|
group->prefix, testcase->name,
|
||||||
|
(testcase->flags & TT_SKIP) ? "SKIPPED" : "DISABLED");
|
||||||
++n_skipped;
|
++n_skipped;
|
||||||
return SKIP;
|
return SKIP;
|
||||||
}
|
}
|
||||||
@ -259,7 +263,7 @@ testcase_run_one(const struct testgroup_t *group,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
tinytest_set_flag_(struct testgroup_t *groups, const char *arg, unsigned long flag)
|
tinytest_set_flag_(struct testgroup_t *groups, const char *arg, int set, unsigned long flag)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
size_t length = LONGEST_TEST_NAME;
|
size_t length = LONGEST_TEST_NAME;
|
||||||
@ -269,12 +273,23 @@ tinytest_set_flag_(struct testgroup_t *groups, const char *arg, unsigned long fl
|
|||||||
length = strstr(arg,"..")-arg;
|
length = strstr(arg,"..")-arg;
|
||||||
for (i=0; groups[i].prefix; ++i) {
|
for (i=0; groups[i].prefix; ++i) {
|
||||||
for (j=0; groups[i].cases[j].name; ++j) {
|
for (j=0; groups[i].cases[j].name; ++j) {
|
||||||
|
struct testcase_t *testcase = &groups[i].cases[j];
|
||||||
snprintf(fullname, sizeof(fullname), "%s%s",
|
snprintf(fullname, sizeof(fullname), "%s%s",
|
||||||
groups[i].prefix, groups[i].cases[j].name);
|
groups[i].prefix, testcase->name);
|
||||||
if (!flag) /* Hack! */
|
if (!flag) { /* Hack! */
|
||||||
printf(" %s\n", fullname);
|
printf(" %s", fullname);
|
||||||
|
if (testcase->flags & TT_OFF_BY_DEFAULT)
|
||||||
|
puts(" (Off by default)");
|
||||||
|
else if (testcase->flags & TT_SKIP)
|
||||||
|
puts(" (DISABLED)");
|
||||||
|
else
|
||||||
|
puts("");
|
||||||
|
}
|
||||||
if (!strncmp(fullname, arg, length)) {
|
if (!strncmp(fullname, arg, length)) {
|
||||||
groups[i].cases[j].flags |= flag;
|
if (set)
|
||||||
|
testcase->flags |= flag;
|
||||||
|
else
|
||||||
|
testcase->flags &= ~flag;
|
||||||
++found;
|
++found;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -287,15 +302,69 @@ usage(struct testgroup_t *groups, int list_groups)
|
|||||||
{
|
{
|
||||||
puts("Options are: [--verbose|--quiet|--terse] [--no-fork]");
|
puts("Options are: [--verbose|--quiet|--terse] [--no-fork]");
|
||||||
puts(" Specify tests by name, or using a prefix ending with '..'");
|
puts(" Specify tests by name, or using a prefix ending with '..'");
|
||||||
puts(" To skip a test, list give its name prefixed with a colon.");
|
puts(" To skip a test, prefix its name with a colon.");
|
||||||
|
puts(" To enable a disabled test, prefix its name with a plus.");
|
||||||
puts(" Use --list-tests for a list of tests.");
|
puts(" Use --list-tests for a list of tests.");
|
||||||
if (list_groups) {
|
if (list_groups) {
|
||||||
puts("Known tests are:");
|
puts("Known tests are:");
|
||||||
tinytest_set_flag_(groups, "..", 0);
|
tinytest_set_flag_(groups, "..", 1, 0);
|
||||||
}
|
}
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
process_test_alias(struct testgroup_t *groups, const char *test)
|
||||||
|
{
|
||||||
|
int i, j, n, r;
|
||||||
|
for (i=0; cfg_aliases && cfg_aliases[i].name; ++i) {
|
||||||
|
if (!strcmp(cfg_aliases[i].name, test)) {
|
||||||
|
n = 0;
|
||||||
|
for (j = 0; cfg_aliases[i].tests[j]; ++j) {
|
||||||
|
r = process_test_option(groups, cfg_aliases[i].tests[j]);
|
||||||
|
if (r<0)
|
||||||
|
return -1;
|
||||||
|
n += r;
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("No such test alias as @%s!",test);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
process_test_option(struct testgroup_t *groups, const char *test)
|
||||||
|
{
|
||||||
|
int flag = TT_ENABLED_;
|
||||||
|
int n = 0;
|
||||||
|
if (test[0] == '@') {
|
||||||
|
return process_test_alias(groups, test + 1);
|
||||||
|
} else if (test[0] == ':') {
|
||||||
|
++test;
|
||||||
|
flag = TT_SKIP;
|
||||||
|
} else if (test[0] == '+') {
|
||||||
|
++test;
|
||||||
|
++n;
|
||||||
|
if (!tinytest_set_flag_(groups, test, 0, TT_OFF_BY_DEFAULT)) {
|
||||||
|
printf("No such test as %s!\n", test);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
++n;
|
||||||
|
}
|
||||||
|
if (!tinytest_set_flag_(groups, test, 1, flag)) {
|
||||||
|
printf("No such test as %s!\n", test);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tinytest_set_aliases(const struct testlist_alias_t *aliases)
|
||||||
|
{
|
||||||
|
cfg_aliases = aliases;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
tinytest_main(int c, const char **v, struct testgroup_t *groups)
|
tinytest_main(int c, const char **v, struct testgroup_t *groups)
|
||||||
{
|
{
|
||||||
@ -333,22 +402,14 @@ tinytest_main(int c, const char **v, struct testgroup_t *groups)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const char *test = v[i];
|
int r = process_test_option(groups, v[i]);
|
||||||
int flag = TT_ENABLED_;
|
if (r<0)
|
||||||
if (test[0] == ':') {
|
|
||||||
++test;
|
|
||||||
flag = TT_SKIP;
|
|
||||||
} else {
|
|
||||||
++n;
|
|
||||||
}
|
|
||||||
if (!tinytest_set_flag_(groups, test, flag)) {
|
|
||||||
printf("No such test as %s!\n", v[i]);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
n += r;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!n)
|
if (!n)
|
||||||
tinytest_set_flag_(groups, "..", TT_ENABLED_);
|
tinytest_set_flag_(groups, "..", 1, TT_ENABLED_);
|
||||||
|
|
||||||
setvbuf(stdout, NULL, _IONBF, 0);
|
setvbuf(stdout, NULL, _IONBF, 0);
|
||||||
|
|
||||||
|
@ -32,8 +32,10 @@
|
|||||||
#define TT_SKIP (1<<1)
|
#define TT_SKIP (1<<1)
|
||||||
/** Internal runtime flag for a test we've decided to run. */
|
/** Internal runtime flag for a test we've decided to run. */
|
||||||
#define TT_ENABLED_ (1<<2)
|
#define TT_ENABLED_ (1<<2)
|
||||||
|
/** Flag for a test that's off by default. */
|
||||||
|
#define TT_OFF_BY_DEFAULT (1<<3)
|
||||||
/** If you add your own flags, make them start at this point. */
|
/** If you add your own flags, make them start at this point. */
|
||||||
#define TT_FIRST_USER_FLAG (1<<3)
|
#define TT_FIRST_USER_FLAG (1<<4)
|
||||||
|
|
||||||
typedef void (*testcase_fn)(void *);
|
typedef void (*testcase_fn)(void *);
|
||||||
|
|
||||||
@ -64,6 +66,12 @@ struct testgroup_t {
|
|||||||
};
|
};
|
||||||
#define END_OF_GROUPS { NULL, NULL}
|
#define END_OF_GROUPS { NULL, NULL}
|
||||||
|
|
||||||
|
struct testlist_alias_t {
|
||||||
|
const char *name;
|
||||||
|
const char **tests;
|
||||||
|
};
|
||||||
|
#define END_OF_ALIASES { NULL, NULL }
|
||||||
|
|
||||||
/** Implementation: called from a test to indicate failure, before logging. */
|
/** Implementation: called from a test to indicate failure, before logging. */
|
||||||
void tinytest_set_test_failed_(void);
|
void tinytest_set_test_failed_(void);
|
||||||
/** Implementation: called from a test to indicate that we're skipping. */
|
/** Implementation: called from a test to indicate that we're skipping. */
|
||||||
@ -72,7 +80,7 @@ void tinytest_set_test_skipped_(void);
|
|||||||
int tinytest_get_verbosity_(void);
|
int tinytest_get_verbosity_(void);
|
||||||
/** Implementation: Set a flag on tests matching a name; returns number
|
/** Implementation: Set a flag on tests matching a name; returns number
|
||||||
* of tests that matched. */
|
* of tests that matched. */
|
||||||
int tinytest_set_flag_(struct testgroup_t *, const char *, unsigned long);
|
int tinytest_set_flag_(struct testgroup_t *, const char *, int set, unsigned long);
|
||||||
|
|
||||||
/** Set all tests in 'groups' matching the name 'named' to be skipped. */
|
/** Set all tests in 'groups' matching the name 'named' to be skipped. */
|
||||||
#define tinytest_skip(groups, named) \
|
#define tinytest_skip(groups, named) \
|
||||||
@ -80,6 +88,9 @@ int tinytest_set_flag_(struct testgroup_t *, const char *, unsigned long);
|
|||||||
|
|
||||||
/** Run a single testcase in a single group. */
|
/** Run a single testcase in a single group. */
|
||||||
int testcase_run_one(const struct testgroup_t *,const struct testcase_t *);
|
int testcase_run_one(const struct testgroup_t *,const struct testcase_t *);
|
||||||
|
|
||||||
|
void tinytest_set_aliases(const struct testlist_alias_t *aliases);
|
||||||
|
|
||||||
/** Run a set of testcases from an END_OF_GROUPS-terminated array of groups,
|
/** Run a set of testcases from an END_OF_GROUPS-terminated array of groups,
|
||||||
as selected from the command line. */
|
as selected from the command line. */
|
||||||
int tinytest_main(int argc, const char **argv, struct testgroup_t *groups);
|
int tinytest_main(int argc, const char **argv, struct testgroup_t *groups);
|
||||||
|
@ -35,6 +35,10 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <time.h>
|
||||||
|
#ifndef _WIN32
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/* ============================================================ */
|
/* ============================================================ */
|
||||||
|
|
||||||
@ -162,6 +166,27 @@ test_memcpy(void *ptr)
|
|||||||
free(mem);
|
free(mem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
test_timeout(void *ptr)
|
||||||
|
{
|
||||||
|
time_t t1, t2;
|
||||||
|
(void)ptr;
|
||||||
|
t1 = time(NULL);
|
||||||
|
#ifdef _WIN32
|
||||||
|
Sleep(5000);
|
||||||
|
#else
|
||||||
|
sleep(5);
|
||||||
|
#endif
|
||||||
|
t2 = time(NULL);
|
||||||
|
|
||||||
|
tt_int_op(t2-t1, >=, 4);
|
||||||
|
|
||||||
|
tt_int_op(t2-t1, <=, 6);
|
||||||
|
|
||||||
|
end:
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
/* ============================================================ */
|
/* ============================================================ */
|
||||||
|
|
||||||
/* Now we need to make sure that our tests get invoked. First, you take
|
/* Now we need to make sure that our tests get invoked. First, you take
|
||||||
@ -178,6 +203,10 @@ struct testcase_t demo_tests[] = {
|
|||||||
its environment. */
|
its environment. */
|
||||||
{ "memcpy", test_memcpy, TT_FORK, &data_buffer_setup },
|
{ "memcpy", test_memcpy, TT_FORK, &data_buffer_setup },
|
||||||
|
|
||||||
|
/* This flag is off-by-default, since it takes a while to run. You
|
||||||
|
* can enable it manually by passing +demo/timeout at the command line.*/
|
||||||
|
{ "timeout", test_timeout, TT_OFF_BY_DEFAULT },
|
||||||
|
|
||||||
/* The array has to end with END_OF_TESTCASES. */
|
/* The array has to end with END_OF_TESTCASES. */
|
||||||
END_OF_TESTCASES
|
END_OF_TESTCASES
|
||||||
};
|
};
|
||||||
@ -192,6 +221,18 @@ struct testgroup_t groups[] = {
|
|||||||
END_OF_GROUPS
|
END_OF_GROUPS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* We can also define test aliases. These can be used for types of tests that
|
||||||
|
* cut across groups. */
|
||||||
|
const char *alltests[] = { "+..", NULL };
|
||||||
|
const char *slowtests[] = { "+demo/timeout", NULL };
|
||||||
|
struct testlist_alias_t aliases[] = {
|
||||||
|
|
||||||
|
{ "ALL", alltests },
|
||||||
|
{ "SLOW", slowtests },
|
||||||
|
|
||||||
|
END_OF_ALIASES
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int c, const char **v)
|
main(int c, const char **v)
|
||||||
@ -211,5 +252,6 @@ main(int c, const char **v)
|
|||||||
"tinytest-demo" and "tinytest-demo .." mean the same thing.
|
"tinytest-demo" and "tinytest-demo .." mean the same thing.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
tinytest_set_aliases(aliases);
|
||||||
return tinytest_main(c, v, groups);
|
return tinytest_main(c, v, groups);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user