X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=test%2Ftestutil%2Ftests.c;h=a60af0764f62f160348635e68ba3a13973acd9e7;hp=a6c9a99df0fb767576065c4f7cc5cc505774d230;hb=b7af3f1433cc0d8d5f88c0b8dcd55c0c2261281a;hpb=4f2a569535953b43f7d55ac6df60458dce326221 diff --git a/test/testutil/tests.c b/test/testutil/tests.c index a6c9a99df0..a60af0764f 100644 --- a/test/testutil/tests.c +++ b/test/testutil/tests.c @@ -11,42 +11,38 @@ #include "output.h" #include "tu_local.h" +#include #include #include -#include "../../e_os.h" +#include "internal/nelem.h" +#include -/* The size of memory buffers to display on failure */ -#define MEM_BUFFER_SIZE (33) -#define MAX_STRING_WIDTH (80) - -/* Special representation of -0 */ -static char BN_minus_zero[] = "-0"; - -/* Output a failed test first line */ -static void test_fail_message_prefix(const char *prefix, const char *file, - int line, const char *type, - const char *left, const char *right, - const char *op) +/* + * Output a failed test first line. + * All items are optional are generally not preinted if passed as NULL. + * The special cases are for prefix where "ERROR" is assumed and for left + * and right where a non-failure message is produced if either is NULL. + */ +void test_fail_message_prefix(const char *prefix, const char *file, + int line, const char *type, + const char *left, const char *right, + const char *op) { - test_printf_stderr("%*s# %s: ", subtest_level(), "", - prefix != NULL ? prefix : "ERROR"); + test_printf_stderr("%s: ", prefix != NULL ? prefix : "ERROR"); if (type) test_printf_stderr("(%s) ", type); - if (op != NULL) - test_printf_stderr("'%s %s %s' failed", left, op, right); + if (op != NULL) { + if (left != NULL && right != NULL) + test_printf_stderr("'%s %s %s' failed", left, op, right); + else + test_printf_stderr("'%s'", op); + } if (file != NULL) { test_printf_stderr(" @ %s:%d", file, line); } test_printf_stderr("\n"); } -/* Output a diff header */ -static void test_diff_header(const char *left, const char *right) -{ - test_printf_stderr("%*s# --- %s\n", subtest_level(), "", left); - test_printf_stderr("%*s# +++ %s\n", subtest_level(), "", right); -} - /* * A common routine to output test failure messages. Generally this should not * be called directly, rather it should be called by the following functions. @@ -83,264 +79,9 @@ static void test_fail_message_va(const char *prefix, const char *file, { test_fail_message_prefix(prefix, file, line, type, left, right, op); if (fmt != NULL) { - test_printf_stderr("%*s# ", subtest_level(), ""); test_vprintf_stderr(fmt, ap); test_printf_stderr("\n"); } - test_printf_stderr("\n"); - test_flush_stderr(); -} - -static void test_fail_string_message(const char *prefix, const char *file, - int line, const char *type, - const char *left, const char *right, - const char *op, const char *m1, size_t l1, - const char *m2, size_t l2) -{ - const int indent = subtest_level(); - const size_t width = (MAX_STRING_WIDTH - indent - 12) / 16 * 16; - char b1[MAX_STRING_WIDTH + 1], b2[MAX_STRING_WIDTH + 1]; - char bdiff[MAX_STRING_WIDTH + 1]; - size_t n1, n2, i; - unsigned int cnt = 0, diff; - - test_fail_message_prefix(prefix, file, line, type, left, right, op); - if (m1 == NULL) - l1 = 0; - if (m2 == NULL) - l2 = 0; - if (l1 == 0 && l2 == 0) { - if ((m1 == NULL) == (m2 == NULL)) { - test_printf_stderr("%*s# % 4s %s\n", indent, "", "", - m1 == NULL ? "NULL" : "''"); - } else { - test_diff_header(left, right); - test_printf_stderr("%*s# % 4s - %s\n", indent, "", "", - m1 == NULL ? "NULL" : "''"); - test_printf_stderr("%*s# % 4s + %s\n", indent, "", "", - m2 == NULL ? "NULL" : "''"); - } - goto fin; - } - - if (l1 != l2 || strcmp(m1, m2) != 0) - test_diff_header(left, right); - - while (l1 > 0 || l2 > 0) { - n1 = n2 = 0; - if (l1 > 0) { - b1[n1 = l1 > width ? width : l1] = 0; - for (i = 0; i < n1; i++) - b1[i] = isprint(m1[i]) ? m1[i] : '.'; - } - if (l2 > 0) { - b2[n2 = l2 > width ? width : l2] = 0; - for (i = 0; i < n2; i++) - b2[i] = isprint(m2[i]) ? m2[i] : '.'; - } - diff = n1 != n2; - i = 0; - if (n1 > 0 && n2 > 0) { - const size_t j = n1 < n2 ? n1 : n2; - const size_t k = n1 > n2 ? n1 : n2; - - for (; i < j; i++) - if (m1[i] == m2[i]) { - bdiff[i] = ' '; - } else { - bdiff[i] = '^'; - diff = 1; - } - for (; i < k; i++) - bdiff[i] = '^'; - bdiff[i] = '\0'; - } - if (!diff) { - test_printf_stderr("%*s# % 4u: '%s'\n", indent, "", cnt, b1); - } else { - if (cnt == 0 && m1 == NULL) - test_printf_stderr("%*s# % 4s - NULL\n", indent, "", ""); - else if (cnt == 0 && *m1 == '\0') - test_printf_stderr("%*s# % 4s - ''\n", indent, "", ""); - else if (n1 > 0) - test_printf_stderr("%*s# % 4u:- '%s'\n", indent, "", cnt, b1); - if (cnt == 0 && m2 == NULL) - test_printf_stderr("%*s# % 4s + NULL\n", indent, "", ""); - else if (cnt == 0 && *m2 == '\0') - test_printf_stderr("%*s# % 4s + ''\n", indent, "", ""); - else if (n2 > 0) - test_printf_stderr("%*s# % 4u:+ '%s'\n", indent, "", cnt, b2); - if (i > 0) - test_printf_stderr("%*s# % 4s %s\n", indent, "", "", bdiff); - } - m1 += n1; - m2 += n2; - l1 -= n1; - l2 -= n2; - cnt += width; - } -fin: - test_printf_stderr("\n"); - test_flush_stderr(); -} - -static char *convertBN(const BIGNUM *b) -{ - if (b == NULL) - return NULL; - if (BN_is_zero(b) && BN_is_negative(b)) - return BN_minus_zero; - return BN_bn2hex(b); -} - -static void test_fail_bignum_message(const char *prefix, const char *file, - int line, const char *type, - const char *left, const char *right, - const char *op, - const BIGNUM *bn1, const BIGNUM *bn2) -{ - char *s1 = convertBN(bn1), *s2 = convertBN(bn2); - size_t l1 = s1 != NULL ? strlen(s1) : 0; - size_t l2 = s2 != NULL ? strlen(s2) : 0; - - test_fail_string_message(prefix, file, line, type, left, right, op, - s1, l1, s2, l2); - if (s1 != BN_minus_zero) - OPENSSL_free(s1); - if (s2 != BN_minus_zero) - OPENSSL_free(s2); -} - -static void test_fail_bignum_mono_message(const char *prefix, const char *file, - int line, const char *type, - const char *left, const char *right, - const char *op, const BIGNUM *bn) -{ - char *s = convertBN(bn); - size_t l = s != NULL ? strlen(s) : 0; - - test_fail_string_message(prefix, file, line, type, left, right, op, - s, l, s, l); - if (s != BN_minus_zero) - OPENSSL_free(s); -} - -static void hex_convert_memory(const char *m, size_t n, char *b) -{ - size_t i; - - for (i = 0; i < n; i++) { - const unsigned char c = *m++; - - *b++ = "0123456789abcdef"[c >> 4]; - *b++ = "0123456789abcdef"[c & 15]; - if ((i % 8) == 7 && i != n - 1) - *b++ = ' '; - } - *b = '\0'; -} - -static void test_fail_memory_message(const char *prefix, const char *file, - int line, const char *type, - const char *left, const char *right, - const char *op, const char *m1, size_t l1, - const char *m2, size_t l2) -{ - const int indent = subtest_level(); - const size_t bytes = (MAX_STRING_WIDTH - 9) / 17 * 8; - char b1[MAX_STRING_WIDTH + 1], b2[MAX_STRING_WIDTH + 1]; - char *p, bdiff[MAX_STRING_WIDTH + 1]; - size_t n1, n2, i; - unsigned int cnt = 0, diff; - - test_fail_message_prefix(prefix, file, line, type, left, right, op); - if (m1 == NULL) - l1 = 0; - if (m2 == NULL) - l2 = 0; - if (l1 == 0 && l2 == 0) { - if ((m1 == NULL) == (m2 == NULL)) { - test_printf_stderr("%*s# %04s %s\n", indent, "", "", - m1 == NULL ? "NULL" : "empty"); - } else { - test_diff_header(left, right); - test_printf_stderr("%*s# %04s -%s\n", indent, "", "", - m1 == NULL ? "NULL" : "empty"); - test_printf_stderr("%*s# %04s +%s\n", indent, "", "", - m2 == NULL ? "NULL" : "empty"); - } - goto fin; - } - - if (l1 != l2 || memcmp(m1, m2, l1) != 0) - test_diff_header(left, right); - - while (l1 > 0 || l2 > 0) { - n1 = n2 = 0; - if (l1 > 0) { - n1 = l1 > bytes ? bytes : l1; - hex_convert_memory(m1, n1, b1); - } - if (l2 > 0) { - n2 = l2 > bytes ? bytes : l2; - hex_convert_memory(m2, n2, b2); - } - - diff = n1 != n2; - i = 0; - p = bdiff; - if (n1 > 0 && n2 > 0) { - const size_t j = n1 < n2 ? n1 : n2; - const size_t k = n1 > n2 ? n1 : n2; - - for (; i < j; i++) { - if (m1[i] == m2[i]) { - *p++ = ' '; - *p++ = ' '; - } else { - *p++ = '^'; - *p++ = '^'; - diff = 1; - } - if ((i % 8) == 7 && (i != j - 1 || j != k)) - *p++ = ' '; - } - - for (; i < k; i++) { - *p++ = '^'; - *p++ = '^'; - if ((i % 8) == 7 && i != k - 1) - *p++ = ' '; - } - *p++ = '\0'; - } - - if (!diff) { - test_printf_stderr("%*s# %04x: %s\n", indent, "", cnt, b1); - } else { - if (cnt == 0 && m1 == NULL) - test_printf_stderr("%*s# %04s -NULL\n", indent, "", ""); - else if (cnt == 0 && l1 == 0) - test_printf_stderr("%*s# %04s -empty\n", indent, "", ""); - else if (n1 > 0) - test_printf_stderr("%*s# %04x:-%s\n", indent, "", cnt, b1); - if (cnt == 0 && m2 == NULL) - test_printf_stderr("%*s# %04s +NULL\n", indent, "", ""); - else if (cnt == 0 && l2 == 0) - test_printf_stderr("%*s# %04s +empty\n", indent, "", ""); - else if (n2 > 0) - test_printf_stderr("%*s# %04x:+%s\n", indent, "", cnt, b2); - if (i > 0) - test_printf_stderr("%*s# % 4s %s\n", indent, "", "", bdiff); - } - m1 += n1; - m2 += n2; - l1 -= n1; - l2 -= n2; - cnt += bytes; - } -fin: - test_printf_stderr("\n"); test_flush_stderr(); } @@ -379,8 +120,9 @@ void test_error_c90(const char *desc, ...) va_list ap; va_start(ap, desc); - test_fail_message(NULL, NULL, -1, NULL, NULL, NULL, NULL, desc, ap); + test_fail_message_va(NULL, NULL, -1, NULL, NULL, NULL, NULL, desc, ap); va_end(ap); + test_printf_stderr("\n"); } void test_error(const char *file, int line, const char *desc, ...) @@ -390,11 +132,35 @@ void test_error(const char *file, int line, const char *desc, ...) va_start(ap, desc); test_fail_message_va(NULL, file, line, NULL, NULL, NULL, NULL, desc, ap); va_end(ap); + test_printf_stderr("\n"); +} + +void test_perror(const char *s) +{ + /* + * Using openssl_strerror_r causes linking issues since it isn't + * exported from libcrypto.so + */ + TEST_error("%s: %s", s, strerror(errno)); +} + +void test_note(const char *fmt, ...) +{ + if (fmt != NULL) { + va_list ap; + + va_start(ap, fmt); + test_vprintf_stderr(fmt, ap); + va_end(ap); + test_printf_stderr("\n"); + } + test_flush_stderr(); } void test_openssl_errors(void) { ERR_print_errors_cb(openssl_error_cb, NULL); + ERR_clear_error(); } /* @@ -607,8 +373,7 @@ int test_BN_odd(const char *file, int line, const char *s, const BIGNUM *a) { if (a != NULL && BN_is_odd(a)) return 1; - test_fail_bignum_mono_message(NULL, file, line, "BIGNUM", "ODD(", ")", s, - a); + test_fail_bignum_mono_message(NULL, file, line, "BIGNUM", "ODD(", ")", s, a); return 0; } @@ -652,3 +417,32 @@ int test_BN_abs_eq_word(const char *file, int line, const char *bns, BN_free(aa); return 0; } + +static const char *print_time(const ASN1_TIME *t) +{ + return t == NULL ? "" : (char *)ASN1_STRING_get0_data(t); +} + +#define DEFINE_TIME_T_COMPARISON(opname, op) \ + int test_time_t_ ## opname(const char *file, int line, \ + const char *s1, const char *s2, \ + const time_t t1, const time_t t2) \ + { \ + ASN1_TIME *at1 = ASN1_TIME_set(NULL, t1); \ + ASN1_TIME *at2 = ASN1_TIME_set(NULL, t2); \ + int r = at1 != NULL && at2 != NULL \ + && ASN1_TIME_compare(at1, at2) op 0; \ + if (!r) \ + test_fail_message(NULL, file, line, "time_t", s1, s2, #op, \ + "[%s] compared to [%s]", \ + print_time(at1), print_time(at2)); \ + ASN1_STRING_free(at1); \ + ASN1_STRING_free(at2); \ + return r; \ + } +DEFINE_TIME_T_COMPARISON(eq, ==) +DEFINE_TIME_T_COMPARISON(ne, !=) +DEFINE_TIME_T_COMPARISON(gt, >) +DEFINE_TIME_T_COMPARISON(ge, >=) +DEFINE_TIME_T_COMPARISON(lt, <) +DEFINE_TIME_T_COMPARISON(le, <=)