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