tests.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. /*
  2. * Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  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
  8. */
  9. #include "../testutil.h"
  10. #include "output.h"
  11. #include "tu_local.h"
  12. #include <string.h>
  13. #include "../../e_os.h"
  14. /* The size of memory buffers to display on failure */
  15. #define MEM_BUFFER_SIZE (33)
  16. /*
  17. * A common routine to output test failure messages. Generally this should not
  18. * be called directly, rather it should be called by the following functions.
  19. *
  20. * |desc| is a printf formatted description with arguments |args| that is
  21. * supplied by the user and |desc| can be NULL. |type| is the data type
  22. * that was tested (int, char, ptr, ...). |fmt| is a system provided
  23. * printf format with following arguments that spell out the failure
  24. * details i.e. the actual values compared and the operator used.
  25. *
  26. * The typical use for this is from an utility test function:
  27. *
  28. * int test6(const char *file, int line, int n) {
  29. * if (n != 6) {
  30. * test_fail_message(1, file, line, "int", "value %d is not %d", n, 6);
  31. * return 0;
  32. * }
  33. * return 1;
  34. * }
  35. *
  36. * calling test6(3, "oops") will return 0 and produce out along the lines of:
  37. * FAIL oops: (int) value 3 is not 6\n
  38. *
  39. * It general, test_fail_message should not be called directly.
  40. */
  41. static void test_fail_message(const char *prefix, const char *file, int line,
  42. const char *type, const char *fmt, ...)
  43. PRINTF_FORMAT(5, 6);
  44. static void test_fail_message_va(const char *prefix, const char *file, int line,
  45. const char *type, const char *fmt, va_list ap)
  46. {
  47. test_printf_stderr("%*s# %s: ", subtest_level(), "",
  48. prefix != NULL ? prefix : "ERROR");
  49. if (type)
  50. test_printf_stderr("(%s)", type);
  51. if (fmt != NULL) {
  52. test_vprintf_stderr(fmt, ap);
  53. }
  54. if (file != NULL) {
  55. test_printf_stderr(" @ %s:%d", file, line);
  56. }
  57. test_printf_stderr("\n");
  58. test_flush_stderr();
  59. }
  60. static void test_fail_message(const char *prefix, const char *file, int line,
  61. const char *type, const char *fmt, ...)
  62. {
  63. va_list ap;
  64. va_start(ap, fmt);
  65. test_fail_message_va(prefix, file, line, type, fmt, ap);
  66. va_end(ap);
  67. }
  68. void test_info_c90(const char *desc, ...)
  69. {
  70. va_list ap;
  71. va_start(ap, desc);
  72. test_fail_message_va("INFO", NULL, -1, NULL, desc, ap);
  73. va_end(ap);
  74. }
  75. void test_info(const char *file, int line, const char *desc, ...)
  76. {
  77. va_list ap;
  78. va_start(ap, desc);
  79. test_fail_message_va("INFO", file, line, NULL, desc, ap);
  80. va_end(ap);
  81. }
  82. void test_error_c90(const char *desc, ...)
  83. {
  84. va_list ap;
  85. va_start(ap, desc);
  86. test_fail_message(NULL, NULL, -1, NULL, desc, ap);
  87. va_end(ap);
  88. }
  89. void test_error(const char *file, int line, const char *desc, ...)
  90. {
  91. va_list ap;
  92. va_start(ap, desc);
  93. test_fail_message_va(NULL, file, line, NULL, desc, ap);
  94. va_end(ap);
  95. }
  96. void test_openssl_errors(void)
  97. {
  98. ERR_print_errors_cb(openssl_error_cb, NULL);
  99. }
  100. /*
  101. * Define some comparisons between pairs of various types.
  102. * These functions return 1 if the test is true.
  103. * Otherwise, they return 0 and pretty-print diagnostics.
  104. *
  105. * In each case the functions produced are:
  106. * int test_name_eq(const type t1, const type t2, const char *desc, ...);
  107. * int test_name_ne(const type t1, const type t2, const char *desc, ...);
  108. * int test_name_lt(const type t1, const type t2, const char *desc, ...);
  109. * int test_name_le(const type t1, const type t2, const char *desc, ...);
  110. * int test_name_gt(const type t1, const type t2, const char *desc, ...);
  111. * int test_name_ge(const type t1, const type t2, const char *desc, ...);
  112. *
  113. * The t1 and t2 arguments are to be compared for equality, inequality,
  114. * less than, less than or equal to, greater than and greater than or
  115. * equal to respectively. If the specified condition holds, the functions
  116. * return 1. If the condition does not hold, the functions print a diagnostic
  117. * message and return 0.
  118. *
  119. * The desc argument is a printf format string followed by its arguments and
  120. * this is included in the output if the condition being tested for is false.
  121. */
  122. #define DEFINE_COMPARISON(type, name, opname, op, fmt) \
  123. int test_ ## name ## _ ## opname(const char *file, int line, \
  124. const char *s1, const char *s2, \
  125. const type t1, const type t2) \
  126. { \
  127. if (t1 op t2) \
  128. return 1; \
  129. test_fail_message(NULL, file, line, #type, \
  130. "%s [" fmt "] " #op " %s [" fmt "]", \
  131. s1, t1, s2, t2); \
  132. return 0; \
  133. }
  134. #define DEFINE_COMPARISONS(type, name, fmt) \
  135. DEFINE_COMPARISON(type, name, eq, ==, fmt) \
  136. DEFINE_COMPARISON(type, name, ne, !=, fmt) \
  137. DEFINE_COMPARISON(type, name, lt, <, fmt) \
  138. DEFINE_COMPARISON(type, name, le, <=, fmt) \
  139. DEFINE_COMPARISON(type, name, gt, >, fmt) \
  140. DEFINE_COMPARISON(type, name, ge, >=, fmt)
  141. DEFINE_COMPARISONS(int, int, "%d")
  142. DEFINE_COMPARISONS(unsigned int, uint, "%u")
  143. DEFINE_COMPARISONS(char, char, "%c")
  144. DEFINE_COMPARISONS(unsigned char, uchar, "%u")
  145. DEFINE_COMPARISONS(long, long, "%ld")
  146. DEFINE_COMPARISONS(unsigned long, ulong, "%lu")
  147. DEFINE_COMPARISONS(size_t, size_t, "%zu")
  148. DEFINE_COMPARISON(void *, ptr, eq, ==, "%p")
  149. DEFINE_COMPARISON(void *, ptr, ne, !=, "%p")
  150. int test_ptr_null(const char *file, int line, const char *s, const void *p)
  151. {
  152. if (p == NULL)
  153. return 1;
  154. test_fail_message(NULL, file, line, "ptr", "%s [%p] == NULL", s, p);
  155. return 0;
  156. }
  157. int test_ptr(const char *file, int line, const char *s, const void *p)
  158. {
  159. if (p != NULL)
  160. return 1;
  161. test_fail_message(NULL, file, line, "ptr", "%s [%p] != NULL", s, p);
  162. return 0;
  163. }
  164. int test_true(const char *file, int line, const char *s, int b)
  165. {
  166. if (b)
  167. return 1;
  168. test_fail_message(NULL, file, line, "bool", "%s [false] == true", s);
  169. return 0;
  170. }
  171. int test_false(const char *file, int line, const char *s, int b)
  172. {
  173. if (!b)
  174. return 1;
  175. test_fail_message(NULL, file, line, "bool", "%s [true] == false", s);
  176. return 0;
  177. }
  178. static const char *print_string_maybe_null(const char *s)
  179. {
  180. return s == NULL ? "(NULL)" : s;
  181. }
  182. int test_str_eq(const char *file, int line, const char *st1, const char *st2,
  183. const char *s1, const char *s2)
  184. {
  185. if (s1 == NULL && s2 == NULL)
  186. return 1;
  187. if (s1 == NULL || s2 == NULL || strcmp(s1, s2) != 0) {
  188. test_fail_message(NULL, file, line, "string", "%s [%s] == %s [%s]",
  189. st1, print_string_maybe_null(s1),
  190. st2, print_string_maybe_null(s2));
  191. return 0;
  192. }
  193. return 1;
  194. }
  195. int test_str_ne(const char *file, int line, const char *st1, const char *st2,
  196. const char *s1, const char *s2)
  197. {
  198. if ((s1 == NULL) ^ (s2 == NULL))
  199. return 1;
  200. if (s1 == NULL || strcmp(s1, s2) == 0) {
  201. test_fail_message(NULL, file, line, "string", "%s [%s] != %s [%s]",
  202. st1, print_string_maybe_null(s1),
  203. st2, print_string_maybe_null(s2));
  204. return 0;
  205. }
  206. return 1;
  207. }
  208. int test_strn_eq(const char *file, int line, const char *st1, const char *st2,
  209. const char *s1, const char *s2, size_t len)
  210. {
  211. int prec = (int)len;
  212. if (s1 == NULL && s2 == NULL)
  213. return 1;
  214. if (s1 == NULL || s2 == NULL || strncmp(s1, s2, len) != 0) {
  215. test_fail_message(NULL, file, line, "string", "%.s [%.*s] == %s [%.*s]",
  216. st1, prec, print_string_maybe_null(s1),
  217. st2, prec, print_string_maybe_null(s2));
  218. return 0;
  219. }
  220. return 1;
  221. }
  222. int test_strn_ne(const char *file, int line, const char *st1, const char *st2,
  223. const char *s1, const char *s2, size_t len)
  224. {
  225. int prec = (int)len;
  226. if ((s1 == NULL) ^ (s2 == NULL))
  227. return 1;
  228. if (s1 == NULL || strncmp(s1, s2, len) == 0) {
  229. test_fail_message(NULL, file, line, "string", "%s [%.*s] != %s [%.*s]",
  230. st1, prec, print_string_maybe_null(s1),
  231. st2, prec, print_string_maybe_null(s2));
  232. return 0;
  233. }
  234. return 1;
  235. }
  236. /*
  237. * We could use OPENSSL_buf2hexstr() to do this but trying to allocate memory
  238. * in a failure state isn't generally a great idea and if it fails, we want a
  239. * fall back position using caller supplied buffers.
  240. *
  241. * If the return value is different from the buffer supplied, it needs to be
  242. * freed by the caller.
  243. */
  244. static char *print_mem_maybe_null(const void *s, size_t n,
  245. char outbuf[MEM_BUFFER_SIZE])
  246. {
  247. size_t i;
  248. const unsigned char *p = (const unsigned char *)s;
  249. char *out = outbuf;
  250. int pad = 2 * n >= MEM_BUFFER_SIZE;
  251. if (s == NULL)
  252. return strcpy(outbuf, "(NULL)");
  253. if (pad) {
  254. if ((out = OPENSSL_malloc(2 * n + 1)) == NULL) {
  255. out = outbuf;
  256. n = (MEM_BUFFER_SIZE - 4) / 2;
  257. } else {
  258. pad = 0;
  259. }
  260. }
  261. for (i = 0; i < 2 * n; ) {
  262. const unsigned char c = *p++;
  263. out[i++] = "0123456789abcdef"[c >> 4];
  264. out[i++] = "0123456789abcdef"[c & 15];
  265. }
  266. if (pad) {
  267. out[i++] = '.';
  268. out[i++] = '.';
  269. out[i++] = '.';
  270. }
  271. out[i] = '\0';
  272. return out;
  273. }
  274. int test_mem_eq(const char *file, int line, const char *st1, const char *st2,
  275. const void *s1, size_t n1, const void *s2, size_t n2)
  276. {
  277. char b1[MEM_BUFFER_SIZE], b2[MEM_BUFFER_SIZE];
  278. if (s1 == NULL && s2 == NULL)
  279. return 1;
  280. if (n1 != n2 || s1 == NULL || s2 == NULL || memcmp(s1, s2, n1) != 0) {
  281. char *m1 = print_mem_maybe_null(s1, n1, b1);
  282. char *m2 = print_mem_maybe_null(s2, n2, b2);
  283. test_fail_message(NULL, file, line, "memory",
  284. "%s %s [%zu] == %s %s [%zu]",
  285. st1, m1, n1, st2, m2, n2);
  286. if (m1 != b1)
  287. OPENSSL_free(m1);
  288. if (m2 != b2)
  289. OPENSSL_free(m2);
  290. return 0;
  291. }
  292. return 1;
  293. }
  294. int test_mem_ne(const char *file, int line, const char *st1, const char *st2,
  295. const void *s1, size_t n1, const void *s2, size_t n2)
  296. {
  297. char b1[MEM_BUFFER_SIZE], b2[MEM_BUFFER_SIZE];
  298. if ((s1 == NULL) ^ (s2 == NULL))
  299. return 1;
  300. if (n1 != n2)
  301. return 1;
  302. if (s1 == NULL || memcmp(s1, s2, n1) == 0) {
  303. char *m1 = print_mem_maybe_null(s1, n1, b1);
  304. char *m2 = print_mem_maybe_null(s2, n2, b2);
  305. test_fail_message(NULL, file, line, "memory",
  306. "%s %s [%zu] != %s %s [%zu]",
  307. st1, m1, n1, st2, m2, n2);
  308. if (m1 != b1)
  309. OPENSSL_free(m1);
  310. if (m2 != b2)
  311. OPENSSL_free(m2);
  312. return 0;
  313. }
  314. return 1;
  315. }