blob: b93b9a5725ea407128f29edd5b9bdea87b5f7f99 [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 Tiller45724b32015-09-22 10:42:19 -070055static gpr_timespec
56test_deadline (void)
57{
58 return GRPC_TIMEOUT_SECONDS_TO_DEADLINE (10);
ctiller18b49ab2014-12-09 14:39:16 -080059}
60
Craig Tiller45724b32015-09-22 10:42:19 -070061static void
62finish_connection ()
63{
64 gpr_mu_lock (GRPC_POLLSET_MU (&g_pollset));
Craig Tillercb63a9b2015-05-13 09:52:36 -070065 g_connections_complete++;
Craig Tiller45724b32015-09-22 10:42:19 -070066 grpc_pollset_kick (&g_pollset, NULL);
67 gpr_mu_unlock (GRPC_POLLSET_MU (&g_pollset));
Craig Tillercb63a9b2015-05-13 09:52:36 -070068}
69
Craig Tiller45724b32015-09-22 10:42:19 -070070static void
Craig Tiller1be70cc2015-09-22 10:45:28 -070071must_succeed (grpc_exec_ctx * exec_ctx, void *arg, int success)
Craig Tiller45724b32015-09-22 10:42:19 -070072{
73 GPR_ASSERT (g_connecting != NULL);
74 GPR_ASSERT (success);
75 grpc_endpoint_shutdown (g_connecting, closure_list);
76 grpc_endpoint_destroy (g_connecting, closure_list);
Craig Tillerdfff1b82015-09-21 14:39:57 -070077 g_connecting = NULL;
Craig Tiller45724b32015-09-22 10:42:19 -070078 finish_connection ();
ctiller18b49ab2014-12-09 14:39:16 -080079}
80
Craig Tiller45724b32015-09-22 10:42:19 -070081static void
Craig Tiller1be70cc2015-09-22 10:45:28 -070082must_fail (grpc_exec_ctx * exec_ctx, void *arg, int success)
Craig Tiller45724b32015-09-22 10:42:19 -070083{
84 GPR_ASSERT (g_connecting == NULL);
85 GPR_ASSERT (!success);
86 finish_connection ();
ctiller18b49ab2014-12-09 14:39:16 -080087}
88
Craig Tiller45724b32015-09-22 10:42:19 -070089void
90test_succeeds (void)
91{
ctiller18b49ab2014-12-09 14:39:16 -080092 struct sockaddr_in addr;
Craig Tiller45724b32015-09-22 10:42:19 -070093 socklen_t addr_len = sizeof (addr);
ctiller18b49ab2014-12-09 14:39:16 -080094 int svr_fd;
95 int r;
Craig Tillercb63a9b2015-05-13 09:52:36 -070096 int connections_complete_before;
Craig Tillerdfff1b82015-09-21 14:39:57 -070097 grpc_closure done;
Craig Tillerd9ccbbf2015-09-22 09:30:00 -070098 grpc_closure_list closure_list = GRPC_CLOSURE_LIST_INIT;
ctiller18b49ab2014-12-09 14:39:16 -080099
Craig Tiller45724b32015-09-22 10:42:19 -0700100 gpr_log (GPR_DEBUG, "test_succeeds");
Craig Tillere9593352015-07-15 07:35:09 -0700101
Craig Tiller45724b32015-09-22 10:42:19 -0700102 memset (&addr, 0, sizeof (addr));
ctiller18b49ab2014-12-09 14:39:16 -0800103 addr.sin_family = AF_INET;
104
105 /* create a dummy server */
Craig Tiller45724b32015-09-22 10:42:19 -0700106 svr_fd = socket (AF_INET, SOCK_STREAM, 0);
107 GPR_ASSERT (svr_fd >= 0);
108 GPR_ASSERT (0 == bind (svr_fd, (struct sockaddr *) &addr, addr_len));
109 GPR_ASSERT (0 == listen (svr_fd, 1));
ctiller18b49ab2014-12-09 14:39:16 -0800110
Craig Tiller45724b32015-09-22 10:42:19 -0700111 gpr_mu_lock (GRPC_POLLSET_MU (&g_pollset));
Craig Tillercb63a9b2015-05-13 09:52:36 -0700112 connections_complete_before = g_connections_complete;
Craig Tiller45724b32015-09-22 10:42:19 -0700113 gpr_mu_unlock (GRPC_POLLSET_MU (&g_pollset));
Craig Tillercb63a9b2015-05-13 09:52:36 -0700114
ctiller18b49ab2014-12-09 14:39:16 -0800115 /* connect to it */
Craig Tiller45724b32015-09-22 10:42:19 -0700116 GPR_ASSERT (getsockname (svr_fd, (struct sockaddr *) &addr, &addr_len) == 0);
117 grpc_closure_init (&done, must_succeed, NULL);
118 grpc_tcp_client_connect (&done, &g_connecting, &g_pollset_set, (struct sockaddr *) &addr, addr_len, gpr_inf_future (GPR_CLOCK_REALTIME), &closure_list);
ctiller18b49ab2014-12-09 14:39:16 -0800119
120 /* await the connection */
Craig Tiller45724b32015-09-22 10:42:19 -0700121 do
122 {
123 addr_len = sizeof (addr);
124 r = accept (svr_fd, (struct sockaddr *) &addr, &addr_len);
125 }
126 while (r == -1 && errno == EINTR);
127 GPR_ASSERT (r >= 0);
128 close (r);
ctiller18b49ab2014-12-09 14:39:16 -0800129
Craig Tiller45724b32015-09-22 10:42:19 -0700130 gpr_mu_lock (GRPC_POLLSET_MU (&g_pollset));
Craig Tillercb63a9b2015-05-13 09:52:36 -0700131
Craig Tiller45724b32015-09-22 10:42:19 -0700132 while (g_connections_complete == connections_complete_before)
133 {
134 grpc_pollset_worker worker;
135 grpc_pollset_work (&g_pollset, &worker, gpr_now (GPR_CLOCK_MONOTONIC), GRPC_TIMEOUT_SECONDS_TO_DEADLINE (5), &closure_list);
136 gpr_mu_unlock (GRPC_POLLSET_MU (&g_pollset));
137 grpc_closure_list_run (&closure_list);
138 gpr_mu_lock (GRPC_POLLSET_MU (&g_pollset));
139 }
Craig Tillercb63a9b2015-05-13 09:52:36 -0700140
Craig Tiller45724b32015-09-22 10:42:19 -0700141 gpr_mu_unlock (GRPC_POLLSET_MU (&g_pollset));
ctiller18b49ab2014-12-09 14:39:16 -0800142}
143
Craig Tiller45724b32015-09-22 10:42:19 -0700144void
145test_fails (void)
146{
ctiller18b49ab2014-12-09 14:39:16 -0800147 struct sockaddr_in addr;
Craig Tiller45724b32015-09-22 10:42:19 -0700148 socklen_t addr_len = sizeof (addr);
Craig Tillercb63a9b2015-05-13 09:52:36 -0700149 int connections_complete_before;
Craig Tillerdfff1b82015-09-21 14:39:57 -0700150 grpc_closure done;
Craig Tillerd9ccbbf2015-09-22 09:30:00 -0700151 grpc_closure_list closure_list = GRPC_CLOSURE_LIST_INIT;
ctiller18b49ab2014-12-09 14:39:16 -0800152
Craig Tiller45724b32015-09-22 10:42:19 -0700153 gpr_log (GPR_DEBUG, "test_fails");
Craig Tillere9593352015-07-15 07:35:09 -0700154
Craig Tiller45724b32015-09-22 10:42:19 -0700155 memset (&addr, 0, sizeof (addr));
ctiller18b49ab2014-12-09 14:39:16 -0800156 addr.sin_family = AF_INET;
157
Craig Tiller45724b32015-09-22 10:42:19 -0700158 gpr_mu_lock (GRPC_POLLSET_MU (&g_pollset));
Craig Tillercb63a9b2015-05-13 09:52:36 -0700159 connections_complete_before = g_connections_complete;
Craig Tiller45724b32015-09-22 10:42:19 -0700160 gpr_mu_unlock (GRPC_POLLSET_MU (&g_pollset));
Craig Tillercb63a9b2015-05-13 09:52:36 -0700161
ctiller18b49ab2014-12-09 14:39:16 -0800162 /* connect to a broken address */
Craig Tiller45724b32015-09-22 10:42:19 -0700163 grpc_closure_init (&done, must_fail, NULL);
164 grpc_tcp_client_connect (&done, &g_connecting, &g_pollset_set, (struct sockaddr *) &addr, addr_len, gpr_inf_future (GPR_CLOCK_REALTIME), &closure_list);
ctiller18b49ab2014-12-09 14:39:16 -0800165
Craig Tiller45724b32015-09-22 10:42:19 -0700166 gpr_mu_lock (GRPC_POLLSET_MU (&g_pollset));
Craig Tillercb63a9b2015-05-13 09:52:36 -0700167
ctiller18b49ab2014-12-09 14:39:16 -0800168 /* wait for the connection callback to finish */
Craig Tiller45724b32015-09-22 10:42:19 -0700169 while (g_connections_complete == connections_complete_before)
170 {
171 grpc_pollset_worker worker;
172 grpc_pollset_work (&g_pollset, &worker, gpr_now (GPR_CLOCK_MONOTONIC), test_deadline (), &closure_list);
173 gpr_mu_unlock (GRPC_POLLSET_MU (&g_pollset));
174 grpc_closure_list_run (&closure_list);
175 gpr_mu_lock (GRPC_POLLSET_MU (&g_pollset));
176 }
Craig Tillercb63a9b2015-05-13 09:52:36 -0700177
Craig Tiller45724b32015-09-22 10:42:19 -0700178 gpr_mu_unlock (GRPC_POLLSET_MU (&g_pollset));
ctiller18b49ab2014-12-09 14:39:16 -0800179}
180
Craig Tiller45724b32015-09-22 10:42:19 -0700181void
182test_times_out (void)
183{
ctiller18b49ab2014-12-09 14:39:16 -0800184 struct sockaddr_in addr;
Craig Tiller45724b32015-09-22 10:42:19 -0700185 socklen_t addr_len = sizeof (addr);
ctiller18b49ab2014-12-09 14:39:16 -0800186 int svr_fd;
Craig Tillere9593352015-07-15 07:35:09 -0700187#define NUM_CLIENT_CONNECTS 100
ctiller18b49ab2014-12-09 14:39:16 -0800188 int client_fd[NUM_CLIENT_CONNECTS];
189 int i;
190 int r;
Craig Tillercb63a9b2015-05-13 09:52:36 -0700191 int connections_complete_before;
ctiller18b49ab2014-12-09 14:39:16 -0800192 gpr_timespec connect_deadline;
Craig Tillerdfff1b82015-09-21 14:39:57 -0700193 grpc_closure done;
Craig Tillerd9ccbbf2015-09-22 09:30:00 -0700194 grpc_closure_list closure_list = GRPC_CLOSURE_LIST_INIT;
ctiller18b49ab2014-12-09 14:39:16 -0800195
Craig Tiller45724b32015-09-22 10:42:19 -0700196 gpr_log (GPR_DEBUG, "test_times_out");
Craig Tillere9593352015-07-15 07:35:09 -0700197
Craig Tiller45724b32015-09-22 10:42:19 -0700198 memset (&addr, 0, sizeof (addr));
ctiller18b49ab2014-12-09 14:39:16 -0800199 addr.sin_family = AF_INET;
200
201 /* create a dummy server */
Craig Tiller45724b32015-09-22 10:42:19 -0700202 svr_fd = socket (AF_INET, SOCK_STREAM, 0);
203 GPR_ASSERT (svr_fd >= 0);
204 GPR_ASSERT (0 == bind (svr_fd, (struct sockaddr *) &addr, addr_len));
205 GPR_ASSERT (0 == listen (svr_fd, 1));
ctiller18b49ab2014-12-09 14:39:16 -0800206 /* Get its address */
Craig Tiller45724b32015-09-22 10:42:19 -0700207 GPR_ASSERT (getsockname (svr_fd, (struct sockaddr *) &addr, &addr_len) == 0);
ctiller18b49ab2014-12-09 14:39:16 -0800208
209 /* tie up the listen buffer, which is somewhat arbitrarily sized. */
Craig Tiller45724b32015-09-22 10:42:19 -0700210 for (i = 0; i < NUM_CLIENT_CONNECTS; ++i)
211 {
212 client_fd[i] = socket (AF_INET, SOCK_STREAM, 0);
213 grpc_set_socket_nonblocking (client_fd[i], 1);
214 do
215 {
216 r = connect (client_fd[i], (struct sockaddr *) &addr, addr_len);
217 }
218 while (r == -1 && errno == EINTR);
219 GPR_ASSERT (r < 0);
220 GPR_ASSERT (errno == EWOULDBLOCK || errno == EINPROGRESS);
221 }
ctiller18b49ab2014-12-09 14:39:16 -0800222
223 /* connect to dummy server address */
224
Craig Tiller45724b32015-09-22 10:42:19 -0700225 connect_deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE (1);
ctiller18b49ab2014-12-09 14:39:16 -0800226
Craig Tiller45724b32015-09-22 10:42:19 -0700227 gpr_mu_lock (GRPC_POLLSET_MU (&g_pollset));
Craig Tillercb63a9b2015-05-13 09:52:36 -0700228 connections_complete_before = g_connections_complete;
Craig Tiller45724b32015-09-22 10:42:19 -0700229 gpr_mu_unlock (GRPC_POLLSET_MU (&g_pollset));
ctiller18b49ab2014-12-09 14:39:16 -0800230
Craig Tiller45724b32015-09-22 10:42:19 -0700231 grpc_closure_init (&done, must_fail, NULL);
232 grpc_tcp_client_connect (&done, &g_connecting, &g_pollset_set, (struct sockaddr *) &addr, addr_len, connect_deadline, &closure_list);
Craig Tillercb63a9b2015-05-13 09:52:36 -0700233
234 /* Make sure the event doesn't trigger early */
Craig Tiller45724b32015-09-22 10:42:19 -0700235 gpr_mu_lock (GRPC_POLLSET_MU (&g_pollset));
236 for (;;)
237 {
238 grpc_pollset_worker worker;
239 gpr_timespec now = gpr_now (connect_deadline.clock_type);
240 gpr_timespec continue_verifying_time = gpr_time_from_seconds (5, GPR_TIMESPAN);
241 gpr_timespec grace_time = gpr_time_from_seconds (3, GPR_TIMESPAN);
242 gpr_timespec finish_time = gpr_time_add (connect_deadline, continue_verifying_time);
243 gpr_timespec restart_verifying_time = gpr_time_add (connect_deadline, grace_time);
244 int is_after_deadline = gpr_time_cmp (now, connect_deadline) > 0;
245 if (gpr_time_cmp (now, finish_time) > 0)
246 {
247 break;
248 }
249 gpr_log (GPR_DEBUG, "now=%d.%09d connect_deadline=%d.%09d", now.tv_sec, now.tv_nsec, connect_deadline.tv_sec, connect_deadline.tv_nsec);
250 if (is_after_deadline && gpr_time_cmp (now, restart_verifying_time) <= 0)
251 {
252 /* allow some slack before insisting that things be done */
253 }
254 else
255 {
256 GPR_ASSERT (g_connections_complete == connections_complete_before + is_after_deadline);
257 }
258 grpc_pollset_work (&g_pollset, &worker, gpr_now (GPR_CLOCK_MONOTONIC), GRPC_TIMEOUT_MILLIS_TO_DEADLINE (10), &closure_list);
259 gpr_mu_unlock (GRPC_POLLSET_MU (&g_pollset));
260 grpc_closure_list_run (&closure_list);
261 gpr_mu_lock (GRPC_POLLSET_MU (&g_pollset));
Craig Tillerbe952492015-08-25 16:59:00 -0700262 }
Craig Tiller45724b32015-09-22 10:42:19 -0700263 gpr_mu_unlock (GRPC_POLLSET_MU (&g_pollset));
Craig Tillercb63a9b2015-05-13 09:52:36 -0700264
Craig Tiller45724b32015-09-22 10:42:19 -0700265 close (svr_fd);
266 for (i = 0; i < NUM_CLIENT_CONNECTS; ++i)
267 {
268 close (client_fd[i]);
269 }
ctiller18b49ab2014-12-09 14:39:16 -0800270}
271
Craig Tiller45724b32015-09-22 10:42:19 -0700272static void
Craig Tiller1be70cc2015-09-22 10:45:28 -0700273destroy_pollset (grpc_exec_ctx * exec_ctx, void *p, int success)
Craig Tiller45724b32015-09-22 10:42:19 -0700274{
275 grpc_pollset_destroy (p);
Craig Tillerdfff1b82015-09-21 14:39:57 -0700276}
Craig Tillercb63a9b2015-05-13 09:52:36 -0700277
Craig Tiller45724b32015-09-22 10:42:19 -0700278int
279main (int argc, char **argv)
280{
Craig Tillerdfff1b82015-09-21 14:39:57 -0700281 grpc_closure destroyed;
Craig Tillerd9ccbbf2015-09-22 09:30:00 -0700282 grpc_closure_list closure_list = GRPC_CLOSURE_LIST_INIT;
Craig Tiller45724b32015-09-22 10:42:19 -0700283 grpc_test_init (argc, argv);
284 grpc_init ();
285 grpc_pollset_set_init (&g_pollset_set);
286 grpc_pollset_init (&g_pollset);
287 grpc_pollset_set_add_pollset (&g_pollset_set, &g_pollset, &closure_list);
288 grpc_closure_list_run (&closure_list);
289 test_succeeds ();
290 gpr_log (GPR_ERROR, "End of first test");
291 test_fails ();
292 test_times_out ();
293 grpc_pollset_set_destroy (&g_pollset_set);
294 grpc_closure_init (&destroyed, destroy_pollset, &g_pollset);
295 grpc_pollset_shutdown (&g_pollset, &destroyed, &closure_list);
296 grpc_closure_list_run (&closure_list);
297 grpc_shutdown ();
ctiller18b49ab2014-12-09 14:39:16 -0800298 return 0;
Craig Tiller190d3602015-02-18 09:23:38 -0800299}