blob: 436e5cf7dfa11b2f7675c7c5a59727f07de83de8 [file] [log] [blame]
ctiller18b49ab2014-12-09 14:39:16 -08001/*
2 *
Craig Tiller06059952015-02-18 08:34:56 -08003 * Copyright 2015, Google Inc.
ctiller18b49ab2014-12-09 14:39:16 -08004 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following disclaimer
14 * in the documentation and/or other materials provided with the
15 * distribution.
16 * * Neither the name of Google Inc. nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
33
34#include "src/core/iomgr/tcp_client.h"
35
36#include <errno.h>
37#include <netinet/in.h>
38#include <string.h>
39#include <sys/socket.h>
40#include <unistd.h>
41
Craig Tillerbe952492015-08-25 16:59:00 -070042#include <grpc/grpc.h>
ctiller18b49ab2014-12-09 14:39:16 -080043#include <grpc/support/log.h>
44#include <grpc/support/time.h>
Craig Tillerbe952492015-08-25 16:59:00 -070045
46#include "src/core/iomgr/iomgr.h"
47#include "src/core/iomgr/socket_utils_posix.h"
Craig Tiller8ad8a412015-02-25 08:36:40 -080048#include "test/core/util/test_config.h"
ctiller18b49ab2014-12-09 14:39:16 -080049
Craig Tillerb1fa1d52015-05-11 10:27:53 -070050static grpc_pollset_set g_pollset_set;
51static grpc_pollset g_pollset;
Craig Tillercb63a9b2015-05-13 09:52:36 -070052static int g_connections_complete = 0;
Craig Tillerdfff1b82015-09-21 14:39:57 -070053static grpc_endpoint *g_connecting = NULL;
Craig Tillerb1fa1d52015-05-11 10:27:53 -070054
Craig Tiller32946d32015-01-15 11:37:30 -080055static gpr_timespec test_deadline(void) {
Craig Tiller8ad8a412015-02-25 08:36:40 -080056 return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10);
ctiller18b49ab2014-12-09 14:39:16 -080057}
58
Craig Tillercb63a9b2015-05-13 09:52:36 -070059static void finish_connection() {
60 gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
61 g_connections_complete++;
Craig Tiller5ddbb9d2015-07-29 15:58:11 -070062 grpc_pollset_kick(&g_pollset, NULL);
Craig Tillercb63a9b2015-05-13 09:52:36 -070063 gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
64}
65
Craig Tillerd9ccbbf2015-09-22 09:30:00 -070066static void must_succeed(void *arg, int success,
67 grpc_closure_list *closure_list) {
Craig Tillerdfff1b82015-09-21 14:39:57 -070068 GPR_ASSERT(g_connecting != NULL);
69 GPR_ASSERT(success);
Craig Tillerd9ccbbf2015-09-22 09:30:00 -070070 grpc_endpoint_shutdown(g_connecting, closure_list);
71 grpc_endpoint_destroy(g_connecting, closure_list);
Craig Tillerdfff1b82015-09-21 14:39:57 -070072 g_connecting = NULL;
Craig Tillercb63a9b2015-05-13 09:52:36 -070073 finish_connection();
ctiller18b49ab2014-12-09 14:39:16 -080074}
75
Craig Tillerd9ccbbf2015-09-22 09:30:00 -070076static void must_fail(void *arg, int success, grpc_closure_list *closure_list) {
Craig Tillerdfff1b82015-09-21 14:39:57 -070077 GPR_ASSERT(g_connecting == NULL);
78 GPR_ASSERT(!success);
Craig Tillercb63a9b2015-05-13 09:52:36 -070079 finish_connection();
ctiller18b49ab2014-12-09 14:39:16 -080080}
81
Craig Tiller32946d32015-01-15 11:37:30 -080082void test_succeeds(void) {
ctiller18b49ab2014-12-09 14:39:16 -080083 struct sockaddr_in addr;
84 socklen_t addr_len = sizeof(addr);
85 int svr_fd;
86 int r;
Craig Tillercb63a9b2015-05-13 09:52:36 -070087 int connections_complete_before;
Craig Tillerdfff1b82015-09-21 14:39:57 -070088 grpc_closure done;
Craig Tillerd9ccbbf2015-09-22 09:30:00 -070089 grpc_closure_list closure_list = GRPC_CLOSURE_LIST_INIT;
ctiller18b49ab2014-12-09 14:39:16 -080090
Craig Tillere9593352015-07-15 07:35:09 -070091 gpr_log(GPR_DEBUG, "test_succeeds");
92
ctiller18b49ab2014-12-09 14:39:16 -080093 memset(&addr, 0, sizeof(addr));
94 addr.sin_family = AF_INET;
95
96 /* create a dummy server */
97 svr_fd = socket(AF_INET, SOCK_STREAM, 0);
98 GPR_ASSERT(svr_fd >= 0);
99 GPR_ASSERT(0 == bind(svr_fd, (struct sockaddr *)&addr, addr_len));
100 GPR_ASSERT(0 == listen(svr_fd, 1));
101
Craig Tillercb63a9b2015-05-13 09:52:36 -0700102 gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
103 connections_complete_before = g_connections_complete;
104 gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
105
ctiller18b49ab2014-12-09 14:39:16 -0800106 /* connect to it */
107 GPR_ASSERT(getsockname(svr_fd, (struct sockaddr *)&addr, &addr_len) == 0);
Craig Tillerdfff1b82015-09-21 14:39:57 -0700108 grpc_closure_init(&done, must_succeed, NULL);
109 grpc_tcp_client_connect(&done, &g_connecting, &g_pollset_set,
Craig Tiller143e7bf2015-07-13 08:41:49 -0700110 (struct sockaddr *)&addr, addr_len,
Craig Tillerd9ccbbf2015-09-22 09:30:00 -0700111 gpr_inf_future(GPR_CLOCK_REALTIME), &closure_list);
ctiller18b49ab2014-12-09 14:39:16 -0800112
113 /* await the connection */
114 do {
115 addr_len = sizeof(addr);
116 r = accept(svr_fd, (struct sockaddr *)&addr, &addr_len);
117 } while (r == -1 && errno == EINTR);
118 GPR_ASSERT(r >= 0);
119 close(r);
120
Craig Tillercb63a9b2015-05-13 09:52:36 -0700121 gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
122
123 while (g_connections_complete == connections_complete_before) {
Craig Tiller5ddbb9d2015-07-29 15:58:11 -0700124 grpc_pollset_worker worker;
Craig Tiller4c06b822015-08-06 08:41:31 -0700125 grpc_pollset_work(&g_pollset, &worker, gpr_now(GPR_CLOCK_MONOTONIC),
Craig Tillerd9ccbbf2015-09-22 09:30:00 -0700126 GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), &closure_list);
Craig Tillerdfff1b82015-09-21 14:39:57 -0700127 gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
Craig Tillerd9ccbbf2015-09-22 09:30:00 -0700128 grpc_closure_list_run(&closure_list);
Craig Tillerdfff1b82015-09-21 14:39:57 -0700129 gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
Craig Tillercb63a9b2015-05-13 09:52:36 -0700130 }
131
132 gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
ctiller18b49ab2014-12-09 14:39:16 -0800133}
134
Craig Tiller32946d32015-01-15 11:37:30 -0800135void test_fails(void) {
ctiller18b49ab2014-12-09 14:39:16 -0800136 struct sockaddr_in addr;
137 socklen_t addr_len = sizeof(addr);
Craig Tillercb63a9b2015-05-13 09:52:36 -0700138 int connections_complete_before;
Craig Tillerdfff1b82015-09-21 14:39:57 -0700139 grpc_closure done;
Craig Tillerd9ccbbf2015-09-22 09:30:00 -0700140 grpc_closure_list closure_list = GRPC_CLOSURE_LIST_INIT;
ctiller18b49ab2014-12-09 14:39:16 -0800141
Craig Tillere9593352015-07-15 07:35:09 -0700142 gpr_log(GPR_DEBUG, "test_fails");
143
ctiller18b49ab2014-12-09 14:39:16 -0800144 memset(&addr, 0, sizeof(addr));
145 addr.sin_family = AF_INET;
146
Craig Tillercb63a9b2015-05-13 09:52:36 -0700147 gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
148 connections_complete_before = g_connections_complete;
149 gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
150
ctiller18b49ab2014-12-09 14:39:16 -0800151 /* connect to a broken address */
Craig Tillerdfff1b82015-09-21 14:39:57 -0700152 grpc_closure_init(&done, must_fail, NULL);
153 grpc_tcp_client_connect(&done, &g_connecting, &g_pollset_set,
Craig Tiller143e7bf2015-07-13 08:41:49 -0700154 (struct sockaddr *)&addr, addr_len,
Craig Tillerd9ccbbf2015-09-22 09:30:00 -0700155 gpr_inf_future(GPR_CLOCK_REALTIME), &closure_list);
ctiller18b49ab2014-12-09 14:39:16 -0800156
Craig Tillercb63a9b2015-05-13 09:52:36 -0700157 gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
158
ctiller18b49ab2014-12-09 14:39:16 -0800159 /* wait for the connection callback to finish */
Craig Tillercb63a9b2015-05-13 09:52:36 -0700160 while (g_connections_complete == connections_complete_before) {
Craig Tiller5ddbb9d2015-07-29 15:58:11 -0700161 grpc_pollset_worker worker;
Craig Tiller4c06b822015-08-06 08:41:31 -0700162 grpc_pollset_work(&g_pollset, &worker, gpr_now(GPR_CLOCK_MONOTONIC),
Craig Tillerd9ccbbf2015-09-22 09:30:00 -0700163 test_deadline(), &closure_list);
Craig Tillerdfff1b82015-09-21 14:39:57 -0700164 gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
Craig Tillerd9ccbbf2015-09-22 09:30:00 -0700165 grpc_closure_list_run(&closure_list);
Craig Tillerdfff1b82015-09-21 14:39:57 -0700166 gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
Craig Tillercb63a9b2015-05-13 09:52:36 -0700167 }
168
169 gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
ctiller18b49ab2014-12-09 14:39:16 -0800170}
171
Craig Tiller32946d32015-01-15 11:37:30 -0800172void test_times_out(void) {
ctiller18b49ab2014-12-09 14:39:16 -0800173 struct sockaddr_in addr;
174 socklen_t addr_len = sizeof(addr);
175 int svr_fd;
Craig Tillere9593352015-07-15 07:35:09 -0700176#define NUM_CLIENT_CONNECTS 100
ctiller18b49ab2014-12-09 14:39:16 -0800177 int client_fd[NUM_CLIENT_CONNECTS];
178 int i;
179 int r;
Craig Tillercb63a9b2015-05-13 09:52:36 -0700180 int connections_complete_before;
ctiller18b49ab2014-12-09 14:39:16 -0800181 gpr_timespec connect_deadline;
Craig Tillerdfff1b82015-09-21 14:39:57 -0700182 grpc_closure done;
Craig Tillerd9ccbbf2015-09-22 09:30:00 -0700183 grpc_closure_list closure_list = GRPC_CLOSURE_LIST_INIT;
ctiller18b49ab2014-12-09 14:39:16 -0800184
Craig Tillere9593352015-07-15 07:35:09 -0700185 gpr_log(GPR_DEBUG, "test_times_out");
186
ctiller18b49ab2014-12-09 14:39:16 -0800187 memset(&addr, 0, sizeof(addr));
188 addr.sin_family = AF_INET;
189
190 /* create a dummy server */
191 svr_fd = socket(AF_INET, SOCK_STREAM, 0);
192 GPR_ASSERT(svr_fd >= 0);
193 GPR_ASSERT(0 == bind(svr_fd, (struct sockaddr *)&addr, addr_len));
194 GPR_ASSERT(0 == listen(svr_fd, 1));
195 /* Get its address */
196 GPR_ASSERT(getsockname(svr_fd, (struct sockaddr *)&addr, &addr_len) == 0);
197
198 /* tie up the listen buffer, which is somewhat arbitrarily sized. */
199 for (i = 0; i < NUM_CLIENT_CONNECTS; ++i) {
Craig Tiller5d8fbe22015-01-21 16:33:54 -0800200 client_fd[i] = socket(AF_INET, SOCK_STREAM, 0);
Yang Gao5fd0d292015-01-26 00:19:48 -0800201 grpc_set_socket_nonblocking(client_fd[i], 1);
ctiller18b49ab2014-12-09 14:39:16 -0800202 do {
203 r = connect(client_fd[i], (struct sockaddr *)&addr, addr_len);
204 } while (r == -1 && errno == EINTR);
205 GPR_ASSERT(r < 0);
206 GPR_ASSERT(errno == EWOULDBLOCK || errno == EINPROGRESS);
207 }
208
209 /* connect to dummy server address */
210
Craig Tiller8ad8a412015-02-25 08:36:40 -0800211 connect_deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(1);
ctiller18b49ab2014-12-09 14:39:16 -0800212
Craig Tillercb63a9b2015-05-13 09:52:36 -0700213 gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
214 connections_complete_before = g_connections_complete;
215 gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
ctiller18b49ab2014-12-09 14:39:16 -0800216
Craig Tillerdfff1b82015-09-21 14:39:57 -0700217 grpc_closure_init(&done, must_fail, NULL);
218 grpc_tcp_client_connect(&done, &g_connecting, &g_pollset_set,
219 (struct sockaddr *)&addr, addr_len, connect_deadline,
Craig Tillerd9ccbbf2015-09-22 09:30:00 -0700220 &closure_list);
Craig Tillercb63a9b2015-05-13 09:52:36 -0700221
222 /* Make sure the event doesn't trigger early */
223 gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
Craig Tillerbe952492015-08-25 16:59:00 -0700224 for (;;) {
Craig Tiller5ddbb9d2015-07-29 15:58:11 -0700225 grpc_pollset_worker worker;
Craig Tillerbe952492015-08-25 16:59:00 -0700226 gpr_timespec now = gpr_now(connect_deadline.clock_type);
Craig Tiller4fc085f2015-09-21 21:46:01 -0700227 gpr_timespec continue_verifying_time =
228 gpr_time_from_seconds(5, GPR_TIMESPAN);
229 gpr_timespec grace_time = gpr_time_from_seconds(3, GPR_TIMESPAN);
Craig Tillerbe952492015-08-25 16:59:00 -0700230 gpr_timespec finish_time = gpr_time_add(connect_deadline, continue_verifying_time);
231 gpr_timespec restart_verifying_time = gpr_time_add(connect_deadline, grace_time);
232 int is_after_deadline = gpr_time_cmp(now, connect_deadline) > 0;
233 if (gpr_time_cmp(now, finish_time) > 0) {
234 break;
235 }
236 gpr_log(GPR_DEBUG, "now=%d.%09d connect_deadline=%d.%09d",
237 now.tv_sec, now.tv_nsec, connect_deadline.tv_sec, connect_deadline.tv_nsec);
Craig Tiller9a576332015-06-17 10:21:49 -0700238 if (is_after_deadline &&
Craig Tillerbe952492015-08-25 16:59:00 -0700239 gpr_time_cmp(now, restart_verifying_time) <= 0) {
Craig Tillercb63a9b2015-05-13 09:52:36 -0700240 /* allow some slack before insisting that things be done */
241 } else {
Craig Tiller9a576332015-06-17 10:21:49 -0700242 GPR_ASSERT(g_connections_complete ==
243 connections_complete_before + is_after_deadline);
Craig Tillercb63a9b2015-05-13 09:52:36 -0700244 }
Craig Tiller4c06b822015-08-06 08:41:31 -0700245 grpc_pollset_work(&g_pollset, &worker, gpr_now(GPR_CLOCK_MONOTONIC),
Craig Tillerd9ccbbf2015-09-22 09:30:00 -0700246 GRPC_TIMEOUT_MILLIS_TO_DEADLINE(10), &closure_list);
Craig Tillerdfff1b82015-09-21 14:39:57 -0700247 gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
Craig Tillerd9ccbbf2015-09-22 09:30:00 -0700248 grpc_closure_list_run(&closure_list);
Craig Tiller4fc085f2015-09-21 21:46:01 -0700249 gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
Craig Tillercb63a9b2015-05-13 09:52:36 -0700250 }
251 gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
252
ctiller18b49ab2014-12-09 14:39:16 -0800253 close(svr_fd);
254 for (i = 0; i < NUM_CLIENT_CONNECTS; ++i) {
255 close(client_fd[i]);
256 }
257}
258
Craig Tillerd9ccbbf2015-09-22 09:30:00 -0700259static void destroy_pollset(void *p, int success,
260 grpc_closure_list *closure_list) {
Craig Tillerdfff1b82015-09-21 14:39:57 -0700261 grpc_pollset_destroy(p);
262}
Craig Tillercb63a9b2015-05-13 09:52:36 -0700263
Craig Tiller8ad8a412015-02-25 08:36:40 -0800264int main(int argc, char **argv) {
Craig Tillerdfff1b82015-09-21 14:39:57 -0700265 grpc_closure destroyed;
Craig Tillerd9ccbbf2015-09-22 09:30:00 -0700266 grpc_closure_list closure_list = GRPC_CLOSURE_LIST_INIT;
Craig Tiller8ad8a412015-02-25 08:36:40 -0800267 grpc_test_init(argc, argv);
Craig Tillerbe952492015-08-25 16:59:00 -0700268 grpc_init();
Craig Tillerb1fa1d52015-05-11 10:27:53 -0700269 grpc_pollset_set_init(&g_pollset_set);
270 grpc_pollset_init(&g_pollset);
Craig Tillerd9ccbbf2015-09-22 09:30:00 -0700271 grpc_pollset_set_add_pollset(&g_pollset_set, &g_pollset, &closure_list);
272 grpc_closure_list_run(&closure_list);
ctiller18b49ab2014-12-09 14:39:16 -0800273 test_succeeds();
David Klempnerbaced4d2015-02-10 17:10:15 -0800274 gpr_log(GPR_ERROR, "End of first test");
ctiller18b49ab2014-12-09 14:39:16 -0800275 test_fails();
276 test_times_out();
Craig Tillerb1fa1d52015-05-11 10:27:53 -0700277 grpc_pollset_set_destroy(&g_pollset_set);
Craig Tillerdfff1b82015-09-21 14:39:57 -0700278 grpc_closure_init(&destroyed, destroy_pollset, &g_pollset);
Craig Tillerd9ccbbf2015-09-22 09:30:00 -0700279 grpc_pollset_shutdown(&g_pollset, &destroyed, &closure_list);
280 grpc_closure_list_run(&closure_list);
Craig Tillerbe952492015-08-25 16:59:00 -0700281 grpc_shutdown();
ctiller18b49ab2014-12-09 14:39:16 -0800282 return 0;
Craig Tiller190d3602015-02-18 09:23:38 -0800283}