1/* $OpenBSD */ 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#include <sys/types.h> 21 22#include <fcntl.h> 23#include <limits.h> 24#include <stdio.h> 25#include <stdint.h> 26#include <stdlib.h> 27#include <string.h> 28#include <assert.h> 29#include <unistd.h> 30 31#include <openssl/bn.h> 32 33#include <vis.h> 34 35#include "test_helper.h" 36 37#define TEST_CHECK_INT(r, pred) do { \ 38 switch (pred) { \ 39 case TEST_EQ: \ 40 if (r == 0) \ 41 return; \ 42 break; \ 43 case TEST_NE: \ 44 if (r != 0) \ 45 return; \ 46 break; \ 47 case TEST_LT: \ 48 if (r < 0) \ 49 return; \ 50 break; \ 51 case TEST_LE: \ 52 if (r <= 0) \ 53 return; \ 54 break; \ 55 case TEST_GT: \ 56 if (r > 0) \ 57 return; \ 58 break; \ 59 case TEST_GE: \ 60 if (r >= 0) \ 61 return; \ 62 break; \ 63 default: \ 64 abort(); \ 65 } \ 66 } while (0) 67 68#define TEST_CHECK(x1, x2, pred) do { \ 69 switch (pred) { \ 70 case TEST_EQ: \ 71 if (x1 == x2) \ 72 return; \ 73 break; \ 74 case TEST_NE: \ 75 if (x1 != x2) \ 76 return; \ 77 break; \ 78 case TEST_LT: \ 79 if (x1 < x2) \ 80 return; \ 81 break; \ 82 case TEST_LE: \ 83 if (x1 <= x2) \ 84 return; \ 85 break; \ 86 case TEST_GT: \ 87 if (x1 > x2) \ 88 return; \ 89 break; \ 90 case TEST_GE: \ 91 if (x1 >= x2) \ 92 return; \ 93 break; \ 94 default: \ 95 abort(); \ 96 } \ 97 } while (0) 98 99extern char *__progname; 100 101static int verbose_mode = 0; 102static int quiet_mode = 0; 103static char *active_test_name = NULL; 104static u_int test_number = 0; 105static test_onerror_func_t *test_onerror = NULL; 106static void *onerror_ctx = NULL; 107static const char *data_dir = NULL; 108 109int 110main(int argc, char **argv) 111{ 112 int ch; 113 114 while ((ch = getopt(argc, argv, "vqd:")) != -1) { 115 switch (ch) { 116 case 'd': 117 data_dir = optarg; 118 break; 119 case 'q': 120 verbose_mode = 0; 121 quiet_mode = 1; 122 break; 123 case 'v': 124 verbose_mode = 1; 125 quiet_mode = 0; 126 break; 127 default: 128 fprintf(stderr, "Unrecognised command line option\n"); 129 fprintf(stderr, "Usage: %s [-v]\n", __progname); 130 exit(1); 131 } 132 } 133 setvbuf(stdout, NULL, _IONBF, 0); 134 if (!quiet_mode) 135 printf("%s: ", __progname); 136 if (verbose_mode) 137 printf("\n"); 138 139 tests(); 140 141 if (!quiet_mode) 142 printf(" %u tests ok\n", test_number); 143 return 0; 144} 145 146const char * 147test_data_file(const char *name) 148{ 149 static char ret[PATH_MAX]; 150 151 if (data_dir != NULL) 152 snprintf(ret, sizeof(ret), "%s/%s", data_dir, name); 153 else 154 strlcpy(ret, name, sizeof(ret)); 155 if (access(ret, F_OK) != 0) { 156 fprintf(stderr, "Cannot access data file %s: %s\n", 157 ret, strerror(errno)); 158 exit(1); 159 } 160 return ret; 161} 162 163void 164test_start(const char *n) 165{ 166 assert(active_test_name == NULL); 167 assert((active_test_name = strdup(n)) != NULL); 168 if (verbose_mode) 169 printf("test %u - \"%s\": ", test_number, active_test_name); 170 test_number++; 171} 172 173void 174set_onerror_func(test_onerror_func_t *f, void *ctx) 175{ 176 test_onerror = f; 177 onerror_ctx = ctx; 178} 179 180void 181test_done(void) 182{ 183 assert(active_test_name != NULL); 184 free(active_test_name); 185 active_test_name = NULL; 186 if (verbose_mode) 187 printf("OK\n"); 188 else if (!quiet_mode) { 189 printf("."); 190 fflush(stdout); 191 } 192} 193 194static const char * 195pred_name(enum test_predicate p) 196{ 197 switch (p) { 198 case TEST_EQ: 199 return "EQ"; 200 case TEST_NE: 201 return "NE"; 202 case TEST_LT: 203 return "LT"; 204 case TEST_LE: 205 return "LE"; 206 case TEST_GT: 207 return "GT"; 208 case TEST_GE: 209 return "GE"; 210 default: 211 return "UNKNOWN"; 212 } 213} 214 215static void 216test_die(void) 217{ 218 if (test_onerror != NULL) 219 test_onerror(onerror_ctx); 220 abort(); 221} 222 223static void 224test_header(const char *file, int line, const char *a1, const char *a2, 225 const char *name, enum test_predicate pred) 226{ 227 fprintf(stderr, "\n%s:%d test #%u \"%s\"\n", 228 file, line, test_number, active_test_name); 229 fprintf(stderr, "ASSERT_%s_%s(%s%s%s) failed:\n", 230 name, pred_name(pred), a1, 231 a2 != NULL ? ", " : "", a2 != NULL ? a2 : ""); 232} 233 234void 235assert_string(const char *file, int line, const char *a1, const char *a2, 236 const char *aa1, const char *aa2, enum test_predicate pred) 237{ 238 int r = strcmp(aa1, aa2); 239 240 TEST_CHECK_INT(r, pred); 241 test_header(file, line, a1, a2, "STRING", pred); 242 fprintf(stderr, "%12s = %s (len %zu)\n", a1, aa1, strlen(aa1)); 243 fprintf(stderr, "%12s = %s (len %zu)\n", a2, aa2, strlen(aa2)); 244 test_die(); 245} 246 247static char * 248tohex(const void *_s, size_t l) 249{ 250 uint8_t *s = (uint8_t *)_s; 251 size_t i, j; 252 const char *hex = "0123456789abcdef"; 253 char *r = malloc((l * 2) + 1); 254 255 assert(r != NULL); 256 for (i = j = 0; i < l; i++) { 257 r[j++] = hex[(s[i] >> 4) & 0xf]; 258 r[j++] = hex[s[i] & 0xf]; 259 } 260 r[j] = '\0'; 261 return r; 262} 263 264void 265assert_mem(const char *file, int line, const char *a1, const char *a2, 266 const void *aa1, const void *aa2, size_t l, enum test_predicate pred) 267{ 268 int r = memcmp(aa1, aa2, l); 269 270 TEST_CHECK_INT(r, pred); 271 test_header(file, line, a1, a2, "STRING", pred); 272 fprintf(stderr, "%12s = %s (len %zu)\n", a1, 273 tohex(aa1, MINIMUM(l, 256)), l); 274 fprintf(stderr, "%12s = %s (len %zu)\n", a2, 275 tohex(aa2, MINIMUM(l, 256)), l); 276 test_die(); 277} 278 279static int 280memvalcmp(const uint8_t *s, u_char v, size_t l, size_t *where) 281{ 282 size_t i; 283 284 for (i = 0; i < l; i++) { 285 if (s[i] != v) { 286 *where = i; 287 return 1; 288 } 289 } 290 return 0; 291} 292 293void 294assert_mem_filled(const char *file, int line, const char *a1, 295 const void *aa1, u_char v, size_t l, enum test_predicate pred) 296{ 297 size_t where = -1; 298 int r = memvalcmp(aa1, v, l, &where); 299 char tmp[64]; 300 301 if (l == 0) 302 return; 303 TEST_CHECK_INT(r, pred); 304 test_header(file, line, a1, NULL, "MEM_ZERO", pred); 305 fprintf(stderr, "%20s = %s%s (len %zu)\n", a1, 306 tohex(aa1, MINIMUM(l, 20)), l > 20 ? "..." : "", l); 307 snprintf(tmp, sizeof(tmp), "(%s)[%zu]", a1, where); 308 fprintf(stderr, "%20s = 0x%02x (expected 0x%02x)\n", tmp, 309 ((u_char *)aa1)[where], v); 310 test_die(); 311} 312 313void 314assert_int(const char *file, int line, const char *a1, const char *a2, 315 int aa1, int aa2, enum test_predicate pred) 316{ 317 TEST_CHECK(aa1, aa2, pred); 318 test_header(file, line, a1, a2, "INT", pred); 319 fprintf(stderr, "%12s = %d\n", a1, aa1); 320 fprintf(stderr, "%12s = %d\n", a2, aa2); 321 test_die(); 322} 323 324void 325assert_size_t(const char *file, int line, const char *a1, const char *a2, 326 size_t aa1, size_t aa2, enum test_predicate pred) 327{ 328 TEST_CHECK(aa1, aa2, pred); 329 test_header(file, line, a1, a2, "SIZE_T", pred); 330 fprintf(stderr, "%12s = %zu\n", a1, aa1); 331 fprintf(stderr, "%12s = %zu\n", a2, aa2); 332 test_die(); 333} 334 335void 336assert_u_int(const char *file, int line, const char *a1, const char *a2, 337 u_int aa1, u_int aa2, enum test_predicate pred) 338{ 339 TEST_CHECK(aa1, aa2, pred); 340 test_header(file, line, a1, a2, "U_INT", pred); 341 fprintf(stderr, "%12s = %u / 0x%x\n", a1, aa1, aa1); 342 fprintf(stderr, "%12s = %u / 0x%x\n", a2, aa2, aa2); 343 test_die(); 344} 345 346void 347assert_long_long(const char *file, int line, const char *a1, const char *a2, 348 long long aa1, long long aa2, enum test_predicate pred) 349{ 350 TEST_CHECK(aa1, aa2, pred); 351 test_header(file, line, a1, a2, "LONG LONG", pred); 352 fprintf(stderr, "%12s = %lld / 0x%llx\n", a1, aa1, aa1); 353 fprintf(stderr, "%12s = %lld / 0x%llx\n", a2, aa2, aa2); 354 test_die(); 355} 356 357void 358assert_char(const char *file, int line, const char *a1, const char *a2, 359 char aa1, char aa2, enum test_predicate pred) 360{ 361 char buf[8]; 362 363 TEST_CHECK(aa1, aa2, pred); 364 test_header(file, line, a1, a2, "CHAR", pred); 365 fprintf(stderr, "%12s = '%s' / 0x02%x\n", a1, 366 vis(buf, aa1, VIS_SAFE|VIS_NL|VIS_TAB|VIS_OCTAL, 0), aa1); 367 fprintf(stderr, "%12s = '%s' / 0x02%x\n", a1, 368 vis(buf, aa2, VIS_SAFE|VIS_NL|VIS_TAB|VIS_OCTAL, 0), aa2); 369 test_die(); 370} 371 372void 373assert_u8(const char *file, int line, const char *a1, const char *a2, 374 uint8_t aa1, uint8_t aa2, enum test_predicate pred) 375{ 376 TEST_CHECK(aa1, aa2, pred); 377 test_header(file, line, a1, a2, "U8", pred); 378 fprintf(stderr, "%12s = 0x%02x %u\n", a1, aa1, aa1); 379 fprintf(stderr, "%12s = 0x%02x %u\n", a2, aa2, aa2); 380 test_die(); 381} 382 383void 384assert_u16(const char *file, int line, const char *a1, const char *a2, 385 uint16_t aa1, uint16_t aa2, enum test_predicate pred) 386{ 387 TEST_CHECK(aa1, aa2, pred); 388 test_header(file, line, a1, a2, "U16", pred); 389 fprintf(stderr, "%12s = 0x%04x %u\n", a1, aa1, aa1); 390 fprintf(stderr, "%12s = 0x%04x %u\n", a2, aa2, aa2); 391 test_die(); 392} 393 394void 395assert_u32(const char *file, int line, const char *a1, const char *a2, 396 uint32_t aa1, uint32_t aa2, enum test_predicate pred) 397{ 398 TEST_CHECK(aa1, aa2, pred); 399 test_header(file, line, a1, a2, "U32", pred); 400 fprintf(stderr, "%12s = 0x%08x %u\n", a1, aa1, aa1); 401 fprintf(stderr, "%12s = 0x%08x %u\n", a2, aa2, aa2); 402 test_die(); 403} 404 405void 406assert_u64(const char *file, int line, const char *a1, const char *a2, 407 uint64_t aa1, uint64_t aa2, enum test_predicate pred) 408{ 409 TEST_CHECK(aa1, aa2, pred); 410 test_header(file, line, a1, a2, "U64", pred); 411 fprintf(stderr, "%12s = 0x%016llx %llu\n", a1, 412 (unsigned long long)aa1, (unsigned long long)aa1); 413 fprintf(stderr, "%12s = 0x%016llx %llu\n", a2, 414 (unsigned long long)aa2, (unsigned long long)aa2); 415 test_die(); 416} 417 418void 419assert_ptr(const char *file, int line, const char *a1, const char *a2, 420 const void *aa1, const void *aa2, enum test_predicate pred) 421{ 422 TEST_CHECK(aa1, aa2, pred); 423 test_header(file, line, a1, a2, "PTR", pred); 424 fprintf(stderr, "%12s = %p\n", a1, aa1); 425 fprintf(stderr, "%12s = %p\n", a2, aa2); 426 test_die(); 427} 428 429