3 * Copyright (C) 1997-2009 Net Integration Technologies, Inc.
4 * Licensed under the GNU Library General Public License, version 2.
5 * See the included file named LICENSE for license information.
23 #ifdef HAVE_VALGRIND_MEMCHECK_H
24 # include <valgrind/memcheck.h>
25 # include <valgrind/valgrind.h>
27 # define VALGRIND_COUNT_ERRORS 0
28 # define VALGRIND_DO_LEAK_CHECK
29 # define VALGRIND_COUNT_LEAKS(a,b,c,d) (a=b=c=d=0)
32 #define MAX_TEST_TIME 40 // max seconds for a single test to run
33 #define MAX_TOTAL_TIME 120*60 // max seconds for the entire suite to run
35 #define TEST_START_FORMAT "! %s:%-5d %-40s "
39 return (int)VALGRIND_COUNT_ERRORS;
44 int leaked = 0, dubious = 0, reachable = 0, suppressed = 0;
45 VALGRIND_DO_LEAK_CHECK;
46 VALGRIND_COUNT_LEAKS(leaked, dubious, reachable, suppressed);
47 printf("memleaks: sure:%d dubious:%d reachable:%d suppress:%d\n",
48 leaked, dubious, reachable, suppressed);
51 // dubious+reachable are normally non-zero because of globals...
52 // return leaked+dubious+reachable;
56 // Return 1 if no children are running or zombies, 0 if there are any running
57 // or zombie children.
58 // Will wait for any already-terminated children first.
59 // Passes if no rogue children were running, fails otherwise.
60 // If your test gets a failure in here, either you're not killing all your
61 // children, or you're not calling waitpid(2) on all of them.
62 static bool no_running_children()
67 // Acknowledge and complain about any zombie children
71 wait_result = waitpid(-1, &status, WNOHANG);
76 snprintf(buf, sizeof(buf) - 1, "%d", wait_result);
77 buf[sizeof(buf)-1] = '\0';
78 WVFAILEQ("Unclaimed dead child process", buf);
80 } while (wait_result > 0);
82 // There should not be any running children, so waitpid should return -1
83 WVPASSEQ(errno, ECHILD);
84 WVPASSEQ(wait_result, -1);
85 return (wait_result == -1 && errno == ECHILD);
91 WvTest *WvTest::first, *WvTest::last;
92 int WvTest::fails, WvTest::runs;
93 time_t WvTest::start_time;
94 bool WvTest::run_twice = false;
96 void WvTest::alarm_handler(int)
98 printf("\n! WvTest Current test took longer than %d seconds! FAILED\n",
105 static const char *pathstrip(const char *filename)
108 cptr = strrchr(filename, '/');
109 if (cptr) filename = cptr + 1;
110 cptr = strrchr(filename, '\\');
111 if (cptr) filename = cptr + 1;
116 WvTest::WvTest(const char *_descr, const char *_idstr, MainFunc *_main,
119 idstr(pathstrip(_idstr)),
132 static bool prefix_match(const char *s, const char * const *prefixes)
134 for (const char * const *prefix = prefixes; prefix && *prefix; prefix++)
136 if (!strncasecmp(s, *prefix, strlen(*prefix)))
143 int WvTest::run_all(const char * const *prefixes)
145 int old_valgrind_errs = 0, new_valgrind_errs;
146 int old_valgrind_leaks = 0, new_valgrind_leaks;
149 /* I should be doing something to do with SetTimer here,
150 * not sure exactly what just yet */
152 char *disable(getenv("WVTEST_DISABLE_TIMEOUT"));
153 if (disable != NULL && disable[0] != '\0' && disable[0] != '0')
154 signal(SIGALRM, SIG_IGN);
156 signal(SIGALRM, alarm_handler);
157 alarm(MAX_TEST_TIME);
159 start_time = time(NULL);
161 // make sure we can always start out in the same directory, so tests have
162 // access to their files. If a test uses chdir(), we want to be able to
165 if (!getcwd(wd, sizeof(wd)))
168 const char *slowstr1 = getenv("WVTEST_MIN_SLOWNESS");
169 const char *slowstr2 = getenv("WVTEST_MAX_SLOWNESS");
170 int min_slowness = 0, max_slowness = 65535;
171 if (slowstr1) min_slowness = atoi(slowstr1);
172 if (slowstr2) max_slowness = atoi(slowstr2);
177 char *parallel_str = getenv("WVTEST_PARALLEL");
179 run_twice = atoi(parallel_str) > 0;
182 // there are lots of fflush() calls in here because stupid win32 doesn't
183 // flush very often by itself.
185 for (WvTest *cur = first; cur; cur = cur->next)
187 if (cur->slowness <= max_slowness
188 && cur->slowness >= min_slowness
190 || prefix_match(cur->idstr, prefixes)
191 || prefix_match(cur->descr, prefixes)))
194 // set SIGPIPE back to default, helps catch tests which don't set
195 // this signal to SIG_IGN (which is almost always what you want)
197 signal(SIGPIPE, SIG_DFL);
202 // I see everything twice!
203 printf("Running test in parallel.\n");
208 printf("\nTesting \"%s\" in %s:\n", cur->descr, cur->idstr);
214 new_valgrind_errs = memerrs();
215 WVPASS(new_valgrind_errs == old_valgrind_errs);
216 old_valgrind_errs = new_valgrind_errs;
218 new_valgrind_leaks = memleaks();
219 WVPASS(new_valgrind_leaks == old_valgrind_leaks);
220 old_valgrind_leaks = new_valgrind_leaks;
231 // I see everything once!
232 printf("Child exiting.\n");
237 printf("Waiting for child to exit.\n");
239 while ((result = waitpid(child, NULL, 0)) == -1 &&
241 printf("Waitpid interrupted, retrying.\n");
246 WVPASS(no_running_children());
252 if (prefixes && *prefixes && **prefixes)
253 printf("WvTest: WARNING: only ran tests starting with "
254 "specifed prefix(es).\n");
256 printf("WvTest: ran all tests.\n");
257 printf("WvTest: %d test%s, %d failure%s.\n",
258 runs, runs==1 ? "" : "s",
259 fails, fails==1 ? "": "s");
266 // If we aren't running in parallel, we want to output the name of the test
267 // before we run it, so we know what happened if it crashes. If we are
268 // running in parallel, outputting this information in multiple printf()s
269 // can confuse parsers, so we want to output everything in one printf().
271 // This function gets called by both start() and check(). If we're not
272 // running in parallel, just print the data. If we're running in parallel,
273 // and we're starting a test, save a copy of the file/line/description until
274 // the test is done and we can output it all at once.
276 // Yes, this is probably the worst API of all time.
277 void WvTest::print_result(bool start, const char *_file, int _line,
278 const char *_condstr, bool result)
281 static char *condstr;
290 file = strdup(pathstrip(_file));
291 condstr = strdup(_condstr);
294 for (char *cptr = condstr; *cptr; cptr++)
296 if (!isprint((unsigned char)*cptr))
301 const char *result_str = result ? "ok\n" : "FAILED\n";
305 printf(TEST_START_FORMAT "%s", file, line, condstr, result_str);
310 printf(TEST_START_FORMAT, file, line, condstr);
312 printf("%s", result_str);
322 file = condstr = NULL;
327 void WvTest::start(const char *file, int line, const char *condstr)
329 // Either print the file, line, and condstr, or save them for later.
330 print_result(true, file, line, condstr, 0);
334 void WvTest::check(bool cond)
337 alarm(MAX_TEST_TIME); // restart per-test timeout
339 if (!start_time) start_time = time(NULL);
341 if (time(NULL) - start_time > MAX_TOTAL_TIME)
343 printf("\n! WvTest Total run time exceeded %d seconds! FAILED\n",
351 print_result(false, NULL, 0, NULL, cond);
357 if (getenv("WVTEST_DIE_FAST"))
363 bool WvTest::start_check_eq(const char *file, int line,
364 const char *a, const char *b, bool expect_pass)
369 size_t len = strlen(a) + strlen(b) + 8 + 1;
370 char *str = new char[len];
371 sprintf(str, "[%s] %s [%s]", a, expect_pass ? "==" : "!=", b);
373 start(file, line, str);
376 bool cond = !strcmp(a, b);
385 bool WvTest::start_check_eq(const char *file, int line,
386 const std::string &a, const std::string &b,
389 return start_check_eq(file, line, a.c_str(), b.c_str(), expect_pass);
393 bool WvTest::start_check_eq(const char *file, int line,
394 int a, int b, bool expect_pass)
396 size_t len = 128 + 128 + 8 + 1;
397 char *str = new char[len];
398 sprintf(str, "%d %s %d", a, expect_pass ? "==" : "!=", b);
400 start(file, line, str);
403 bool cond = (a == b);
412 bool WvTest::start_check_lt(const char *file, int line,
413 const char *a, const char *b)
418 size_t len = strlen(a) + strlen(b) + 8 + 1;
419 char *str = new char[len];
420 sprintf(str, "[%s] < [%s]", a, b);
422 start(file, line, str);
425 bool cond = strcmp(a, b) < 0;
431 bool WvTest::start_check_lt(const char *file, int line, int a, int b)
433 size_t len = 128 + 128 + 8 + 1;
434 char *str = new char[len];
435 sprintf(str, "%d < %d", a, b);
437 start(file, line, str);