Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Update to latest tinytest (911b4f0349377)

  • Loading branch information...
commit ef7c4f7956bc5237f51b58dcd9fdf556570cdd67 1 parent def3b83
Nick Mathewson authored
Showing with 138 additions and 24 deletions.
  1. +83 −22 test/tinytest.c
  2. +13 −2 test/tinytest.h
  3. +42 −0 test/tinytest_demo.c
105 test/tinytest.c
View
@@ -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 */
const char *verbosity_flag = "";
+const struct testlist_alias_t *cfg_aliases=NULL;
+
enum outcome { SKIP=2, OK=1, FAIL=0 };
static enum outcome cur_test_outcome = 0;
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)
__attribute__((noreturn));
+static int process_test_option(struct testgroup_t *groups, const char *test);
static enum outcome
testcase_run_bare_(const struct testcase_t *testcase)
@@ -214,10 +217,11 @@ testcase_run_one(const struct testgroup_t *group,
{
enum outcome outcome;
- if (testcase->flags & TT_SKIP) {
+ if (testcase->flags & (TT_SKIP|TT_OFF_BY_DEFAULT)) {
if (opt_verbosity>0)
- printf("%s%s: SKIPPED\n",
- group->prefix, testcase->name);
+ printf("%s%s: %s\n",
+ group->prefix, testcase->name,
+ (testcase->flags & TT_SKIP) ? "SKIPPED" : "DISABLED");
++n_skipped;
return SKIP;
}
@@ -259,7 +263,7 @@ testcase_run_one(const struct testgroup_t *group,
}
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;
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;
for (i=0; groups[i].prefix; ++i) {
for (j=0; groups[i].cases[j].name; ++j) {
+ struct testcase_t *testcase = &groups[i].cases[j];
snprintf(fullname, sizeof(fullname), "%s%s",
- groups[i].prefix, groups[i].cases[j].name);
- if (!flag) /* Hack! */
- printf(" %s\n", fullname);
+ groups[i].prefix, testcase->name);
+ if (!flag) { /* Hack! */
+ 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)) {
- groups[i].cases[j].flags |= flag;
+ if (set)
+ testcase->flags |= flag;
+ else
+ testcase->flags &= ~flag;
++found;
}
}
@@ -287,15 +302,69 @@ usage(struct testgroup_t *groups, int list_groups)
{
puts("Options are: [--verbose|--quiet|--terse] [--no-fork]");
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.");
if (list_groups) {
puts("Known tests are:");
- tinytest_set_flag_(groups, "..", 0);
+ tinytest_set_flag_(groups, "..", 1, 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
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;
}
} else {
- const char *test = v[i];
- int flag = TT_ENABLED_;
- 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]);
+ int r = process_test_option(groups, v[i]);
+ if (r<0)
return -1;
- }
+ n += r;
}
}
if (!n)
- tinytest_set_flag_(groups, "..", TT_ENABLED_);
+ tinytest_set_flag_(groups, "..", 1, TT_ENABLED_);
setvbuf(stdout, NULL, _IONBF, 0);
15 test/tinytest.h
View
@@ -32,8 +32,10 @@
#define TT_SKIP (1<<1)
/** Internal runtime flag for a test we've decided to run. */
#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. */
-#define TT_FIRST_USER_FLAG (1<<3)
+#define TT_FIRST_USER_FLAG (1<<4)
typedef void (*testcase_fn)(void *);
@@ -64,6 +66,12 @@ struct testgroup_t {
};
#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. */
void tinytest_set_test_failed_(void);
/** 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);
/** Implementation: Set a flag on tests matching a name; returns number
* 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. */
#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. */
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,
as selected from the command line. */
int tinytest_main(int argc, const char **argv, struct testgroup_t *groups);
42 test/tinytest_demo.c
View
@@ -35,6 +35,10 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
+#include <time.h>
+#ifndef _WIN32
+#include <unistd.h>
+#endif
/* ============================================================ */
@@ -162,6 +166,27 @@ test_memcpy(void *ptr)
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
@@ -178,6 +203,10 @@ struct testcase_t demo_tests[] = {
its environment. */
{ "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. */
END_OF_TESTCASES
};
@@ -192,6 +221,18 @@ struct testgroup_t 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
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_set_aliases(aliases);
return tinytest_main(c, v, groups);
}
Please sign in to comment.
Something went wrong with that request. Please try again.