1 /* 2 * 3 * Copyright 2015 gRPC authors. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19 #ifndef _POSIX_SOURCE 20 #define _POSIX_SOURCE 21 #endif 22 23 #include <assert.h> 24 #include <signal.h> 25 #include <stdio.h> 26 #include <stdlib.h> 27 #include <string.h> 28 #include <sys/types.h> 29 #include <sys/wait.h> 30 #include <unistd.h> 31 32 #include <gflags/gflags.h> 33 #include <grpc/support/alloc.h> 34 #include <grpc/support/log.h> 35 #include <grpc/support/string_util.h> 36 #include "test/core/util/port.h" 37 #include "test/cpp/util/test_config.h" 38 39 #include "src/core/lib/gpr/host_port.h" 40 #include "src/core/lib/gpr/string.h" 41 #include "src/core/lib/iomgr/socket_utils_posix.h" 42 43 DEFINE_string(extra_server_flags, "", "Extra flags to pass to server."); 44 45 int test_client(const char* root, const char* host, int port) { 46 int status; 47 pid_t cli; 48 cli = fork(); 49 if (cli == 0) { 50 char* binary_path; 51 char* port_arg; 52 gpr_asprintf(&binary_path, "%s/interop_client", root); 53 gpr_asprintf(&port_arg, "--server_port=%d", port); 54 55 execl(binary_path, binary_path, port_arg, NULL); 56 57 gpr_free(binary_path); 58 gpr_free(port_arg); 59 return 1; 60 } 61 /* wait for client */ 62 gpr_log(GPR_INFO, "Waiting for client: %s", host); 63 if (waitpid(cli, &status, 0) == -1) return 2; 64 if (!WIFEXITED(status)) return 4; 65 if (WEXITSTATUS(status)) return WEXITSTATUS(status); 66 return 0; 67 } 68 69 int main(int argc, char** argv) { 70 grpc::testing::InitTest(&argc, &argv, true); 71 char* me = argv[0]; 72 char* lslash = strrchr(me, '/'); 73 char root[1024]; 74 int port = grpc_pick_unused_port_or_die(); 75 int status; 76 pid_t svr; 77 int ret; 78 int do_ipv6 = 1; 79 /* seed rng with pid, so we don't end up with the same random numbers as a 80 concurrently running test binary */ 81 srand(getpid()); 82 if (!grpc_ipv6_loopback_available()) { 83 gpr_log(GPR_INFO, "Can't bind to ::1. Skipping IPv6 tests."); 84 do_ipv6 = 0; 85 } 86 /* figure out where we are */ 87 if (lslash) { 88 memcpy(root, me, lslash - me); 89 root[lslash - me] = 0; 90 } else { 91 strcpy(root, "."); 92 } 93 /* start the server */ 94 svr = fork(); 95 if (svr == 0) { 96 const size_t num_args = 3 + !FLAGS_extra_server_flags.empty(); 97 char** args = (char**)gpr_malloc(sizeof(char*) * num_args); 98 memset(args, 0, sizeof(char*) * num_args); 99 gpr_asprintf(&args[0], "%s/interop_server", root); 100 gpr_asprintf(&args[1], "--port=%d", port); 101 if (!FLAGS_extra_server_flags.empty()) { 102 args[2] = gpr_strdup(FLAGS_extra_server_flags.c_str()); 103 } 104 execv(args[0], args); 105 for (size_t i = 0; i < num_args - 1; ++i) { 106 gpr_free(args[i]); 107 } 108 gpr_free(args); 109 return 1; 110 } 111 /* wait a little */ 112 sleep(10); 113 /* start the clients */ 114 ret = test_client(root, "127.0.0.1", port); 115 if (ret != 0) return ret; 116 ret = test_client(root, "::ffff:127.0.0.1", port); 117 if (ret != 0) return ret; 118 ret = test_client(root, "localhost", port); 119 if (ret != 0) return ret; 120 if (do_ipv6) { 121 ret = test_client(root, "::1", port); 122 if (ret != 0) return ret; 123 } 124 /* wait for server */ 125 gpr_log(GPR_INFO, "Waiting for server"); 126 kill(svr, SIGINT); 127 if (waitpid(svr, &status, 0) == -1) return 2; 128 if (!WIFEXITED(status)) return 4; 129 if (WEXITSTATUS(status)) return WEXITSTATUS(status); 130 return 0; 131 } 132