2 * Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
10 #include "../testutil.h"
16 #include "../../e_os.h"
18 /* The size of memory buffers to display on failure */
19 #define MEM_BUFFER_SIZE (33)
20 #define MAX_STRING_WIDTH (80)
22 /* Special representation of -0 */
23 static char BN_minus_zero[] = "-0";
25 /* Output a failed test first line */
26 static void test_fail_message_prefix(const char *prefix, const char *file,
27 int line, const char *type,
28 const char *left, const char *right,
31 test_printf_stderr("%*s# %s: ", subtest_level(), "",
32 prefix != NULL ? prefix : "ERROR");
34 test_printf_stderr("(%s) ", type);
36 test_printf_stderr("%s %s %s", left, op, right);
38 test_printf_stderr(" @ %s:%d", file, line);
40 test_printf_stderr("\n");
43 /* Output a diff header */
44 static void test_diff_header(const char *left, const char *right)
46 test_printf_stderr("%*s# --- %s\n", subtest_level(), "", left);
47 test_printf_stderr("%*s# +++ %s\n", subtest_level(), "", right);
51 * A common routine to output test failure messages. Generally this should not
52 * be called directly, rather it should be called by the following functions.
54 * |desc| is a printf formatted description with arguments |args| that is
55 * supplied by the user and |desc| can be NULL. |type| is the data type
56 * that was tested (int, char, ptr, ...). |fmt| is a system provided
57 * printf format with following arguments that spell out the failure
58 * details i.e. the actual values compared and the operator used.
60 * The typical use for this is from an utility test function:
62 * int test6(const char *file, int line, int n) {
64 * test_fail_message(1, file, line, "int", "value %d is not %d", n, 6);
70 * calling test6(3, "oops") will return 0 and produce out along the lines of:
71 * FAIL oops: (int) value 3 is not 6\n
73 static void test_fail_message(const char *prefix, const char *file, int line,
74 const char *type, const char *left,
75 const char *right, const char *op,
79 static void test_fail_message_va(const char *prefix, const char *file,
80 int line, const char *type,
81 const char *left, const char *right,
82 const char *op, const char *fmt, va_list ap)
84 test_fail_message_prefix(prefix, file, line, type, left, right, op);
86 test_printf_stderr("%*s# ", subtest_level(), "");
87 test_vprintf_stderr(fmt, ap);
88 test_printf_stderr("\n");
90 test_printf_stderr("\n");
94 static void test_fail_string_message(const char *prefix, const char *file,
95 int line, const char *type,
96 const char *left, const char *right,
97 const char *op, const char *m1, size_t l1,
98 const char *m2, size_t l2)
100 const int indent = subtest_level();
101 const size_t width = (MAX_STRING_WIDTH - indent - 12) / 16 * 16;
102 char b1[MAX_STRING_WIDTH + 1], b2[MAX_STRING_WIDTH + 1];
103 char bdiff[MAX_STRING_WIDTH + 1];
105 unsigned int cnt = 0, diff;
107 test_fail_message_prefix(prefix, file, line, type, left, right, op);
112 if (l1 == 0 && l2 == 0) {
113 if ((m1 == NULL) == (m2 == NULL)) {
114 test_printf_stderr("%*s# % 4s %s\n", indent, "", "",
115 m1 == NULL ? "NULL" : "''");
117 test_diff_header(left, right);
118 test_printf_stderr("%*s# % 4s - %s\n", indent, "", "",
119 m1 == NULL ? "NULL" : "''");
120 test_printf_stderr("%*s# % 4s + %s\n", indent, "", "",
121 m2 == NULL ? "NULL" : "''");
126 if (l1 != l2 || strcmp(m1, m2) != 0)
127 test_diff_header(left, right);
129 while (l1 > 0 || l2 > 0) {
132 b1[n1 = l1 > width ? width : l1] = 0;
133 for (i = 0; i < n1; i++)
134 b1[i] = isprint(m1[i]) ? m1[i] : '.';
137 b2[n2 = l2 > width ? width : l2] = 0;
138 for (i = 0; i < n2; i++)
139 b2[i] = isprint(m2[i]) ? m2[i] : '.';
143 if (n1 > 0 && n2 > 0) {
144 const size_t j = n1 < n2 ? n1 : n2;
145 const size_t k = n1 > n2 ? n1 : n2;
148 if (m1[i] == m2[i]) {
159 test_printf_stderr("%*s# % 4u: '%s'\n", indent, "", cnt, b1);
161 if (cnt == 0 && m1 == NULL)
162 test_printf_stderr("%*s# % 4s - NULL\n", indent, "", "");
163 else if (cnt == 0 && *m1 == '\0')
164 test_printf_stderr("%*s# % 4s - ''\n", indent, "", "");
166 test_printf_stderr("%*s# % 4u:- '%s'\n", indent, "", cnt, b1);
167 if (cnt == 0 && m2 == NULL)
168 test_printf_stderr("%*s# % 4s + NULL\n", indent, "", "");
169 else if (cnt == 0 && *m2 == '\0')
170 test_printf_stderr("%*s# % 4s + ''\n", indent, "", "");
172 test_printf_stderr("%*s# % 4u:+ '%s'\n", indent, "", cnt, b2);
174 test_printf_stderr("%*s# % 4s %s\n", indent, "", "", bdiff);
183 test_printf_stderr("\n");
187 static char *convertBN(const BIGNUM *b)
191 if (BN_is_zero(b) && BN_is_negative(b))
192 return BN_minus_zero;
196 static void test_fail_bignum_message(const char *prefix, const char *file,
197 int line, const char *type,
198 const char *left, const char *right,
200 const BIGNUM *bn1, const BIGNUM *bn2)
202 char *s1 = convertBN(bn1), *s2 = convertBN(bn2);
203 size_t l1 = s1 != NULL ? strlen(s1) : 0;
204 size_t l2 = s2 != NULL ? strlen(s2) : 0;
206 test_fail_string_message(prefix, file, line, type, left, right, op,
208 if (s1 != BN_minus_zero)
210 if (s2 != BN_minus_zero)
214 static void test_fail_bignum_mono_message(const char *prefix, const char *file,
215 int line, const char *type,
216 const char *left, const char *right,
217 const char *op, const BIGNUM *bn)
219 char *s = convertBN(bn);
220 size_t l = s != NULL ? strlen(s) : 0;
222 test_fail_string_message(prefix, file, line, type, left, right, op,
224 if (s != BN_minus_zero)
228 static void hex_convert_memory(const char *m, size_t n, char *b)
232 for (i = 0; i < n; i++) {
233 const unsigned char c = *m++;
235 *b++ = "0123456789abcdef"[c >> 4];
236 *b++ = "0123456789abcdef"[c & 15];
237 if ((i % 8) == 7 && i != n - 1)
243 static void test_fail_memory_message(const char *prefix, const char *file,
244 int line, const char *type,
245 const char *left, const char *right,
246 const char *op, const char *m1, size_t l1,
247 const char *m2, size_t l2)
249 const int indent = subtest_level();
250 const size_t bytes = (MAX_STRING_WIDTH - 9) / 17 * 8;
251 char b1[MAX_STRING_WIDTH + 1], b2[MAX_STRING_WIDTH + 1];
252 char *p, bdiff[MAX_STRING_WIDTH + 1];
254 unsigned int cnt = 0, diff;
256 test_fail_message_prefix(prefix, file, line, type, left, right, op);
261 if (l1 == 0 && l2 == 0) {
262 if ((m1 == NULL) == (m2 == NULL)) {
263 test_printf_stderr("%*s# %04s %s\n", indent, "", "",
264 m1 == NULL ? "NULL" : "empty");
266 test_diff_header(left, right);
267 test_printf_stderr("%*s# %04s -%s\n", indent, "", "",
268 m1 == NULL ? "NULL" : "empty");
269 test_printf_stderr("%*s# %04s +%s\n", indent, "", "",
270 m2 == NULL ? "NULL" : "empty");
275 if (l1 != l2 || memcmp(m1, m2, l1) != 0)
276 test_diff_header(left, right);
278 while (l1 > 0 || l2 > 0) {
281 n1 = l1 > bytes ? bytes : l1;
282 hex_convert_memory(m1, n1, b1);
285 n2 = l2 > bytes ? bytes : l2;
286 hex_convert_memory(m2, n2, b2);
292 if (n1 > 0 && n2 > 0) {
293 const size_t j = n1 < n2 ? n1 : n2;
294 const size_t k = n1 > n2 ? n1 : n2;
297 if (m1[i] == m2[i]) {
305 if ((i % 8) == 7 && (i != j - 1 || j != k))
312 if ((i % 8) == 7 && i != k - 1)
319 test_printf_stderr("%*s# %04x: %s\n", indent, "", cnt, b1);
321 if (cnt == 0 && m1 == NULL)
322 test_printf_stderr("%*s# %04s -NULL\n", indent, "", "");
323 else if (cnt == 0 && l1 == 0)
324 test_printf_stderr("%*s# %04s -empty\n", indent, "", "");
326 test_printf_stderr("%*s# %04x:-%s\n", indent, "", cnt, b1);
327 if (cnt == 0 && m2 == NULL)
328 test_printf_stderr("%*s# %04s +NULL\n", indent, "", "");
329 else if (cnt == 0 && l2 == 0)
330 test_printf_stderr("%*s# %04s +empty\n", indent, "", "");
332 test_printf_stderr("%*s# %04x:+%s\n", indent, "", cnt, b2);
334 test_printf_stderr("%*s# % 4s %s\n", indent, "", "", bdiff);
343 test_printf_stderr("\n");
347 static void test_fail_message(const char *prefix, const char *file,
348 int line, const char *type,
349 const char *left, const char *right,
350 const char *op, const char *fmt, ...)
355 test_fail_message_va(prefix, file, line, type, left, right, op, fmt, ap);
359 void test_info_c90(const char *desc, ...)
364 test_fail_message_va("INFO", NULL, -1, NULL, NULL, NULL, NULL, desc, ap);
368 void test_info(const char *file, int line, const char *desc, ...)
373 test_fail_message_va("INFO", file, line, NULL, NULL, NULL, NULL, desc, ap);
377 void test_error_c90(const char *desc, ...)
382 test_fail_message(NULL, NULL, -1, NULL, NULL, NULL, NULL, desc, ap);
386 void test_error(const char *file, int line, const char *desc, ...)
391 test_fail_message_va(NULL, file, line, NULL, NULL, NULL, NULL, desc, ap);
395 void test_openssl_errors(void)
397 ERR_print_errors_cb(openssl_error_cb, NULL);
401 * Define some comparisons between pairs of various types.
402 * These functions return 1 if the test is true.
403 * Otherwise, they return 0 and pretty-print diagnostics.
405 * In each case the functions produced are:
406 * int test_name_eq(const type t1, const type t2, const char *desc, ...);
407 * int test_name_ne(const type t1, const type t2, const char *desc, ...);
408 * int test_name_lt(const type t1, const type t2, const char *desc, ...);
409 * int test_name_le(const type t1, const type t2, const char *desc, ...);
410 * int test_name_gt(const type t1, const type t2, const char *desc, ...);
411 * int test_name_ge(const type t1, const type t2, const char *desc, ...);
413 * The t1 and t2 arguments are to be compared for equality, inequality,
414 * less than, less than or equal to, greater than and greater than or
415 * equal to respectively. If the specified condition holds, the functions
416 * return 1. If the condition does not hold, the functions print a diagnostic
417 * message and return 0.
419 * The desc argument is a printf format string followed by its arguments and
420 * this is included in the output if the condition being tested for is false.
422 #define DEFINE_COMPARISON(type, name, opname, op, fmt) \
423 int test_ ## name ## _ ## opname(const char *file, int line, \
424 const char *s1, const char *s2, \
425 const type t1, const type t2) \
429 test_fail_message(NULL, file, line, #type, s1, s2, #op, \
430 "[" fmt "] compared to [" fmt "]", \
435 #define DEFINE_COMPARISONS(type, name, fmt) \
436 DEFINE_COMPARISON(type, name, eq, ==, fmt) \
437 DEFINE_COMPARISON(type, name, ne, !=, fmt) \
438 DEFINE_COMPARISON(type, name, lt, <, fmt) \
439 DEFINE_COMPARISON(type, name, le, <=, fmt) \
440 DEFINE_COMPARISON(type, name, gt, >, fmt) \
441 DEFINE_COMPARISON(type, name, ge, >=, fmt)
443 DEFINE_COMPARISONS(int, int, "%d")
444 DEFINE_COMPARISONS(unsigned int, uint, "%u")
445 DEFINE_COMPARISONS(char, char, "%c")
446 DEFINE_COMPARISONS(unsigned char, uchar, "%u")
447 DEFINE_COMPARISONS(long, long, "%ld")
448 DEFINE_COMPARISONS(unsigned long, ulong, "%lu")
449 DEFINE_COMPARISONS(size_t, size_t, "%zu")
451 DEFINE_COMPARISON(void *, ptr, eq, ==, "%p")
452 DEFINE_COMPARISON(void *, ptr, ne, !=, "%p")
454 int test_ptr_null(const char *file, int line, const char *s, const void *p)
458 test_fail_message(NULL, file, line, "ptr", s, "NULL", "==", "%p", p);
462 int test_ptr(const char *file, int line, const char *s, const void *p)
466 test_fail_message(NULL, file, line, "ptr", s, "NULL", "!=", "%p", p);
470 int test_true(const char *file, int line, const char *s, int b)
474 test_fail_message(NULL, file, line, "bool", s, "true", "==", "false");
478 int test_false(const char *file, int line, const char *s, int b)
482 test_fail_message(NULL, file, line, "bool", s, "false", "==", "true");
486 int test_str_eq(const char *file, int line, const char *st1, const char *st2,
487 const char *s1, const char *s2)
489 if (s1 == NULL && s2 == NULL)
491 if (s1 == NULL || s2 == NULL || strcmp(s1, s2) != 0) {
492 test_fail_string_message(NULL, file, line, "string", st1, st2, "==",
493 s1, s1 == NULL ? 0 : strlen(s1),
494 s2, s2 == NULL ? 0 : strlen(s2));
500 int test_str_ne(const char *file, int line, const char *st1, const char *st2,
501 const char *s1, const char *s2)
503 if ((s1 == NULL) ^ (s2 == NULL))
505 if (s1 == NULL || strcmp(s1, s2) == 0) {
506 test_fail_string_message(NULL, file, line, "string", st1, st2, "!=",
507 s1, s1 == NULL ? 0 : strlen(s1),
508 s2, s2 == NULL ? 0 : strlen(s2));
514 int test_strn_eq(const char *file, int line, const char *st1, const char *st2,
515 const char *s1, const char *s2, size_t len)
517 if (s1 == NULL && s2 == NULL)
519 if (s1 == NULL || s2 == NULL || strncmp(s1, s2, len) != 0) {
520 test_fail_string_message(NULL, file, line, "string", st1, st2, "==",
521 s1, s1 == NULL ? 0 : OPENSSL_strnlen(s1, len),
522 s2, s2 == NULL ? 0 : OPENSSL_strnlen(s2, len));
528 int test_strn_ne(const char *file, int line, const char *st1, const char *st2,
529 const char *s1, const char *s2, size_t len)
531 if ((s1 == NULL) ^ (s2 == NULL))
533 if (s1 == NULL || strncmp(s1, s2, len) == 0) {
534 test_fail_string_message(NULL, file, line, "string", st1, st2, "!=",
535 s1, s1 == NULL ? 0 : OPENSSL_strnlen(s1, len),
536 s2, s2 == NULL ? 0 : OPENSSL_strnlen(s2, len));
542 int test_mem_eq(const char *file, int line, const char *st1, const char *st2,
543 const void *s1, size_t n1, const void *s2, size_t n2)
545 if (s1 == NULL && s2 == NULL)
547 if (n1 != n2 || s1 == NULL || s2 == NULL || memcmp(s1, s2, n1) != 0) {
548 test_fail_memory_message(NULL, file, line, "memory", st1, st2, "==",
555 int test_mem_ne(const char *file, int line, const char *st1, const char *st2,
556 const void *s1, size_t n1, const void *s2, size_t n2)
558 if ((s1 == NULL) ^ (s2 == NULL))
562 if (s1 == NULL || memcmp(s1, s2, n1) == 0) {
563 test_fail_memory_message(NULL, file, line, "memory", st1, st2, "!=",
570 #define DEFINE_BN_COMPARISONS(opname, op, zero_cond) \
571 int test_BN_ ## opname(const char *file, int line, \
572 const char *s1, const char *s2, \
573 const BIGNUM *t1, const BIGNUM *t2) \
575 if (BN_cmp(t1, t2) op 0) \
577 test_fail_bignum_message(NULL, file, line, "BIGNUM", s1, s2, \
581 int test_BN_ ## opname ## _zero(const char *file, int line, \
582 const char *s, const BIGNUM *a) \
584 if (a != NULL &&(zero_cond)) \
586 test_fail_bignum_mono_message(NULL, file, line, "BIGNUM", \
591 DEFINE_BN_COMPARISONS(eq, ==, BN_is_zero(a))
592 DEFINE_BN_COMPARISONS(ne, !=, !BN_is_zero(a))
593 DEFINE_BN_COMPARISONS(gt, >, !BN_is_negative(a) && !BN_is_zero(a))
594 DEFINE_BN_COMPARISONS(ge, >=, !BN_is_negative(a) || BN_is_zero(a))
595 DEFINE_BN_COMPARISONS(lt, <, BN_is_negative(a) && !BN_is_zero(a))
596 DEFINE_BN_COMPARISONS(le, <=, BN_is_negative(a) || BN_is_zero(a))
598 int test_BN_eq_one(const char *file, int line, const char *s, const BIGNUM *a)
600 if (a != NULL && BN_is_one(a))
602 test_fail_bignum_mono_message(NULL, file, line, "BIGNUM", s, "1", "==", a);
606 int test_BN_odd(const char *file, int line, const char *s, const BIGNUM *a)
608 if (a != NULL && BN_is_odd(a))
610 test_fail_bignum_mono_message(NULL, file, line, "BIGNUM", "ODD(", ")", s,
615 int test_BN_even(const char *file, int line, const char *s, const BIGNUM *a)
617 if (a != NULL && !BN_is_odd(a))
619 test_fail_bignum_mono_message(NULL, file, line, "BIGNUM", "EVEN(", ")", s,
624 int test_BN_eq_word(const char *file, int line, const char *bns, const char *ws,
625 const BIGNUM *a, BN_ULONG w)
629 if (a != NULL && BN_is_word(a, w))
633 test_fail_bignum_message(NULL, file, line, "BIGNUM", bns, ws, "==", a, bw);
638 int test_BN_abs_eq_word(const char *file, int line, const char *bns,
639 const char *ws, const BIGNUM *a, BN_ULONG w)
643 if (a != NULL && BN_abs_is_word(a, w))
647 BN_set_negative(aa, 0);
649 test_fail_bignum_message(NULL, file, line, "BIGNUM", bns, ws, "abs==",