The current code for calculating the timeout in darwin_reenumerate_device_timeout...
[platform/upstream/libusb.git] / tests / testlib.c
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
20 #include <config.h>
21
22 #include <errno.h>
23 #include <stdarg.h>
24 #include <stdbool.h>
25 #include <stdio.h>
26 #include <string.h>
27
28 #include "libusb_testlib.h"
29
30 #if defined(PLATFORM_POSIX)
31 #define NULL_PATH "/dev/null"
32 #elif defined(PLATFORM_WINDOWS)
33 #define NULL_PATH "nul"
34 #endif
35
36 /**
37  * Converts a test result code into a human readable string.
38  */
39 static const char *test_result_to_str(libusb_testlib_result result)
40 {
41         switch (result) {
42         case TEST_STATUS_SUCCESS:
43                 return "Success";
44         case TEST_STATUS_FAILURE:
45                 return "Failure";
46         case TEST_STATUS_ERROR:
47                 return "Error";
48         case TEST_STATUS_SKIP:
49                 return "Skip";
50         default:
51                 return "Unknown";
52         }
53 }
54
55 static void print_usage(const char *progname)
56 {
57         printf("Usage: %s [-l] [-v] [<test_name> ...]\n", progname);
58         printf("   -l   List available tests\n");
59         printf("   -v   Don't redirect STDERR before running tests\n");
60         printf("   -h   Display this help and exit\n");
61 }
62
63 void libusb_testlib_logf(const char *fmt, ...)
64 {
65         va_list va;
66
67         va_start(va, fmt);
68         vfprintf(stdout, fmt, va);
69         va_end(va);
70         fputc('\n', stdout);
71         fflush(stdout);
72 }
73
74 int libusb_testlib_run_tests(int argc, char *argv[],
75         const libusb_testlib_test *tests)
76 {
77         int run_count = 0;
78         int idx = 0;
79         int pass_count = 0;
80         int fail_count = 0;
81         int error_count = 0;
82         int skip_count = 0;
83
84         /* Setup default mode of operation */
85         char **test_names = NULL;
86         int test_count = 0;
87         bool list_tests = false;
88         bool verbose = false;
89
90         /* Parse command line options */
91         if (argc >= 2) {
92                 for (int j = 1; j < argc; j++) {
93                         const char *argstr = argv[j];
94                         size_t arglen = strlen(argstr);
95
96                         if (argstr[0] == '-' || argstr[0] == '/') {
97                                 if (arglen == 2) {
98                                         switch (argstr[1]) {
99                                         case 'l':
100                                                 list_tests = true;
101                                                 continue;
102                                         case 'v':
103                                                 verbose = true;
104                                                 continue;
105                                         case 'h':
106                                                 print_usage(argv[0]);
107                                                 return 0;
108                                         }
109                                 }
110
111                                 fprintf(stderr, "Unknown option: '%s'\n", argstr);
112                                 print_usage(argv[0]);
113                                 return 1;
114                         } else {
115                                 /* End of command line options, remaining must be list of tests to run */
116                                 test_names = argv + j;
117                                 test_count = argc - j;
118                                 break;
119                         }
120                 }
121         }
122
123         /* Validate command line options */
124         if (test_names && list_tests) {
125                 fprintf(stderr, "List of tests requested but test list provided\n");
126                 print_usage(argv[0]);
127                 return 1;
128         }
129
130         /* Setup test log output */
131         if (!verbose) {
132                 if (!freopen(NULL_PATH, "w", stderr)) {
133                         printf("Failed to open null handle: %d\n", errno);
134                         return 1;
135                 }
136         }
137
138         /* Act on any options not related to running tests */
139         if (list_tests) {
140                 while (tests[idx].function)
141                         libusb_testlib_logf("%s", tests[idx++].name);
142                 return 0;
143         }
144
145         /* Run any requested tests */
146         while (tests[idx].function) {
147                 const libusb_testlib_test *test = &tests[idx++];
148                 libusb_testlib_result test_result;
149
150                 if (test_count > 0) {
151                         /* Filtering tests to run, check if this is one of them */
152                         int i;
153
154                         for (i = 0; i < test_count; i++) {
155                                 if (!strcmp(test_names[i], test->name))
156                                         /* Matches a requested test name */
157                                         break;
158                         }
159                         if (i == test_count) {
160                                 /* Failed to find a test match, so do the next loop iteration */
161                                 continue;
162                         }
163                 }
164                 libusb_testlib_logf("Starting test run: %s...", test->name);
165                 test_result = test->function();
166                 libusb_testlib_logf("%s (%d)", test_result_to_str(test_result), test_result);
167                 switch (test_result) {
168                 case TEST_STATUS_SUCCESS: pass_count++; break;
169                 case TEST_STATUS_FAILURE: fail_count++; break;
170                 case TEST_STATUS_ERROR: error_count++; break;
171                 case TEST_STATUS_SKIP: skip_count++; break;
172                 }
173                 run_count++;
174         }
175
176         libusb_testlib_logf("---");
177         libusb_testlib_logf("Ran %d tests", run_count);
178         libusb_testlib_logf("Passed %d tests", pass_count);
179         libusb_testlib_logf("Failed %d tests", fail_count);
180         libusb_testlib_logf("Error in %d tests", error_count);
181         libusb_testlib_logf("Skipped %d tests", skip_count);
182
183         return pass_count != run_count;
184 }