1c4ffb725Sdjm@openbsd.org /*	$OpenBSD: test_helper.c,v 1.12 2019/08/02 01:41:24 djm Exp $	*/
2def1de08SDamien Miller /*
3def1de08SDamien Miller  * Copyright (c) 2011 Damien Miller <djm@mindrot.org>
4def1de08SDamien Miller  *
5def1de08SDamien Miller  * Permission to use, copy, modify, and distribute this software for any
6def1de08SDamien Miller  * purpose with or without fee is hereby granted, provided that the above
7def1de08SDamien Miller  * copyright notice and this permission notice appear in all copies.
8def1de08SDamien Miller  *
9def1de08SDamien Miller  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10def1de08SDamien Miller  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11def1de08SDamien Miller  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12def1de08SDamien Miller  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13def1de08SDamien Miller  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14def1de08SDamien Miller  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15def1de08SDamien Miller  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16def1de08SDamien Miller  */
17def1de08SDamien Miller 
18def1de08SDamien Miller /* Utility functions/framework for regress tests */
19def1de08SDamien Miller 
20e7429f2bSDamien Miller #include "includes.h"
21e7429f2bSDamien Miller 
22def1de08SDamien Miller #include <sys/types.h>
23def1de08SDamien Miller #include <sys/param.h>
24771bb47aSdjm@openbsd.org #include <sys/uio.h>
25def1de08SDamien Miller 
26*f61f29afSDamien Miller #include <stdarg.h>
27def1de08SDamien Miller #include <fcntl.h>
28def1de08SDamien Miller #include <stdio.h>
29985ee2cbSDarren Tucker #ifdef HAVE_STDINT_H
30def1de08SDamien Miller # include <stdint.h>
31985ee2cbSDarren Tucker #endif
32def1de08SDamien Miller #include <stdlib.h>
33def1de08SDamien Miller #include <string.h>
34def1de08SDamien Miller #include <assert.h>
35def1de08SDamien Miller #include <unistd.h>
36771bb47aSdjm@openbsd.org #include <signal.h>
37def1de08SDamien Miller 
38*f61f29afSDamien Miller #ifdef WITH_OPENSSL
39def1de08SDamien Miller #include <openssl/bn.h>
4042c5ec4bSDamien Miller #include <openssl/err.h>
41*f61f29afSDamien Miller #endif
42def1de08SDamien Miller 
43e7429f2bSDamien Miller #if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H) && !defined(BROKEN_STRNVIS)
44def1de08SDamien Miller # include <vis.h>
45e7429f2bSDamien Miller #endif
46def1de08SDamien Miller 
4742c5ec4bSDamien Miller #include "entropy.h"
48def1de08SDamien Miller #include "test_helper.h"
49771bb47aSdjm@openbsd.org #include "atomicio.h"
50def1de08SDamien Miller 
51def1de08SDamien Miller #define TEST_CHECK_INT(r, pred) do {		\
52def1de08SDamien Miller 		switch (pred) {			\
53def1de08SDamien Miller 		case TEST_EQ:			\
54def1de08SDamien Miller 			if (r == 0)		\
55def1de08SDamien Miller 				return;		\
56def1de08SDamien Miller 			break;			\
57def1de08SDamien Miller 		case TEST_NE:			\
58def1de08SDamien Miller 			if (r != 0)		\
59def1de08SDamien Miller 				return;		\
60def1de08SDamien Miller 			break;			\
61def1de08SDamien Miller 		case TEST_LT:			\
62def1de08SDamien Miller 			if (r < 0)		\
63def1de08SDamien Miller 				return;		\
64def1de08SDamien Miller 			break;			\
65def1de08SDamien Miller 		case TEST_LE:			\
66def1de08SDamien Miller 			if (r <= 0)		\
67def1de08SDamien Miller 				return;		\
68def1de08SDamien Miller 			break;			\
69def1de08SDamien Miller 		case TEST_GT:			\
70def1de08SDamien Miller 			if (r > 0)		\
71def1de08SDamien Miller 				return;		\
72def1de08SDamien Miller 			break;			\
73def1de08SDamien Miller 		case TEST_GE:			\
74def1de08SDamien Miller 			if (r >= 0)		\
75def1de08SDamien Miller 				return;		\
76def1de08SDamien Miller 			break;			\
77def1de08SDamien Miller 		default:			\
78def1de08SDamien Miller 			abort();		\
79def1de08SDamien Miller 		}				\
80def1de08SDamien Miller 	} while (0)
81def1de08SDamien Miller 
82def1de08SDamien Miller #define TEST_CHECK(x1, x2, pred) do {		\
83def1de08SDamien Miller 		switch (pred) {			\
84def1de08SDamien Miller 		case TEST_EQ:			\
85def1de08SDamien Miller 			if (x1 == x2)		\
86def1de08SDamien Miller 				return;		\
87def1de08SDamien Miller 			break;			\
88def1de08SDamien Miller 		case TEST_NE:			\
89def1de08SDamien Miller 			if (x1 != x2)		\
90def1de08SDamien Miller 				return;		\
91def1de08SDamien Miller 			break;			\
92def1de08SDamien Miller 		case TEST_LT:			\
93def1de08SDamien Miller 			if (x1 < x2)		\
94def1de08SDamien Miller 				return;		\
95def1de08SDamien Miller 			break;			\
96def1de08SDamien Miller 		case TEST_LE:			\
97def1de08SDamien Miller 			if (x1 <= x2)		\
98def1de08SDamien Miller 				return;		\
99def1de08SDamien Miller 			break;			\
100def1de08SDamien Miller 		case TEST_GT:			\
101def1de08SDamien Miller 			if (x1 > x2)		\
102def1de08SDamien Miller 				return;		\
103def1de08SDamien Miller 			break;			\
104def1de08SDamien Miller 		case TEST_GE:			\
105def1de08SDamien Miller 			if (x1 >= x2)		\
106def1de08SDamien Miller 				return;		\
107def1de08SDamien Miller 			break;			\
108def1de08SDamien Miller 		default:			\
109def1de08SDamien Miller 			abort();		\
110def1de08SDamien Miller 		}				\
111def1de08SDamien Miller 	} while (0)
112def1de08SDamien Miller 
113def1de08SDamien Miller extern char *__progname;
114def1de08SDamien Miller 
115def1de08SDamien Miller static int verbose_mode = 0;
116def1de08SDamien Miller static int quiet_mode = 0;
117def1de08SDamien Miller static char *active_test_name = NULL;
118def1de08SDamien Miller static u_int test_number = 0;
119def1de08SDamien Miller static test_onerror_func_t *test_onerror = NULL;
120def1de08SDamien Miller static void *onerror_ctx = NULL;
121def1de08SDamien Miller static const char *data_dir = NULL;
122d333f89aSdjm@openbsd.org static char subtest_info[512];
12335d0e5feSdjm@openbsd.org static int fast = 0;
12435d0e5feSdjm@openbsd.org static int slow = 0;
125def1de08SDamien Miller 
126def1de08SDamien Miller int
main(int argc,char ** argv)127def1de08SDamien Miller main(int argc, char **argv)
128def1de08SDamien Miller {
129def1de08SDamien Miller 	int ch;
130def1de08SDamien Miller 
13142c5ec4bSDamien Miller 	seed_rng();
132*f61f29afSDamien Miller #ifdef WITH_OPENSSL
13342c5ec4bSDamien Miller 	ERR_load_CRYPTO_strings();
134*f61f29afSDamien Miller #endif
13542c5ec4bSDamien Miller 
1364f1ff1edSDamien Miller 	/* Handle systems without __progname */
1374f1ff1edSDamien Miller 	if (__progname == NULL) {
1384f1ff1edSDamien Miller 		__progname = strrchr(argv[0], '/');
1394f1ff1edSDamien Miller 		if (__progname == NULL || __progname[1] == '\0')
1404f1ff1edSDamien Miller 			__progname = argv[0];
1414f1ff1edSDamien Miller 		else
1424f1ff1edSDamien Miller 			__progname++;
1434f1ff1edSDamien Miller 		if ((__progname = strdup(__progname)) == NULL) {
1444f1ff1edSDamien Miller 			fprintf(stderr, "strdup failed\n");
1454f1ff1edSDamien Miller 			exit(1);
1464f1ff1edSDamien Miller 		}
1474f1ff1edSDamien Miller 	}
1484f1ff1edSDamien Miller 
14935d0e5feSdjm@openbsd.org 	while ((ch = getopt(argc, argv, "Ffvqd:")) != -1) {
150def1de08SDamien Miller 		switch (ch) {
15135d0e5feSdjm@openbsd.org 		case 'F':
15235d0e5feSdjm@openbsd.org 			slow = 1;
15335d0e5feSdjm@openbsd.org 			break;
15435d0e5feSdjm@openbsd.org 		case 'f':
15535d0e5feSdjm@openbsd.org 			fast = 1;
15635d0e5feSdjm@openbsd.org 			break;
157def1de08SDamien Miller 		case 'd':
158def1de08SDamien Miller 			data_dir = optarg;
159def1de08SDamien Miller 			break;
160def1de08SDamien Miller 		case 'q':
161def1de08SDamien Miller 			verbose_mode = 0;
162def1de08SDamien Miller 			quiet_mode = 1;
163def1de08SDamien Miller 			break;
164def1de08SDamien Miller 		case 'v':
165def1de08SDamien Miller 			verbose_mode = 1;
166def1de08SDamien Miller 			quiet_mode = 0;
167def1de08SDamien Miller 			break;
168def1de08SDamien Miller 		default:
169def1de08SDamien Miller 			fprintf(stderr, "Unrecognised command line option\n");
170def1de08SDamien Miller 			fprintf(stderr, "Usage: %s [-v]\n", __progname);
171def1de08SDamien Miller 			exit(1);
172def1de08SDamien Miller 		}
173def1de08SDamien Miller 	}
174def1de08SDamien Miller 	setvbuf(stdout, NULL, _IONBF, 0);
175def1de08SDamien Miller 	if (!quiet_mode)
176def1de08SDamien Miller 		printf("%s: ", __progname);
177def1de08SDamien Miller 	if (verbose_mode)
178def1de08SDamien Miller 		printf("\n");
179def1de08SDamien Miller 
180def1de08SDamien Miller 	tests();
181def1de08SDamien Miller 
182def1de08SDamien Miller 	if (!quiet_mode)
183def1de08SDamien Miller 		printf(" %u tests ok\n", test_number);
184def1de08SDamien Miller 	return 0;
185def1de08SDamien Miller }
186def1de08SDamien Miller 
1873b252c20Sdjm@openbsd.org int
test_is_verbose(void)18835d0e5feSdjm@openbsd.org test_is_verbose(void)
1893b252c20Sdjm@openbsd.org {
1903b252c20Sdjm@openbsd.org 	return verbose_mode;
1913b252c20Sdjm@openbsd.org }
1923b252c20Sdjm@openbsd.org 
1933b252c20Sdjm@openbsd.org int
test_is_quiet(void)19435d0e5feSdjm@openbsd.org test_is_quiet(void)
1953b252c20Sdjm@openbsd.org {
1963b252c20Sdjm@openbsd.org 	return quiet_mode;
1973b252c20Sdjm@openbsd.org }
1983b252c20Sdjm@openbsd.org 
19935d0e5feSdjm@openbsd.org int
test_is_fast(void)20035d0e5feSdjm@openbsd.org test_is_fast(void)
20135d0e5feSdjm@openbsd.org {
20235d0e5feSdjm@openbsd.org 	return fast;
20335d0e5feSdjm@openbsd.org }
20435d0e5feSdjm@openbsd.org 
20535d0e5feSdjm@openbsd.org int
test_is_slow(void)20635d0e5feSdjm@openbsd.org test_is_slow(void)
20735d0e5feSdjm@openbsd.org {
20835d0e5feSdjm@openbsd.org 	return slow;
20935d0e5feSdjm@openbsd.org }
21035d0e5feSdjm@openbsd.org 
211def1de08SDamien Miller const char *
test_data_file(const char * name)212def1de08SDamien Miller test_data_file(const char *name)
213def1de08SDamien Miller {
214def1de08SDamien Miller 	static char ret[PATH_MAX];
215def1de08SDamien Miller 
216def1de08SDamien Miller 	if (data_dir != NULL)
217def1de08SDamien Miller 		snprintf(ret, sizeof(ret), "%s/%s", data_dir, name);
218def1de08SDamien Miller 	else
219def1de08SDamien Miller 		strlcpy(ret, name, sizeof(ret));
220def1de08SDamien Miller 	if (access(ret, F_OK) != 0) {
221def1de08SDamien Miller 		fprintf(stderr, "Cannot access data file %s: %s\n",
222def1de08SDamien Miller 		    ret, strerror(errno));
223def1de08SDamien Miller 		exit(1);
224def1de08SDamien Miller 	}
225def1de08SDamien Miller 	return ret;
226def1de08SDamien Miller }
227def1de08SDamien Miller 
228def1de08SDamien Miller void
test_info(char * s,size_t len)229771bb47aSdjm@openbsd.org test_info(char *s, size_t len)
230771bb47aSdjm@openbsd.org {
231d333f89aSdjm@openbsd.org 	snprintf(s, len, "In test %u: \"%s\"%s%s\n", test_number,
232d333f89aSdjm@openbsd.org 	    active_test_name == NULL ? "<none>" : active_test_name,
233d333f89aSdjm@openbsd.org 	    *subtest_info != '\0' ? " - " : "", subtest_info);
234771bb47aSdjm@openbsd.org }
235771bb47aSdjm@openbsd.org 
236771bb47aSdjm@openbsd.org static void
siginfo(int unused)2373f7f5e6cSdjm@openbsd.org siginfo(int unused __attribute__((__unused__)))
238771bb47aSdjm@openbsd.org {
239771bb47aSdjm@openbsd.org 	char buf[256];
240771bb47aSdjm@openbsd.org 
241771bb47aSdjm@openbsd.org 	test_info(buf, sizeof(buf));
242771bb47aSdjm@openbsd.org 	atomicio(vwrite, STDERR_FILENO, buf, strlen(buf));
243771bb47aSdjm@openbsd.org }
244771bb47aSdjm@openbsd.org 
245771bb47aSdjm@openbsd.org void
test_start(const char * n)246def1de08SDamien Miller test_start(const char *n)
247def1de08SDamien Miller {
248def1de08SDamien Miller 	assert(active_test_name == NULL);
249def1de08SDamien Miller 	assert((active_test_name = strdup(n)) != NULL);
250d333f89aSdjm@openbsd.org 	*subtest_info = '\0';
251def1de08SDamien Miller 	if (verbose_mode)
252def1de08SDamien Miller 		printf("test %u - \"%s\": ", test_number, active_test_name);
253def1de08SDamien Miller 	test_number++;
254771bb47aSdjm@openbsd.org #ifdef SIGINFO
255771bb47aSdjm@openbsd.org 	signal(SIGINFO, siginfo);
256771bb47aSdjm@openbsd.org #endif
2570aa1f230SDamien Miller 	signal(SIGUSR1, siginfo);
258def1de08SDamien Miller }
259def1de08SDamien Miller 
260def1de08SDamien Miller void
set_onerror_func(test_onerror_func_t * f,void * ctx)261def1de08SDamien Miller set_onerror_func(test_onerror_func_t *f, void *ctx)
262def1de08SDamien Miller {
263def1de08SDamien Miller 	test_onerror = f;
264def1de08SDamien Miller 	onerror_ctx = ctx;
265def1de08SDamien Miller }
266def1de08SDamien Miller 
267def1de08SDamien Miller void
test_done(void)268def1de08SDamien Miller test_done(void)
269def1de08SDamien Miller {
270d333f89aSdjm@openbsd.org 	*subtest_info = '\0';
271def1de08SDamien Miller 	assert(active_test_name != NULL);
272def1de08SDamien Miller 	free(active_test_name);
273def1de08SDamien Miller 	active_test_name = NULL;
274def1de08SDamien Miller 	if (verbose_mode)
275def1de08SDamien Miller 		printf("OK\n");
276def1de08SDamien Miller 	else if (!quiet_mode) {
277def1de08SDamien Miller 		printf(".");
278def1de08SDamien Miller 		fflush(stdout);
279def1de08SDamien Miller 	}
280def1de08SDamien Miller }
281def1de08SDamien Miller 
282def1de08SDamien Miller void
test_subtest_info(const char * fmt,...)283d333f89aSdjm@openbsd.org test_subtest_info(const char *fmt, ...)
284d333f89aSdjm@openbsd.org {
285d333f89aSdjm@openbsd.org 	va_list ap;
286d333f89aSdjm@openbsd.org 
287d333f89aSdjm@openbsd.org 	va_start(ap, fmt);
288d333f89aSdjm@openbsd.org 	vsnprintf(subtest_info, sizeof(subtest_info), fmt, ap);
289d333f89aSdjm@openbsd.org 	va_end(ap);
290d333f89aSdjm@openbsd.org }
291d333f89aSdjm@openbsd.org 
292d333f89aSdjm@openbsd.org void
ssl_err_check(const char * file,int line)293def1de08SDamien Miller ssl_err_check(const char *file, int line)
294def1de08SDamien Miller {
295*f61f29afSDamien Miller #ifdef WITH_OPENSSL
296def1de08SDamien Miller 	long openssl_error = ERR_get_error();
297def1de08SDamien Miller 
298def1de08SDamien Miller 	if (openssl_error == 0)
299def1de08SDamien Miller 		return;
300def1de08SDamien Miller 
301def1de08SDamien Miller 	fprintf(stderr, "\n%s:%d: uncaught OpenSSL error: %s",
302def1de08SDamien Miller 	    file, line, ERR_error_string(openssl_error, NULL));
303*f61f29afSDamien Miller #else /* WITH_OPENSSL */
304*f61f29afSDamien Miller 	fprintf(stderr, "\n%s:%d: uncaught OpenSSL error ",
305*f61f29afSDamien Miller 	    file, line);
306*f61f29afSDamien Miller #endif /* WITH_OPENSSL */
307def1de08SDamien Miller 	abort();
308def1de08SDamien Miller }
309def1de08SDamien Miller 
310def1de08SDamien Miller static const char *
pred_name(enum test_predicate p)311def1de08SDamien Miller pred_name(enum test_predicate p)
312def1de08SDamien Miller {
313def1de08SDamien Miller 	switch (p) {
314def1de08SDamien Miller 	case TEST_EQ:
315def1de08SDamien Miller 		return "EQ";
316def1de08SDamien Miller 	case TEST_NE:
317def1de08SDamien Miller 		return "NE";
318def1de08SDamien Miller 	case TEST_LT:
319def1de08SDamien Miller 		return "LT";
320def1de08SDamien Miller 	case TEST_LE:
321def1de08SDamien Miller 		return "LE";
322def1de08SDamien Miller 	case TEST_GT:
323def1de08SDamien Miller 		return "GT";
324def1de08SDamien Miller 	case TEST_GE:
325def1de08SDamien Miller 		return "GE";
326def1de08SDamien Miller 	default:
327def1de08SDamien Miller 		return "UNKNOWN";
328def1de08SDamien Miller 	}
329def1de08SDamien Miller }
330def1de08SDamien Miller 
331def1de08SDamien Miller static void
test_die(void)332def1de08SDamien Miller test_die(void)
333def1de08SDamien Miller {
334def1de08SDamien Miller 	if (test_onerror != NULL)
335def1de08SDamien Miller 		test_onerror(onerror_ctx);
336def1de08SDamien Miller 	abort();
337def1de08SDamien Miller }
338def1de08SDamien Miller 
339def1de08SDamien Miller static void
test_header(const char * file,int line,const char * a1,const char * a2,const char * name,enum test_predicate pred)340def1de08SDamien Miller test_header(const char *file, int line, const char *a1, const char *a2,
341def1de08SDamien Miller     const char *name, enum test_predicate pred)
342def1de08SDamien Miller {
343d333f89aSdjm@openbsd.org 	fprintf(stderr, "\n%s:%d test #%u \"%s\"%s%s\n",
344d333f89aSdjm@openbsd.org 	    file, line, test_number, active_test_name,
345d333f89aSdjm@openbsd.org 	    *subtest_info != '\0' ? " - " : "", subtest_info);
346def1de08SDamien Miller 	fprintf(stderr, "ASSERT_%s_%s(%s%s%s) failed:\n",
347def1de08SDamien Miller 	    name, pred_name(pred), a1,
348def1de08SDamien Miller 	    a2 != NULL ? ", " : "", a2 != NULL ? a2 : "");
349def1de08SDamien Miller }
350def1de08SDamien Miller 
351*f61f29afSDamien Miller #ifdef WITH_OPENSSL
352def1de08SDamien Miller void
assert_bignum(const char * file,int line,const char * a1,const char * a2,const BIGNUM * aa1,const BIGNUM * aa2,enum test_predicate pred)353def1de08SDamien Miller assert_bignum(const char *file, int line, const char *a1, const char *a2,
354def1de08SDamien Miller     const BIGNUM *aa1, const BIGNUM *aa2, enum test_predicate pred)
355def1de08SDamien Miller {
356def1de08SDamien Miller 	int r = BN_cmp(aa1, aa2);
357def1de08SDamien Miller 
358def1de08SDamien Miller 	TEST_CHECK_INT(r, pred);
359def1de08SDamien Miller 	test_header(file, line, a1, a2, "BIGNUM", pred);
360def1de08SDamien Miller 	fprintf(stderr, "%12s = 0x%s\n", a1, BN_bn2hex(aa1));
361def1de08SDamien Miller 	fprintf(stderr, "%12s = 0x%s\n", a2, BN_bn2hex(aa2));
362def1de08SDamien Miller 	test_die();
363def1de08SDamien Miller }
364*f61f29afSDamien Miller #endif
365def1de08SDamien Miller 
366def1de08SDamien Miller void
assert_string(const char * file,int line,const char * a1,const char * a2,const char * aa1,const char * aa2,enum test_predicate pred)367def1de08SDamien Miller assert_string(const char *file, int line, const char *a1, const char *a2,
368def1de08SDamien Miller     const char *aa1, const char *aa2, enum test_predicate pred)
369def1de08SDamien Miller {
37068a5d647Sdjm@openbsd.org 	int r;
371def1de08SDamien Miller 
37268a5d647Sdjm@openbsd.org 	/* Verify pointers are not NULL */
37368a5d647Sdjm@openbsd.org 	assert_ptr(file, line, a1, "NULL", aa1, NULL, TEST_NE);
37468a5d647Sdjm@openbsd.org 	assert_ptr(file, line, a2, "NULL", aa2, NULL, TEST_NE);
37568a5d647Sdjm@openbsd.org 
37668a5d647Sdjm@openbsd.org 	r = strcmp(aa1, aa2);
377def1de08SDamien Miller 	TEST_CHECK_INT(r, pred);
378def1de08SDamien Miller 	test_header(file, line, a1, a2, "STRING", pred);
379def1de08SDamien Miller 	fprintf(stderr, "%12s = %s (len %zu)\n", a1, aa1, strlen(aa1));
380def1de08SDamien Miller 	fprintf(stderr, "%12s = %s (len %zu)\n", a2, aa2, strlen(aa2));
381def1de08SDamien Miller 	test_die();
382def1de08SDamien Miller }
383def1de08SDamien Miller 
384def1de08SDamien Miller static char *
tohex(const void * _s,size_t l)385def1de08SDamien Miller tohex(const void *_s, size_t l)
386def1de08SDamien Miller {
387def1de08SDamien Miller 	u_int8_t *s = (u_int8_t *)_s;
388def1de08SDamien Miller 	size_t i, j;
389def1de08SDamien Miller 	const char *hex = "0123456789abcdef";
390def1de08SDamien Miller 	char *r = malloc((l * 2) + 1);
391def1de08SDamien Miller 
392def1de08SDamien Miller 	assert(r != NULL);
393def1de08SDamien Miller 	for (i = j = 0; i < l; i++) {
394def1de08SDamien Miller 		r[j++] = hex[(s[i] >> 4) & 0xf];
395def1de08SDamien Miller 		r[j++] = hex[s[i] & 0xf];
396def1de08SDamien Miller 	}
397def1de08SDamien Miller 	r[j] = '\0';
398def1de08SDamien Miller 	return r;
399def1de08SDamien Miller }
400def1de08SDamien Miller 
401def1de08SDamien Miller void
assert_mem(const char * file,int line,const char * a1,const char * a2,const void * aa1,const void * aa2,size_t l,enum test_predicate pred)402def1de08SDamien Miller assert_mem(const char *file, int line, const char *a1, const char *a2,
403def1de08SDamien Miller     const void *aa1, const void *aa2, size_t l, enum test_predicate pred)
404def1de08SDamien Miller {
40568a5d647Sdjm@openbsd.org 	int r;
406c4ffb725Sdjm@openbsd.org 	char *aa1_tohex = NULL;
407c4ffb725Sdjm@openbsd.org 	char *aa2_tohex = NULL;
408def1de08SDamien Miller 
40968a5d647Sdjm@openbsd.org 	if (l == 0)
41068a5d647Sdjm@openbsd.org 		return;
41168a5d647Sdjm@openbsd.org 	/* If length is >0, then verify pointers are not NULL */
41268a5d647Sdjm@openbsd.org 	assert_ptr(file, line, a1, "NULL", aa1, NULL, TEST_NE);
41368a5d647Sdjm@openbsd.org 	assert_ptr(file, line, a2, "NULL", aa2, NULL, TEST_NE);
41468a5d647Sdjm@openbsd.org 
41568a5d647Sdjm@openbsd.org 	r = memcmp(aa1, aa2, l);
416def1de08SDamien Miller 	TEST_CHECK_INT(r, pred);
417def1de08SDamien Miller 	test_header(file, line, a1, a2, "STRING", pred);
418c4ffb725Sdjm@openbsd.org 	aa1_tohex = tohex(aa1, MIN(l, 256));
419c4ffb725Sdjm@openbsd.org 	aa2_tohex = tohex(aa2, MIN(l, 256));
420c4ffb725Sdjm@openbsd.org 	fprintf(stderr, "%12s = %s (len %zu)\n", a1, aa1_tohex, l);
421c4ffb725Sdjm@openbsd.org 	fprintf(stderr, "%12s = %s (len %zu)\n", a2, aa2_tohex, l);
422c4ffb725Sdjm@openbsd.org 	free(aa1_tohex);
423c4ffb725Sdjm@openbsd.org 	free(aa2_tohex);
424def1de08SDamien Miller 	test_die();
425def1de08SDamien Miller }
426def1de08SDamien Miller 
427def1de08SDamien Miller static int
memvalcmp(const u_int8_t * s,u_char v,size_t l,size_t * where)428def1de08SDamien Miller memvalcmp(const u_int8_t *s, u_char v, size_t l, size_t *where)
429def1de08SDamien Miller {
430def1de08SDamien Miller 	size_t i;
431def1de08SDamien Miller 
432def1de08SDamien Miller 	for (i = 0; i < l; i++) {
433def1de08SDamien Miller 		if (s[i] != v) {
434def1de08SDamien Miller 			*where = i;
435def1de08SDamien Miller 			return 1;
436def1de08SDamien Miller 		}
437def1de08SDamien Miller 	}
438def1de08SDamien Miller 	return 0;
439def1de08SDamien Miller }
440def1de08SDamien Miller 
441def1de08SDamien Miller void
assert_mem_filled(const char * file,int line,const char * a1,const void * aa1,u_char v,size_t l,enum test_predicate pred)442def1de08SDamien Miller assert_mem_filled(const char *file, int line, const char *a1,
443def1de08SDamien Miller     const void *aa1, u_char v, size_t l, enum test_predicate pred)
444def1de08SDamien Miller {
445def1de08SDamien Miller 	size_t where = -1;
44668a5d647Sdjm@openbsd.org 	int r;
447def1de08SDamien Miller 	char tmp[64];
448c4ffb725Sdjm@openbsd.org 	char *aa1_tohex = NULL;
449def1de08SDamien Miller 
450def1de08SDamien Miller 	if (l == 0)
451def1de08SDamien Miller 		return;
45268a5d647Sdjm@openbsd.org 	/* If length is >0, then verify the pointer is not NULL */
45368a5d647Sdjm@openbsd.org 	assert_ptr(file, line, a1, "NULL", aa1, NULL, TEST_NE);
45468a5d647Sdjm@openbsd.org 
45568a5d647Sdjm@openbsd.org 	r = memvalcmp(aa1, v, l, &where);
456def1de08SDamien Miller 	TEST_CHECK_INT(r, pred);
457def1de08SDamien Miller 	test_header(file, line, a1, NULL, "MEM_ZERO", pred);
458c4ffb725Sdjm@openbsd.org 	aa1_tohex = tohex(aa1, MIN(l, 20));
459def1de08SDamien Miller 	fprintf(stderr, "%20s = %s%s (len %zu)\n", a1,
460c4ffb725Sdjm@openbsd.org 	    aa1_tohex, l > 20 ? "..." : "", l);
461c4ffb725Sdjm@openbsd.org 	free(aa1_tohex);
462def1de08SDamien Miller 	snprintf(tmp, sizeof(tmp), "(%s)[%zu]", a1, where);
463def1de08SDamien Miller 	fprintf(stderr, "%20s = 0x%02x (expected 0x%02x)\n", tmp,
464def1de08SDamien Miller 	    ((u_char *)aa1)[where], v);
465def1de08SDamien Miller 	test_die();
466def1de08SDamien Miller }
467def1de08SDamien Miller 
468def1de08SDamien Miller void
assert_int(const char * file,int line,const char * a1,const char * a2,int aa1,int aa2,enum test_predicate pred)469def1de08SDamien Miller assert_int(const char *file, int line, const char *a1, const char *a2,
470def1de08SDamien Miller     int aa1, int aa2, enum test_predicate pred)
471def1de08SDamien Miller {
472def1de08SDamien Miller 	TEST_CHECK(aa1, aa2, pred);
473def1de08SDamien Miller 	test_header(file, line, a1, a2, "INT", pred);
474def1de08SDamien Miller 	fprintf(stderr, "%12s = %d\n", a1, aa1);
475def1de08SDamien Miller 	fprintf(stderr, "%12s = %d\n", a2, aa2);
476def1de08SDamien Miller 	test_die();
477def1de08SDamien Miller }
478def1de08SDamien Miller 
479def1de08SDamien Miller void
assert_size_t(const char * file,int line,const char * a1,const char * a2,size_t aa1,size_t aa2,enum test_predicate pred)480def1de08SDamien Miller assert_size_t(const char *file, int line, const char *a1, const char *a2,
481def1de08SDamien Miller     size_t aa1, size_t aa2, enum test_predicate pred)
482def1de08SDamien Miller {
483def1de08SDamien Miller 	TEST_CHECK(aa1, aa2, pred);
484def1de08SDamien Miller 	test_header(file, line, a1, a2, "SIZE_T", pred);
485def1de08SDamien Miller 	fprintf(stderr, "%12s = %zu\n", a1, aa1);
486def1de08SDamien Miller 	fprintf(stderr, "%12s = %zu\n", a2, aa2);
487def1de08SDamien Miller 	test_die();
488def1de08SDamien Miller }
489def1de08SDamien Miller 
490def1de08SDamien Miller void
assert_u_int(const char * file,int line,const char * a1,const char * a2,u_int aa1,u_int aa2,enum test_predicate pred)491def1de08SDamien Miller assert_u_int(const char *file, int line, const char *a1, const char *a2,
492def1de08SDamien Miller     u_int aa1, u_int aa2, enum test_predicate pred)
493def1de08SDamien Miller {
494def1de08SDamien Miller 	TEST_CHECK(aa1, aa2, pred);
495def1de08SDamien Miller 	test_header(file, line, a1, a2, "U_INT", pred);
496def1de08SDamien Miller 	fprintf(stderr, "%12s = %u / 0x%x\n", a1, aa1, aa1);
497def1de08SDamien Miller 	fprintf(stderr, "%12s = %u / 0x%x\n", a2, aa2, aa2);
498def1de08SDamien Miller 	test_die();
499def1de08SDamien Miller }
500def1de08SDamien Miller 
501def1de08SDamien Miller void
assert_long(const char * file,int line,const char * a1,const char * a2,long aa1,long aa2,enum test_predicate pred)5028884b724Sdtucker@openbsd.org assert_long(const char *file, int line, const char *a1, const char *a2,
5038884b724Sdtucker@openbsd.org     long aa1, long aa2, enum test_predicate pred)
5048884b724Sdtucker@openbsd.org {
5058884b724Sdtucker@openbsd.org 	TEST_CHECK(aa1, aa2, pred);
5068884b724Sdtucker@openbsd.org 	test_header(file, line, a1, a2, "LONG", pred);
5078884b724Sdtucker@openbsd.org 	fprintf(stderr, "%12s = %ld / 0x%lx\n", a1, aa1, aa1);
5088884b724Sdtucker@openbsd.org 	fprintf(stderr, "%12s = %ld / 0x%lx\n", a2, aa2, aa2);
5098884b724Sdtucker@openbsd.org 	test_die();
5108884b724Sdtucker@openbsd.org }
5118884b724Sdtucker@openbsd.org 
5128884b724Sdtucker@openbsd.org void
assert_long_long(const char * file,int line,const char * a1,const char * a2,long long aa1,long long aa2,enum test_predicate pred)513def1de08SDamien Miller assert_long_long(const char *file, int line, const char *a1, const char *a2,
514def1de08SDamien Miller     long long aa1, long long aa2, enum test_predicate pred)
515def1de08SDamien Miller {
516def1de08SDamien Miller 	TEST_CHECK(aa1, aa2, pred);
517def1de08SDamien Miller 	test_header(file, line, a1, a2, "LONG LONG", pred);
518def1de08SDamien Miller 	fprintf(stderr, "%12s = %lld / 0x%llx\n", a1, aa1, aa1);
519def1de08SDamien Miller 	fprintf(stderr, "%12s = %lld / 0x%llx\n", a2, aa2, aa2);
520def1de08SDamien Miller 	test_die();
521def1de08SDamien Miller }
522def1de08SDamien Miller 
523def1de08SDamien Miller void
assert_char(const char * file,int line,const char * a1,const char * a2,char aa1,char aa2,enum test_predicate pred)524def1de08SDamien Miller assert_char(const char *file, int line, const char *a1, const char *a2,
525def1de08SDamien Miller     char aa1, char aa2, enum test_predicate pred)
526def1de08SDamien Miller {
527def1de08SDamien Miller 	char buf[8];
528def1de08SDamien Miller 
529def1de08SDamien Miller 	TEST_CHECK(aa1, aa2, pred);
530def1de08SDamien Miller 	test_header(file, line, a1, a2, "CHAR", pred);
531def1de08SDamien Miller 	fprintf(stderr, "%12s = '%s' / 0x02%x\n", a1,
532def1de08SDamien Miller 	    vis(buf, aa1, VIS_SAFE|VIS_NL|VIS_TAB|VIS_OCTAL, 0), aa1);
533def1de08SDamien Miller 	fprintf(stderr, "%12s = '%s' / 0x02%x\n", a1,
534def1de08SDamien Miller 	    vis(buf, aa2, VIS_SAFE|VIS_NL|VIS_TAB|VIS_OCTAL, 0), aa2);
535def1de08SDamien Miller 	test_die();
536def1de08SDamien Miller }
537def1de08SDamien Miller 
538def1de08SDamien Miller void
assert_u8(const char * file,int line,const char * a1,const char * a2,u_int8_t aa1,u_int8_t aa2,enum test_predicate pred)539def1de08SDamien Miller assert_u8(const char *file, int line, const char *a1, const char *a2,
540def1de08SDamien Miller     u_int8_t aa1, u_int8_t aa2, enum test_predicate pred)
541def1de08SDamien Miller {
542def1de08SDamien Miller 	TEST_CHECK(aa1, aa2, pred);
543def1de08SDamien Miller 	test_header(file, line, a1, a2, "U8", pred);
544def1de08SDamien Miller 	fprintf(stderr, "%12s = 0x%02x %u\n", a1, aa1, aa1);
545def1de08SDamien Miller 	fprintf(stderr, "%12s = 0x%02x %u\n", a2, aa2, aa2);
546def1de08SDamien Miller 	test_die();
547def1de08SDamien Miller }
548def1de08SDamien Miller 
549