utils_module_tests.c revision 4ae50e65ef0eefe6d5c356acbc1839f8eac68af5
1/* 2 * utils module tests 3 * Copyright (c) 2014-2015, Jouni Malinen <j@w1.fi> 4 * 5 * This software may be distributed under the terms of the BSD license. 6 * See README for more details. 7 */ 8 9#include "utils/includes.h" 10 11#include "utils/common.h" 12#include "common/ieee802_11_defs.h" 13#include "utils/bitfield.h" 14#include "utils/ext_password.h" 15#include "utils/trace.h" 16#include "utils/base64.h" 17#include "utils/ip_addr.h" 18#include "utils/eloop.h" 19#include "utils/module_tests.h" 20 21 22struct printf_test_data { 23 u8 *data; 24 size_t len; 25 char *encoded; 26}; 27 28static const struct printf_test_data printf_tests[] = { 29 { (u8 *) "abcde", 5, "abcde" }, 30 { (u8 *) "a\0b\nc\ed\re\tf\"\\", 13, "a\\0b\\nc\\ed\\re\\tf\\\"\\\\" }, 31 { (u8 *) "\x00\x31\x00\x32\x00\x39", 6, "\\x001\\0002\\09" }, 32 { (u8 *) "\n\n\n", 3, "\n\12\x0a" }, 33 { (u8 *) "\303\245\303\244\303\266\303\205\303\204\303\226", 12, 34 "\\xc3\\xa5\xc3\\xa4\\xc3\\xb6\\xc3\\x85\\xc3\\x84\\xc3\\x96" }, 35 { (u8 *) "\303\245\303\244\303\266\303\205\303\204\303\226", 12, 36 "\\303\\245\\303\\244\\303\\266\\303\\205\\303\\204\\303\\226" }, 37 { (u8 *) "\xe5\xe4\xf6\xc5\xc4\xd6", 6, 38 "\\xe5\\xe4\\xf6\\xc5\\xc4\\xd6" }, 39 { NULL, 0, NULL } 40}; 41 42 43static int printf_encode_decode_tests(void) 44{ 45 int i; 46 size_t binlen; 47 char buf[100]; 48 u8 bin[100]; 49 int errors = 0; 50 int array[10]; 51 52 wpa_printf(MSG_INFO, "printf encode/decode tests"); 53 54 for (i = 0; printf_tests[i].data; i++) { 55 const struct printf_test_data *test = &printf_tests[i]; 56 printf_encode(buf, sizeof(buf), test->data, test->len); 57 wpa_printf(MSG_INFO, "%d: -> \"%s\"", i, buf); 58 59 binlen = printf_decode(bin, sizeof(bin), buf); 60 if (binlen != test->len || 61 os_memcmp(bin, test->data, binlen) != 0) { 62 wpa_hexdump(MSG_ERROR, "Error in decoding#1", 63 bin, binlen); 64 errors++; 65 } 66 67 binlen = printf_decode(bin, sizeof(bin), test->encoded); 68 if (binlen != test->len || 69 os_memcmp(bin, test->data, binlen) != 0) { 70 wpa_hexdump(MSG_ERROR, "Error in decoding#2", 71 bin, binlen); 72 errors++; 73 } 74 } 75 76 buf[5] = 'A'; 77 printf_encode(buf, 5, (const u8 *) "abcde", 5); 78 if (buf[5] != 'A') { 79 wpa_printf(MSG_ERROR, "Error in bounds checking#1"); 80 errors++; 81 } 82 83 for (i = 5; i < 10; i++) { 84 buf[i] = 'A'; 85 printf_encode(buf, i, (const u8 *) "\xdd\xdd\xdd\xdd\xdd", 5); 86 if (buf[i] != 'A') { 87 wpa_printf(MSG_ERROR, "Error in bounds checking#2(%d)", 88 i); 89 errors++; 90 } 91 } 92 93 if (printf_decode(bin, 3, "abcde") != 2) 94 errors++; 95 96 if (printf_decode(bin, 3, "\\xa") != 1 || bin[0] != 10) 97 errors++; 98 99 if (printf_decode(bin, 3, "\\xq") != 1 || bin[0] != 'q') 100 errors++; 101 102 if (printf_decode(bin, 3, "\\a") != 1 || bin[0] != 'a') 103 errors++; 104 105 array[0] = 10; 106 array[1] = 10; 107 array[2] = 5; 108 array[3] = 10; 109 array[4] = 5; 110 array[5] = 0; 111 if (int_array_len(array) != 5) 112 errors++; 113 int_array_sort_unique(array); 114 if (int_array_len(array) != 2) 115 errors++; 116 117 if (errors) { 118 wpa_printf(MSG_ERROR, "%d printf test(s) failed", errors); 119 return -1; 120 } 121 122 return 0; 123} 124 125 126static int bitfield_tests(void) 127{ 128 struct bitfield *bf; 129 int i; 130 int errors = 0; 131 132 wpa_printf(MSG_INFO, "bitfield tests"); 133 134 bf = bitfield_alloc(123); 135 if (bf == NULL) 136 return -1; 137 138 for (i = 0; i < 123; i++) { 139 if (bitfield_is_set(bf, i) || bitfield_is_set(bf, i + 1)) 140 errors++; 141 if (i > 0 && bitfield_is_set(bf, i - 1)) 142 errors++; 143 bitfield_set(bf, i); 144 if (!bitfield_is_set(bf, i)) 145 errors++; 146 bitfield_clear(bf, i); 147 if (bitfield_is_set(bf, i)) 148 errors++; 149 } 150 151 for (i = 123; i < 200; i++) { 152 if (bitfield_is_set(bf, i) || bitfield_is_set(bf, i + 1)) 153 errors++; 154 if (i > 0 && bitfield_is_set(bf, i - 1)) 155 errors++; 156 bitfield_set(bf, i); 157 if (bitfield_is_set(bf, i)) 158 errors++; 159 bitfield_clear(bf, i); 160 if (bitfield_is_set(bf, i)) 161 errors++; 162 } 163 164 for (i = 0; i < 123; i++) { 165 if (bitfield_is_set(bf, i) || bitfield_is_set(bf, i + 1)) 166 errors++; 167 bitfield_set(bf, i); 168 if (!bitfield_is_set(bf, i)) 169 errors++; 170 } 171 172 for (i = 0; i < 123; i++) { 173 if (!bitfield_is_set(bf, i)) 174 errors++; 175 bitfield_clear(bf, i); 176 if (bitfield_is_set(bf, i)) 177 errors++; 178 } 179 180 for (i = 0; i < 123; i++) { 181 if (bitfield_get_first_zero(bf) != i) 182 errors++; 183 bitfield_set(bf, i); 184 } 185 if (bitfield_get_first_zero(bf) != -1) 186 errors++; 187 for (i = 0; i < 123; i++) { 188 if (!bitfield_is_set(bf, i)) 189 errors++; 190 bitfield_clear(bf, i); 191 if (bitfield_get_first_zero(bf) != i) 192 errors++; 193 bitfield_set(bf, i); 194 } 195 if (bitfield_get_first_zero(bf) != -1) 196 errors++; 197 198 bitfield_free(bf); 199 200 bf = bitfield_alloc(8); 201 if (bf == NULL) 202 return -1; 203 if (bitfield_get_first_zero(bf) != 0) 204 errors++; 205 for (i = 0; i < 8; i++) 206 bitfield_set(bf, i); 207 if (bitfield_get_first_zero(bf) != -1) 208 errors++; 209 bitfield_free(bf); 210 211 if (errors) { 212 wpa_printf(MSG_ERROR, "%d bitfield test(s) failed", errors); 213 return -1; 214 } 215 216 return 0; 217} 218 219 220static int int_array_tests(void) 221{ 222 int test1[] = { 1, 2, 3, 4, 5, 6, 0 }; 223 int test2[] = { 1, -1, 0 }; 224 int test3[] = { 1, 1, 1, -1, 2, 3, 4, 1, 2, 0 }; 225 int test3_res[] = { -1, 1, 2, 3, 4, 0 }; 226 int errors = 0; 227 int len; 228 229 wpa_printf(MSG_INFO, "int_array tests"); 230 231 if (int_array_len(test1) != 6 || 232 int_array_len(test2) != 2) 233 errors++; 234 235 int_array_sort_unique(test3); 236 len = int_array_len(test3_res); 237 if (int_array_len(test3) != len) 238 errors++; 239 else if (os_memcmp(test3, test3_res, len * sizeof(int)) != 0) 240 errors++; 241 242 if (errors) { 243 wpa_printf(MSG_ERROR, "%d int_array test(s) failed", errors); 244 return -1; 245 } 246 247 return 0; 248} 249 250 251static int ext_password_tests(void) 252{ 253 struct ext_password_data *data; 254 int ret = 0; 255 struct wpabuf *pw; 256 257 wpa_printf(MSG_INFO, "ext_password tests"); 258 259 data = ext_password_init("unknown", "foo"); 260 if (data != NULL) 261 return -1; 262 263 data = ext_password_init("test", NULL); 264 if (data == NULL) 265 return -1; 266 pw = ext_password_get(data, "foo"); 267 if (pw != NULL) 268 ret = -1; 269 ext_password_free(pw); 270 271 ext_password_deinit(data); 272 273 pw = ext_password_get(NULL, "foo"); 274 if (pw != NULL) 275 ret = -1; 276 ext_password_free(pw); 277 278 return ret; 279} 280 281 282static int trace_tests(void) 283{ 284 wpa_printf(MSG_INFO, "trace tests"); 285 286 wpa_trace_show("test backtrace"); 287 wpa_trace_dump_funcname("test funcname", trace_tests); 288 289 return 0; 290} 291 292 293static int base64_tests(void) 294{ 295 int errors = 0; 296 unsigned char *res; 297 size_t res_len; 298 299 wpa_printf(MSG_INFO, "base64 tests"); 300 301 res = base64_encode((const unsigned char *) "", ~0, &res_len); 302 if (res) { 303 errors++; 304 os_free(res); 305 } 306 307 res = base64_encode((const unsigned char *) "=", 1, &res_len); 308 if (!res || res_len != 5 || res[0] != 'P' || res[1] != 'Q' || 309 res[2] != '=' || res[3] != '=' || res[4] != '\n') 310 errors++; 311 os_free(res); 312 313 res = base64_encode((const unsigned char *) "=", 1, NULL); 314 if (!res || res[0] != 'P' || res[1] != 'Q' || 315 res[2] != '=' || res[3] != '=' || res[4] != '\n') 316 errors++; 317 os_free(res); 318 319 res = base64_decode((const unsigned char *) "", 0, &res_len); 320 if (res) { 321 errors++; 322 os_free(res); 323 } 324 325 res = base64_decode((const unsigned char *) "a", 1, &res_len); 326 if (res) { 327 errors++; 328 os_free(res); 329 } 330 331 res = base64_decode((const unsigned char *) "====", 4, &res_len); 332 if (res) { 333 errors++; 334 os_free(res); 335 } 336 337 res = base64_decode((const unsigned char *) "PQ==", 4, &res_len); 338 if (!res || res_len != 1 || res[0] != '=') 339 errors++; 340 os_free(res); 341 342 res = base64_decode((const unsigned char *) "P.Q-=!=*", 8, &res_len); 343 if (!res || res_len != 1 || res[0] != '=') 344 errors++; 345 os_free(res); 346 347 if (errors) { 348 wpa_printf(MSG_ERROR, "%d base64 test(s) failed", errors); 349 return -1; 350 } 351 352 return 0; 353} 354 355 356static int common_tests(void) 357{ 358 char buf[3], longbuf[100]; 359 u8 addr[ETH_ALEN] = { 1, 2, 3, 4, 5, 6 }; 360 u8 bin[3]; 361 int errors = 0; 362 struct wpa_freq_range_list ranges; 363 size_t len; 364 const char *txt; 365 u8 ssid[255]; 366 367 wpa_printf(MSG_INFO, "common tests"); 368 369 if (hwaddr_mask_txt(buf, 3, addr, addr) != -1) 370 errors++; 371 372 if (wpa_scnprintf(buf, 0, "hello") != 0 || 373 wpa_scnprintf(buf, 3, "hello") != 2) 374 errors++; 375 376 if (wpa_snprintf_hex(buf, 0, addr, ETH_ALEN) != 0 || 377 wpa_snprintf_hex(buf, 3, addr, ETH_ALEN) != 2) 378 errors++; 379 380 if (merge_byte_arrays(bin, 3, addr, ETH_ALEN, NULL, 0) != 3 || 381 merge_byte_arrays(bin, 3, NULL, 0, addr, ETH_ALEN) != 3) 382 errors++; 383 384 if (dup_binstr(NULL, 0) != NULL) 385 errors++; 386 387 if (freq_range_list_includes(NULL, 0) != 0) 388 errors++; 389 390 os_memset(&ranges, 0, sizeof(ranges)); 391 if (freq_range_list_parse(&ranges, "") != 0 || 392 freq_range_list_includes(&ranges, 0) != 0 || 393 freq_range_list_str(&ranges) != NULL) 394 errors++; 395 396 if (utf8_unescape(NULL, 0, buf, sizeof(buf)) != 0 || 397 utf8_unescape("a", 1, NULL, 0) != 0 || 398 utf8_unescape("a\\", 2, buf, sizeof(buf)) != 0 || 399 utf8_unescape("abcde", 5, buf, sizeof(buf)) != 0 || 400 utf8_unescape("abc", 3, buf, 3) != 3) 401 errors++; 402 403 if (utf8_unescape("a", 0, buf, sizeof(buf)) != 1 || buf[0] != 'a') 404 errors++; 405 406 if (utf8_unescape("\\b", 2, buf, sizeof(buf)) != 1 || buf[0] != 'b') 407 errors++; 408 409 if (utf8_escape(NULL, 0, buf, sizeof(buf)) != 0 || 410 utf8_escape("a", 1, NULL, 0) != 0 || 411 utf8_escape("abcde", 5, buf, sizeof(buf)) != 0 || 412 utf8_escape("a\\bcde", 6, buf, sizeof(buf)) != 0 || 413 utf8_escape("ab\\cde", 6, buf, sizeof(buf)) != 0 || 414 utf8_escape("abc\\de", 6, buf, sizeof(buf)) != 0 || 415 utf8_escape("abc", 3, buf, 3) != 3) 416 errors++; 417 418 if (utf8_escape("a", 0, buf, sizeof(buf)) != 1 || buf[0] != 'a') 419 errors++; 420 421 os_memset(ssid, 0, sizeof(ssid)); 422 txt = wpa_ssid_txt(ssid, sizeof(ssid)); 423 len = os_strlen(txt); 424 /* Verify that SSID_MAX_LEN * 4 buffer limit is enforced. */ 425 if (len != SSID_MAX_LEN * 4) { 426 wpa_printf(MSG_ERROR, 427 "Unexpected wpa_ssid_txt() result with too long SSID"); 428 errors++; 429 } 430 431 if (wpa_snprintf_hex_sep(longbuf, 0, addr, ETH_ALEN, '-') != 0 || 432 wpa_snprintf_hex_sep(longbuf, 5, addr, ETH_ALEN, '-') != 3 || 433 os_strcmp(longbuf, "01-0") != 0) 434 errors++; 435 436 if (errors) { 437 wpa_printf(MSG_ERROR, "%d common test(s) failed", errors); 438 return -1; 439 } 440 441 return 0; 442} 443 444 445static int os_tests(void) 446{ 447 int errors = 0; 448 void *ptr; 449 os_time_t t; 450 451 wpa_printf(MSG_INFO, "os tests"); 452 453 ptr = os_calloc((size_t) -1, (size_t) -1); 454 if (ptr) { 455 errors++; 456 os_free(ptr); 457 } 458 ptr = os_calloc((size_t) 2, (size_t) -1); 459 if (ptr) { 460 errors++; 461 os_free(ptr); 462 } 463 ptr = os_calloc((size_t) -1, (size_t) 2); 464 if (ptr) { 465 errors++; 466 os_free(ptr); 467 } 468 469 ptr = os_realloc_array(NULL, (size_t) -1, (size_t) -1); 470 if (ptr) { 471 errors++; 472 os_free(ptr); 473 } 474 475 os_sleep(1, 1); 476 477 if (os_mktime(1969, 1, 1, 1, 1, 1, &t) == 0 || 478 os_mktime(1971, 0, 1, 1, 1, 1, &t) == 0 || 479 os_mktime(1971, 13, 1, 1, 1, 1, &t) == 0 || 480 os_mktime(1971, 1, 0, 1, 1, 1, &t) == 0 || 481 os_mktime(1971, 1, 32, 1, 1, 1, &t) == 0 || 482 os_mktime(1971, 1, 1, -1, 1, 1, &t) == 0 || 483 os_mktime(1971, 1, 1, 24, 1, 1, &t) == 0 || 484 os_mktime(1971, 1, 1, 1, -1, 1, &t) == 0 || 485 os_mktime(1971, 1, 1, 1, 60, 1, &t) == 0 || 486 os_mktime(1971, 1, 1, 1, 1, -1, &t) == 0 || 487 os_mktime(1971, 1, 1, 1, 1, 61, &t) == 0 || 488 os_mktime(1971, 1, 1, 1, 1, 1, &t) != 0 || 489 os_mktime(2020, 1, 2, 3, 4, 5, &t) != 0 || 490 os_mktime(2015, 12, 31, 23, 59, 59, &t) != 0) 491 errors++; 492 493 if (os_setenv("hwsim_test_env", "test value", 0) != 0 || 494 os_setenv("hwsim_test_env", "test value 2", 1) != 0 || 495 os_unsetenv("hwsim_test_env") != 0) 496 errors++; 497 498 if (os_file_exists("/this-file-does-not-exists-hwsim") != 0) 499 errors++; 500 501 if (errors) { 502 wpa_printf(MSG_ERROR, "%d os test(s) failed", errors); 503 return -1; 504 } 505 506 return 0; 507} 508 509 510static int wpabuf_tests(void) 511{ 512 int errors = 0; 513 void *ptr; 514 struct wpabuf *buf; 515 516 wpa_printf(MSG_INFO, "wpabuf tests"); 517 518 ptr = os_malloc(100); 519 if (ptr) { 520 buf = wpabuf_alloc_ext_data(ptr, 100); 521 if (buf) { 522 if (wpabuf_resize(&buf, 100) < 0) 523 errors++; 524 else 525 wpabuf_put(buf, 100); 526 wpabuf_free(buf); 527 } else { 528 errors++; 529 os_free(ptr); 530 } 531 } else { 532 errors++; 533 } 534 535 buf = wpabuf_alloc(100); 536 if (buf) { 537 struct wpabuf *buf2; 538 539 wpabuf_put(buf, 100); 540 if (wpabuf_resize(&buf, 100) < 0) 541 errors++; 542 else 543 wpabuf_put(buf, 100); 544 buf2 = wpabuf_concat(buf, NULL); 545 if (buf2 != buf) 546 errors++; 547 wpabuf_free(buf2); 548 } else { 549 errors++; 550 } 551 552 buf = NULL; 553 buf = wpabuf_zeropad(buf, 10); 554 if (buf != NULL) 555 errors++; 556 557 if (errors) { 558 wpa_printf(MSG_ERROR, "%d wpabuf test(s) failed", errors); 559 return -1; 560 } 561 562 return 0; 563} 564 565 566static int ip_addr_tests(void) 567{ 568 int errors = 0; 569 struct hostapd_ip_addr addr; 570 char buf[100]; 571 572 wpa_printf(MSG_INFO, "ip_addr tests"); 573 574 if (hostapd_parse_ip_addr("1.2.3.4", &addr) != 0 || 575 addr.af != AF_INET || 576 hostapd_ip_txt(NULL, buf, sizeof(buf)) != NULL || 577 hostapd_ip_txt(&addr, buf, 1) != buf || buf[0] != '\0' || 578 hostapd_ip_txt(&addr, buf, 0) != NULL || 579 hostapd_ip_txt(&addr, buf, sizeof(buf)) != buf) 580 errors++; 581 582 if (hostapd_parse_ip_addr("::", &addr) != 0 || 583 addr.af != AF_INET6 || 584 hostapd_ip_txt(&addr, buf, 1) != buf || buf[0] != '\0' || 585 hostapd_ip_txt(&addr, buf, sizeof(buf)) != buf) 586 errors++; 587 588 if (errors) { 589 wpa_printf(MSG_ERROR, "%d ip_addr test(s) failed", errors); 590 return -1; 591 } 592 593 return 0; 594} 595 596 597struct test_eloop { 598 unsigned int magic; 599 int close_in_timeout; 600 int pipefd1[2]; 601 int pipefd2[2]; 602}; 603 604 605static void eloop_tests_start(int close_in_timeout); 606 607 608static void eloop_test_read_2(int sock, void *eloop_ctx, void *sock_ctx) 609{ 610 struct test_eloop *t = eloop_ctx; 611 ssize_t res; 612 char buf[10]; 613 614 wpa_printf(MSG_INFO, "%s: sock=%d", __func__, sock); 615 616 if (t->magic != 0x12345678) { 617 wpa_printf(MSG_INFO, "%s: unexpected magic 0x%x", 618 __func__, t->magic); 619 } 620 621 if (t->pipefd2[0] != sock) { 622 wpa_printf(MSG_INFO, "%s: unexpected sock %d != %d", 623 __func__, sock, t->pipefd2[0]); 624 } 625 626 res = read(sock, buf, sizeof(buf)); 627 wpa_printf(MSG_INFO, "%s: sock=%d --> res=%d", 628 __func__, sock, (int) res); 629} 630 631 632static void eloop_test_read_2_wrong(int sock, void *eloop_ctx, void *sock_ctx) 633{ 634 struct test_eloop *t = eloop_ctx; 635 636 wpa_printf(MSG_INFO, "%s: sock=%d", __func__, sock); 637 638 if (t->magic != 0x12345678) { 639 wpa_printf(MSG_INFO, "%s: unexpected magic 0x%x", 640 __func__, t->magic); 641 } 642 643 if (t->pipefd2[0] != sock) { 644 wpa_printf(MSG_INFO, "%s: unexpected sock %d != %d", 645 __func__, sock, t->pipefd2[0]); 646 } 647 648 /* 649 * This is expected to block due to the original socket with data having 650 * been closed and no new data having been written to the new socket 651 * with the same fd. To avoid blocking the process during test, skip the 652 * read here. 653 */ 654 wpa_printf(MSG_ERROR, "%s: FAIL - should not have called this function", 655 __func__); 656} 657 658 659static void reopen_pipefd2(struct test_eloop *t) 660{ 661 if (t->pipefd2[0] < 0) { 662 wpa_printf(MSG_INFO, "pipefd2 had been closed"); 663 } else { 664 int res; 665 666 wpa_printf(MSG_INFO, "close pipefd2"); 667 eloop_unregister_read_sock(t->pipefd2[0]); 668 close(t->pipefd2[0]); 669 t->pipefd2[0] = -1; 670 close(t->pipefd2[1]); 671 t->pipefd2[1] = -1; 672 673 res = pipe(t->pipefd2); 674 if (res < 0) { 675 wpa_printf(MSG_INFO, "pipe: %s", strerror(errno)); 676 t->pipefd2[0] = -1; 677 t->pipefd2[1] = -1; 678 return; 679 } 680 681 wpa_printf(MSG_INFO, 682 "re-register pipefd2 with new sockets %d,%d", 683 t->pipefd2[0], t->pipefd2[1]); 684 eloop_register_read_sock(t->pipefd2[0], eloop_test_read_2_wrong, 685 t, NULL); 686 } 687} 688 689 690static void eloop_test_read_1(int sock, void *eloop_ctx, void *sock_ctx) 691{ 692 struct test_eloop *t = eloop_ctx; 693 ssize_t res; 694 char buf[10]; 695 696 wpa_printf(MSG_INFO, "%s: sock=%d", __func__, sock); 697 698 if (t->magic != 0x12345678) { 699 wpa_printf(MSG_INFO, "%s: unexpected magic 0x%x", 700 __func__, t->magic); 701 } 702 703 if (t->pipefd1[0] != sock) { 704 wpa_printf(MSG_INFO, "%s: unexpected sock %d != %d", 705 __func__, sock, t->pipefd1[0]); 706 } 707 708 res = read(sock, buf, sizeof(buf)); 709 wpa_printf(MSG_INFO, "%s: sock=%d --> res=%d", 710 __func__, sock, (int) res); 711 712 if (!t->close_in_timeout) 713 reopen_pipefd2(t); 714} 715 716 717static void eloop_test_cb(void *eloop_data, void *user_ctx) 718{ 719 struct test_eloop *t = eloop_data; 720 721 wpa_printf(MSG_INFO, "%s", __func__); 722 723 if (t->magic != 0x12345678) { 724 wpa_printf(MSG_INFO, "%s: unexpected magic 0x%x", 725 __func__, t->magic); 726 } 727 728 if (t->close_in_timeout) 729 reopen_pipefd2(t); 730} 731 732 733static void eloop_test_timeout(void *eloop_data, void *user_ctx) 734{ 735 struct test_eloop *t = eloop_data; 736 int next_run = 0; 737 738 wpa_printf(MSG_INFO, "%s", __func__); 739 740 if (t->magic != 0x12345678) { 741 wpa_printf(MSG_INFO, "%s: unexpected magic 0x%x", 742 __func__, t->magic); 743 } 744 745 if (t->pipefd1[0] >= 0) { 746 wpa_printf(MSG_INFO, "pipefd1 had not been closed"); 747 eloop_unregister_read_sock(t->pipefd1[0]); 748 close(t->pipefd1[0]); 749 t->pipefd1[0] = -1; 750 close(t->pipefd1[1]); 751 t->pipefd1[1] = -1; 752 } 753 754 if (t->pipefd2[0] >= 0) { 755 wpa_printf(MSG_INFO, "pipefd2 had not been closed"); 756 eloop_unregister_read_sock(t->pipefd2[0]); 757 close(t->pipefd2[0]); 758 t->pipefd2[0] = -1; 759 close(t->pipefd2[1]); 760 t->pipefd2[1] = -1; 761 } 762 763 next_run = t->close_in_timeout; 764 t->magic = 0; 765 wpa_printf(MSG_INFO, "%s - free(%p)", __func__, t); 766 os_free(t); 767 768 if (next_run) 769 eloop_tests_start(0); 770} 771 772 773static void eloop_tests_start(int close_in_timeout) 774{ 775 struct test_eloop *t; 776 int res; 777 778 t = os_zalloc(sizeof(*t)); 779 if (!t) 780 return; 781 t->magic = 0x12345678; 782 t->close_in_timeout = close_in_timeout; 783 784 wpa_printf(MSG_INFO, "starting eloop tests (%p) (close_in_timeout=%d)", 785 t, close_in_timeout); 786 787 res = pipe(t->pipefd1); 788 if (res < 0) { 789 wpa_printf(MSG_INFO, "pipe: %s", strerror(errno)); 790 os_free(t); 791 return; 792 } 793 794 res = pipe(t->pipefd2); 795 if (res < 0) { 796 wpa_printf(MSG_INFO, "pipe: %s", strerror(errno)); 797 close(t->pipefd1[0]); 798 close(t->pipefd1[1]); 799 os_free(t); 800 return; 801 } 802 803 wpa_printf(MSG_INFO, "pipe fds: %d,%d %d,%d", 804 t->pipefd1[0], t->pipefd1[1], 805 t->pipefd2[0], t->pipefd2[1]); 806 807 eloop_register_read_sock(t->pipefd1[0], eloop_test_read_1, t, NULL); 808 eloop_register_read_sock(t->pipefd2[0], eloop_test_read_2, t, NULL); 809 eloop_register_timeout(0, 0, eloop_test_cb, t, NULL); 810 eloop_register_timeout(0, 200000, eloop_test_timeout, t, NULL); 811 812 if (write(t->pipefd1[1], "HELLO", 5) < 0) 813 wpa_printf(MSG_INFO, "write: %s", strerror(errno)); 814 if (write(t->pipefd2[1], "TEST", 4) < 0) 815 wpa_printf(MSG_INFO, "write: %s", strerror(errno)); 816 os_sleep(0, 50000); 817 wpa_printf(MSG_INFO, "waiting for eloop callbacks"); 818} 819 820 821static void eloop_tests_run(void *eloop_data, void *user_ctx) 822{ 823 eloop_tests_start(1); 824} 825 826 827static int eloop_tests(void) 828{ 829 wpa_printf(MSG_INFO, "schedule eloop tests to be run"); 830 831 /* 832 * Cannot return error from these without a significant design change, 833 * so for now, run the tests from a scheduled timeout and require 834 * separate verification of the results from the debug log. 835 */ 836 eloop_register_timeout(0, 0, eloop_tests_run, NULL, NULL); 837 838 return 0; 839} 840 841 842int utils_module_tests(void) 843{ 844 int ret = 0; 845 846 wpa_printf(MSG_INFO, "utils module tests"); 847 848 if (printf_encode_decode_tests() < 0 || 849 ext_password_tests() < 0 || 850 trace_tests() < 0 || 851 bitfield_tests() < 0 || 852 base64_tests() < 0 || 853 common_tests() < 0 || 854 os_tests() < 0 || 855 wpabuf_tests() < 0 || 856 ip_addr_tests() < 0 || 857 eloop_tests() < 0 || 858 int_array_tests() < 0) 859 ret = -1; 860 861 return ret; 862} 863