From f0bd83ea88788c595fa78ed5da4a91efd36eca48 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Thu, 9 Sep 2010 16:13:09 -0400 Subject: [PATCH] Bump to the latest version of tinytest This lets us do without libevent-specific code in tinytest.c, and lets us add a feature to skip individual tests from the command line. --- test/Makefile.am | 4 ++-- test/tinytest.c | 37 ++++++++++++++++++++++++++----------- test/tinytest_demo.c | 14 +++++++------- test/tinytest_local.h | 9 +++++++++ test/tinytest_macros.h | 38 ++++++++++++++++++++++++++++++-------- 5 files changed, 74 insertions(+), 28 deletions(-) create mode 100644 test/tinytest_local.h diff --git a/test/Makefile.am b/test/Makefile.am index 20692f6e..97682fb4 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -1,13 +1,13 @@ AUTOMAKE_OPTIONS = foreign -AM_CFLAGS = -I$(top_srcdir) -I$(top_srcdir)/compat -I$(top_srcdir)/include -I../include +AM_CFLAGS = -I$(top_srcdir) -I$(top_srcdir)/compat -I$(top_srcdir)/include -I../include -DTINYTEST_LOCAL EXTRA_DIST = regress.rpc regress.gen.h regress.gen.c test.sh noinst_PROGRAMS = test-init test-eof test-weof test-time regress \ bench bench_cascade bench_http bench_httpclient test-ratelim \ test-changelist -noinst_HEADERS = tinytest.h tinytest_macros.h regress.h +noinst_HEADERS = tinytest.h tinytest_macros.h regress.h tinytest_local.h TESTS = $(top_srcdir)/test/test.sh diff --git a/test/tinytest.c b/test/tinytest.c index 865dff63..11ffc2fe 100644 --- a/test/tinytest.c +++ b/test/tinytest.c @@ -29,7 +29,6 @@ #include #ifdef WIN32 -#include #include #else #include @@ -37,8 +36,13 @@ #include #endif -#include +#ifndef __GNUC__ +#define __attribute__(x) +#endif +#ifdef TINYTEST_LOCAL +#include "tinytest_local.h" +#endif #include "tinytest.h" #include "tinytest_macros.h" @@ -57,7 +61,7 @@ const char *verbosity_flag = ""; 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 */ -/** Name of the current test, if we haven't logged is yet. Used for --quiet */ +/** Name of the current test, if we haven't logged is yet. Used for --quiet */ const char *cur_test_name = NULL; #ifdef WIN32 @@ -65,6 +69,9 @@ const char *cur_test_name = NULL; static const char *commandname = NULL; #endif +static void usage(struct testgroup_t *groups, int list_groups) + __attribute__((noreturn)); + static enum outcome _testcase_run_bare(const struct testcase_t *testcase) { @@ -119,7 +126,7 @@ _testcase_run_forked(const struct testgroup_t *group, if (opt_verbosity>0) printf("[forking] "); - evutil_snprintf(buffer, sizeof(buffer), "%s --RUNNING-FORKED %s %s%s", + snprintf(buffer, sizeof(buffer), "%s --RUNNING-FORKED %s %s%s", commandname, verbosity_flag, group->prefix, testcase->name); memset(&si, 0, sizeof(si)); @@ -161,7 +168,7 @@ _testcase_run_forked(const struct testgroup_t *group, test_r = _testcase_run_bare(testcase); assert(0<=(int)test_r && (int)test_r<=2); b[0] = "NYS"[test_r]; - write_r = write(outcome_pipe[1], b, 1); + write_r = (int)write(outcome_pipe[1], b, 1); if (write_r != 1) { perror("write outcome to pipe"); exit(1); @@ -174,7 +181,7 @@ _testcase_run_forked(const struct testgroup_t *group, /* Close this now, so that if the other side closes it, * our read fails. */ close(outcome_pipe[1]); - r = read(outcome_pipe[0], b, 1); + r = (int)read(outcome_pipe[0], b, 1); if (r == 0) { printf("[Lost connection!] "); return 0; @@ -213,7 +220,7 @@ testcase_run_one(const struct testgroup_t *group, if ((testcase->flags & TT_FORK) && !(opt_forked||opt_nofork)) { outcome = _testcase_run_forked(group, testcase); } else { - outcome = _testcase_run_bare(testcase); + outcome = _testcase_run_bare(testcase); } if (outcome == OK) { @@ -241,14 +248,14 @@ int _tinytest_set_flag(struct testgroup_t *groups, const char *arg, unsigned long flag) { int i, j; - int length = LONGEST_TEST_NAME; + size_t length = LONGEST_TEST_NAME; char fullname[LONGEST_TEST_NAME]; int found=0; if (strstr(arg, "..")) length = strstr(arg,"..")-arg; for (i=0; groups[i].prefix; ++i) { for (j=0; groups[i].cases[j].name; ++j) { - evutil_snprintf(fullname, sizeof(fullname), "%s%s", + snprintf(fullname, sizeof(fullname), "%s%s", groups[i].prefix, groups[i].cases[j].name); if (!flag) /* Hack! */ printf(" %s\n", fullname); @@ -266,6 +273,7 @@ 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(" Use --list-tests for a list of tests."); if (list_groups) { puts("Known tests are:"); @@ -306,8 +314,15 @@ tinytest_main(int c, const char **v, struct testgroup_t *groups) return -1; } } else { - ++n; - if (!_tinytest_set_flag(groups, v[i], _TT_ENABLED)) { + 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]); return -1; } diff --git a/test/tinytest_demo.c b/test/tinytest_demo.c index 5fbccc76..8838459b 100644 --- a/test/tinytest_demo.c +++ b/test/tinytest_demo.c @@ -53,7 +53,7 @@ test_strcmp(void *data) } /* Pretty often, calling tt_abort_msg to indicate failure is more - heavy-weight than you want. Instead, just say: */ + heavy-weight than you want. Instead, just say: */ tt_assert(strcmp("testcase", "testcase") == 0); /* Occasionally, you don't want to stop the current testcase just @@ -86,12 +86,12 @@ test_strcmp(void *data) /* Now let's mess with setup and teardown functions! These are handy if you have a bunch of tests that all need a similar environment, and you - wnat to reconstruct that environment freshly for each one. */ + want to reconstruct that environment freshly for each one. */ /* First you declare a type to hold the environment info, and functions to set it up and tear it down. */ struct data_buffer { - /* We're just going to have couple of character buffer. Using + /* We're just going to have couple of character buffer. Using setup/teardown functions is probably overkill for this case. You could also do file descriptors, complicated handles, temporary @@ -164,7 +164,7 @@ test_memcpy(void *ptr) /* ============================================================ */ -/* 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 a bunch of related tests and put them into an array of struct testcase_t. */ @@ -183,7 +183,7 @@ struct testcase_t demo_tests[] = { }; /* Next, we make an array of testgroups. This is mandatory. Unlike more - heavy-duty testing frameworks, groups can't next. */ + heavy-duty testing frameworks, groups can't nest. */ struct testgroup_t groups[] = { /* Every group has a 'prefix', and an array of tests. That's it. */ @@ -196,8 +196,8 @@ struct testgroup_t groups[] = { int main(int c, const char **v) { - /* Finally, just call tinytest_main(). It lets you specify verbose - or quiet output with --verbose and --quiet. You can list + /* Finally, just call tinytest_main(). It lets you specify verbose + or quiet output with --verbose and --quiet. You can list specific tests: tinytest-demo demo/memcpy diff --git a/test/tinytest_local.h b/test/tinytest_local.h new file mode 100644 index 00000000..bc90d0e0 --- /dev/null +++ b/test/tinytest_local.h @@ -0,0 +1,9 @@ + +#ifdef WIN32 +#include +#endif + +#include +#include "util-internal.h" + +#define snprintf evutil_snprintf diff --git a/test/tinytest_macros.h b/test/tinytest_macros.h index 62210f50..a7fa64a8 100644 --- a/test/tinytest_macros.h +++ b/test/tinytest_macros.h @@ -45,7 +45,7 @@ TT_STMT_END #endif -/* Announce a failure. Args are parenthesized printf args. */ +/* Announce a failure. Args are parenthesized printf args. */ #define TT_GRIPE(args) TT_DECLARE("FAIL", args) /* Announce a non-failure if we're verbose. */ @@ -110,19 +110,40 @@ /* Assert b, and stop the test if b fails. */ #define tt_assert(b) tt_assert_msg((b), "assert("#b")") -#define tt_assert_test_type(a,b,str_test,type,test,fmt) \ +#define tt_assert_test_fmt_type(a,b,str_test,type,test,printf_type,printf_fmt, \ + setup_block,cleanup_block) \ TT_STMT_BEGIN \ type _val1 = (type)(a); \ type _val2 = (type)(b); \ - if (!(test)) { \ - TT_DIE(("assert(%s): "fmt" vs "fmt, \ - str_test, _val1, _val2)); \ - } else { \ - TT_BLATHER(("assert(%s): "fmt" vs "fmt, \ - str_test, _val1, _val2)); \ + int _tt_status = (test); \ + if (!_tt_status || _tinytest_get_verbosity()>1) { \ + printf_type _print; \ + printf_type _print1; \ + printf_type _print2; \ + type _value = _val1; \ + setup_block; \ + _print1 = _print; \ + _value = _val2; \ + setup_block; \ + _print2 = _print; \ + TT_DECLARE(_tt_status?" OK":"FAIL", \ + ("assert(%s): "printf_fmt" vs "printf_fmt, \ + str_test, _print1, _print2)); \ + _print = _print1; \ + cleanup_block; \ + _print = _print2; \ + cleanup_block; \ + if (!_tt_status) { \ + _tinytest_set_test_failed(); \ + TT_EXIT_TEST_FUNCTION; \ + } \ } \ TT_STMT_END +#define tt_assert_test_type(a,b,str_test,type,test,fmt) \ + tt_assert_test_fmt_type(a,b,str_test,type,test,type,fmt, \ + {_print=_value;},{}) + /* Helper: assert that a op b, when cast to type. Format the values with * printf format fmt on failure. */ #define tt_assert_op_type(a,op,b,type,fmt) \ @@ -134,6 +155,7 @@ #define tt_uint_op(a,op,b) \ tt_assert_test_type(a,b,#a" "#op" "#b,unsigned long, \ (_val1 op _val2),"%lu") + #define tt_ptr_op(a,op,b) \ tt_assert_test_type(a,b,#a" "#op" "#b,void*, \ (_val1 op _val2),"%p") -- 2.40.0