/* * libusb test library helper functions * Copyright © 2012 Toby Gray * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include "libusb_testlib.h" #if defined(PLATFORM_POSIX) #define NULL_PATH "/dev/null" #elif defined(PLATFORM_WINDOWS) #define NULL_PATH "nul" #endif /** * Converts a test result code into a human readable string. */ static const char *test_result_to_str(libusb_testlib_result result) { switch (result) { case TEST_STATUS_SUCCESS: return "Success"; case TEST_STATUS_FAILURE: return "Failure"; case TEST_STATUS_ERROR: return "Error"; case TEST_STATUS_SKIP: return "Skip"; default: return "Unknown"; } } static void print_usage(const char *progname) { printf("Usage: %s [-l] [-v] [ ...]\n", progname); printf(" -l List available tests\n"); printf(" -v Don't redirect STDERR before running tests\n"); printf(" -h Display this help and exit\n"); } void libusb_testlib_logf(const char *fmt, ...) { va_list va; va_start(va, fmt); vfprintf(stdout, fmt, va); va_end(va); fputc('\n', stdout); fflush(stdout); } int libusb_testlib_run_tests(int argc, char *argv[], const libusb_testlib_test *tests) { int run_count = 0; int idx = 0; int pass_count = 0; int fail_count = 0; int error_count = 0; int skip_count = 0; /* Setup default mode of operation */ char **test_names = NULL; int test_count = 0; bool list_tests = false; bool verbose = false; /* Parse command line options */ if (argc >= 2) { for (int j = 1; j < argc; j++) { const char *argstr = argv[j]; size_t arglen = strlen(argstr); if (argstr[0] == '-' || argstr[0] == '/') { if (arglen == 2) { switch (argstr[1]) { case 'l': list_tests = true; continue; case 'v': verbose = true; continue; case 'h': print_usage(argv[0]); return 0; } } fprintf(stderr, "Unknown option: '%s'\n", argstr); print_usage(argv[0]); return 1; } else { /* End of command line options, remaining must be list of tests to run */ test_names = argv + j; test_count = argc - j; break; } } } /* Validate command line options */ if (test_names && list_tests) { fprintf(stderr, "List of tests requested but test list provided\n"); print_usage(argv[0]); return 1; } /* Setup test log output */ if (!verbose) { if (!freopen(NULL_PATH, "w", stderr)) { printf("Failed to open null handle: %d\n", errno); return 1; } } /* Act on any options not related to running tests */ if (list_tests) { while (tests[idx].function) libusb_testlib_logf("%s", tests[idx++].name); return 0; } /* Run any requested tests */ while (tests[idx].function) { const libusb_testlib_test *test = &tests[idx++]; libusb_testlib_result test_result; if (test_count > 0) { /* Filtering tests to run, check if this is one of them */ int i; for (i = 0; i < test_count; i++) { if (!strcmp(test_names[i], test->name)) /* Matches a requested test name */ break; } if (i == test_count) { /* Failed to find a test match, so do the next loop iteration */ continue; } } libusb_testlib_logf("Starting test run: %s...", test->name); test_result = test->function(); libusb_testlib_logf("%s (%d)", test_result_to_str(test_result), test_result); switch (test_result) { case TEST_STATUS_SUCCESS: pass_count++; break; case TEST_STATUS_FAILURE: fail_count++; break; case TEST_STATUS_ERROR: error_count++; break; case TEST_STATUS_SKIP: skip_count++; break; } run_count++; } libusb_testlib_logf("---"); libusb_testlib_logf("Ran %d tests", run_count); libusb_testlib_logf("Passed %d tests", pass_count); libusb_testlib_logf("Failed %d tests", fail_count); libusb_testlib_logf("Error in %d tests", error_count); libusb_testlib_logf("Skipped %d tests", skip_count); return pass_count != run_count; }