summaryrefslogtreecommitdiff
path: root/regress/unittests/test_helper/test_helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'regress/unittests/test_helper/test_helper.c')
-rw-r--r--regress/unittests/test_helper/test_helper.c471
1 files changed, 471 insertions, 0 deletions
diff --git a/regress/unittests/test_helper/test_helper.c b/regress/unittests/test_helper/test_helper.c
new file mode 100644
index 000000000..d0bc67833
--- /dev/null
+++ b/regress/unittests/test_helper/test_helper.c
@@ -0,0 +1,471 @@
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 "includes.h"
21
22#include <sys/types.h>
23#include <sys/param.h>
24
25#include <fcntl.h>
26#include <stdio.h>
27#ifdef HAVE_STDINT_H
28# include <stdint.h>
29#endif
30#include <stdlib.h>
31#include <string.h>
32#include <assert.h>
33#include <unistd.h>
34
35#include <openssl/bn.h>
36
37#if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H) && !defined(BROKEN_STRNVIS)
38# include <vis.h>
39#endif
40
41#include "test_helper.h"
42
43#define TEST_CHECK_INT(r, pred) do { \
44 switch (pred) { \
45 case TEST_EQ: \
46 if (r == 0) \
47 return; \
48 break; \
49 case TEST_NE: \
50 if (r != 0) \
51 return; \
52 break; \
53 case TEST_LT: \
54 if (r < 0) \
55 return; \
56 break; \
57 case TEST_LE: \
58 if (r <= 0) \
59 return; \
60 break; \
61 case TEST_GT: \
62 if (r > 0) \
63 return; \
64 break; \
65 case TEST_GE: \
66 if (r >= 0) \
67 return; \
68 break; \
69 default: \
70 abort(); \
71 } \
72 } while (0)
73
74#define TEST_CHECK(x1, x2, pred) do { \
75 switch (pred) { \
76 case TEST_EQ: \
77 if (x1 == x2) \
78 return; \
79 break; \
80 case TEST_NE: \
81 if (x1 != x2) \
82 return; \
83 break; \
84 case TEST_LT: \
85 if (x1 < x2) \
86 return; \
87 break; \
88 case TEST_LE: \
89 if (x1 <= x2) \
90 return; \
91 break; \
92 case TEST_GT: \
93 if (x1 > x2) \
94 return; \
95 break; \
96 case TEST_GE: \
97 if (x1 >= x2) \
98 return; \
99 break; \
100 default: \
101 abort(); \
102 } \
103 } while (0)
104
105extern char *__progname;
106
107static int verbose_mode = 0;
108static int quiet_mode = 0;
109static char *active_test_name = NULL;
110static u_int test_number = 0;
111static test_onerror_func_t *test_onerror = NULL;
112static void *onerror_ctx = NULL;
113static const char *data_dir = NULL;
114
115int
116main(int argc, char **argv)
117{
118 int ch;
119
120 /* Handle systems without __progname */
121 if (__progname == NULL) {
122 __progname = strrchr(argv[0], '/');
123 if (__progname == NULL || __progname[1] == '\0')
124 __progname = argv[0];
125 else
126 __progname++;
127 if ((__progname = strdup(__progname)) == NULL) {
128 fprintf(stderr, "strdup failed\n");
129 exit(1);
130 }
131 }
132
133 while ((ch = getopt(argc, argv, "vqd:")) != -1) {
134 switch (ch) {
135 case 'd':
136 data_dir = optarg;
137 break;
138 case 'q':
139 verbose_mode = 0;
140 quiet_mode = 1;
141 break;
142 case 'v':
143 verbose_mode = 1;
144 quiet_mode = 0;
145 break;
146 default:
147 fprintf(stderr, "Unrecognised command line option\n");
148 fprintf(stderr, "Usage: %s [-v]\n", __progname);
149 exit(1);
150 }
151 }
152 setvbuf(stdout, NULL, _IONBF, 0);
153 if (!quiet_mode)
154 printf("%s: ", __progname);
155 if (verbose_mode)
156 printf("\n");
157
158 tests();
159
160 if (!quiet_mode)
161 printf(" %u tests ok\n", test_number);
162 return 0;
163}
164
165const char *
166test_data_file(const char *name)
167{
168 static char ret[PATH_MAX];
169
170 if (data_dir != NULL)
171 snprintf(ret, sizeof(ret), "%s/%s", data_dir, name);
172 else
173 strlcpy(ret, name, sizeof(ret));
174 if (access(ret, F_OK) != 0) {
175 fprintf(stderr, "Cannot access data file %s: %s\n",
176 ret, strerror(errno));
177 exit(1);
178 }
179 return ret;
180}
181
182void
183test_start(const char *n)
184{
185 assert(active_test_name == NULL);
186 assert((active_test_name = strdup(n)) != NULL);
187 if (verbose_mode)
188 printf("test %u - \"%s\": ", test_number, active_test_name);
189 test_number++;
190}
191
192void
193set_onerror_func(test_onerror_func_t *f, void *ctx)
194{
195 test_onerror = f;
196 onerror_ctx = ctx;
197}
198
199void
200test_done(void)
201{
202 assert(active_test_name != NULL);
203 free(active_test_name);
204 active_test_name = NULL;
205 if (verbose_mode)
206 printf("OK\n");
207 else if (!quiet_mode) {
208 printf(".");
209 fflush(stdout);
210 }
211}
212
213void
214ssl_err_check(const char *file, int line)
215{
216 long openssl_error = ERR_get_error();
217
218 if (openssl_error == 0)
219 return;
220
221 fprintf(stderr, "\n%s:%d: uncaught OpenSSL error: %s",
222 file, line, ERR_error_string(openssl_error, NULL));
223 abort();
224}
225
226static const char *
227pred_name(enum test_predicate p)
228{
229 switch (p) {
230 case TEST_EQ:
231 return "EQ";
232 case TEST_NE:
233 return "NE";
234 case TEST_LT:
235 return "LT";
236 case TEST_LE:
237 return "LE";
238 case TEST_GT:
239 return "GT";
240 case TEST_GE:
241 return "GE";
242 default:
243 return "UNKNOWN";
244 }
245}
246
247static void
248test_die(void)
249{
250 if (test_onerror != NULL)
251 test_onerror(onerror_ctx);
252 abort();
253}
254
255static void
256test_header(const char *file, int line, const char *a1, const char *a2,
257 const char *name, enum test_predicate pred)
258{
259 fprintf(stderr, "\n%s:%d test #%u \"%s\"\n",
260 file, line, test_number, active_test_name);
261 fprintf(stderr, "ASSERT_%s_%s(%s%s%s) failed:\n",
262 name, pred_name(pred), a1,
263 a2 != NULL ? ", " : "", a2 != NULL ? a2 : "");
264}
265
266void
267assert_bignum(const char *file, int line, const char *a1, const char *a2,
268 const BIGNUM *aa1, const BIGNUM *aa2, enum test_predicate pred)
269{
270 int r = BN_cmp(aa1, aa2);
271
272 TEST_CHECK_INT(r, pred);
273 test_header(file, line, a1, a2, "BIGNUM", pred);
274 fprintf(stderr, "%12s = 0x%s\n", a1, BN_bn2hex(aa1));
275 fprintf(stderr, "%12s = 0x%s\n", a2, BN_bn2hex(aa2));
276 test_die();
277}
278
279void
280assert_string(const char *file, int line, const char *a1, const char *a2,
281 const char *aa1, const char *aa2, enum test_predicate pred)
282{
283 int r = strcmp(aa1, aa2);
284
285 TEST_CHECK_INT(r, pred);
286 test_header(file, line, a1, a2, "STRING", pred);
287 fprintf(stderr, "%12s = %s (len %zu)\n", a1, aa1, strlen(aa1));
288 fprintf(stderr, "%12s = %s (len %zu)\n", a2, aa2, strlen(aa2));
289 test_die();
290}
291
292static char *
293tohex(const void *_s, size_t l)
294{
295 u_int8_t *s = (u_int8_t *)_s;
296 size_t i, j;
297 const char *hex = "0123456789abcdef";
298 char *r = malloc((l * 2) + 1);
299
300 assert(r != NULL);
301 for (i = j = 0; i < l; i++) {
302 r[j++] = hex[(s[i] >> 4) & 0xf];
303 r[j++] = hex[s[i] & 0xf];
304 }
305 r[j] = '\0';
306 return r;
307}
308
309void
310assert_mem(const char *file, int line, const char *a1, const char *a2,
311 const void *aa1, const void *aa2, size_t l, enum test_predicate pred)
312{
313 int r = memcmp(aa1, aa2, l);
314
315 TEST_CHECK_INT(r, pred);
316 test_header(file, line, a1, a2, "STRING", pred);
317 fprintf(stderr, "%12s = %s (len %zu)\n", a1, tohex(aa1, MIN(l, 256)), l);
318 fprintf(stderr, "%12s = %s (len %zu)\n", a2, tohex(aa2, MIN(l, 256)), l);
319 test_die();
320}
321
322static int
323memvalcmp(const u_int8_t *s, u_char v, size_t l, size_t *where)
324{
325 size_t i;
326
327 for (i = 0; i < l; i++) {
328 if (s[i] != v) {
329 *where = i;
330 return 1;
331 }
332 }
333 return 0;
334}
335
336void
337assert_mem_filled(const char *file, int line, const char *a1,
338 const void *aa1, u_char v, size_t l, enum test_predicate pred)
339{
340 size_t where = -1;
341 int r = memvalcmp(aa1, v, l, &where);
342 char tmp[64];
343
344 if (l == 0)
345 return;
346 TEST_CHECK_INT(r, pred);
347 test_header(file, line, a1, NULL, "MEM_ZERO", pred);
348 fprintf(stderr, "%20s = %s%s (len %zu)\n", a1,
349 tohex(aa1, MIN(l, 20)), l > 20 ? "..." : "", l);
350 snprintf(tmp, sizeof(tmp), "(%s)[%zu]", a1, where);
351 fprintf(stderr, "%20s = 0x%02x (expected 0x%02x)\n", tmp,
352 ((u_char *)aa1)[where], v);
353 test_die();
354}
355
356void
357assert_int(const char *file, int line, const char *a1, const char *a2,
358 int aa1, int aa2, enum test_predicate pred)
359{
360 TEST_CHECK(aa1, aa2, pred);
361 test_header(file, line, a1, a2, "INT", pred);
362 fprintf(stderr, "%12s = %d\n", a1, aa1);
363 fprintf(stderr, "%12s = %d\n", a2, aa2);
364 test_die();
365}
366
367void
368assert_size_t(const char *file, int line, const char *a1, const char *a2,
369 size_t aa1, size_t aa2, enum test_predicate pred)
370{
371 TEST_CHECK(aa1, aa2, pred);
372 test_header(file, line, a1, a2, "SIZE_T", pred);
373 fprintf(stderr, "%12s = %zu\n", a1, aa1);
374 fprintf(stderr, "%12s = %zu\n", a2, aa2);
375 test_die();
376}
377
378void
379assert_u_int(const char *file, int line, const char *a1, const char *a2,
380 u_int aa1, u_int aa2, enum test_predicate pred)
381{
382 TEST_CHECK(aa1, aa2, pred);
383 test_header(file, line, a1, a2, "U_INT", pred);
384 fprintf(stderr, "%12s = %u / 0x%x\n", a1, aa1, aa1);
385 fprintf(stderr, "%12s = %u / 0x%x\n", a2, aa2, aa2);
386 test_die();
387}
388
389void
390assert_long_long(const char *file, int line, const char *a1, const char *a2,
391 long long aa1, long long aa2, enum test_predicate pred)
392{
393 TEST_CHECK(aa1, aa2, pred);
394 test_header(file, line, a1, a2, "LONG LONG", pred);
395 fprintf(stderr, "%12s = %lld / 0x%llx\n", a1, aa1, aa1);
396 fprintf(stderr, "%12s = %lld / 0x%llx\n", a2, aa2, aa2);
397 test_die();
398}
399
400void
401assert_char(const char *file, int line, const char *a1, const char *a2,
402 char aa1, char aa2, enum test_predicate pred)
403{
404 char buf[8];
405
406 TEST_CHECK(aa1, aa2, pred);
407 test_header(file, line, a1, a2, "CHAR", pred);
408 fprintf(stderr, "%12s = '%s' / 0x02%x\n", a1,
409 vis(buf, aa1, VIS_SAFE|VIS_NL|VIS_TAB|VIS_OCTAL, 0), aa1);
410 fprintf(stderr, "%12s = '%s' / 0x02%x\n", a1,
411 vis(buf, aa2, VIS_SAFE|VIS_NL|VIS_TAB|VIS_OCTAL, 0), aa2);
412 test_die();
413}
414
415void
416assert_u8(const char *file, int line, const char *a1, const char *a2,
417 u_int8_t aa1, u_int8_t aa2, enum test_predicate pred)
418{
419 TEST_CHECK(aa1, aa2, pred);
420 test_header(file, line, a1, a2, "U8", pred);
421 fprintf(stderr, "%12s = 0x%02x %u\n", a1, aa1, aa1);
422 fprintf(stderr, "%12s = 0x%02x %u\n", a2, aa2, aa2);
423 test_die();
424}
425
426void
427assert_u16(const char *file, int line, const char *a1, const char *a2,
428 u_int16_t aa1, u_int16_t aa2, enum test_predicate pred)
429{
430 TEST_CHECK(aa1, aa2, pred);
431 test_header(file, line, a1, a2, "U16", pred);
432 fprintf(stderr, "%12s = 0x%04x %u\n", a1, aa1, aa1);
433 fprintf(stderr, "%12s = 0x%04x %u\n", a2, aa2, aa2);
434 test_die();
435}
436
437void
438assert_u32(const char *file, int line, const char *a1, const char *a2,
439 u_int32_t aa1, u_int32_t aa2, enum test_predicate pred)
440{
441 TEST_CHECK(aa1, aa2, pred);
442 test_header(file, line, a1, a2, "U32", pred);
443 fprintf(stderr, "%12s = 0x%08x %u\n", a1, aa1, aa1);
444 fprintf(stderr, "%12s = 0x%08x %u\n", a2, aa2, aa2);
445 test_die();
446}
447
448void
449assert_u64(const char *file, int line, const char *a1, const char *a2,
450 u_int64_t aa1, u_int64_t aa2, enum test_predicate pred)
451{
452 TEST_CHECK(aa1, aa2, pred);
453 test_header(file, line, a1, a2, "U64", pred);
454 fprintf(stderr, "%12s = 0x%016llx %llu\n", a1,
455 (unsigned long long)aa1, (unsigned long long)aa1);
456 fprintf(stderr, "%12s = 0x%016llx %llu\n", a2,
457 (unsigned long long)aa2, (unsigned long long)aa2);
458 test_die();
459}
460
461void
462assert_ptr(const char *file, int line, const char *a1, const char *a2,
463 const void *aa1, const void *aa2, enum test_predicate pred)
464{
465 TEST_CHECK(aa1, aa2, pred);
466 test_header(file, line, a1, a2, "PTR", pred);
467 fprintf(stderr, "%12s = %p\n", a1, aa1);
468 fprintf(stderr, "%12s = %p\n", a2, aa2);
469 test_die();
470}
471