testlib.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. /*
  2. * libusb test library helper functions
  3. * Copyright © 2012 Toby Gray <toby.gray@realvnc.com>
  4. *
  5. * This library is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU Lesser General Public
  7. * License as published by the Free Software Foundation; either
  8. * version 2.1 of the License, or (at your option) any later version.
  9. *
  10. * This library is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * Lesser General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Lesser General Public
  16. * License along with this library; if not, write to the Free Software
  17. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  18. */
  19. #include <config.h>
  20. #include <errno.h>
  21. #include <stdarg.h>
  22. #include <stdbool.h>
  23. #include <stdio.h>
  24. #include <string.h>
  25. #include "libusb_testlib.h"
  26. #if defined(PLATFORM_POSIX)
  27. #define NULL_PATH "/dev/null"
  28. #elif defined(PLATFORM_WINDOWS)
  29. #define NULL_PATH "nul"
  30. #endif
  31. /**
  32. * Converts a test result code into a human readable string.
  33. */
  34. static const char *test_result_to_str(libusb_testlib_result result)
  35. {
  36. switch (result) {
  37. case TEST_STATUS_SUCCESS:
  38. return "Success";
  39. case TEST_STATUS_FAILURE:
  40. return "Failure";
  41. case TEST_STATUS_ERROR:
  42. return "Error";
  43. case TEST_STATUS_SKIP:
  44. return "Skip";
  45. default:
  46. return "Unknown";
  47. }
  48. }
  49. static void print_usage(const char *progname)
  50. {
  51. printf("Usage: %s [-l] [-v] [<test_name> ...]\n", progname);
  52. printf(" -l List available tests\n");
  53. printf(" -v Don't redirect STDERR before running tests\n");
  54. printf(" -h Display this help and exit\n");
  55. }
  56. void libusb_testlib_logf(const char *fmt, ...)
  57. {
  58. va_list va;
  59. va_start(va, fmt);
  60. vfprintf(stdout, fmt, va);
  61. va_end(va);
  62. fputc('\n', stdout);
  63. fflush(stdout);
  64. }
  65. int libusb_testlib_run_tests(int argc, char *argv[],
  66. const libusb_testlib_test *tests)
  67. {
  68. int run_count = 0;
  69. int idx = 0;
  70. int pass_count = 0;
  71. int fail_count = 0;
  72. int error_count = 0;
  73. int skip_count = 0;
  74. /* Setup default mode of operation */
  75. char **test_names = NULL;
  76. int test_count = 0;
  77. bool list_tests = false;
  78. bool verbose = false;
  79. /* Parse command line options */
  80. if (argc >= 2) {
  81. for (int j = 1; j < argc; j++) {
  82. const char *argstr = argv[j];
  83. size_t arglen = strlen(argstr);
  84. if (argstr[0] == '-' || argstr[0] == '/') {
  85. if (arglen == 2) {
  86. switch (argstr[1]) {
  87. case 'l':
  88. list_tests = true;
  89. continue;
  90. case 'v':
  91. verbose = true;
  92. continue;
  93. case 'h':
  94. print_usage(argv[0]);
  95. return 0;
  96. }
  97. }
  98. fprintf(stderr, "Unknown option: '%s'\n", argstr);
  99. print_usage(argv[0]);
  100. return 1;
  101. } else {
  102. /* End of command line options, remaining must be list of tests to run */
  103. test_names = argv + j;
  104. test_count = argc - j;
  105. break;
  106. }
  107. }
  108. }
  109. /* Validate command line options */
  110. if (test_names && list_tests) {
  111. fprintf(stderr, "List of tests requested but test list provided\n");
  112. print_usage(argv[0]);
  113. return 1;
  114. }
  115. /* Setup test log output */
  116. if (!verbose) {
  117. if (!freopen(NULL_PATH, "w", stderr)) {
  118. printf("Failed to open null handle: %d\n", errno);
  119. return 1;
  120. }
  121. }
  122. /* Act on any options not related to running tests */
  123. if (list_tests) {
  124. while (tests[idx].function)
  125. libusb_testlib_logf("%s", tests[idx++].name);
  126. return 0;
  127. }
  128. /* Run any requested tests */
  129. while (tests[idx].function) {
  130. const libusb_testlib_test *test = &tests[idx++];
  131. libusb_testlib_result test_result;
  132. if (test_count > 0) {
  133. /* Filtering tests to run, check if this is one of them */
  134. int i;
  135. for (i = 0; i < test_count; i++) {
  136. if (!strcmp(test_names[i], test->name))
  137. /* Matches a requested test name */
  138. break;
  139. }
  140. if (i == test_count) {
  141. /* Failed to find a test match, so do the next loop iteration */
  142. continue;
  143. }
  144. }
  145. libusb_testlib_logf("Starting test run: %s...", test->name);
  146. test_result = test->function();
  147. libusb_testlib_logf("%s (%d)", test_result_to_str(test_result), test_result);
  148. switch (test_result) {
  149. case TEST_STATUS_SUCCESS: pass_count++; break;
  150. case TEST_STATUS_FAILURE: fail_count++; break;
  151. case TEST_STATUS_ERROR: error_count++; break;
  152. case TEST_STATUS_SKIP: skip_count++; break;
  153. }
  154. run_count++;
  155. }
  156. libusb_testlib_logf("---");
  157. libusb_testlib_logf("Ran %d tests", run_count);
  158. libusb_testlib_logf("Passed %d tests", pass_count);
  159. libusb_testlib_logf("Failed %d tests", fail_count);
  160. libusb_testlib_logf("Error in %d tests", error_count);
  161. libusb_testlib_logf("Skipped %d tests", skip_count);
  162. return pass_count != run_count;
  163. }