int TF_Test::run(const char * const *prefixes, const char *suite) { int old_valgrind_errs = 0, new_valgrind_errs; int old_valgrind_leaks = 0, new_valgrind_leaks; signal(SIGALRM, alarm_handler); // signal(SIGALRM, SIG_IGN); alarm(MAX_TEST_TIME); start_time = time(NULL); fails = runs = 0; for (TF_Test *cur = first; cur; cur = cur->next) { if ((!prefixes || prefix_match(cur->idstr, prefixes) || prefix_match(cur->descr, prefixes)) && (!suite || strcmp(cur->m_suite, suite) == 0)) { printf("%s: Testing \"%s\" in %s:\n", cur->m_suite, cur->descr, cur->idstr); cur->main(); new_valgrind_errs = memerrs(); TFPASS(new_valgrind_errs == old_valgrind_errs); old_valgrind_errs = new_valgrind_errs; new_valgrind_leaks = memleaks(); TFPASS(new_valgrind_leaks == old_valgrind_leaks); old_valgrind_leaks = new_valgrind_leaks; printf("\n"); } } if (prefixes && *prefixes) printf("TF_Test: WARNING: only ran tests starting with " "specifed prefix(es).\n"); else if (suite) printf("TF_Test: WARNING: only ran suite %s\n", suite); else printf("TF_Test: ran all tests.\n"); printf("TF_Test: %d test%s, %d failure%s.\n", runs, runs==1 ? "" : "s", fails, fails==1 ? "": "s"); return fails != 0; }
int wvtest_run_all(char * const *prefixes) { int old_valgrind_errs = 0, new_valgrind_errs; int old_valgrind_leaks = 0, new_valgrind_leaks; #ifdef _WIN32 /* I should be doing something to do with SetTimer here, * not sure exactly what just yet */ #else char *disable = getenv("WVTEST_DISABLE_TIMEOUT"); if (disable != NULL && disable[0] != '\0' && disable[0] != '0') signal(SIGALRM, SIG_IGN); else signal(SIGALRM, alarm_handler); alarm(MAX_TEST_TIME); #endif start_time = time(NULL); // make sure we can always start out in the same directory, so tests have // access to their files. If a test uses chdir(), we want to be able to // reverse it. char wd[1024]; if (!getcwd(wd, sizeof(wd))) strcpy(wd, "."); const char *slowstr1 = getenv("WVTEST_MIN_SLOWNESS"); const char *slowstr2 = getenv("WVTEST_MAX_SLOWNESS"); int min_slowness = 0, max_slowness = 65535; if (slowstr1) min_slowness = atoi(slowstr1); if (slowstr2) max_slowness = atoi(slowstr2); #ifdef _WIN32 run_twice = false; #else char *parallel_str = getenv("WVTEST_PARALLEL"); if (parallel_str) run_twice = atoi(parallel_str) > 0; #endif // there are lots of fflush() calls in here because stupid win32 doesn't // flush very often by itself. fails = runs = 0; struct WvTest *cur; for (cur = wvtest_first; cur != NULL; cur = cur->next) { if (cur->slowness <= max_slowness && cur->slowness >= min_slowness && (!prefixes || prefix_match(cur->idstr, prefixes) || prefix_match(cur->descr, prefixes))) { #ifndef _WIN32 // set SIGPIPE back to default, helps catch tests which don't set // this signal to SIG_IGN (which is almost always what you want) // on startup signal(SIGPIPE, SIG_DFL); pid_t child = 0; if (run_twice) { // I see everything twice! printf("Running test in parallel.\n"); child = fork(); } #endif printf("\nTesting \"%s\" in %s:\n", cur->descr, cur->idstr); fflush(stdout); cur->main(); chdir(wd); new_valgrind_errs = memerrs(); WVPASS(new_valgrind_errs == old_valgrind_errs); old_valgrind_errs = new_valgrind_errs; new_valgrind_leaks = memleaks(); WVPASS(new_valgrind_leaks == old_valgrind_leaks); old_valgrind_leaks = new_valgrind_leaks; fflush(stderr); printf("\n"); fflush(stdout); #ifndef _WIN32 if (run_twice) { if (!child) { // I see everything once! printf("Child exiting.\n"); _exit(0); } else { printf("Waiting for child to exit.\n"); int result; while ((result = waitpid(child, NULL, 0)) == -1 && errno == EINTR) printf("Waitpid interrupted, retrying.\n"); } } #endif WVPASS(no_running_children()); } } WVPASS(runs > 0); if (prefixes && *prefixes && **prefixes) printf("WvTest: WARNING: only ran tests starting with " "specifed prefix(es).\n"); else printf("WvTest: ran all tests.\n"); printf("WvTest: %d test%s, %d failure%s.\n", runs, runs==1 ? "" : "s", fails, fails==1 ? "": "s"); fflush(stdout); return fails != 0; }