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