1 /*- 2 * BSD LICENSE 3 * 4 * Copyright (c) Intel Corporation. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name of Intel Corporation nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include "spdk/stdinc.h" 35 #include "spdk/util.h" 36 37 #include "spdk_cunit.h" 38 39 #include "sock/sock.c" 40 #include "sock/posix/posix.c" 41 42 #define UT_IP "test_ip" 43 #define UT_PORT 1234 44 45 bool g_read_data_called; 46 ssize_t g_bytes_read; 47 char g_buf[256]; 48 struct spdk_sock *g_server_sock_read; 49 int g_ut_accept_count; 50 struct spdk_ut_sock *g_ut_listen_sock; 51 struct spdk_ut_sock *g_ut_client_sock; 52 53 struct spdk_ut_sock { 54 struct spdk_sock base; 55 struct spdk_ut_sock *peer; 56 size_t bytes_avail; 57 char buf[256]; 58 }; 59 60 struct spdk_ut_sock_group_impl { 61 struct spdk_sock_group_impl base; 62 struct spdk_ut_sock *sock; 63 }; 64 65 #define __ut_sock(sock) (struct spdk_ut_sock *)sock 66 #define __ut_group(group) (struct spdk_ut_sock_group_impl *)group 67 68 static int 69 spdk_ut_sock_getaddr(struct spdk_sock *_sock, char *saddr, int slen, uint16_t *sport, 70 char *caddr, int clen, uint16_t *cport) 71 { 72 return 0; 73 } 74 75 static struct spdk_sock * 76 spdk_ut_sock_listen(const char *ip, int port) 77 { 78 struct spdk_ut_sock *sock; 79 80 if (strcmp(ip, UT_IP) || port != UT_PORT) { 81 return NULL; 82 } 83 84 CU_ASSERT(g_ut_listen_sock == NULL); 85 86 sock = calloc(1, sizeof(*sock)); 87 SPDK_CU_ASSERT_FATAL(sock != NULL); 88 g_ut_listen_sock = sock; 89 90 return &sock->base; 91 } 92 93 static struct spdk_sock * 94 spdk_ut_sock_connect(const char *ip, int port) 95 { 96 struct spdk_ut_sock *sock; 97 98 if (strcmp(ip, UT_IP) || port != UT_PORT) { 99 return NULL; 100 } 101 102 sock = calloc(1, sizeof(*sock)); 103 SPDK_CU_ASSERT_FATAL(sock != NULL); 104 g_ut_accept_count++; 105 CU_ASSERT(g_ut_client_sock == NULL); 106 g_ut_client_sock = sock; 107 108 return &sock->base; 109 } 110 111 static struct spdk_sock * 112 spdk_ut_sock_accept(struct spdk_sock *_sock) 113 { 114 struct spdk_ut_sock *sock = __ut_sock(_sock); 115 struct spdk_ut_sock *new_sock; 116 117 CU_ASSERT(sock == g_ut_listen_sock); 118 119 if (g_ut_accept_count == 0) { 120 errno = EAGAIN; 121 return NULL; 122 } 123 124 g_ut_accept_count--; 125 new_sock = calloc(1, sizeof(*sock)); 126 if (new_sock == NULL) { 127 SPDK_ERRLOG("sock allocation failed\n"); 128 return NULL; 129 } 130 131 SPDK_CU_ASSERT_FATAL(g_ut_client_sock != NULL); 132 g_ut_client_sock->peer = new_sock; 133 new_sock->peer = g_ut_client_sock; 134 135 return &new_sock->base; 136 } 137 138 static int 139 spdk_ut_sock_close(struct spdk_sock *_sock) 140 { 141 struct spdk_ut_sock *sock = __ut_sock(_sock); 142 143 if (sock == g_ut_listen_sock) { 144 g_ut_listen_sock = NULL; 145 } 146 if (sock == g_ut_client_sock) { 147 g_ut_client_sock = NULL; 148 } 149 150 if (sock->peer != NULL) { 151 sock->peer->peer = NULL; 152 } 153 154 free(_sock); 155 156 return 0; 157 } 158 159 static ssize_t 160 spdk_ut_sock_recv(struct spdk_sock *_sock, void *buf, size_t len) 161 { 162 struct spdk_ut_sock *sock = __ut_sock(_sock); 163 char tmp[256]; 164 165 len = spdk_min(len, sock->bytes_avail); 166 167 if (len == 0) { 168 errno = EAGAIN; 169 return -1; 170 } 171 172 memcpy(buf, sock->buf, len); 173 memcpy(tmp, &sock->buf[len], sock->bytes_avail - len); 174 memcpy(sock->buf, tmp, sock->bytes_avail - len); 175 sock->bytes_avail -= len; 176 177 return len; 178 } 179 180 static ssize_t 181 spdk_ut_sock_readv(struct spdk_sock *_sock, struct iovec *iov, int iovcnt) 182 { 183 struct spdk_ut_sock *sock = __ut_sock(_sock); 184 size_t len; 185 char tmp[256]; 186 187 /* Test implementation only supports single iov for now. */ 188 CU_ASSERT(iovcnt == 1); 189 190 len = spdk_min(iov[0].iov_len, sock->bytes_avail); 191 192 if (len == 0) { 193 errno = EAGAIN; 194 return -1; 195 } 196 197 memcpy(iov[0].iov_base, sock->buf, len); 198 memcpy(tmp, &sock->buf[len], sock->bytes_avail - len); 199 memcpy(sock->buf, tmp, sock->bytes_avail - len); 200 sock->bytes_avail -= len; 201 202 return len; 203 } 204 205 static ssize_t 206 spdk_ut_sock_writev(struct spdk_sock *_sock, struct iovec *iov, int iovcnt) 207 { 208 struct spdk_ut_sock *sock = __ut_sock(_sock); 209 struct spdk_ut_sock *peer; 210 211 SPDK_CU_ASSERT_FATAL(sock->peer != NULL); 212 peer = sock->peer; 213 214 /* Test implementation only supports single iov for now. */ 215 CU_ASSERT(iovcnt == 1); 216 217 memcpy(&peer->buf[peer->bytes_avail], iov[0].iov_base, iov[0].iov_len); 218 peer->bytes_avail += iov[0].iov_len; 219 220 return iov[0].iov_len; 221 } 222 223 static int 224 spdk_ut_sock_set_recvlowat(struct spdk_sock *_sock, int nbytes) 225 { 226 return 0; 227 } 228 229 static int 230 spdk_ut_sock_set_recvbuf(struct spdk_sock *_sock, int sz) 231 { 232 return 0; 233 } 234 235 static int 236 spdk_ut_sock_set_sendbuf(struct spdk_sock *_sock, int sz) 237 { 238 return 0; 239 } 240 241 static bool 242 spdk_ut_sock_is_ipv6(struct spdk_sock *_sock) 243 { 244 return false; 245 } 246 247 static bool 248 spdk_ut_sock_is_ipv4(struct spdk_sock *_sock) 249 { 250 return true; 251 } 252 253 static bool 254 spdk_ut_sock_is_connected(struct spdk_sock *_sock) 255 { 256 struct spdk_ut_sock *sock = __ut_sock(_sock); 257 258 return (sock->peer != NULL); 259 } 260 261 static int 262 spdk_ut_sock_get_placement_id(struct spdk_sock *_sock, int *placement_id) 263 { 264 return -1; 265 } 266 267 static int 268 spdk_ut_sock_set_priority(struct spdk_sock *_sock, int priority) 269 { 270 return 0; 271 } 272 273 static struct spdk_sock_group_impl * 274 spdk_ut_sock_group_impl_create(void) 275 { 276 struct spdk_ut_sock_group_impl *group_impl; 277 278 group_impl = calloc(1, sizeof(*group_impl)); 279 SPDK_CU_ASSERT_FATAL(group_impl != NULL); 280 281 return &group_impl->base; 282 } 283 284 static int 285 spdk_ut_sock_group_impl_add_sock(struct spdk_sock_group_impl *_group, struct spdk_sock *_sock) 286 { 287 struct spdk_ut_sock_group_impl *group = __ut_group(_group); 288 struct spdk_ut_sock *sock = __ut_sock(_sock); 289 290 group->sock = sock; 291 292 return 0; 293 } 294 295 static int 296 spdk_ut_sock_group_impl_remove_sock(struct spdk_sock_group_impl *_group, struct spdk_sock *_sock) 297 { 298 struct spdk_ut_sock_group_impl *group = __ut_group(_group); 299 struct spdk_ut_sock *sock = __ut_sock(_sock); 300 301 CU_ASSERT(group->sock == sock); 302 group->sock = NULL; 303 304 return 0; 305 } 306 307 static int 308 spdk_ut_sock_group_impl_poll(struct spdk_sock_group_impl *_group, int max_events, 309 struct spdk_sock **socks) 310 { 311 struct spdk_ut_sock_group_impl *group = __ut_group(_group); 312 313 if (group->sock != NULL && group->sock->bytes_avail > 0) { 314 socks[0] = &group->sock->base; 315 return 1; 316 } 317 318 return 0; 319 } 320 321 static int 322 spdk_ut_sock_group_impl_close(struct spdk_sock_group_impl *_group) 323 { 324 struct spdk_ut_sock_group_impl *group = __ut_group(_group); 325 326 CU_ASSERT(group->sock == NULL); 327 free(_group); 328 329 return 0; 330 } 331 332 static struct spdk_net_impl g_ut_net_impl = { 333 .name = "ut", 334 .getaddr = spdk_ut_sock_getaddr, 335 .connect = spdk_ut_sock_connect, 336 .listen = spdk_ut_sock_listen, 337 .accept = spdk_ut_sock_accept, 338 .close = spdk_ut_sock_close, 339 .recv = spdk_ut_sock_recv, 340 .readv = spdk_ut_sock_readv, 341 .writev = spdk_ut_sock_writev, 342 .set_recvlowat = spdk_ut_sock_set_recvlowat, 343 .set_recvbuf = spdk_ut_sock_set_recvbuf, 344 .set_sendbuf = spdk_ut_sock_set_sendbuf, 345 .set_priority = spdk_ut_sock_set_priority, 346 .is_ipv6 = spdk_ut_sock_is_ipv6, 347 .is_ipv4 = spdk_ut_sock_is_ipv4, 348 .is_connected = spdk_ut_sock_is_connected, 349 .get_placement_id = spdk_ut_sock_get_placement_id, 350 .group_impl_create = spdk_ut_sock_group_impl_create, 351 .group_impl_add_sock = spdk_ut_sock_group_impl_add_sock, 352 .group_impl_remove_sock = spdk_ut_sock_group_impl_remove_sock, 353 .group_impl_poll = spdk_ut_sock_group_impl_poll, 354 .group_impl_close = spdk_ut_sock_group_impl_close, 355 }; 356 357 SPDK_NET_IMPL_REGISTER(ut, &g_ut_net_impl); 358 359 static void 360 _sock(const char *ip, int port) 361 { 362 struct spdk_sock *listen_sock; 363 struct spdk_sock *server_sock; 364 struct spdk_sock *client_sock; 365 char *test_string = "abcdef"; 366 char buffer[64]; 367 ssize_t bytes_read, bytes_written; 368 struct iovec iov; 369 int rc; 370 371 listen_sock = spdk_sock_listen(ip, port); 372 SPDK_CU_ASSERT_FATAL(listen_sock != NULL); 373 374 server_sock = spdk_sock_accept(listen_sock); 375 CU_ASSERT(server_sock == NULL); 376 CU_ASSERT(errno == EAGAIN || errno == EWOULDBLOCK); 377 378 client_sock = spdk_sock_connect(ip, port); 379 SPDK_CU_ASSERT_FATAL(client_sock != NULL); 380 381 /* 382 * Delay a bit here before checking if server socket is 383 * ready. 384 */ 385 usleep(1000); 386 387 server_sock = spdk_sock_accept(listen_sock); 388 SPDK_CU_ASSERT_FATAL(server_sock != NULL); 389 CU_ASSERT(spdk_sock_is_connected(client_sock) == true); 390 CU_ASSERT(spdk_sock_is_connected(server_sock) == true); 391 392 /* Test spdk_sock_recv */ 393 iov.iov_base = test_string; 394 iov.iov_len = 7; 395 bytes_written = spdk_sock_writev(client_sock, &iov, 1); 396 CU_ASSERT(bytes_written == 7); 397 398 usleep(1000); 399 400 bytes_read = spdk_sock_recv(server_sock, buffer, 2); 401 CU_ASSERT(bytes_read == 2); 402 403 usleep(1000); 404 405 bytes_read += spdk_sock_recv(server_sock, buffer + 2, 5); 406 CU_ASSERT(bytes_read == 7); 407 408 CU_ASSERT(strncmp(test_string, buffer, 7) == 0); 409 410 /* Test spdk_sock_readv */ 411 iov.iov_base = test_string; 412 iov.iov_len = 7; 413 bytes_written = spdk_sock_writev(client_sock, &iov, 1); 414 CU_ASSERT(bytes_written == 7); 415 416 usleep(1000); 417 418 iov.iov_base = buffer; 419 iov.iov_len = 2; 420 bytes_read = spdk_sock_readv(server_sock, &iov, 1); 421 CU_ASSERT(bytes_read == 2); 422 423 usleep(1000); 424 425 iov.iov_base = buffer + 2; 426 iov.iov_len = 5; 427 bytes_read += spdk_sock_readv(server_sock, &iov, 1); 428 CU_ASSERT(bytes_read == 7); 429 430 usleep(1000); 431 432 CU_ASSERT(strncmp(test_string, buffer, 7) == 0); 433 434 rc = spdk_sock_close(&client_sock); 435 CU_ASSERT(client_sock == NULL); 436 CU_ASSERT(rc == 0); 437 438 /* On FreeBSD, it takes a small amount of time for a close to propagate to the 439 * other side, even in loopback. Introduce a small sleep. */ 440 sleep(1); 441 CU_ASSERT(spdk_sock_is_connected(server_sock) == false); 442 443 rc = spdk_sock_close(&server_sock); 444 CU_ASSERT(server_sock == NULL); 445 CU_ASSERT(rc == 0); 446 447 rc = spdk_sock_close(&listen_sock); 448 CU_ASSERT(listen_sock == NULL); 449 CU_ASSERT(rc == 0); 450 } 451 452 static void 453 posix_sock(void) 454 { 455 _sock("127.0.0.1", UT_PORT); 456 } 457 458 static void 459 ut_sock(void) 460 { 461 _sock(UT_IP, UT_PORT); 462 } 463 464 static void 465 read_data(void *cb_arg, struct spdk_sock_group *group, struct spdk_sock *sock) 466 { 467 struct spdk_sock *server_sock = cb_arg; 468 469 CU_ASSERT(server_sock == sock); 470 471 g_read_data_called = true; 472 g_bytes_read += spdk_sock_recv(server_sock, g_buf + g_bytes_read, sizeof(g_buf) - g_bytes_read); 473 } 474 475 static void 476 _sock_group(const char *ip, int port) 477 { 478 struct spdk_sock_group *group; 479 struct spdk_sock *listen_sock; 480 struct spdk_sock *server_sock; 481 struct spdk_sock *client_sock; 482 char *test_string = "abcdef"; 483 ssize_t bytes_written; 484 struct iovec iov; 485 int rc; 486 487 listen_sock = spdk_sock_listen(ip, port); 488 SPDK_CU_ASSERT_FATAL(listen_sock != NULL); 489 490 server_sock = spdk_sock_accept(listen_sock); 491 CU_ASSERT(server_sock == NULL); 492 CU_ASSERT(errno == EAGAIN || errno == EWOULDBLOCK); 493 494 client_sock = spdk_sock_connect(ip, port); 495 SPDK_CU_ASSERT_FATAL(client_sock != NULL); 496 497 usleep(1000); 498 499 server_sock = spdk_sock_accept(listen_sock); 500 SPDK_CU_ASSERT_FATAL(server_sock != NULL); 501 502 group = spdk_sock_group_create(NULL); 503 SPDK_CU_ASSERT_FATAL(group != NULL); 504 505 /* pass null cb_fn */ 506 rc = spdk_sock_group_add_sock(group, server_sock, NULL, NULL); 507 CU_ASSERT(rc == -1); 508 CU_ASSERT(errno == EINVAL); 509 510 rc = spdk_sock_group_add_sock(group, server_sock, read_data, server_sock); 511 CU_ASSERT(rc == 0); 512 513 /* try adding sock a second time */ 514 rc = spdk_sock_group_add_sock(group, server_sock, read_data, server_sock); 515 CU_ASSERT(rc == -1); 516 CU_ASSERT(errno == EBUSY); 517 518 g_read_data_called = false; 519 g_bytes_read = 0; 520 rc = spdk_sock_group_poll(group); 521 522 CU_ASSERT(rc == 0); 523 CU_ASSERT(g_read_data_called == false); 524 525 iov.iov_base = test_string; 526 iov.iov_len = 7; 527 bytes_written = spdk_sock_writev(client_sock, &iov, 1); 528 CU_ASSERT(bytes_written == 7); 529 530 usleep(1000); 531 532 g_read_data_called = false; 533 g_bytes_read = 0; 534 rc = spdk_sock_group_poll(group); 535 536 CU_ASSERT(rc == 1); 537 CU_ASSERT(g_read_data_called == true); 538 CU_ASSERT(g_bytes_read == 7); 539 540 CU_ASSERT(strncmp(test_string, g_buf, 7) == 0); 541 542 rc = spdk_sock_close(&client_sock); 543 CU_ASSERT(client_sock == NULL); 544 CU_ASSERT(rc == 0); 545 546 /* Try to close sock_group while it still has sockets. */ 547 rc = spdk_sock_group_close(&group); 548 CU_ASSERT(rc == -1); 549 CU_ASSERT(errno == EBUSY); 550 551 /* Try to close sock while it is still part of a sock_group. */ 552 rc = spdk_sock_close(&server_sock); 553 CU_ASSERT(rc == -1); 554 CU_ASSERT(errno == EBUSY); 555 556 rc = spdk_sock_group_remove_sock(group, server_sock); 557 CU_ASSERT(rc == 0); 558 559 rc = spdk_sock_group_close(&group); 560 CU_ASSERT(group == NULL); 561 CU_ASSERT(rc == 0); 562 563 rc = spdk_sock_close(&server_sock); 564 CU_ASSERT(server_sock == NULL); 565 CU_ASSERT(rc == 0); 566 567 rc = spdk_sock_close(&listen_sock); 568 CU_ASSERT(listen_sock == NULL); 569 CU_ASSERT(rc == 0); 570 } 571 572 static void 573 posix_sock_group(void) 574 { 575 _sock_group("127.0.0.1", UT_PORT); 576 } 577 578 static void 579 ut_sock_group(void) 580 { 581 _sock_group(UT_IP, UT_PORT); 582 } 583 584 static void 585 read_data_fairness(void *cb_arg, struct spdk_sock_group *group, struct spdk_sock *sock) 586 { 587 struct spdk_sock *server_sock = cb_arg; 588 ssize_t bytes_read; 589 char buf[1]; 590 591 CU_ASSERT(g_server_sock_read == NULL); 592 CU_ASSERT(server_sock == sock); 593 594 g_server_sock_read = server_sock; 595 bytes_read = spdk_sock_recv(server_sock, buf, 1); 596 CU_ASSERT(bytes_read == 1); 597 } 598 599 static void 600 posix_sock_group_fairness(void) 601 { 602 struct spdk_sock_group *group; 603 struct spdk_sock *listen_sock; 604 struct spdk_sock *server_sock[3]; 605 struct spdk_sock *client_sock[3]; 606 char test_char = 'a'; 607 ssize_t bytes_written; 608 struct iovec iov; 609 int i, rc; 610 611 listen_sock = spdk_sock_listen("127.0.0.1", UT_PORT); 612 SPDK_CU_ASSERT_FATAL(listen_sock != NULL); 613 614 group = spdk_sock_group_create(NULL); 615 SPDK_CU_ASSERT_FATAL(group != NULL); 616 617 for (i = 0; i < 3; i++) { 618 client_sock[i] = spdk_sock_connect("127.0.0.1", UT_PORT); 619 SPDK_CU_ASSERT_FATAL(client_sock[i] != NULL); 620 621 usleep(1000); 622 623 server_sock[i] = spdk_sock_accept(listen_sock); 624 SPDK_CU_ASSERT_FATAL(server_sock[i] != NULL); 625 626 rc = spdk_sock_group_add_sock(group, server_sock[i], 627 read_data_fairness, server_sock[i]); 628 CU_ASSERT(rc == 0); 629 } 630 631 iov.iov_base = &test_char; 632 iov.iov_len = 1; 633 634 for (i = 0; i < 3; i++) { 635 bytes_written = spdk_sock_writev(client_sock[i], &iov, 1); 636 CU_ASSERT(bytes_written == 1); 637 } 638 639 usleep(1000); 640 641 /* 642 * Poll for just one event - this should be server sock 0, since that 643 * is the peer of the first client sock that we wrote to. 644 */ 645 g_server_sock_read = NULL; 646 rc = spdk_sock_group_poll_count(group, 1); 647 CU_ASSERT(rc == 1); 648 CU_ASSERT(g_server_sock_read == server_sock[0]); 649 650 /* 651 * Now write another byte to client sock 0. We want to ensure that 652 * the sock group does not unfairly process the event for this sock 653 * before the socks that were written to earlier. 654 */ 655 bytes_written = spdk_sock_writev(client_sock[0], &iov, 1); 656 CU_ASSERT(bytes_written == 1); 657 658 usleep(1000); 659 660 g_server_sock_read = NULL; 661 rc = spdk_sock_group_poll_count(group, 1); 662 CU_ASSERT(rc == 1); 663 CU_ASSERT(g_server_sock_read == server_sock[1]); 664 665 g_server_sock_read = NULL; 666 rc = spdk_sock_group_poll_count(group, 1); 667 CU_ASSERT(rc == 1); 668 CU_ASSERT(g_server_sock_read == server_sock[2]); 669 670 g_server_sock_read = NULL; 671 rc = spdk_sock_group_poll_count(group, 1); 672 CU_ASSERT(rc == 1); 673 CU_ASSERT(g_server_sock_read == server_sock[0]); 674 675 for (i = 0; i < 3; i++) { 676 rc = spdk_sock_group_remove_sock(group, server_sock[i]); 677 CU_ASSERT(rc == 0); 678 679 rc = spdk_sock_close(&client_sock[i]); 680 CU_ASSERT(client_sock[i] == NULL); 681 CU_ASSERT(rc == 0); 682 683 rc = spdk_sock_close(&server_sock[i]); 684 CU_ASSERT(server_sock[i] == NULL); 685 CU_ASSERT(rc == 0); 686 } 687 688 rc = spdk_sock_group_close(&group); 689 CU_ASSERT(group == NULL); 690 CU_ASSERT(rc == 0); 691 692 rc = spdk_sock_close(&listen_sock); 693 CU_ASSERT(listen_sock == NULL); 694 CU_ASSERT(rc == 0); 695 } 696 697 int 698 main(int argc, char **argv) 699 { 700 CU_pSuite suite = NULL; 701 unsigned int num_failures; 702 703 if (CU_initialize_registry() != CUE_SUCCESS) { 704 return CU_get_error(); 705 } 706 707 suite = CU_add_suite("sock", NULL, NULL); 708 if (suite == NULL) { 709 CU_cleanup_registry(); 710 return CU_get_error(); 711 } 712 713 if ( 714 CU_add_test(suite, "posix_sock", posix_sock) == NULL || 715 CU_add_test(suite, "ut_sock", ut_sock) == NULL || 716 CU_add_test(suite, "posix_sock_group", posix_sock_group) == NULL || 717 CU_add_test(suite, "ut_sock_group", ut_sock_group) == NULL || 718 CU_add_test(suite, "posix_sock_group_fairness", posix_sock_group_fairness) == NULL) { 719 CU_cleanup_registry(); 720 return CU_get_error(); 721 } 722 723 CU_basic_set_mode(CU_BRM_VERBOSE); 724 725 CU_basic_run_tests(); 726 727 num_failures = CU_get_number_of_failures(); 728 CU_cleanup_registry(); 729 730 return num_failures; 731 } 732