775e3daf5549a2d38d6d4bc05b97639d8b6401a2
[openssl.git] / test / testutil / driver.c
1 /*
2  * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9
10 #include "../testutil.h"
11 #include "output.h"
12 #include "tu_local.h"
13
14 #include <string.h>
15 #include <assert.h>
16
17 #include "internal/nelem.h"
18 #include <openssl/bio.h>
19
20 #include "platform.h"            /* From libapps */
21
22 #ifdef _WIN32
23 # define strdup _strdup
24 #endif
25
26
27 /*
28  * Declares the structures needed to register each test case function.
29  */
30 typedef struct test_info {
31     const char *test_case_name;
32     int (*test_fn) (void);
33     int (*param_test_fn)(int idx);
34     int num;
35
36     /* flags */
37     int subtest:1;
38 } TEST_INFO;
39
40 static TEST_INFO all_tests[1024];
41 static int num_tests = 0;
42 static int show_list = 0;
43 static int single_test = -1;
44 static int single_iter = -1;
45 static int level = 0;
46 static int seed = 0;
47 /*
48  * A parameterised test runs a loop of test cases.
49  * |num_test_cases| counts the total number of test cases
50  * across all tests.
51  */
52 static int num_test_cases = 0;
53
54 static int process_shared_options(void);
55
56
57 void add_test(const char *test_case_name, int (*test_fn) (void))
58 {
59     assert(num_tests != OSSL_NELEM(all_tests));
60     all_tests[num_tests].test_case_name = test_case_name;
61     all_tests[num_tests].test_fn = test_fn;
62     all_tests[num_tests].num = -1;
63     ++num_tests;
64     ++num_test_cases;
65 }
66
67 void add_all_tests(const char *test_case_name, int(*test_fn)(int idx),
68                    int num, int subtest)
69 {
70     assert(num_tests != OSSL_NELEM(all_tests));
71     all_tests[num_tests].test_case_name = test_case_name;
72     all_tests[num_tests].param_test_fn = test_fn;
73     all_tests[num_tests].num = num;
74     all_tests[num_tests].subtest = subtest;
75     ++num_tests;
76     num_test_cases += num;
77 }
78
79 static int gcd(int a, int b)
80 {
81     while (b != 0) {
82         int t = b;
83         b = a % b;
84         a = t;
85     }
86     return a;
87 }
88
89 static void set_seed(int s)
90 {
91     seed = s;
92     if (seed <= 0)
93         seed = (int)time(NULL);
94     test_printf_stdout("RAND SEED %d\n", seed);
95     test_flush_stdout();
96     test_random_seed(seed);
97 }
98
99
100 int setup_test_framework(int argc, char *argv[])
101 {
102     char *test_seed = getenv("OPENSSL_TEST_RAND_ORDER");
103     char *TAP_levels = getenv("HARNESS_OSSL_LEVEL");
104
105     if (TAP_levels != NULL)
106         level = 4 * atoi(TAP_levels);
107     test_adjust_streams_tap_level(level);
108     if (test_seed != NULL)
109         set_seed(atoi(test_seed));
110
111 #if defined(OPENSSL_SYS_VMS) && defined(__DECC)
112     argv = copy_argv(&argc, argv);
113 #elif defined(_WIN32)
114     /*
115      * Replace argv[] with UTF-8 encoded strings.
116      */
117     win32_utf8argv(&argc, &argv);
118 #endif
119
120     if (!opt_init(argc, argv, test_get_options()))
121         return 0;
122     return 1;
123 }
124
125
126 /*
127  * This can only be called after setup() has run, since num_tests and
128  * all_tests[] are setup at this point
129  */
130 static int check_single_test_params(char *name, char *testname, char *itname)
131 {
132     if (name != NULL) {
133         int i;
134         for (i = 0; i < num_tests; ++i) {
135             if (strcmp(name, all_tests[i].test_case_name) == 0) {
136                 single_test = 1 + i;
137                 break;
138             }
139         }
140         if (i >= num_tests)
141             single_test = atoi(name);
142     }
143
144
145     /* if only iteration is specified, assume we want the first test */
146     if (single_test == -1 && single_iter != -1)
147         single_test = 1;
148
149     if (single_test != -1) {
150         if (single_test < 1 || single_test > num_tests) {
151             test_printf_stderr("Invalid -%s value "
152                                "(Value must be a valid test name OR a value between %d..%d)\n",
153                                testname, 1, num_tests);
154             return 0;
155         }
156     }
157     if (single_iter != -1) {
158         if (all_tests[single_test - 1].num == -1) {
159             test_printf_stderr("-%s option is not valid for test %d:%s\n",
160                                itname,
161                                single_test,
162                                all_tests[single_test - 1].test_case_name);
163             return 0;
164         } else if (single_iter < 1
165                    || single_iter > all_tests[single_test - 1].num) {
166             test_printf_stderr("Invalid -%s value for test %d:%s\t"
167                                "(Value must be in the range %d..%d)\n",
168                                itname, single_test,
169                                all_tests[single_test - 1].test_case_name,
170                                1, all_tests[single_test - 1].num);
171             return 0;
172         }
173     }
174     return 1;
175 }
176
177 static int process_shared_options(void)
178 {
179     OPTION_CHOICE_DEFAULT o;
180     int value;
181     int ret = -1;
182     char *flag_test = "";
183     char *flag_iter = "";
184     char *testname = NULL;
185
186     opt_begin();
187     while ((o = opt_next()) != OPT_EOF) {
188         switch (o) {
189         /* Ignore any test options at this level */
190         default:
191             break;
192         case OPT_ERR:
193             return ret;
194         case OPT_TEST_HELP:
195             opt_help(test_get_options());
196             return 0;
197         case OPT_TEST_LIST:
198             show_list = 1;
199             break;
200         case OPT_TEST_SINGLE:
201             flag_test = opt_flag();
202             testname = opt_arg();
203             break;
204         case OPT_TEST_ITERATION:
205             flag_iter = opt_flag();
206             if (!opt_int(opt_arg(), &single_iter))
207                 goto end;
208             break;
209         case OPT_TEST_INDENT:
210             if (!opt_int(opt_arg(), &value))
211                 goto end;
212             level = 4 * value;
213             test_adjust_streams_tap_level(level);
214             break;
215         case OPT_TEST_SEED:
216             if (!opt_int(opt_arg(), &value))
217                 goto end;
218             set_seed(value);
219             break;
220         }
221     }
222     if (!check_single_test_params(testname, flag_test, flag_iter))
223         goto end;
224     ret = 1;
225 end:
226     return ret;
227 }
228
229
230 int pulldown_test_framework(int ret)
231 {
232     set_test_title(NULL);
233     return ret;
234 }
235
236 static void finalize(int success)
237 {
238     if (success)
239         ERR_clear_error();
240     else
241         ERR_print_errors_cb(openssl_error_cb, NULL);
242 }
243
244 static char *test_title = NULL;
245
246 void set_test_title(const char *title)
247 {
248     free(test_title);
249     test_title = title == NULL ? NULL : strdup(title);
250 }
251
252 PRINTF_FORMAT(2, 3) static void test_verdict(int verdict,
253                                              const char *description, ...)
254 {
255     va_list ap;
256
257     test_flush_stdout();
258     test_flush_stderr();
259
260     test_printf_tapout("%s ", verdict != 0 ? "ok" : "not ok");
261     va_start(ap, description);
262     test_vprintf_tapout(description, ap);
263     va_end(ap);
264     if (verdict == TEST_SKIP_CODE)
265         test_printf_tapout(" # skipped");
266     test_printf_tapout("\n");
267     test_flush_stdout();
268 }
269
270 int run_tests(const char *test_prog_name)
271 {
272     int num_failed = 0;
273     int verdict = 1;
274     int ii, i, jj, j, jstep;
275     int permute[OSSL_NELEM(all_tests)];
276
277     i = process_shared_options();
278     if (i == 0)
279         return EXIT_SUCCESS;
280     if (i == -1)
281         return EXIT_FAILURE;
282
283     if (num_tests < 1) {
284         test_printf_tapout("1..0 # Skipped: %s\n", test_prog_name);
285     } else if (show_list == 0 && single_test == -1) {
286         if (level > 0)
287             test_printf_stdout("Subtest: %s\n", test_prog_name);
288         test_printf_tapout("1..%d\n", num_tests);
289     }
290
291     test_flush_stdout();
292
293     for (i = 0; i < num_tests; i++)
294         permute[i] = i;
295     if (seed != 0)
296         for (i = num_tests - 1; i >= 1; i--) {
297             j = test_random() % (1 + i);
298             ii = permute[j];
299             permute[j] = permute[i];
300             permute[i] = ii;
301         }
302
303     for (ii = 0; ii != num_tests; ++ii) {
304         i = permute[ii];
305
306         if (single_test != -1 && ((i+1) != single_test)) {
307             continue;
308         }
309         else if (show_list) {
310             if (all_tests[i].num != -1) {
311                 test_printf_tapout("%d - %s (%d..%d)\n", ii + 1,
312                                    all_tests[i].test_case_name, 1,
313                                    all_tests[i].num);
314             } else {
315                 test_printf_tapout("%d - %s\n", ii + 1,
316                                    all_tests[i].test_case_name);
317             }
318             test_flush_stdout();
319         } else if (all_tests[i].num == -1) {
320             set_test_title(all_tests[i].test_case_name);
321             verdict = all_tests[i].test_fn();
322             test_verdict(verdict, "%d - %s", ii + 1, test_title);
323             finalize(verdict != 0);
324             if (verdict == 0)
325                 num_failed++;
326         } else {
327             int num_failed_inner = 0;
328
329             verdict = TEST_SKIP_CODE;
330             level += 4;
331             test_adjust_streams_tap_level(level);
332             if (all_tests[i].subtest && single_iter == -1) {
333                 test_printf_stdout("Subtest: %s\n",
334                                    all_tests[i].test_case_name);
335                 test_printf_tapout("%d..%d\n", 1, all_tests[i].num);
336                 test_flush_stdout();
337             }
338
339             j = -1;
340             if (seed == 0 || all_tests[i].num < 3)
341                 jstep = 1;
342             else
343                 do
344                     jstep = test_random() % all_tests[i].num;
345                 while (jstep == 0 || gcd(all_tests[i].num, jstep) != 1);
346
347             for (jj = 0; jj < all_tests[i].num; jj++) {
348                 int v;
349
350                 j = (j + jstep) % all_tests[i].num;
351                 if (single_iter != -1 && ((jj + 1) != single_iter))
352                     continue;
353                 set_test_title(NULL);
354                 v = all_tests[i].param_test_fn(j);
355
356                 if (v == 0) {
357                     ++num_failed_inner;
358                     verdict = 0;
359                 } else if (v != TEST_SKIP_CODE && verdict != 0) {
360                     verdict = 1;
361                 }
362
363                 finalize(v != 0);
364
365                 if (all_tests[i].subtest) {
366                     if (test_title != NULL)
367                         test_verdict(v, "%d - %s", jj + 1, test_title);
368                     else
369                         test_verdict(v, "%d - iteration %d", jj + 1, j + 1);
370                 }
371             }
372
373             level -= 4;
374             test_adjust_streams_tap_level(level);
375             if (verdict == 0)
376                 ++num_failed;
377             test_verdict(verdict, "%d - %s", ii + 1,
378                          all_tests[i].test_case_name);
379         }
380     }
381     if (num_failed != 0)
382         return EXIT_FAILURE;
383     return EXIT_SUCCESS;
384 }
385
386 /*
387  * Glue an array of strings together and return it as an allocated string.
388  * Optionally return the whole length of this string in |out_len|
389  */
390 char *glue_strings(const char *list[], size_t *out_len)
391 {
392     size_t len = 0;
393     char *p, *ret;
394     int i;
395
396     for (i = 0; list[i] != NULL; i++)
397         len += strlen(list[i]);
398
399     if (out_len != NULL)
400         *out_len = len;
401
402     if (!TEST_ptr(ret = p = OPENSSL_malloc(len + 1)))
403         return NULL;
404
405     for (i = 0; list[i] != NULL; i++)
406         p += strlen(strcpy(p, list[i]));
407
408     return ret;
409 }
410
411 char *test_mk_file_path(const char *dir, const char *file)
412 {
413 # ifndef OPENSSL_SYS_VMS
414     const char *sep = "/";
415 # else
416     const char *sep = "";
417 # endif
418     size_t len = strlen(dir) + strlen(sep) + strlen(file) + 1;
419     char *full_file = OPENSSL_zalloc(len);
420
421     if (full_file != NULL) {
422         OPENSSL_strlcpy(full_file, dir, len);
423         OPENSSL_strlcat(full_file, sep, len);
424         OPENSSL_strlcat(full_file, file, len);
425     }
426
427     return full_file;
428 }