1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <stdio.h> 18 #include <errno.h> 19 #include <stdbool.h> 20 #include <string.h> 21 #include <stdlib.h> 22 #include <unistd.h> 23 #include <getopt.h> 24 #include <sys/uio.h> 25 26 #include <trusty/tipc.h> 27 28 #define TIPC_DEFAULT_DEVNAME "/dev/trusty-ipc-dev0" 29 30 static const char *dev_name = NULL; 31 static const char *test_name = NULL; 32 33 static const char *uuid_name = "com.android.ipc-unittest.srv.uuid"; 34 static const char *echo_name = "com.android.ipc-unittest.srv.echo"; 35 static const char *ta_only_name = "com.android.ipc-unittest.srv.ta_only"; 36 static const char *ns_only_name = "com.android.ipc-unittest.srv.ns_only"; 37 static const char *datasink_name = "com.android.ipc-unittest.srv.datasink"; 38 static const char *closer1_name = "com.android.ipc-unittest.srv.closer1"; 39 static const char *closer2_name = "com.android.ipc-unittest.srv.closer2"; 40 static const char *closer3_name = "com.android.ipc-unittest.srv.closer3"; 41 static const char *main_ctrl_name = "com.android.ipc-unittest.ctrl"; 42 43 static const char *_sopts = "hsvD:t:r:m:b:"; 44 static const struct option _lopts[] = { 45 {"help", no_argument, 0, 'h'}, 46 {"silent", no_argument, 0, 's'}, 47 {"variable",no_argument, 0, 'v'}, 48 {"dev", required_argument, 0, 'D'}, 49 {"repeat", required_argument, 0, 'r'}, 50 {"burst", required_argument, 0, 'b'}, 51 {"msgsize", required_argument, 0, 'm'}, 52 {0, 0, 0, 0} 53 }; 54 55 static const char *usage = 56 "Usage: %s [options]\n" 57 "\n" 58 "options:\n" 59 " -h, --help prints this message and exit\n" 60 " -D, --dev name device name\n" 61 " -t, --test name test to run\n" 62 " -r, --repeat cnt repeat count\n" 63 " -m, --msgsize size max message size\n" 64 " -v, --variable variable message size\n" 65 " -s, --silent silent\n" 66 "\n" 67 ; 68 69 static const char *usage_long = 70 "\n" 71 "The following tests are available:\n" 72 " connect - connect to datasink service\n" 73 " connect_foo - connect to non existing service\n" 74 " burst_write - send messages to datasink service\n" 75 " echo - send/receive messages to echo service\n" 76 " select - test select call\n" 77 " blocked_read - test blocked read\n" 78 " closer1 - connection closed by remote (test1)\n" 79 " closer2 - connection closed by remote (test2)\n" 80 " closer3 - connection closed by remote (test3)\n" 81 " ta2ta-ipc - execute TA to TA unittest\n" 82 " dev-uuid - print device uuid\n" 83 " ta-access - test ta-access flags\n" 84 " writev - writev test\n" 85 " readv - readv test\n" 86 "\n" 87 ; 88 89 static uint opt_repeat = 1; 90 static uint opt_msgsize = 32; 91 static uint opt_msgburst = 32; 92 static bool opt_variable = false; 93 static bool opt_silent = false; 94 95 static void print_usage_and_exit(const char *prog, int code, bool verbose) 96 { 97 fprintf (stderr, usage, prog); 98 if (verbose) 99 fprintf (stderr, "%s", usage_long); 100 exit(code); 101 } 102 103 static void parse_options(int argc, char **argv) 104 { 105 int c; 106 int oidx = 0; 107 108 while (1) 109 { 110 c = getopt_long (argc, argv, _sopts, _lopts, &oidx); 111 if (c == -1) 112 break; /* done */ 113 114 switch (c) { 115 116 case 'D': 117 dev_name = strdup(optarg); 118 break; 119 120 case 't': 121 test_name = strdup(optarg); 122 break; 123 124 case 'v': 125 opt_variable = true; 126 break; 127 128 case 'r': 129 opt_repeat = atoi(optarg); 130 break; 131 132 case 'm': 133 opt_msgsize = atoi(optarg); 134 break; 135 136 case 'b': 137 opt_msgburst = atoi(optarg); 138 break; 139 140 case 's': 141 opt_silent = true; 142 break; 143 144 case 'h': 145 print_usage_and_exit(argv[0], EXIT_SUCCESS, true); 146 break; 147 148 default: 149 print_usage_and_exit(argv[0], EXIT_FAILURE, false); 150 } 151 } 152 } 153 154 static int connect_test(uint repeat) 155 { 156 uint i; 157 int echo_fd; 158 int dsink_fd; 159 160 if (!opt_silent) { 161 printf("%s: repeat = %u\n", __func__, repeat); 162 } 163 164 for (i = 0; i < repeat; i++) { 165 echo_fd = tipc_connect(dev_name, echo_name); 166 if (echo_fd < 0) { 167 fprintf(stderr, "Failed to connect to '%s' service\n", 168 "echo"); 169 } 170 dsink_fd = tipc_connect(dev_name, datasink_name); 171 if (dsink_fd < 0) { 172 fprintf(stderr, "Failed to connect to '%s' service\n", 173 "datasink"); 174 } 175 176 if (echo_fd >= 0) { 177 tipc_close(echo_fd); 178 } 179 if (dsink_fd >= 0) { 180 tipc_close(dsink_fd); 181 } 182 } 183 184 if (!opt_silent) { 185 printf("%s: done\n", __func__); 186 } 187 188 return 0; 189 } 190 191 static int connect_foo(uint repeat) 192 { 193 uint i; 194 int fd; 195 196 if (!opt_silent) { 197 printf("%s: repeat = %u\n", __func__, repeat); 198 } 199 200 for (i = 0; i < repeat; i++) { 201 fd = tipc_connect(dev_name, "foo"); 202 if (fd >= 0) { 203 fprintf(stderr, "succeeded to connect to '%s' service\n", 204 "foo"); 205 tipc_close(fd); 206 } 207 } 208 209 if (!opt_silent) { 210 printf("%s: done\n", __func__); 211 } 212 213 return 0; 214 } 215 216 217 static int closer1_test(uint repeat) 218 { 219 uint i; 220 int fd; 221 222 if (!opt_silent) { 223 printf("%s: repeat = %u\n", __func__, repeat); 224 } 225 226 for (i = 0; i < repeat; i++) { 227 fd = tipc_connect(dev_name, closer1_name); 228 if (fd < 0) { 229 fprintf(stderr, "Failed to connect to '%s' service\n", 230 "closer1"); 231 continue; 232 } 233 if (!opt_silent) { 234 printf("%s: connected\n", __func__); 235 } 236 tipc_close(fd); 237 } 238 239 if (!opt_silent) { 240 printf("%s: done\n", __func__); 241 } 242 243 return 0; 244 } 245 246 static int closer2_test(uint repeat) 247 { 248 uint i; 249 int fd; 250 251 if (!opt_silent) { 252 printf("%s: repeat = %u\n", __func__, repeat); 253 } 254 255 for (i = 0; i < repeat; i++) { 256 fd = tipc_connect(dev_name, closer2_name); 257 if (fd < 0) { 258 if (!opt_silent) { 259 printf("failed to connect to '%s' service\n", "closer2"); 260 } 261 } else { 262 /* this should always fail */ 263 fprintf(stderr, "connected to '%s' service\n", "closer2"); 264 tipc_close(fd); 265 } 266 } 267 268 if (!opt_silent) { 269 printf("%s: done\n", __func__); 270 } 271 272 return 0; 273 } 274 275 static int closer3_test(uint repeat) 276 { 277 uint i, j; 278 ssize_t rc; 279 int fd[4]; 280 char buf[64]; 281 282 if (!opt_silent) { 283 printf("%s: repeat = %u\n", __func__, repeat); 284 } 285 286 for (i = 0; i < repeat; i++) { 287 288 /* open 4 connections to closer3 service */ 289 for (j = 0; j < 4; j++) { 290 fd[j] = tipc_connect(dev_name, closer3_name); 291 if (fd[j] < 0) { 292 fprintf(stderr, "fd[%d]: failed to connect to '%s' service\n", j, "closer3"); 293 } else { 294 if (!opt_silent) { 295 printf("%s: fd[%d]=%d: connected\n", __func__, j, fd[j]); 296 } 297 memset(buf, i + j, sizeof(buf)); 298 rc = write(fd[j], buf, sizeof(buf)); 299 if (rc != sizeof(buf)) { 300 if (!opt_silent) { 301 printf("%s: fd[%d]=%d: write returned = %zd\n", 302 __func__, j, fd[j], rc); 303 } 304 perror("closer3_test: write"); 305 } 306 } 307 } 308 309 /* sleep a bit */ 310 sleep(1); 311 312 /* It is expected that they will be closed by remote */ 313 for (j = 0; j < 4; j++) { 314 if (fd[j] < 0) 315 continue; 316 rc = write(fd[j], buf, sizeof(buf)); 317 if (rc != sizeof(buf)) { 318 if (!opt_silent) { 319 printf("%s: fd[%d]=%d: write returned = %zd\n", 320 __func__, j, fd[j], rc); 321 } 322 perror("closer3_test: write"); 323 } 324 } 325 326 /* then they have to be closed by remote */ 327 for (j = 0; j < 4; j++) { 328 if (fd[j] >= 0) { 329 tipc_close(fd[j]); 330 } 331 } 332 } 333 334 if (!opt_silent) { 335 printf("%s: done\n", __func__); 336 } 337 338 return 0; 339 } 340 341 342 static int echo_test(uint repeat, uint msgsz, bool var) 343 { 344 uint i; 345 ssize_t rc; 346 size_t msg_len; 347 int echo_fd =-1; 348 char tx_buf[msgsz]; 349 char rx_buf[msgsz]; 350 351 if (!opt_silent) { 352 printf("%s: repeat %u: msgsz %u: variable %s\n", 353 __func__, repeat, msgsz, var ? "true" : "false"); 354 } 355 356 echo_fd = tipc_connect(dev_name, echo_name); 357 if (echo_fd < 0) { 358 fprintf(stderr, "Failed to connect to service\n"); 359 return echo_fd; 360 } 361 362 for (i = 0; i < repeat; i++) { 363 364 msg_len = msgsz; 365 if (opt_variable && msgsz) { 366 msg_len = rand() % msgsz; 367 } 368 369 memset(tx_buf, i + 1, msg_len); 370 371 rc = write(echo_fd, tx_buf, msg_len); 372 if ((size_t)rc != msg_len) { 373 perror("echo_test: write"); 374 break; 375 } 376 377 rc = read(echo_fd, rx_buf, msg_len); 378 if (rc < 0) { 379 perror("echo_test: read"); 380 break; 381 } 382 383 if ((size_t)rc != msg_len) { 384 fprintf(stderr, "data truncated (%zu vs. %zu)\n", 385 rc, msg_len); 386 continue; 387 } 388 389 if (memcmp(tx_buf, rx_buf, (size_t) rc)) { 390 fprintf(stderr, "data mismatch\n"); 391 continue; 392 } 393 } 394 395 tipc_close(echo_fd); 396 397 if (!opt_silent) { 398 printf("%s: done\n",__func__); 399 } 400 401 return 0; 402 } 403 404 static int burst_write_test(uint repeat, uint msgburst, uint msgsz, bool var) 405 { 406 int fd; 407 uint i, j; 408 ssize_t rc; 409 size_t msg_len; 410 char tx_buf[msgsz]; 411 412 if (!opt_silent) { 413 printf("%s: repeat %u: burst %u: msgsz %u: variable %s\n", 414 __func__, repeat, msgburst, msgsz, 415 var ? "true" : "false"); 416 } 417 418 for (i = 0; i < repeat; i++) { 419 420 fd = tipc_connect(dev_name, datasink_name); 421 if (fd < 0) { 422 fprintf(stderr, "Failed to connect to '%s' service\n", 423 "datasink"); 424 break; 425 } 426 427 for (j = 0; j < msgburst; j++) { 428 msg_len = msgsz; 429 if (var && msgsz) { 430 msg_len = rand() % msgsz; 431 } 432 433 memset(tx_buf, i + 1, msg_len); 434 rc = write(fd, tx_buf, msg_len); 435 if ((size_t)rc != msg_len) { 436 perror("burst_test: write"); 437 break; 438 } 439 } 440 441 tipc_close(fd); 442 } 443 444 if (!opt_silent) { 445 printf("%s: done\n",__func__); 446 } 447 448 return 0; 449 } 450 451 452 static int _wait_for_msg(int fd, uint msgsz, int timeout) 453 { 454 int rc; 455 fd_set rfds; 456 uint msgcnt = 0; 457 char rx_buf[msgsz]; 458 struct timeval tv; 459 460 if (!opt_silent) { 461 printf("waiting (%d) for msg\n", timeout); 462 } 463 464 FD_ZERO(&rfds); 465 FD_SET(fd, &rfds); 466 467 tv.tv_sec = timeout; 468 tv.tv_usec = 0; 469 470 for(;;) { 471 rc = select(fd+1, &rfds, NULL, NULL, &tv); 472 473 if (rc == 0) { 474 if (!opt_silent) { 475 printf("select timedout\n"); 476 } 477 break; 478 } 479 480 if (rc == -1) { 481 perror("select_test: select"); 482 return rc; 483 } 484 485 rc = read(fd, rx_buf, sizeof(rx_buf)); 486 if (rc < 0) { 487 perror("select_test: read"); 488 return rc; 489 } else { 490 if (rc > 0) { 491 msgcnt++; 492 } 493 } 494 } 495 496 if (!opt_silent) { 497 printf("got %u messages\n", msgcnt); 498 } 499 500 return 0; 501 } 502 503 504 static int select_test(uint repeat, uint msgburst, uint msgsz) 505 { 506 int fd; 507 uint i, j; 508 ssize_t rc; 509 char tx_buf[msgsz]; 510 511 if (!opt_silent) { 512 printf("%s: repeat %u\n", __func__, repeat); 513 } 514 515 fd = tipc_connect(dev_name, echo_name); 516 if (fd < 0) { 517 fprintf(stderr, "Failed to connect to '%s' service\n", 518 "echo"); 519 return fd; 520 } 521 522 for (i = 0; i < repeat; i++) { 523 524 _wait_for_msg(fd, msgsz, 1); 525 526 if (!opt_silent) { 527 printf("sending burst: %u msg\n", msgburst); 528 } 529 530 for (j = 0; j < msgburst; j++) { 531 memset(tx_buf, i + j, msgsz); 532 rc = write(fd, tx_buf, msgsz); 533 if ((size_t)rc != msgsz) { 534 perror("burst_test: write"); 535 break; 536 } 537 } 538 } 539 540 tipc_close(fd); 541 542 if (!opt_silent) { 543 printf("%s: done\n",__func__); 544 } 545 546 return 0; 547 } 548 549 static int blocked_read_test(uint repeat) 550 { 551 int fd; 552 uint i; 553 ssize_t rc; 554 char rx_buf[512]; 555 556 if (!opt_silent) { 557 printf("%s: repeat %u\n", __func__, repeat); 558 } 559 560 fd = tipc_connect(dev_name, echo_name); 561 if (fd < 0) { 562 fprintf(stderr, "Failed to connect to '%s' service\n", 563 "echo"); 564 return fd; 565 } 566 567 for (i = 0; i < repeat; i++) { 568 rc = read(fd, rx_buf, sizeof(rx_buf)); 569 if (rc < 0) { 570 perror("select_test: read"); 571 break; 572 } else { 573 if (!opt_silent) { 574 printf("got %zd bytes\n", rc); 575 } 576 } 577 } 578 579 tipc_close(fd); 580 581 if (!opt_silent) { 582 printf("%s: done\n",__func__); 583 } 584 585 return 0; 586 } 587 588 static int ta2ta_ipc_test(void) 589 { 590 int fd; 591 char rx_buf[64]; 592 593 if (!opt_silent) { 594 printf("%s:\n", __func__); 595 } 596 597 fd = tipc_connect(dev_name, main_ctrl_name); 598 if (fd < 0) { 599 fprintf(stderr, "Failed to connect to '%s' service\n", 600 "main_ctrl"); 601 return fd; 602 } 603 604 /* wait for test to complete */ 605 (void) read(fd, rx_buf, sizeof(rx_buf)); 606 607 tipc_close(fd); 608 609 return 0; 610 } 611 612 typedef struct uuid 613 { 614 uint32_t time_low; 615 uint16_t time_mid; 616 uint16_t time_hi_and_version; 617 uint8_t clock_seq_and_node[8]; 618 } uuid_t; 619 620 static void print_uuid(const char *dev, uuid_t *uuid) 621 { 622 printf("%s:", dev); 623 printf("uuid: %08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x\n", 624 uuid->time_low, 625 uuid->time_mid, 626 uuid->time_hi_and_version, 627 uuid->clock_seq_and_node[0], 628 uuid->clock_seq_and_node[1], 629 uuid->clock_seq_and_node[2], 630 uuid->clock_seq_and_node[3], 631 uuid->clock_seq_and_node[4], 632 uuid->clock_seq_and_node[5], 633 uuid->clock_seq_and_node[6], 634 uuid->clock_seq_and_node[7] 635 ); 636 } 637 638 static int dev_uuid_test(void) 639 { 640 int fd; 641 ssize_t rc; 642 uuid_t uuid; 643 644 fd = tipc_connect(dev_name, uuid_name); 645 if (fd < 0) { 646 fprintf(stderr, "Failed to connect to '%s' service\n", 647 "uuid"); 648 return fd; 649 } 650 651 /* wait for test to complete */ 652 rc = read(fd, &uuid, sizeof(uuid)); 653 if (rc < 0) { 654 perror("dev_uuid_test: read"); 655 } else if (rc != sizeof(uuid)) { 656 fprintf(stderr, "unexpected uuid size (%d vs. %d)\n", 657 (int)rc, (int)sizeof(uuid)); 658 } else { 659 print_uuid(dev_name, &uuid); 660 } 661 662 tipc_close(fd); 663 664 return 0; 665 } 666 667 static int ta_access_test(void) 668 { 669 int fd; 670 671 if (!opt_silent) { 672 printf("%s:\n", __func__); 673 } 674 675 fd = tipc_connect(dev_name, ta_only_name); 676 if (fd >= 0) { 677 fprintf(stderr, "Succeed to connect to '%s' service\n", 678 "ta_only"); 679 tipc_close(fd); 680 } 681 682 fd = tipc_connect(dev_name, ns_only_name); 683 if (fd < 0) { 684 fprintf(stderr, "Failed to connect to '%s' service\n", 685 "ns_only"); 686 return fd; 687 } 688 tipc_close(fd); 689 690 if (!opt_silent) { 691 printf("%s: done\n",__func__); 692 } 693 694 return 0; 695 } 696 697 698 static int writev_test(uint repeat, uint msgsz, bool var) 699 { 700 uint i; 701 ssize_t rc; 702 size_t msg_len; 703 int echo_fd = -1; 704 char tx0_buf[msgsz]; 705 char tx1_buf[msgsz]; 706 char rx_buf [msgsz]; 707 struct iovec iovs[2]= {{tx0_buf, 0}, {tx1_buf, 0}}; 708 709 if (!opt_silent) { 710 printf("%s: repeat %u: msgsz %u: variable %s\n", 711 __func__, repeat, msgsz, var ? "true" : "false"); 712 } 713 714 echo_fd = tipc_connect(dev_name, echo_name); 715 if (echo_fd < 0) { 716 fprintf(stderr, "Failed to connect to service\n"); 717 return echo_fd; 718 } 719 720 for (i = 0; i < repeat; i++) { 721 722 msg_len = msgsz; 723 if (opt_variable && msgsz) { 724 msg_len = rand() % msgsz; 725 } 726 727 iovs[0].iov_len = msg_len / 3; 728 iovs[1].iov_len = msg_len - iovs[0].iov_len; 729 730 memset(tx0_buf, i + 1, iovs[0].iov_len); 731 memset(tx1_buf, i + 2, iovs[1].iov_len); 732 memset(rx_buf, i + 3, sizeof(rx_buf)); 733 734 rc = writev(echo_fd, iovs, 2); 735 if (rc < 0) { 736 perror("writev_test: writev"); 737 break; 738 } 739 740 if ((size_t)rc != msg_len) { 741 fprintf(stderr, 742 "%s: %s: data size mismatch (%zd vs. %zd)\n", 743 __func__, "writev", (size_t)rc, msg_len); 744 break; 745 } 746 747 rc = read(echo_fd, rx_buf, sizeof(rx_buf)); 748 if (rc < 0) { 749 perror("writev_test: read"); 750 break; 751 } 752 753 if ((size_t)rc != msg_len) { 754 fprintf(stderr, 755 "%s: %s: data size mismatch (%zd vs. %zd)\n", 756 __func__, "read", (size_t)rc, msg_len); 757 break; 758 } 759 760 if (memcmp(tx0_buf, rx_buf, iovs[0].iov_len)) { 761 fprintf(stderr, "%s: data mismatch: buf 0\n", __func__); 762 break; 763 } 764 765 if (memcmp(tx1_buf, rx_buf + iovs[0].iov_len, iovs[1].iov_len)) { 766 fprintf(stderr, "%s: data mismatch, buf 1\n", __func__); 767 break; 768 } 769 } 770 771 tipc_close(echo_fd); 772 773 if (!opt_silent) { 774 printf("%s: done\n",__func__); 775 } 776 777 return 0; 778 } 779 780 static int readv_test(uint repeat, uint msgsz, bool var) 781 { 782 uint i; 783 ssize_t rc; 784 size_t msg_len; 785 int echo_fd = -1; 786 char tx_buf [msgsz]; 787 char rx0_buf[msgsz]; 788 char rx1_buf[msgsz]; 789 struct iovec iovs[2]= {{rx0_buf, 0}, {rx1_buf, 0}}; 790 791 if (!opt_silent) { 792 printf("%s: repeat %u: msgsz %u: variable %s\n", 793 __func__, repeat, msgsz, var ? "true" : "false"); 794 } 795 796 echo_fd = tipc_connect(dev_name, echo_name); 797 if (echo_fd < 0) { 798 fprintf(stderr, "Failed to connect to service\n"); 799 return echo_fd; 800 } 801 802 for (i = 0; i < repeat; i++) { 803 804 msg_len = msgsz; 805 if (opt_variable && msgsz) { 806 msg_len = rand() % msgsz; 807 } 808 809 iovs[0].iov_len = msg_len / 3; 810 iovs[1].iov_len = msg_len - iovs[0].iov_len; 811 812 memset(tx_buf, i + 1, sizeof(tx_buf)); 813 memset(rx0_buf, i + 2, iovs[0].iov_len); 814 memset(rx1_buf, i + 3, iovs[1].iov_len); 815 816 rc = write(echo_fd, tx_buf, msg_len); 817 if (rc < 0) { 818 perror("readv_test: write"); 819 break; 820 } 821 822 if ((size_t)rc != msg_len) { 823 fprintf(stderr, 824 "%s: %s: data size mismatch (%zd vs. %zd)\n", 825 __func__, "write", (size_t)rc, msg_len); 826 break; 827 } 828 829 rc = readv(echo_fd, iovs, 2); 830 if (rc < 0) { 831 perror("readv_test: readv"); 832 break; 833 } 834 835 if ((size_t)rc != msg_len) { 836 fprintf(stderr, 837 "%s: %s: data size mismatch (%zd vs. %zd)\n", 838 __func__, "write", (size_t)rc, msg_len); 839 break; 840 } 841 842 if (memcmp(rx0_buf, tx_buf, iovs[0].iov_len)) { 843 fprintf(stderr, "%s: data mismatch: buf 0\n", __func__); 844 break; 845 } 846 847 if (memcmp(rx1_buf, tx_buf + iovs[0].iov_len, iovs[1].iov_len)) { 848 fprintf(stderr, "%s: data mismatch, buf 1\n", __func__); 849 break; 850 } 851 } 852 853 tipc_close(echo_fd); 854 855 if (!opt_silent) { 856 printf("%s: done\n",__func__); 857 } 858 859 return 0; 860 } 861 862 863 int main(int argc, char **argv) 864 { 865 int rc = 0; 866 867 if (argc <= 1) { 868 print_usage_and_exit(argv[0], EXIT_FAILURE, false); 869 } 870 871 parse_options(argc, argv); 872 873 if (!dev_name) { 874 dev_name = TIPC_DEFAULT_DEVNAME; 875 } 876 877 if (!test_name) { 878 fprintf(stderr, "need a Test to run\n"); 879 print_usage_and_exit(argv[0], EXIT_FAILURE, true); 880 } 881 882 if (strcmp(test_name, "connect") == 0) { 883 rc = connect_test(opt_repeat); 884 } else if (strcmp(test_name, "connect_foo") == 0) { 885 rc = connect_foo(opt_repeat); 886 } else if (strcmp(test_name, "burst_write") == 0) { 887 rc = burst_write_test(opt_repeat, opt_msgburst, opt_msgsize, opt_variable); 888 } else if (strcmp(test_name, "select") == 0) { 889 rc = select_test(opt_repeat, opt_msgburst, opt_msgsize); 890 } else if (strcmp(test_name, "blocked_read") == 0) { 891 rc = blocked_read_test(opt_repeat); 892 } else if (strcmp(test_name, "closer1") == 0) { 893 rc = closer1_test(opt_repeat); 894 } else if (strcmp(test_name, "closer2") == 0) { 895 rc = closer2_test(opt_repeat); 896 } else if (strcmp(test_name, "closer3") == 0) { 897 rc = closer3_test(opt_repeat); 898 } else if (strcmp(test_name, "echo") == 0) { 899 rc = echo_test(opt_repeat, opt_msgsize, opt_variable); 900 } else if(strcmp(test_name, "ta2ta-ipc") == 0) { 901 rc = ta2ta_ipc_test(); 902 } else if (strcmp(test_name, "dev-uuid") == 0) { 903 rc = dev_uuid_test(); 904 } else if (strcmp(test_name, "ta-access") == 0) { 905 rc = ta_access_test(); 906 } else if (strcmp(test_name, "writev") == 0) { 907 rc = writev_test(opt_repeat, opt_msgsize, opt_variable); 908 } else if (strcmp(test_name, "readv") == 0) { 909 rc = readv_test(opt_repeat, opt_msgsize, opt_variable); 910 } else { 911 fprintf(stderr, "Unrecognized test name '%s'\n", test_name); 912 print_usage_and_exit(argv[0], EXIT_FAILURE, true); 913 } 914 915 return rc == 0 ? EXIT_SUCCESS : EXIT_FAILURE; 916 } 917