X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=common-src%2Ftestutils.c;fp=common-src%2Ftestutils.c;h=a614b7c2b83c3aee9241e0d6c2d60c4ee806a39f;hb=2627875b7d18858bc1f9f7652811e4d8c15a23eb;hp=0000000000000000000000000000000000000000;hpb=fb2bd066c2f8b34addafe48d62550e3033a59431;p=debian%2Famanda diff --git a/common-src/testutils.c b/common-src/testutils.c new file mode 100644 index 0000000..a614b7c --- /dev/null +++ b/common-src/testutils.c @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2005-2008 Zmanda Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Contact information: Zmanda Inc., 465 S Mathlida Ave, Suite 300 + * Sunnyvale, CA 94086, USA, or: http://www.zmanda.com + */ + +#include "amanda.h" +#include "testutils.h" + +int tu_debugging_enabled = FALSE; + +static void +alarm_hdlr(int sig G_GNUC_UNUSED) +{ + fprintf(stderr, "-- TEST TIMED OUT --\n"); + exit(1); +} + +/* Call testfn in a forked process, such that any failures will trigger a + * test failure, but allow the other tests to proceed. + */ +static int +callinfork(TestUtilsTest *test, int ignore_timeouts) +{ + pid_t pid; + int success; + amwait_t status; + + switch (pid = fork()) { + case 0: /* child */ + /* kill the test after a bit */ + signal(SIGALRM, alarm_hdlr); + if (!ignore_timeouts) alarm(test->timeout); + + success = test->fn(); + exit(success? 0:1); + + case -1: + perror("fork"); + exit(1); + + default: /* parent */ + waitpid(pid, &status, 0); + if (status == 0) { + fprintf(stderr, " PASS %s\n", test->name); + } else { + fprintf(stderr, " FAIL %s\n", test->name); + } + return status == 0; + } +} + +static void +usage( + TestUtilsTest *tests) +{ + printf("USAGE: [-d] [-h] [testname [testname [..]]]\n" + "\n" + "\t-h: this message\n" + "\t-d: print debugging messages\n" + "\t-t: ignore timeouts\n" + "\n" + "If no test names are specified, all tests are run. Available tests:\n" + "\n"); + while (tests->fn) { + printf("\t%s\n", tests->name); + tests++; + } +} + +static void +ignore_debug_messages( + const gchar *log_domain G_GNUC_UNUSED, + GLogLevelFlags log_level G_GNUC_UNUSED, + const gchar *message G_GNUC_UNUSED, + gpointer user_data G_GNUC_UNUSED) +{ +} + +int +testutils_run_tests( + int argc, + char **argv, + TestUtilsTest *tests) +{ + TestUtilsTest *t; + int run_all = 1; + int success; + int ignore_timeouts = 0; + + /* first_parse the command line */ + while (argc > 1) { + if (strcmp(argv[1], "-d") == 0) { + tu_debugging_enabled = TRUE; + } else if (strcmp(argv[1], "-t") == 0) { + ignore_timeouts = TRUE; + } else if (strcmp(argv[1], "-h") == 0) { + usage(tests); + return 1; + } else { + int found = 0; + + for (t = tests; t->fn; t++) { + if (strcmp(argv[1], t->name) == 0) { + found = 1; + t->selected = 1; + break; + } + } + + if (!found) { + fprintf(stderr, "Test '%s' not found\n", argv[1]); + return 1; + } + + run_all = 0; + } + + argc--; argv++; + } + + /* Make sure g_critical and g_error will exit */ + g_log_set_always_fatal(G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL); + + /* and silently drop debug messages unless we're debugging */ + if (!tu_debugging_enabled) { + g_log_set_handler(NULL, G_LOG_LEVEL_DEBUG, ignore_debug_messages, NULL); + } + + /* Now actually run the tests */ + success = 1; + for (t = tests; t->fn; t++) { + if (run_all || t->selected) { + success = callinfork(t, ignore_timeouts) && success; + } + } + + return success? 0:1; +}