X-Git-Url: https://git.openssl.org/gitweb/?a=blobdiff_plain;f=test%2Ftestutil%2Ftests.c;h=a60af0764f62f160348635e68ba3a13973acd9e7;hb=681e8cacdbdc44ac00af29b6656fc52745a9baa2;hp=cb6a3bb688dd73e634bba0f50fb61be363a34047;hpb=c5657cb71011eb2471f6d70e558919d3da561f39;p=openssl.git diff --git a/test/testutil/tests.c b/test/testutil/tests.c index cb6a3bb688..a60af0764f 100644 --- a/test/testutil/tests.c +++ b/test/testutil/tests.c @@ -11,11 +11,37 @@ #include "output.h" #include "tu_local.h" +#include #include -#include "../../e_os.h" +#include +#include "internal/nelem.h" +#include -/* The size of memory buffers to display on failure */ -#define MEM_BUFFER_SIZE (21) +/* + * 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: ", prefix != NULL ? prefix : "ERROR"); + if (type) + test_printf_stderr("(%s) ", type); + 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"); +} /* * A common routine to output test failure messages. Generally this should not @@ -39,47 +65,35 @@ * * calling test6(3, "oops") will return 0 and produce out along the lines of: * FAIL oops: (int) value 3 is not 6\n - * - * It general, test_fail_message should not be called directly. */ static void test_fail_message(const char *prefix, const char *file, int line, - const char *type, const char *fmt, ...) - PRINTF_FORMAT(5, 6); -static void helper_printf_stderr(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - test_vprintf_stderr(fmt, ap); - va_end(ap); -} - -static void test_fail_message_va(const char *prefix, const char *file, int line, - const char *type, const char *fmt, va_list ap) + const char *type, const char *left, + const char *right, const char *op, + const char *fmt, ...) + PRINTF_FORMAT(8, 9); + +static void test_fail_message_va(const char *prefix, const char *file, + int line, const char *type, + const char *left, const char *right, + const char *op, const char *fmt, va_list ap) { - helper_printf_stderr("%*s# ", subtest_level(), ""); - test_puts_stderr(prefix != NULL ? prefix : "ERROR"); - test_puts_stderr(":"); - if (type) - helper_printf_stderr(" (%s)", type); + test_fail_message_prefix(prefix, file, line, type, left, right, op); if (fmt != NULL) { - test_puts_stderr(" "); test_vprintf_stderr(fmt, ap); + test_printf_stderr("\n"); } - if (file != NULL) { - helper_printf_stderr(" @ %s:%d", file, line); - } - test_puts_stderr("\n"); test_flush_stderr(); } -static void test_fail_message(const char *prefix, const char *file, int line, - const char *type, const char *fmt, ...) +static void test_fail_message(const char *prefix, const char *file, + int line, const char *type, + const char *left, const char *right, + const char *op, const char *fmt, ...) { va_list ap; va_start(ap, fmt); - test_fail_message_va(prefix, file, line, type, fmt, ap); + test_fail_message_va(prefix, file, line, type, left, right, op, fmt, ap); va_end(ap); } @@ -88,7 +102,7 @@ void test_info_c90(const char *desc, ...) va_list ap; va_start(ap, desc); - test_fail_message_va("INFO", NULL, -1, NULL, desc, ap); + test_fail_message_va("INFO", NULL, -1, NULL, NULL, NULL, NULL, desc, ap); va_end(ap); } @@ -97,7 +111,7 @@ void test_info(const char *file, int line, const char *desc, ...) va_list ap; va_start(ap, desc); - test_fail_message_va("INFO", file, line, NULL, desc, ap); + test_fail_message_va("INFO", file, line, NULL, NULL, NULL, NULL, desc, ap); va_end(ap); } @@ -106,8 +120,9 @@ void test_error_c90(const char *desc, ...) va_list ap; va_start(ap, desc); - test_fail_message(NULL, NULL, -1, 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, ...) @@ -115,8 +130,37 @@ void test_error(const char *file, int line, const char *desc, ...) va_list ap; va_start(ap, desc); - test_fail_message_va(NULL, file, line, NULL, desc, ap); + 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(); } /* @@ -148,9 +192,9 @@ void test_error(const char *file, int line, const char *desc, ...) { \ if (t1 op t2) \ return 1; \ - test_fail_message(NULL, file, line, #type, \ - "%s [" fmt "] " #op " %s [" fmt "]", \ - s1, t1, s2, t2); \ + test_fail_message(NULL, file, line, #type, s1, s2, #op, \ + "[" fmt "] compared to [" fmt "]", \ + t1, t2); \ return 0; \ } @@ -177,7 +221,7 @@ int test_ptr_null(const char *file, int line, const char *s, const void *p) { if (p == NULL) return 1; - test_fail_message(NULL, file, line, "ptr", "%s [%p] == NULL", s, p); + test_fail_message(NULL, file, line, "ptr", s, "NULL", "==", "%p", p); return 0; } @@ -185,7 +229,7 @@ int test_ptr(const char *file, int line, const char *s, const void *p) { if (p != NULL) return 1; - test_fail_message(NULL, file, line, "ptr", "%s [%p] != NULL", s, p); + test_fail_message(NULL, file, line, "ptr", s, "NULL", "!=", "%p", p); return 0; } @@ -193,7 +237,7 @@ int test_true(const char *file, int line, const char *s, int b) { if (b) return 1; - test_fail_message(NULL, file, line, "bool", "%s [false] == true", s); + test_fail_message(NULL, file, line, "bool", s, "true", "==", "false"); return 0; } @@ -201,24 +245,19 @@ int test_false(const char *file, int line, const char *s, int b) { if (!b) return 1; - test_fail_message(NULL, file, line, "bool", "%s [true] == false", s); + test_fail_message(NULL, file, line, "bool", s, "false", "==", "true"); return 0; } -static const char *print_string_maybe_null(const char *s) -{ - return s == NULL ? "(NULL)" : s; -} - int test_str_eq(const char *file, int line, const char *st1, const char *st2, const char *s1, const char *s2) { if (s1 == NULL && s2 == NULL) return 1; if (s1 == NULL || s2 == NULL || strcmp(s1, s2) != 0) { - test_fail_message(NULL, file, line, "string", "%s [%s] == %s [%s]", - st1, print_string_maybe_null(s1), - st2, print_string_maybe_null(s2)); + test_fail_string_message(NULL, file, line, "string", st1, st2, "==", + s1, s1 == NULL ? 0 : strlen(s1), + s2, s2 == NULL ? 0 : strlen(s2)); return 0; } return 1; @@ -230,9 +269,9 @@ int test_str_ne(const char *file, int line, const char *st1, const char *st2, if ((s1 == NULL) ^ (s2 == NULL)) return 1; if (s1 == NULL || strcmp(s1, s2) == 0) { - test_fail_message(NULL, file, line, "string", "%s [%s] != %s [%s]", - st1, print_string_maybe_null(s1), - st2, print_string_maybe_null(s2)); + test_fail_string_message(NULL, file, line, "string", st1, st2, "!=", + s1, s1 == NULL ? 0 : strlen(s1), + s2, s2 == NULL ? 0 : strlen(s2)); return 0; } return 1; @@ -241,14 +280,12 @@ int test_str_ne(const char *file, int line, const char *st1, const char *st2, int test_strn_eq(const char *file, int line, const char *st1, const char *st2, const char *s1, const char *s2, size_t len) { - int prec = (int)len; - if (s1 == NULL && s2 == NULL) return 1; if (s1 == NULL || s2 == NULL || strncmp(s1, s2, len) != 0) { - test_fail_message(NULL, file, line, "string", "%.s [%.*s] == %s [%.*s]", - st1, prec, print_string_maybe_null(s1), - st2, prec, print_string_maybe_null(s2)); + test_fail_string_message(NULL, file, line, "string", st1, st2, "==", + s1, s1 == NULL ? 0 : OPENSSL_strnlen(s1, len), + s2, s2 == NULL ? 0 : OPENSSL_strnlen(s2, len)); return 0; } return 1; @@ -257,68 +294,25 @@ int test_strn_eq(const char *file, int line, const char *st1, const char *st2, int test_strn_ne(const char *file, int line, const char *st1, const char *st2, const char *s1, const char *s2, size_t len) { - int prec = (int)len; - if ((s1 == NULL) ^ (s2 == NULL)) return 1; if (s1 == NULL || strncmp(s1, s2, len) == 0) { - test_fail_message(NULL, file, line, "string", "%s [%.*s] != %s [%.*s]", - st1, prec, print_string_maybe_null(s1), - st2, prec, print_string_maybe_null(s2)); + test_fail_string_message(NULL, file, line, "string", st1, st2, "!=", + s1, s1 == NULL ? 0 : OPENSSL_strnlen(s1, len), + s2, s2 == NULL ? 0 : OPENSSL_strnlen(s2, len)); return 0; } return 1; } -/* - * We could use OPENSSL_buf2hexstr() to do this but trying to allocate memory - * in a failure state isn't generally a great idea. - */ -static const char *print_mem_maybe_null(const void *s, size_t n, - char out[MEM_BUFFER_SIZE]) -{ - size_t i; - const unsigned char *p = (const unsigned char *)s; - int pad = 2*n >= MEM_BUFFER_SIZE; - - if (s == NULL) - return "(NULL)"; - if (pad) - n = MEM_BUFFER_SIZE-4; - - for (i=0; i<2*n; i++) { - unsigned char c = (i & 1) != 0 ? p[i / 2] & 15 : p[i / 2] >> 4; - out[i] = "0123456789abcdef"[c]; - } - if (pad) { - out[i++] = '.'; - out[i++] = '.'; - out[i++] = '.'; - } - out[i] = '\0'; - - return out; -} - int test_mem_eq(const char *file, int line, const char *st1, const char *st2, const void *s1, size_t n1, const void *s2, size_t n2) { - char b1[MEM_BUFFER_SIZE], b2[MEM_BUFFER_SIZE]; - if (s1 == NULL && s2 == NULL) return 1; - if (n1 != n2) { - test_fail_message(NULL, file, line, "memory", - "size mismatch %s %s [%zu] != %s %s [%zu]", - st1, print_mem_maybe_null(s1, n1, b1), n1, - st2, print_mem_maybe_null(s2, n2, b2), n2); - return 0; - } - if (s1 == NULL || s2 == NULL || memcmp(s1, s2, n1) != 0) { - test_fail_message(NULL, file, line, "memory", - "%s %s [%zu] != %s %s [%zu]", - st1, print_mem_maybe_null(s1, n1, b1), n1, - st2, print_mem_maybe_null(s2, n2, b2), n2); + if (n1 != n2 || s1 == NULL || s2 == NULL || memcmp(s1, s2, n1) != 0) { + test_fail_memory_message(NULL, file, line, "memory", st1, st2, "==", + s1, n1, s2, n2); return 0; } return 1; @@ -327,18 +321,128 @@ int test_mem_eq(const char *file, int line, const char *st1, const char *st2, int test_mem_ne(const char *file, int line, const char *st1, const char *st2, const void *s1, size_t n1, const void *s2, size_t n2) { - char b1[MEM_BUFFER_SIZE], b2[MEM_BUFFER_SIZE]; - if ((s1 == NULL) ^ (s2 == NULL)) - return 1; + return 1; if (n1 != n2) return 1; if (s1 == NULL || memcmp(s1, s2, n1) == 0) { - test_fail_message(NULL, file, line, "memory", - "%s %s [%zu] != %s %s [%zu]", - st1, print_mem_maybe_null(s1, n1, b1), n1, - st2, print_mem_maybe_null(s2, n2, b2), n2); + test_fail_memory_message(NULL, file, line, "memory", st1, st2, "!=", + s1, n1, s2, n2); return 0; } return 1; } + +#define DEFINE_BN_COMPARISONS(opname, op, zero_cond) \ + int test_BN_ ## opname(const char *file, int line, \ + const char *s1, const char *s2, \ + const BIGNUM *t1, const BIGNUM *t2) \ + { \ + if (BN_cmp(t1, t2) op 0) \ + return 1; \ + test_fail_bignum_message(NULL, file, line, "BIGNUM", s1, s2, \ + #op, t1, t2); \ + return 0; \ + } \ + int test_BN_ ## opname ## _zero(const char *file, int line, \ + const char *s, const BIGNUM *a) \ + { \ + if (a != NULL &&(zero_cond)) \ + return 1; \ + test_fail_bignum_mono_message(NULL, file, line, "BIGNUM", \ + s, "0", #op, a); \ + return 0; \ + } + +DEFINE_BN_COMPARISONS(eq, ==, BN_is_zero(a)) +DEFINE_BN_COMPARISONS(ne, !=, !BN_is_zero(a)) +DEFINE_BN_COMPARISONS(gt, >, !BN_is_negative(a) && !BN_is_zero(a)) +DEFINE_BN_COMPARISONS(ge, >=, !BN_is_negative(a) || BN_is_zero(a)) +DEFINE_BN_COMPARISONS(lt, <, BN_is_negative(a) && !BN_is_zero(a)) +DEFINE_BN_COMPARISONS(le, <=, BN_is_negative(a) || BN_is_zero(a)) + +int test_BN_eq_one(const char *file, int line, const char *s, const BIGNUM *a) +{ + if (a != NULL && BN_is_one(a)) + return 1; + test_fail_bignum_mono_message(NULL, file, line, "BIGNUM", s, "1", "==", a); + return 0; +} + +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); + return 0; +} + +int test_BN_even(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", "EVEN(", ")", s, + a); + return 0; +} + +int test_BN_eq_word(const char *file, int line, const char *bns, const char *ws, + const BIGNUM *a, BN_ULONG w) +{ + BIGNUM *bw; + + if (a != NULL && BN_is_word(a, w)) + return 1; + bw = BN_new(); + BN_set_word(bw, w); + test_fail_bignum_message(NULL, file, line, "BIGNUM", bns, ws, "==", a, bw); + BN_free(bw); + return 0; +} + +int test_BN_abs_eq_word(const char *file, int line, const char *bns, + const char *ws, const BIGNUM *a, BN_ULONG w) +{ + BIGNUM *bw, *aa; + + if (a != NULL && BN_abs_is_word(a, w)) + return 1; + bw = BN_new(); + aa = BN_dup(a); + BN_set_negative(aa, 0); + BN_set_word(bw, w); + test_fail_bignum_message(NULL, file, line, "BIGNUM", bns, ws, "abs==", + aa, bw); + BN_free(bw); + 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, <=)