summaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorPauli <paul.dale@oracle.com>2017-04-13 08:51:28 +1000
committerRich Salz <rsalz@openssl.org>2017-04-13 08:33:12 -0400
commitd063add7cbdaf82e6208ef01414432320260e974 (patch)
tree794ad8006e58650653d962c8ae692efdd36e4a78 /test
parenta24c1e224338ccd3d2b831bd2e3ba52a1eb31f01 (diff)
Guarantee single argument evaluation for test macros.
Add test case that checks some of them. Reviewed-by: Richard Levitte <levitte@openssl.org> Reviewed-by: Rich Salz <rsalz@openssl.org> (Merged from https://github.com/openssl/openssl/pull/3208)
Diffstat (limited to 'test')
-rw-r--r--test/README14
-rw-r--r--test/test_test.c56
-rw-r--r--test/testutil.h90
3 files changed, 117 insertions, 43 deletions
diff --git a/test/README b/test/README
index cf7e4d4948..7831c860f5 100644
--- a/test/README
+++ b/test/README
@@ -134,4 +134,16 @@ conditions. These macros produce an error message in a standard format if the
condition is not met (and nothing if the condition is met). Additional
information can be presented with the TEST_info macro that takes a printf
format string and arguments. TEST_error is useful for complicated conditions,
-it also takes a printf format string and argument.
+it also takes a printf format string and argument. In all cases the TEST_xxx
+macros are guaranteed to evaluate their arguments exactly once. This means
+that expressions with side effects are allowed as parameters. Thus,
+
+ if (!TEST_ptr(ptr = OPENSSL_malloc(..)))
+
+works fine and can be used in place of:
+
+ ptr = OPENSSL_malloc(..);
+ if (!TEST_ptr(ptr))
+
+The former produces a more meaningful message on failure than the latter.
+
diff --git a/test/test_test.c b/test/test_test.c
index df4725a7a4..a1542892e9 100644
--- a/test/test_test.c
+++ b/test/test_test.c
@@ -259,6 +259,61 @@ static int test_messages(void)
return 1;
}
+static int test_single_eval(void)
+{
+ int i = 4;
+ long l = -9000;
+ char c = 'd';
+ unsigned char uc = 22;
+ unsigned long ul = 500;
+ size_t st = 1234;
+ char buf[4] = { 0 }, *p = buf;
+
+ /* int */
+ return TEST_int_eq(i++, 4)
+ && TEST_int_eq(i, 5)
+ && TEST_int_gt(++i, 5)
+ && TEST_int_le(5, i++)
+ && TEST_int_ne(--i, 5)
+ && TEST_int_eq(12, i *= 2)
+ /* Long */
+ && TEST_long_eq(l--, -9000L)
+ && TEST_long_eq(++l, -9000L)
+ && TEST_long_ne(-9000L, l /= 2)
+ && TEST_long_lt(--l, -4500L)
+ /* char */
+ && TEST_char_eq(++c, 'e')
+ && TEST_char_eq('e', c--)
+ && TEST_char_ne('d', --c)
+ && TEST_char_le('b', --c)
+ && TEST_char_lt(c++, 'c')
+ /* unsigned char */
+ && TEST_uchar_eq(22, uc++)
+ && TEST_uchar_eq(uc /= 2, 11)
+ && TEST_ulong_eq(ul ^= 1, 501)
+ && TEST_ulong_eq(502, ul ^= 3)
+ && TEST_ulong_eq(ul = ul * 3 - 6, 1500)
+ /* size_t */
+ && TEST_size_t_eq((--i, st++), 1234)
+ && TEST_size_t_eq(st, 1235)
+ && TEST_int_eq(11, i)
+ /* pointers */
+ && TEST_ptr_eq(p++, buf)
+ && TEST_ptr_eq(buf + 2, ++p)
+ && TEST_ptr_eq(buf, p -= 2)
+ && TEST_ptr(++p)
+ && TEST_ptr_eq(p, buf + 1)
+ && TEST_ptr_null(p = NULL)
+ /* strings */
+ && TEST_str_eq(p = "123456" + 1, "23456")
+ && TEST_str_eq("3456", ++p)
+ && TEST_str_ne(p++, "456")
+ /* memory */
+ && TEST_mem_eq(--p, sizeof("3456"), "3456", sizeof("3456"))
+ && TEST_mem_ne(p++, sizeof("456"), "456", sizeof("456"))
+ && TEST_mem_eq(p--, sizeof("456"), "456", sizeof("456"));
+}
+
void register_tests(void)
{
ADD_TEST(test_int);
@@ -273,4 +328,5 @@ void register_tests(void)
ADD_TEST(test_string);
ADD_TEST(test_memory);
ADD_TEST(test_messages);
+ ADD_TEST(test_single_eval);
}
diff --git a/test/testutil.h b/test/testutil.h
index a83323b9e8..0631a8b7f8 100644
--- a/test/testutil.h
+++ b/test/testutil.h
@@ -191,7 +191,7 @@ DECLARE_COMPARISON(char *, str, ne)
/*
* Equality test for memory blocks where NULL is a legitimate value.
-* These calls return 1 if the two memory blocks compare true.
+ * These calls return 1 if the two memory blocks compare true.
* Otherwise, they return 0 and pretty-print diagnostics.
* These should not be called directly, use the TEST_xxx macros below instead.
*/
@@ -223,6 +223,12 @@ void test_info_c90(const char *desc, ...) PRINTF_FORMAT(1, 2);
/*
* The following macros provide wrapper calls to the test functions with
* a default description that indicates the file and line number of the error.
+ *
+ * The following macros guarantee to evaluate each argument exactly once.
+ * This allows constructs such as: if(!TEST_ptr(ptr = OPENSSL_malloc(..)))
+ * to produce better contextual output than:
+ * ptr = OPENSSL_malloc(..);
+ * if (!TEST_ptr(ptr))
*/
# define TEST_int_eq(a, b) test_int_eq(__FILE__, __LINE__, #a, #b, a, b)
# define TEST_int_ne(a, b) test_int_ne(__FILE__, __LINE__, #a, #b, a, b)
@@ -238,47 +244,47 @@ void test_info_c90(const char *desc, ...) PRINTF_FORMAT(1, 2);
# define TEST_int_gt(a, b) test_int_gt(__FILE__, __LINE__, #a, #b, a, b)
# define TEST_int_ge(a, b) test_int_ge(__FILE__, __LINE__, #a, #b, a, b)
-# define TEST_uint_eq(a, b) test_uint_eq(__FILE__, __LINE__, #a, #b, a, b)
-# define TEST_uint_ne(a, b) test_uint_ne(__FILE__, __LINE__, #a, #b, a, b)
-# define TEST_uint_lt(a, b) test_uint_lt(__FILE__, __LINE__, #a, #b, a, b)
-# define TEST_uint_le(a, b) test_uint_le(__FILE__, __LINE__, #a, #b, a, b)
-# define TEST_uint_gt(a, b) test_uint_gt(__FILE__, __LINE__, #a, #b, a, b)
-# define TEST_uint_ge(a, b) test_uint_ge(__FILE__, __LINE__, #a, #b, a, b)
-
-# define TEST_char_eq(a, b) test_char_eq(__FILE__, __LINE__, #a, #b, a, b)
-# define TEST_char_ne(a, b) test_char_ne(__FILE__, __LINE__, #a, #b, a, b)
-# define TEST_char_lt(a, b) test_char_lt(__FILE__, __LINE__, #a, #b, a, b)
-# define TEST_char_le(a, b) test_char_le(__FILE__, __LINE__, #a, #b, a, b)
-# define TEST_char_gt(a, b) test_char_gt(__FILE__, __LINE__, #a, #b, a, b)
-# define TEST_char_ge(a, b) test_char_ge(__FILE__, __LINE__, #a, #b, a, b)
-
-# define TEST_uchar_eq(a, b) test_uchar_eq(__FILE__, __LINE__, #a, #b, a, b)
-# define TEST_uchar_ne(a, b) test_uchar_ne(__FILE__, __LINE__, #a, #b, a, b)
-# define TEST_uchar_lt(a, b) test_uchar_lt(__FILE__, __LINE__, #a, #b, a, b)
-# define TEST_uchar_le(a, b) test_uchar_le(__FILE__, __LINE__, #a, #b, a, b)
-# define TEST_uchar_gt(a, b) test_uchar_gt(__FILE__, __LINE__, #a, #b, a, b)
-# define TEST_uchar_ge(a, b) test_uchar_ge(__FILE__, __LINE__, #a, #b, a, b)
-
-# define TEST_long_eq(a, b) test_long_eq(__FILE__, __LINE__, #a, #b, a, b)
-# define TEST_long_ne(a, b) test_long_ne(__FILE__, __LINE__, #a, #b, a, b)
-# define TEST_long_lt(a, b) test_long_lt(__FILE__, __LINE__, #a, #b, a, b)
-# define TEST_long_le(a, b) test_long_le(__FILE__, __LINE__, #a, #b, a, b)
-# define TEST_long_gt(a, b) test_long_gt(__FILE__, __LINE__, #a, #b, a, b)
-# define TEST_long_ge(a, b) test_long_ge(__FILE__, __LINE__, #a, #b, a, b)
-
-# define TEST_ulong_eq(a, b) test_ulong_eq(__FILE__, __LINE__, #a, #b, a, b)
-# define TEST_ulong_ne(a, b) test_ulong_ne(__FILE__, __LINE__, #a, #b, a, b)
-# define TEST_ulong_lt(a, b) test_ulong_lt(__FILE__, __LINE__, #a, #b, a, b)
-# define TEST_ulong_le(a, b) test_ulong_le(__FILE__, __LINE__, #a, #b, a, b)
-# define TEST_ulong_gt(a, b) test_ulong_gt(__FILE__, __LINE__, #a, #b, a, b)
-# define TEST_ulong_ge(a, b) test_ulong_ge(__FILE__, __LINE__, #a, #b, a, b)
-
-# define TEST_size_t_eq(a, b) test_size_t_eq(__FILE__, __LINE__, #a, #b, a, b)
-# define TEST_size_t_ne(a, b) test_size_t_ne(__FILE__, __LINE__, #a, #b, a, b)
-# define TEST_size_t_lt(a, b) test_size_t_lt(__FILE__, __LINE__, #a, #b, a, b)
-# define TEST_size_t_le(a, b) test_size_t_le(__FILE__, __LINE__, #a, #b, a, b)
-# define TEST_size_t_gt(a, b) test_size_t_gt(__FILE__, __LINE__, #a, #b, a, b)
-# define TEST_size_t_ge(a, b) test_size_t_ge(__FILE__, __LINE__, #a, #b, a, b)
+# define TEST_uint_eq(a, b) test_uint_eq(__FILE__, __LINE__, #a, #b, a, b)
+# define TEST_uint_ne(a, b) test_uint_ne(__FILE__, __LINE__, #a, #b, a, b)
+# define TEST_uint_lt(a, b) test_uint_lt(__FILE__, __LINE__, #a, #b, a, b)
+# define TEST_uint_le(a, b) test_uint_le(__FILE__, __LINE__, #a, #b, a, b)
+# define TEST_uint_gt(a, b) test_uint_gt(__FILE__, __LINE__, #a, #b, a, b)
+# define TEST_uint_ge(a, b) test_uint_ge(__FILE__, __LINE__, #a, #b, a, b)
+
+# define TEST_char_eq(a, b) test_char_eq(__FILE__, __LINE__, #a, #b, a, b)
+# define TEST_char_ne(a, b) test_char_ne(__FILE__, __LINE__, #a, #b, a, b)
+# define TEST_char_lt(a, b) test_char_lt(__FILE__, __LINE__, #a, #b, a, b)
+# define TEST_char_le(a, b) test_char_le(__FILE__, __LINE__, #a, #b, a, b)
+# define TEST_char_gt(a, b) test_char_gt(__FILE__, __LINE__, #a, #b, a, b)
+# define TEST_char_ge(a, b) test_char_ge(__FILE__, __LINE__, #a, #b, a, b)
+
+# define TEST_uchar_eq(a, b) test_uchar_eq(__FILE__, __LINE__, #a, #b, a, b)
+# define TEST_uchar_ne(a, b) test_uchar_ne(__FILE__, __LINE__, #a, #b, a, b)
+# define TEST_uchar_lt(a, b) test_uchar_lt(__FILE__, __LINE__, #a, #b, a, b)
+# define TEST_uchar_le(a, b) test_uchar_le(__FILE__, __LINE__, #a, #b, a, b)
+# define TEST_uchar_gt(a, b) test_uchar_gt(__FILE__, __LINE__, #a, #b, a, b)
+# define TEST_uchar_ge(a, b) test_uchar_ge(__FILE__, __LINE__, #a, #b, a, b)
+
+# define TEST_long_eq(a, b) test_long_eq(__FILE__, __LINE__, #a, #b, a, b)
+# define TEST_long_ne(a, b) test_long_ne(__FILE__, __LINE__, #a, #b, a, b)
+# define TEST_long_lt(a, b) test_long_lt(__FILE__, __LINE__, #a, #b, a, b)
+# define TEST_long_le(a, b) test_long_le(__FILE__, __LINE__, #a, #b, a, b)
+# define TEST_long_gt(a, b) test_long_gt(__FILE__, __LINE__, #a, #b, a, b)
+# define TEST_long_ge(a, b) test_long_ge(__FILE__, __LINE__, #a, #b, a, b)
+
+# define TEST_ulong_eq(a, b) test_ulong_eq(__FILE__, __LINE__, #a, #b, a, b)
+# define TEST_ulong_ne(a, b) test_ulong_ne(__FILE__, __LINE__, #a, #b, a, b)
+# define TEST_ulong_lt(a, b) test_ulong_lt(__FILE__, __LINE__, #a, #b, a, b)
+# define TEST_ulong_le(a, b) test_ulong_le(__FILE__, __LINE__, #a, #b, a, b)
+# define TEST_ulong_gt(a, b) test_ulong_gt(__FILE__, __LINE__, #a, #b, a, b)
+# define TEST_ulong_ge(a, b) test_ulong_ge(__FILE__, __LINE__, #a, #b, a, b)
+
+# define TEST_size_t_eq(a, b) test_size_t_eq(__FILE__, __LINE__, #a, #b, a, b)
+# define TEST_size_t_ne(a, b) test_size_t_ne(__FILE__, __LINE__, #a, #b, a, b)
+# define TEST_size_t_lt(a, b) test_size_t_lt(__FILE__, __LINE__, #a, #b, a, b)
+# define TEST_size_t_le(a, b) test_size_t_le(__FILE__, __LINE__, #a, #b, a, b)
+# define TEST_size_t_gt(a, b) test_size_t_gt(__FILE__, __LINE__, #a, #b, a, b)
+# define TEST_size_t_ge(a, b) test_size_t_ge(__FILE__, __LINE__, #a, #b, a, b)
# define TEST_ptr_eq(a, b) test_ptr_eq(__FILE__, __LINE__, #a, #b, a, b)
# define TEST_ptr_ne(a, b) test_ptr_ne(__FILE__, __LINE__, #a, #b, a, b)