1 /* $OpenBSD: test_helper.h,v 1.12 2026/03/06 06:57:33 dtucker Exp $ */ 2 /* 3 * Copyright (c) 2011 Damien Miller <djm@mindrot.org> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 /* Utility functions/framework for regress tests */ 19 20 #ifndef _TEST_HELPER_H 21 #define _TEST_HELPER_H 22 23 #include "includes.h" 24 25 #include <sys/types.h> 26 #include <stdint.h> 27 28 #ifdef WITH_OPENSSL 29 #include <openssl/bn.h> 30 #include <openssl/err.h> 31 #endif 32 33 enum test_predicate { 34 TEST_EQ, TEST_NE, TEST_LT, TEST_LE, TEST_GT, TEST_GE 35 }; 36 typedef void (test_onerror_func_t)(void *); 37 38 /* Supplied by test suite */ 39 void tests(void); 40 void benchmarks(void); 41 42 const char *test_data_file(const char *name); 43 void test_start(const char *n); 44 void test_info(char *s, size_t len); 45 void set_onerror_func(test_onerror_func_t *f, void *ctx); 46 void test_done(void); 47 int test_is_verbose(void); 48 int test_is_quiet(void); 49 int test_is_fast(void); 50 int test_is_slow(void); 51 int test_is_benchmark(void); 52 void test_subtest_info(const char *fmt, ...) 53 __attribute__((format(printf, 1, 2))); 54 void ssl_err_check(const char *file, int line); 55 #ifdef WITH_OPENSSL 56 void assert_bignum(const char *file, int line, 57 const char *a1, const char *a2, 58 const BIGNUM *aa1, const BIGNUM *aa2, enum test_predicate pred); 59 #endif 60 void assert_string(const char *file, int line, 61 const char *a1, const char *a2, 62 const char *aa1, const char *aa2, enum test_predicate pred); 63 void assert_mem(const char *file, int line, 64 const char *a1, const char *a2, 65 const void *aa1, const void *aa2, size_t l, enum test_predicate pred); 66 void assert_mem_filled(const char *file, int line, 67 const char *a1, 68 const void *aa1, u_char v, size_t l, enum test_predicate pred); 69 void assert_int(const char *file, int line, 70 const char *a1, const char *a2, 71 int aa1, int aa2, enum test_predicate pred); 72 void assert_size_t(const char *file, int line, 73 const char *a1, const char *a2, 74 size_t aa1, size_t aa2, enum test_predicate pred); 75 void assert_u_int(const char *file, int line, 76 const char *a1, const char *a2, 77 u_int aa1, u_int aa2, enum test_predicate pred); 78 void assert_long(const char *file, int line, 79 const char *a1, const char *a2, 80 long aa1, long aa2, enum test_predicate pred); 81 void assert_long_long(const char *file, int line, 82 const char *a1, const char *a2, 83 long long aa1, long long aa2, enum test_predicate pred); 84 void assert_char(const char *file, int line, 85 const char *a1, const char *a2, 86 char aa1, char aa2, enum test_predicate pred); 87 void assert_ptr(const char *file, int line, 88 const char *a1, const char *a2, 89 const void *aa1, const void *aa2, enum test_predicate pred); 90 void assert_u8(const char *file, int line, 91 const char *a1, const char *a2, 92 uint8_t aa1, uint8_t aa2, enum test_predicate pred); 93 void assert_u16(const char *file, int line, 94 const char *a1, const char *a2, 95 uint16_t aa1, uint16_t aa2, enum test_predicate pred); 96 void assert_u32(const char *file, int line, 97 const char *a1, const char *a2, 98 uint32_t aa1, uint32_t aa2, enum test_predicate pred); 99 void assert_u64(const char *file, int line, 100 const char *a1, const char *a2, 101 uint64_t aa1, uint64_t aa2, enum test_predicate pred); 102 void assert_double(const char *file, int line, 103 const char *a1, const char *a2, 104 double aa1, double aa2, enum test_predicate pred); 105 106 #define TEST_START(n) test_start(n) 107 #define TEST_DONE() test_done() 108 #define TEST_ONERROR(f, c) set_onerror_func(f, c) 109 #define SSL_ERR_CHECK() ssl_err_check(__FILE__, __LINE__) 110 111 #define ASSERT_BIGNUM_EQ(a1, a2) \ 112 assert_bignum(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ) 113 #define ASSERT_STRING_EQ(a1, a2) \ 114 assert_string(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ) 115 #define ASSERT_MEM_EQ(a1, a2, l) \ 116 assert_mem(__FILE__, __LINE__, #a1, #a2, a1, a2, l, TEST_EQ) 117 #define ASSERT_MEM_FILLED_EQ(a1, c, l) \ 118 assert_mem_filled(__FILE__, __LINE__, #a1, a1, c, l, TEST_EQ) 119 #define ASSERT_MEM_ZERO_EQ(a1, l) \ 120 assert_mem_filled(__FILE__, __LINE__, #a1, a1, '\0', l, TEST_EQ) 121 #define ASSERT_INT_EQ(a1, a2) \ 122 assert_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ) 123 #define ASSERT_SIZE_T_EQ(a1, a2) \ 124 assert_size_t(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ) 125 #define ASSERT_U_INT_EQ(a1, a2) \ 126 assert_u_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ) 127 #define ASSERT_LONG_EQ(a1, a2) \ 128 assert_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ) 129 #define ASSERT_LONG_LONG_EQ(a1, a2) \ 130 assert_long_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ) 131 #define ASSERT_CHAR_EQ(a1, a2) \ 132 assert_char(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ) 133 #define ASSERT_PTR_EQ(a1, a2) \ 134 assert_ptr(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ) 135 #define ASSERT_U8_EQ(a1, a2) \ 136 assert_u8(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ) 137 #define ASSERT_U16_EQ(a1, a2) \ 138 assert_u16(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ) 139 #define ASSERT_U32_EQ(a1, a2) \ 140 assert_u32(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ) 141 #define ASSERT_U64_EQ(a1, a2) \ 142 assert_u64(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ) 143 144 #define ASSERT_BIGNUM_NE(a1, a2) \ 145 assert_bignum(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE) 146 #define ASSERT_STRING_NE(a1, a2) \ 147 assert_string(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE) 148 #define ASSERT_MEM_NE(a1, a2, l) \ 149 assert_mem(__FILE__, __LINE__, #a1, #a2, a1, a2, l, TEST_NE) 150 #define ASSERT_MEM_ZERO_NE(a1, l) \ 151 assert_mem_filled(__FILE__, __LINE__, #a1, a1, '\0', l, TEST_NE) 152 #define ASSERT_INT_NE(a1, a2) \ 153 assert_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE) 154 #define ASSERT_SIZE_T_NE(a1, a2) \ 155 assert_size_t(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE) 156 #define ASSERT_U_INT_NE(a1, a2) \ 157 assert_u_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE) 158 #define ASSERT_LONG_NE(a1, a2) \ 159 assert_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE) 160 #define ASSERT_LONG_LONG_NE(a1, a2) \ 161 assert_long_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE) 162 #define ASSERT_CHAR_NE(a1, a2) \ 163 assert_char(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE) 164 #define ASSERT_PTR_NE(a1, a2) \ 165 assert_ptr(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE) 166 #define ASSERT_U8_NE(a1, a2) \ 167 assert_u8(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE) 168 #define ASSERT_U16_NE(a1, a2) \ 169 assert_u16(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE) 170 #define ASSERT_U32_NE(a1, a2) \ 171 assert_u32(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE) 172 #define ASSERT_U64_NE(a1, a2) \ 173 assert_u64(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE) 174 175 #define ASSERT_BIGNUM_LT(a1, a2) \ 176 assert_bignum(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT) 177 #define ASSERT_STRING_LT(a1, a2) \ 178 assert_string(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT) 179 #define ASSERT_MEM_LT(a1, a2, l) \ 180 assert_mem(__FILE__, __LINE__, #a1, #a2, a1, a2, l, TEST_LT) 181 #define ASSERT_INT_LT(a1, a2) \ 182 assert_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT) 183 #define ASSERT_SIZE_T_LT(a1, a2) \ 184 assert_size_t(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT) 185 #define ASSERT_U_INT_LT(a1, a2) \ 186 assert_u_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT) 187 #define ASSERT_LONG_LT(a1, a2) \ 188 assert_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT) 189 #define ASSERT_LONG_LONG_LT(a1, a2) \ 190 assert_long_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT) 191 #define ASSERT_CHAR_LT(a1, a2) \ 192 assert_char(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT) 193 #define ASSERT_PTR_LT(a1, a2) \ 194 assert_ptr(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT) 195 #define ASSERT_U8_LT(a1, a2) \ 196 assert_u8(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT) 197 #define ASSERT_U16_LT(a1, a2) \ 198 assert_u16(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT) 199 #define ASSERT_U32_LT(a1, a2) \ 200 assert_u32(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT) 201 #define ASSERT_U64_LT(a1, a2) \ 202 assert_u64(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT) 203 204 #define ASSERT_BIGNUM_LE(a1, a2) \ 205 assert_bignum(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE) 206 #define ASSERT_STRING_LE(a1, a2) \ 207 assert_string(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE) 208 #define ASSERT_MEM_LE(a1, a2, l) \ 209 assert_mem(__FILE__, __LINE__, #a1, #a2, a1, a2, l, TEST_LE) 210 #define ASSERT_INT_LE(a1, a2) \ 211 assert_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE) 212 #define ASSERT_SIZE_T_LE(a1, a2) \ 213 assert_size_t(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE) 214 #define ASSERT_U_INT_LE(a1, a2) \ 215 assert_u_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE) 216 #define ASSERT_LONG_LE(a1, a2) \ 217 assert_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE) 218 #define ASSERT_LONG_LONG_LE(a1, a2) \ 219 assert_long_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE) 220 #define ASSERT_CHAR_LE(a1, a2) \ 221 assert_char(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE) 222 #define ASSERT_PTR_LE(a1, a2) \ 223 assert_ptr(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE) 224 #define ASSERT_U8_LE(a1, a2) \ 225 assert_u8(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE) 226 #define ASSERT_U16_LE(a1, a2) \ 227 assert_u16(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE) 228 #define ASSERT_U32_LE(a1, a2) \ 229 assert_u32(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE) 230 #define ASSERT_U64_LE(a1, a2) \ 231 assert_u64(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE) 232 233 #define ASSERT_BIGNUM_GT(a1, a2) \ 234 assert_bignum(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT) 235 #define ASSERT_STRING_GT(a1, a2) \ 236 assert_string(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT) 237 #define ASSERT_MEM_GT(a1, a2, l) \ 238 assert_mem(__FILE__, __LINE__, #a1, #a2, a1, a2, l, TEST_GT) 239 #define ASSERT_INT_GT(a1, a2) \ 240 assert_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT) 241 #define ASSERT_SIZE_T_GT(a1, a2) \ 242 assert_size_t(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT) 243 #define ASSERT_U_INT_GT(a1, a2) \ 244 assert_u_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT) 245 #define ASSERT_LONG_GT(a1, a2) \ 246 assert_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT) 247 #define ASSERT_LONG_LONG_GT(a1, a2) \ 248 assert_long_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT) 249 #define ASSERT_CHAR_GT(a1, a2) \ 250 assert_char(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT) 251 #define ASSERT_PTR_GT(a1, a2) \ 252 assert_ptr(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT) 253 #define ASSERT_U8_GT(a1, a2) \ 254 assert_u8(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT) 255 #define ASSERT_U16_GT(a1, a2) \ 256 assert_u16(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT) 257 #define ASSERT_U32_GT(a1, a2) \ 258 assert_u32(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT) 259 #define ASSERT_U64_GT(a1, a2) \ 260 assert_u64(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT) 261 262 #define ASSERT_BIGNUM_GE(a1, a2) \ 263 assert_bignum(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE) 264 #define ASSERT_STRING_GE(a1, a2) \ 265 assert_string(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE) 266 #define ASSERT_MEM_GE(a1, a2, l) \ 267 assert_mem(__FILE__, __LINE__, #a1, #a2, a1, a2, l, TEST_GE) 268 #define ASSERT_INT_GE(a1, a2) \ 269 assert_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE) 270 #define ASSERT_SIZE_T_GE(a1, a2) \ 271 assert_size_t(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE) 272 #define ASSERT_U_INT_GE(a1, a2) \ 273 assert_u_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE) 274 #define ASSERT_LONG_GE(a1, a2) \ 275 assert_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE) 276 #define ASSERT_LONG_LONG_GE(a1, a2) \ 277 assert_long_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE) 278 #define ASSERT_CHAR_GE(a1, a2) \ 279 assert_char(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE) 280 #define ASSERT_PTR_GE(a1, a2) \ 281 assert_ptr(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE) 282 #define ASSERT_U8_GE(a1, a2) \ 283 assert_u8(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE) 284 #define ASSERT_U16_GE(a1, a2) \ 285 assert_u16(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE) 286 #define ASSERT_U32_GE(a1, a2) \ 287 assert_u32(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE) 288 #define ASSERT_U64_GE(a1, a2) \ 289 assert_u64(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE) 290 291 #define ASSERT_DOUBLE_EQ(a1, a2) \ 292 assert_double(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ) 293 #define ASSERT_DOUBLE_NE(a1, a2) \ 294 assert_double(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE) 295 #define ASSERT_DOUBLE_LT(a1, a2) \ 296 assert_double(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT) 297 #define ASSERT_DOUBLE_LE(a1, a2) \ 298 assert_double(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE) 299 #define ASSERT_DOUBLE_GT(a1, a2) \ 300 assert_double(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT) 301 #define ASSERT_DOUBLE_GE(a1, a2) \ 302 assert_double(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE) 303 304 /* Benchmarking support */ 305 #define BENCH_START(name) \ 306 do { \ 307 bench_start(__FILE__, __LINE__, name); \ 308 while (!bench_done()) { \ 309 bench_case_start(__FILE__, __LINE__); \ 310 do { 311 #define BENCH_FINISH(unit) \ 312 } while (0); \ 313 bench_case_finish(__FILE__, __LINE__); \ 314 } \ 315 bench_finish(__FILE__, __LINE__, unit); \ 316 } while (0) 317 318 void bench_start(const char *file, int line, const char *name); 319 void bench_case_start(const char *file, int line); 320 void bench_case_finish(const char *file, int line); 321 void bench_finish(const char *file, int line, const char *unit); 322 int bench_done(void); 323 324 /* Fuzzing support */ 325 326 struct fuzz; 327 #define FUZZ_1_BIT_FLIP 0x00000001 /* Flip one bit at a time */ 328 #define FUZZ_2_BIT_FLIP 0x00000002 /* Flip two bits at a time */ 329 #define FUZZ_1_BYTE_FLIP 0x00000004 /* Flip one byte at a time */ 330 #define FUZZ_2_BYTE_FLIP 0x00000008 /* Flip two bytes at a time */ 331 #define FUZZ_TRUNCATE_START 0x00000010 /* Truncate from beginning */ 332 #define FUZZ_TRUNCATE_END 0x00000020 /* Truncate from end */ 333 #define FUZZ_BASE64 0x00000040 /* Try all base64 chars */ 334 #define FUZZ_MAX FUZZ_BASE64 335 336 /* Start fuzzing a blob of data with selected strategies (bitmask) */ 337 struct fuzz *fuzz_begin(u_int strategies, const void *p, size_t l); 338 339 /* Free a fuzz context */ 340 void fuzz_cleanup(struct fuzz *fuzz); 341 342 /* Prepare the next fuzz case in the series */ 343 void fuzz_next(struct fuzz *fuzz); 344 345 /* 346 * Check whether this fuzz case is identical to the original 347 * This is slow, but useful if the caller needs to ensure that all tests 348 * generated change the input (e.g. when fuzzing signatures). 349 */ 350 int fuzz_matches_original(struct fuzz *fuzz); 351 352 /* Determine whether the current fuzz sequence is exhausted (nonzero = yes) */ 353 int fuzz_done(struct fuzz *fuzz); 354 355 /* Return the length and a pointer to the current fuzzed case */ 356 size_t fuzz_len(struct fuzz *fuzz); 357 u_char *fuzz_ptr(struct fuzz *fuzz); 358 359 /* Dump the current fuzz case to stderr */ 360 void fuzz_dump(struct fuzz *fuzz); 361 362 #endif /* _TEST_HELPER_H */ 363