xref: /openbsd-src/regress/usr.bin/ssh/unittests/test_helper/test_helper.c (revision e5157e49389faebcb42b7237d55fbf096d9c2523)
1 /*	$OpenBSD: test_helper.c,v 1.2 2014/05/02 09:41:32 andre Exp $	*/
2 /*
3  * Copyright (c) 2011 Damien Miller <djm@mindrot.org>
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 /* Utility functions/framework for regress tests */
19 
20 #include <sys/types.h>
21 #include <sys/param.h>
22 
23 #include <fcntl.h>
24 #include <stdio.h>
25 #include <stdint.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <assert.h>
29 #include <unistd.h>
30 
31 #include <openssl/bn.h>
32 
33 #include <vis.h>
34 
35 #include "test_helper.h"
36 
37 #define TEST_CHECK_INT(r, pred) do {		\
38 		switch (pred) {			\
39 		case TEST_EQ:			\
40 			if (r == 0)		\
41 				return;		\
42 			break;			\
43 		case TEST_NE:			\
44 			if (r != 0)		\
45 				return;		\
46 			break;			\
47 		case TEST_LT:			\
48 			if (r < 0)		\
49 				return;		\
50 			break;			\
51 		case TEST_LE:			\
52 			if (r <= 0)		\
53 				return;		\
54 			break;			\
55 		case TEST_GT:			\
56 			if (r > 0)		\
57 				return;		\
58 			break;			\
59 		case TEST_GE:			\
60 			if (r >= 0)		\
61 				return;		\
62 			break;			\
63 		default:			\
64 			abort();		\
65 		}				\
66 	} while (0)
67 
68 #define TEST_CHECK(x1, x2, pred) do {		\
69 		switch (pred) {			\
70 		case TEST_EQ:			\
71 			if (x1 == x2)		\
72 				return;		\
73 			break;			\
74 		case TEST_NE:			\
75 			if (x1 != x2)		\
76 				return;		\
77 			break;			\
78 		case TEST_LT:			\
79 			if (x1 < x2)		\
80 				return;		\
81 			break;			\
82 		case TEST_LE:			\
83 			if (x1 <= x2)		\
84 				return;		\
85 			break;			\
86 		case TEST_GT:			\
87 			if (x1 > x2)		\
88 				return;		\
89 			break;			\
90 		case TEST_GE:			\
91 			if (x1 >= x2)		\
92 				return;		\
93 			break;			\
94 		default:			\
95 			abort();		\
96 		}				\
97 	} while (0)
98 
99 extern char *__progname;
100 
101 static int verbose_mode = 0;
102 static int quiet_mode = 0;
103 static char *active_test_name = NULL;
104 static u_int test_number = 0;
105 static test_onerror_func_t *test_onerror = NULL;
106 static void *onerror_ctx = NULL;
107 static const char *data_dir = NULL;
108 
109 int
110 main(int argc, char **argv)
111 {
112 	int ch;
113 
114 	while ((ch = getopt(argc, argv, "vqd:")) != -1) {
115 		switch (ch) {
116 		case 'd':
117 			data_dir = optarg;
118 			break;
119 		case 'q':
120 			verbose_mode = 0;
121 			quiet_mode = 1;
122 			break;
123 		case 'v':
124 			verbose_mode = 1;
125 			quiet_mode = 0;
126 			break;
127 		default:
128 			fprintf(stderr, "Unrecognised command line option\n");
129 			fprintf(stderr, "Usage: %s [-v]\n", __progname);
130 			exit(1);
131 		}
132 	}
133 	setvbuf(stdout, NULL, _IONBF, 0);
134 	if (!quiet_mode)
135 		printf("%s: ", __progname);
136 	if (verbose_mode)
137 		printf("\n");
138 
139 	tests();
140 
141 	if (!quiet_mode)
142 		printf(" %u tests ok\n", test_number);
143 	return 0;
144 }
145 
146 const char *
147 test_data_file(const char *name)
148 {
149 	static char ret[PATH_MAX];
150 
151 	if (data_dir != NULL)
152 		snprintf(ret, sizeof(ret), "%s/%s", data_dir, name);
153 	else
154 		strlcpy(ret, name, sizeof(ret));
155 	if (access(ret, F_OK) != 0) {
156 		fprintf(stderr, "Cannot access data file %s: %s\n",
157 		    ret, strerror(errno));
158 		exit(1);
159 	}
160 	return ret;
161 }
162 
163 void
164 test_start(const char *n)
165 {
166 	assert(active_test_name == NULL);
167 	assert((active_test_name = strdup(n)) != NULL);
168 	if (verbose_mode)
169 		printf("test %u - \"%s\": ", test_number, active_test_name);
170 	test_number++;
171 }
172 
173 void
174 set_onerror_func(test_onerror_func_t *f, void *ctx)
175 {
176 	test_onerror = f;
177 	onerror_ctx = ctx;
178 }
179 
180 void
181 test_done(void)
182 {
183 	assert(active_test_name != NULL);
184 	free(active_test_name);
185 	active_test_name = NULL;
186 	if (verbose_mode)
187 		printf("OK\n");
188 	else if (!quiet_mode) {
189 		printf(".");
190 		fflush(stdout);
191 	}
192 }
193 
194 void
195 ssl_err_check(const char *file, int line)
196 {
197 	long openssl_error = ERR_get_error();
198 
199 	if (openssl_error == 0)
200 		return;
201 
202 	fprintf(stderr, "\n%s:%d: uncaught OpenSSL error: %s",
203 	    file, line, ERR_error_string(openssl_error, NULL));
204 	abort();
205 }
206 
207 static const char *
208 pred_name(enum test_predicate p)
209 {
210 	switch (p) {
211 	case TEST_EQ:
212 		return "EQ";
213 	case TEST_NE:
214 		return "NE";
215 	case TEST_LT:
216 		return "LT";
217 	case TEST_LE:
218 		return "LE";
219 	case TEST_GT:
220 		return "GT";
221 	case TEST_GE:
222 		return "GE";
223 	default:
224 		return "UNKNOWN";
225 	}
226 }
227 
228 static void
229 test_die(void)
230 {
231 	if (test_onerror != NULL)
232 		test_onerror(onerror_ctx);
233 	abort();
234 }
235 
236 static void
237 test_header(const char *file, int line, const char *a1, const char *a2,
238     const char *name, enum test_predicate pred)
239 {
240 	fprintf(stderr, "\n%s:%d test #%u \"%s\"\n",
241 	    file, line, test_number, active_test_name);
242 	fprintf(stderr, "ASSERT_%s_%s(%s%s%s) failed:\n",
243 	    name, pred_name(pred), a1,
244 	    a2 != NULL ? ", " : "", a2 != NULL ? a2 : "");
245 }
246 
247 void
248 assert_bignum(const char *file, int line, const char *a1, const char *a2,
249     const BIGNUM *aa1, const BIGNUM *aa2, enum test_predicate pred)
250 {
251 	int r = BN_cmp(aa1, aa2);
252 
253 	TEST_CHECK_INT(r, pred);
254 	test_header(file, line, a1, a2, "BIGNUM", pred);
255 	fprintf(stderr, "%12s = 0x%s\n", a1, BN_bn2hex(aa1));
256 	fprintf(stderr, "%12s = 0x%s\n", a2, BN_bn2hex(aa2));
257 	test_die();
258 }
259 
260 void
261 assert_string(const char *file, int line, const char *a1, const char *a2,
262     const char *aa1, const char *aa2, enum test_predicate pred)
263 {
264 	int r = strcmp(aa1, aa2);
265 
266 	TEST_CHECK_INT(r, pred);
267 	test_header(file, line, a1, a2, "STRING", pred);
268 	fprintf(stderr, "%12s = %s (len %zu)\n", a1, aa1, strlen(aa1));
269 	fprintf(stderr, "%12s = %s (len %zu)\n", a2, aa2, strlen(aa2));
270 	test_die();
271 }
272 
273 static char *
274 tohex(const void *_s, size_t l)
275 {
276 	u_int8_t *s = (u_int8_t *)_s;
277 	size_t i, j;
278 	const char *hex = "0123456789abcdef";
279 	char *r = malloc((l * 2) + 1);
280 
281 	assert(r != NULL);
282 	for (i = j = 0; i < l; i++) {
283 		r[j++] = hex[(s[i] >> 4) & 0xf];
284 		r[j++] = hex[s[i] & 0xf];
285 	}
286 	r[j] = '\0';
287 	return r;
288 }
289 
290 void
291 assert_mem(const char *file, int line, const char *a1, const char *a2,
292     const void *aa1, const void *aa2, size_t l, enum test_predicate pred)
293 {
294 	int r = memcmp(aa1, aa2, l);
295 
296 	TEST_CHECK_INT(r, pred);
297 	test_header(file, line, a1, a2, "STRING", pred);
298 	fprintf(stderr, "%12s = %s (len %zu)\n", a1, tohex(aa1, MIN(l, 256)), l);
299 	fprintf(stderr, "%12s = %s (len %zu)\n", a2, tohex(aa2, MIN(l, 256)), l);
300 	test_die();
301 }
302 
303 static int
304 memvalcmp(const u_int8_t *s, u_char v, size_t l, size_t *where)
305 {
306 	size_t i;
307 
308 	for (i = 0; i < l; i++) {
309 		if (s[i] != v) {
310 			*where = i;
311 			return 1;
312 		}
313 	}
314 	return 0;
315 }
316 
317 void
318 assert_mem_filled(const char *file, int line, const char *a1,
319     const void *aa1, u_char v, size_t l, enum test_predicate pred)
320 {
321 	size_t where = -1;
322 	int r = memvalcmp(aa1, v, l, &where);
323 	char tmp[64];
324 
325 	if (l == 0)
326 		return;
327 	TEST_CHECK_INT(r, pred);
328 	test_header(file, line, a1, NULL, "MEM_ZERO", pred);
329 	fprintf(stderr, "%20s = %s%s (len %zu)\n", a1,
330 	    tohex(aa1, MIN(l, 20)), l > 20 ? "..." : "", l);
331 	snprintf(tmp, sizeof(tmp), "(%s)[%zu]", a1, where);
332 	fprintf(stderr, "%20s = 0x%02x (expected 0x%02x)\n", tmp,
333 	    ((u_char *)aa1)[where], v);
334 	test_die();
335 }
336 
337 void
338 assert_int(const char *file, int line, const char *a1, const char *a2,
339     int aa1, int aa2, enum test_predicate pred)
340 {
341 	TEST_CHECK(aa1, aa2, pred);
342 	test_header(file, line, a1, a2, "INT", pred);
343 	fprintf(stderr, "%12s = %d\n", a1, aa1);
344 	fprintf(stderr, "%12s = %d\n", a2, aa2);
345 	test_die();
346 }
347 
348 void
349 assert_size_t(const char *file, int line, const char *a1, const char *a2,
350     size_t aa1, size_t aa2, enum test_predicate pred)
351 {
352 	TEST_CHECK(aa1, aa2, pred);
353 	test_header(file, line, a1, a2, "SIZE_T", pred);
354 	fprintf(stderr, "%12s = %zu\n", a1, aa1);
355 	fprintf(stderr, "%12s = %zu\n", a2, aa2);
356 	test_die();
357 }
358 
359 void
360 assert_u_int(const char *file, int line, const char *a1, const char *a2,
361     u_int aa1, u_int aa2, enum test_predicate pred)
362 {
363 	TEST_CHECK(aa1, aa2, pred);
364 	test_header(file, line, a1, a2, "U_INT", pred);
365 	fprintf(stderr, "%12s = %u / 0x%x\n", a1, aa1, aa1);
366 	fprintf(stderr, "%12s = %u / 0x%x\n", a2, aa2, aa2);
367 	test_die();
368 }
369 
370 void
371 assert_long_long(const char *file, int line, const char *a1, const char *a2,
372     long long aa1, long long aa2, enum test_predicate pred)
373 {
374 	TEST_CHECK(aa1, aa2, pred);
375 	test_header(file, line, a1, a2, "LONG LONG", pred);
376 	fprintf(stderr, "%12s = %lld / 0x%llx\n", a1, aa1, aa1);
377 	fprintf(stderr, "%12s = %lld / 0x%llx\n", a2, aa2, aa2);
378 	test_die();
379 }
380 
381 void
382 assert_char(const char *file, int line, const char *a1, const char *a2,
383     char aa1, char aa2, enum test_predicate pred)
384 {
385 	char buf[8];
386 
387 	TEST_CHECK(aa1, aa2, pred);
388 	test_header(file, line, a1, a2, "CHAR", pred);
389 	fprintf(stderr, "%12s = '%s' / 0x02%x\n", a1,
390 	    vis(buf, aa1, VIS_SAFE|VIS_NL|VIS_TAB|VIS_OCTAL, 0), aa1);
391 	fprintf(stderr, "%12s = '%s' / 0x02%x\n", a1,
392 	    vis(buf, aa2, VIS_SAFE|VIS_NL|VIS_TAB|VIS_OCTAL, 0), aa2);
393 	test_die();
394 }
395 
396 void
397 assert_u8(const char *file, int line, const char *a1, const char *a2,
398     u_int8_t aa1, u_int8_t aa2, enum test_predicate pred)
399 {
400 	TEST_CHECK(aa1, aa2, pred);
401 	test_header(file, line, a1, a2, "U8", pred);
402 	fprintf(stderr, "%12s = 0x%02x %u\n", a1, aa1, aa1);
403 	fprintf(stderr, "%12s = 0x%02x %u\n", a2, aa2, aa2);
404 	test_die();
405 }
406 
407 void
408 assert_u16(const char *file, int line, const char *a1, const char *a2,
409     u_int16_t aa1, u_int16_t aa2, enum test_predicate pred)
410 {
411 	TEST_CHECK(aa1, aa2, pred);
412 	test_header(file, line, a1, a2, "U16", pred);
413 	fprintf(stderr, "%12s = 0x%04x %u\n", a1, aa1, aa1);
414 	fprintf(stderr, "%12s = 0x%04x %u\n", a2, aa2, aa2);
415 	test_die();
416 }
417 
418 void
419 assert_u32(const char *file, int line, const char *a1, const char *a2,
420     u_int32_t aa1, u_int32_t aa2, enum test_predicate pred)
421 {
422 	TEST_CHECK(aa1, aa2, pred);
423 	test_header(file, line, a1, a2, "U32", pred);
424 	fprintf(stderr, "%12s = 0x%08x %u\n", a1, aa1, aa1);
425 	fprintf(stderr, "%12s = 0x%08x %u\n", a2, aa2, aa2);
426 	test_die();
427 }
428 
429 void
430 assert_u64(const char *file, int line, const char *a1, const char *a2,
431     u_int64_t aa1, u_int64_t aa2, enum test_predicate pred)
432 {
433 	TEST_CHECK(aa1, aa2, pred);
434 	test_header(file, line, a1, a2, "U64", pred);
435 	fprintf(stderr, "%12s = 0x%016llx %llu\n", a1,
436 	    (unsigned long long)aa1, (unsigned long long)aa1);
437 	fprintf(stderr, "%12s = 0x%016llx %llu\n", a2,
438 	    (unsigned long long)aa2, (unsigned long long)aa2);
439 	test_die();
440 }
441 
442 void
443 assert_ptr(const char *file, int line, const char *a1, const char *a2,
444     const void *aa1, const void *aa2, enum test_predicate pred)
445 {
446 	TEST_CHECK(aa1, aa2, pred);
447 	test_header(file, line, a1, a2, "PTR", pred);
448 	fprintf(stderr, "%12s = %p\n", a1, aa1);
449 	fprintf(stderr, "%12s = %p\n", a2, aa2);
450 	test_die();
451 }
452 
453