Back to index

tor  0.2.3.19-rc
Classes | Defines | Typedefs | Functions
tinytest.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  testcase_setup_t
 Functions to initialize/teardown a structure for a testcase. More...
struct  testcase_t
 A single test-case that you can run. More...
struct  testgroup_t
 A group of tests that are selectable together. More...

Defines

#define TT_FORK   (1<<0)
 Flag for a test that needs to run in a subprocess.
#define TT_SKIP   (1<<1)
 Runtime flag for a test we've decided to skip.
#define TT_ENABLED_   (1<<2)
 Internal runtime flag for a test we've decided to run.
#define TT_FIRST_USER_FLAG   (1<<3)
 If you add your own flags, make them start at this point.
#define END_OF_TESTCASES   { NULL, NULL, 0, NULL, NULL }
#define END_OF_GROUPS   { NULL, NULL}
#define tinytest_skip(groups, named)   tinytest_set_flag_(groups, named, TT_SKIP)
 Set all tests in 'groups' matching the name 'named' to be skipped.

Typedefs

typedef void(* testcase_fn )(void *)

Functions

void tinytest_set_test_failed_ (void)
 Implementation: called from a test to indicate failure, before logging.
void tinytest_set_test_skipped_ (void)
 Implementation: called from a test to indicate that we're skipping.
int tinytest_get_verbosity_ (void)
 Implementation: return 0 for quiet, 1 for normal, 2 for loud.
int tinytest_set_flag_ (struct testgroup_t *, const char *, unsigned long)
 Implementation: Set a flag on tests matching a name; returns number of tests that matched.
int testcase_run_one (const struct testgroup_t *, const struct testcase_t *)
 Run a single testcase in a single group.
int tinytest_main (int argc, const char **argv, struct testgroup_t *groups)
 Run a set of testcases from an END_OF_GROUPS-terminated array of groups, as selected from the command line.

Class Documentation

struct testcase_t

A single test-case that you can run.

Definition at line 51 of file tinytest.h.

Collaboration diagram for testcase_t:
Class Members
unsigned long flags Bitfield of TT_* flags.
testcase_fn fn The function to run to implement this case.
const char * name An identifier for this case.
struct testcase_setup_t * setup Optional setup/cleanup fns.
void * setup_data Extra data usable by setup function.
struct testgroup_t

A group of tests that are selectable together.

Definition at line 61 of file tinytest.h.

Collaboration diagram for testgroup_t:
Class Members
struct testcase_t * cases
const char * prefix Prefix to prepend to testnames.

Define Documentation

#define END_OF_GROUPS   { NULL, NULL}

Definition at line 65 of file tinytest.h.

#define END_OF_TESTCASES   { NULL, NULL, 0, NULL, NULL }

Definition at line 58 of file tinytest.h.

#define tinytest_skip (   groups,
  named 
)    tinytest_set_flag_(groups, named, TT_SKIP)

Set all tests in 'groups' matching the name 'named' to be skipped.

Definition at line 78 of file tinytest.h.

#define TT_ENABLED_   (1<<2)

Internal runtime flag for a test we've decided to run.

Definition at line 34 of file tinytest.h.

#define TT_FIRST_USER_FLAG   (1<<3)

If you add your own flags, make them start at this point.

Definition at line 36 of file tinytest.h.

#define TT_FORK   (1<<0)

Flag for a test that needs to run in a subprocess.

Definition at line 30 of file tinytest.h.

#define TT_SKIP   (1<<1)

Runtime flag for a test we've decided to skip.

Definition at line 32 of file tinytest.h.


Typedef Documentation

typedef void(* testcase_fn)(void *)

Definition at line 38 of file tinytest.h.


Function Documentation

int testcase_run_one ( const struct testgroup_t ,
const struct testcase_t  
)

Run a single testcase in a single group.

Definition at line 200 of file tinytest.c.

{
       enum outcome outcome;

       if (testcase->flags & TT_SKIP) {
              if (opt_verbosity>0)
                     printf("%s%s: SKIPPED\n",
                         group->prefix, testcase->name);
              ++n_skipped;
              return SKIP;
       }

       if (opt_verbosity>0 && !opt_forked) {
              printf("%s%s: ", group->prefix, testcase->name);
       } else {
              if (opt_verbosity==0) printf(".");
              cur_test_prefix = group->prefix;
              cur_test_name = testcase->name;
       }

       if ((testcase->flags & TT_FORK) && !(opt_forked||opt_nofork)) {
              outcome = testcase_run_forked_(group, testcase);
       } else {
              outcome = testcase_run_bare_(testcase);
       }

       if (outcome == OK) {
              ++n_ok;
              if (opt_verbosity>0 && !opt_forked)
                     puts(opt_verbosity==1?"OK":"");
       } else if (outcome == SKIP) {
              ++n_skipped;
              if (opt_verbosity>0 && !opt_forked)
                     puts("SKIPPED");
       } else {
              ++n_bad;
              if (!opt_forked)
                     printf("\n  [%s FAILED]\n", testcase->name);
       }

       if (opt_forked) {
              exit(outcome==OK ? 0 : (outcome==SKIP?MAGIC_EXITCODE : 1));
              return 1; /* unreachable */
       } else {
              return (int)outcome;
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

int tinytest_get_verbosity_ ( void  )

Implementation: return 0 for quiet, 1 for normal, 2 for loud.

Definition at line 365 of file tinytest.c.

{
       return opt_verbosity;
}
int tinytest_main ( int  argc,
const char **  argv,
struct testgroup_t groups 
)

Run a set of testcases from an END_OF_GROUPS-terminated array of groups, as selected from the command line.

Definition at line 288 of file tinytest.c.

{
       int i, j, n=0;

#ifdef _WIN32
       const char *sp = strrchr(v[0], '.');
       const char *extension = "";
       if (!sp || stricmp(sp, ".exe"))
              extension = ".exe"; /* Add an exe so CreateProcess will work */
       snprintf(commandname, sizeof(commandname), "%s%s", v[0], extension);
       commandname[MAX_PATH]='\0';
#endif
       for (i=1; i<c; ++i) {
              if (v[i][0] == '-') {
                     if (!strcmp(v[i], "--RUNNING-FORKED")) {
                            opt_forked = 1;
                     } else if (!strcmp(v[i], "--no-fork")) {
                            opt_nofork = 1;
                     } else if (!strcmp(v[i], "--quiet")) {
                            opt_verbosity = -1;
                            verbosity_flag = "--quiet";
                     } else if (!strcmp(v[i], "--verbose")) {
                            opt_verbosity = 2;
                            verbosity_flag = "--verbose";
                     } else if (!strcmp(v[i], "--terse")) {
                            opt_verbosity = 0;
                            verbosity_flag = "--terse";
                     } else if (!strcmp(v[i], "--help")) {
                            usage(groups, 0);
                     } else if (!strcmp(v[i], "--list-tests")) {
                            usage(groups, 1);
                     } else {
                            printf("Unknown option %s.  Try --help\n",v[i]);
                            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]);
                            return -1;
                     }
              }
       }
       if (!n)
              tinytest_set_flag_(groups, "..", TT_ENABLED_);

       setvbuf(stdout, NULL, _IONBF, 0);

       ++in_tinytest_main;
       for (i=0; groups[i].prefix; ++i)
              for (j=0; groups[i].cases[j].name; ++j)
                     if (groups[i].cases[j].flags & TT_ENABLED_)
                            testcase_run_one(&groups[i],
                                           &groups[i].cases[j]);

       --in_tinytest_main;

       if (opt_verbosity==0)
              puts("");

       if (n_bad)
              printf("%d/%d TESTS FAILED. (%d skipped)\n", n_bad,
                     n_bad+n_ok,n_skipped);
       else if (opt_verbosity >= 1)
              printf("%d tests ok.  (%d skipped)\n", n_ok, n_skipped);

       return (n_bad == 0) ? 0 : 1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int tinytest_set_flag_ ( struct testgroup_t ,
const char *  ,
unsigned  long 
)

Implementation: Set a flag on tests matching a name; returns number of tests that matched.

Definition at line 250 of file tinytest.c.

{
       int i, j;
       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) {
                     snprintf(fullname, sizeof(fullname), "%s%s",
                             groups[i].prefix, groups[i].cases[j].name);
                     if (!flag) /* Hack! */
                            printf("    %s\n", fullname);
                     if (!strncmp(fullname, arg, length)) {
                            groups[i].cases[j].flags |= flag;
                            ++found;
                     }
              }
       }
       return found;
}

Here is the caller graph for this function:

void tinytest_set_test_failed_ ( void  )

Implementation: called from a test to indicate failure, before logging.

Definition at line 371 of file tinytest.c.

{
       if (opt_verbosity <= 0 && cur_test_name) {
              if (opt_verbosity==0) puts("");
              printf("%s%s: ", cur_test_prefix, cur_test_name);
              cur_test_name = NULL;
       }
       cur_test_outcome = 0;
}
void tinytest_set_test_skipped_ ( void  )

Implementation: called from a test to indicate that we're skipping.

Definition at line 382 of file tinytest.c.

{
       if (cur_test_outcome==OK)
              cur_test_outcome = SKIP;
}