blob: f0e2de24d95a08cdd74035d3da827eff56cc6c18 [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 Tillerb1fa1d52015-05-11 10:27:53 -070053
Craig Tiller32946d32015-01-15 11:37:30 -080054static gpr_timespec test_deadline(void) {
Craig Tiller8ad8a412015-02-25 08:36:40 -080055 return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10);
ctiller18b49ab2014-12-09 14:39:16 -080056}
57
Craig Tillercb63a9b2015-05-13 09:52:36 -070058static void finish_connection() {
59 gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
60 g_connections_complete++;
Craig Tiller5ddbb9d2015-07-29 15:58:11 -070061 grpc_pollset_kick(&g_pollset, NULL);
Craig Tillercb63a9b2015-05-13 09:52:36 -070062 gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
63}
64
ctiller18b49ab2014-12-09 14:39:16 -080065static void must_succeed(void *arg, grpc_endpoint *tcp) {
66 GPR_ASSERT(tcp);
67 grpc_endpoint_shutdown(tcp);
68 grpc_endpoint_destroy(tcp);
Craig Tillercb63a9b2015-05-13 09:52:36 -070069 finish_connection();
ctiller18b49ab2014-12-09 14:39:16 -080070}
71
72static void must_fail(void *arg, grpc_endpoint *tcp) {
73 GPR_ASSERT(!tcp);
Craig Tillercb63a9b2015-05-13 09:52:36 -070074 finish_connection();
ctiller18b49ab2014-12-09 14:39:16 -080075}
76
Craig Tiller32946d32015-01-15 11:37:30 -080077void test_succeeds(void) {
ctiller18b49ab2014-12-09 14:39:16 -080078 struct sockaddr_in addr;
79 socklen_t addr_len = sizeof(addr);
80 int svr_fd;
81 int r;
Craig Tillercb63a9b2015-05-13 09:52:36 -070082 int connections_complete_before;
ctiller18b49ab2014-12-09 14:39:16 -080083
Craig Tillere9593352015-07-15 07:35:09 -070084 gpr_log(GPR_DEBUG, "test_succeeds");
85
ctiller18b49ab2014-12-09 14:39:16 -080086 memset(&addr, 0, sizeof(addr));
87 addr.sin_family = AF_INET;
88
89 /* create a dummy server */
90 svr_fd = socket(AF_INET, SOCK_STREAM, 0);
91 GPR_ASSERT(svr_fd >= 0);
92 GPR_ASSERT(0 == bind(svr_fd, (struct sockaddr *)&addr, addr_len));
93 GPR_ASSERT(0 == listen(svr_fd, 1));
94
Craig Tillercb63a9b2015-05-13 09:52:36 -070095 gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
96 connections_complete_before = g_connections_complete;
97 gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
98
ctiller18b49ab2014-12-09 14:39:16 -080099 /* connect to it */
100 GPR_ASSERT(getsockname(svr_fd, (struct sockaddr *)&addr, &addr_len) == 0);
Craig Tiller9a576332015-06-17 10:21:49 -0700101 grpc_tcp_client_connect(must_succeed, NULL, &g_pollset_set,
Craig Tiller143e7bf2015-07-13 08:41:49 -0700102 (struct sockaddr *)&addr, addr_len,
103 gpr_inf_future(GPR_CLOCK_REALTIME));
ctiller18b49ab2014-12-09 14:39:16 -0800104
105 /* await the connection */
106 do {
107 addr_len = sizeof(addr);
108 r = accept(svr_fd, (struct sockaddr *)&addr, &addr_len);
109 } while (r == -1 && errno == EINTR);
110 GPR_ASSERT(r >= 0);
111 close(r);
112
Craig Tillercb63a9b2015-05-13 09:52:36 -0700113 gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
114
115 while (g_connections_complete == connections_complete_before) {
Craig Tiller5ddbb9d2015-07-29 15:58:11 -0700116 grpc_pollset_worker worker;
Craig Tiller4c06b822015-08-06 08:41:31 -0700117 grpc_pollset_work(&g_pollset, &worker, gpr_now(GPR_CLOCK_MONOTONIC),
118 GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5));
Craig Tillercb63a9b2015-05-13 09:52:36 -0700119 }
120
121 gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
ctiller18b49ab2014-12-09 14:39:16 -0800122}
123
Craig Tiller32946d32015-01-15 11:37:30 -0800124void test_fails(void) {
ctiller18b49ab2014-12-09 14:39:16 -0800125 struct sockaddr_in addr;
126 socklen_t addr_len = sizeof(addr);
Craig Tillercb63a9b2015-05-13 09:52:36 -0700127 int connections_complete_before;
ctiller18b49ab2014-12-09 14:39:16 -0800128
Craig Tillere9593352015-07-15 07:35:09 -0700129 gpr_log(GPR_DEBUG, "test_fails");
130
ctiller18b49ab2014-12-09 14:39:16 -0800131 memset(&addr, 0, sizeof(addr));
132 addr.sin_family = AF_INET;
133
Craig Tillercb63a9b2015-05-13 09:52:36 -0700134 gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
135 connections_complete_before = g_connections_complete;
136 gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
137
ctiller18b49ab2014-12-09 14:39:16 -0800138 /* connect to a broken address */
Craig Tiller9a576332015-06-17 10:21:49 -0700139 grpc_tcp_client_connect(must_fail, NULL, &g_pollset_set,
Craig Tiller143e7bf2015-07-13 08:41:49 -0700140 (struct sockaddr *)&addr, addr_len,
141 gpr_inf_future(GPR_CLOCK_REALTIME));
ctiller18b49ab2014-12-09 14:39:16 -0800142
Craig Tillercb63a9b2015-05-13 09:52:36 -0700143 gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
144
ctiller18b49ab2014-12-09 14:39:16 -0800145 /* wait for the connection callback to finish */
Craig Tillercb63a9b2015-05-13 09:52:36 -0700146 while (g_connections_complete == connections_complete_before) {
Craig Tiller5ddbb9d2015-07-29 15:58:11 -0700147 grpc_pollset_worker worker;
Craig Tiller4c06b822015-08-06 08:41:31 -0700148 grpc_pollset_work(&g_pollset, &worker, gpr_now(GPR_CLOCK_MONOTONIC),
149 test_deadline());
Craig Tillercb63a9b2015-05-13 09:52:36 -0700150 }
151
152 gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
ctiller18b49ab2014-12-09 14:39:16 -0800153}
154
Craig Tiller32946d32015-01-15 11:37:30 -0800155void test_times_out(void) {
ctiller18b49ab2014-12-09 14:39:16 -0800156 struct sockaddr_in addr;
157 socklen_t addr_len = sizeof(addr);
158 int svr_fd;
Craig Tillere9593352015-07-15 07:35:09 -0700159#define NUM_CLIENT_CONNECTS 100
ctiller18b49ab2014-12-09 14:39:16 -0800160 int client_fd[NUM_CLIENT_CONNECTS];
161 int i;
162 int r;
Craig Tillercb63a9b2015-05-13 09:52:36 -0700163 int connections_complete_before;
ctiller18b49ab2014-12-09 14:39:16 -0800164 gpr_timespec connect_deadline;
165
Craig Tillere9593352015-07-15 07:35:09 -0700166 gpr_log(GPR_DEBUG, "test_times_out");
167
ctiller18b49ab2014-12-09 14:39:16 -0800168 memset(&addr, 0, sizeof(addr));
169 addr.sin_family = AF_INET;
170
171 /* create a dummy server */
172 svr_fd = socket(AF_INET, SOCK_STREAM, 0);
173 GPR_ASSERT(svr_fd >= 0);
174 GPR_ASSERT(0 == bind(svr_fd, (struct sockaddr *)&addr, addr_len));
175 GPR_ASSERT(0 == listen(svr_fd, 1));
176 /* Get its address */
177 GPR_ASSERT(getsockname(svr_fd, (struct sockaddr *)&addr, &addr_len) == 0);
178
179 /* tie up the listen buffer, which is somewhat arbitrarily sized. */
180 for (i = 0; i < NUM_CLIENT_CONNECTS; ++i) {
Craig Tiller5d8fbe22015-01-21 16:33:54 -0800181 client_fd[i] = socket(AF_INET, SOCK_STREAM, 0);
Yang Gao5fd0d292015-01-26 00:19:48 -0800182 grpc_set_socket_nonblocking(client_fd[i], 1);
ctiller18b49ab2014-12-09 14:39:16 -0800183 do {
184 r = connect(client_fd[i], (struct sockaddr *)&addr, addr_len);
185 } while (r == -1 && errno == EINTR);
186 GPR_ASSERT(r < 0);
187 GPR_ASSERT(errno == EWOULDBLOCK || errno == EINPROGRESS);
188 }
189
190 /* connect to dummy server address */
191
Craig Tiller8ad8a412015-02-25 08:36:40 -0800192 connect_deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(1);
ctiller18b49ab2014-12-09 14:39:16 -0800193
Craig Tillercb63a9b2015-05-13 09:52:36 -0700194 gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
195 connections_complete_before = g_connections_complete;
196 gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
ctiller18b49ab2014-12-09 14:39:16 -0800197
Craig Tiller9a576332015-06-17 10:21:49 -0700198 grpc_tcp_client_connect(must_fail, NULL, &g_pollset_set,
199 (struct sockaddr *)&addr, addr_len, connect_deadline);
Craig Tillercb63a9b2015-05-13 09:52:36 -0700200
201 /* Make sure the event doesn't trigger early */
202 gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
Craig Tillerbe952492015-08-25 16:59:00 -0700203 for (;;) {
Craig Tiller5ddbb9d2015-07-29 15:58:11 -0700204 grpc_pollset_worker worker;
Craig Tillerbe952492015-08-25 16:59:00 -0700205 gpr_timespec now = gpr_now(connect_deadline.clock_type);
206 gpr_timespec continue_verifying_time = gpr_time_from_seconds(2, GPR_TIMESPAN);
207 gpr_timespec grace_time = gpr_time_from_seconds(1, GPR_TIMESPAN);
208 gpr_timespec finish_time = gpr_time_add(connect_deadline, continue_verifying_time);
209 gpr_timespec restart_verifying_time = gpr_time_add(connect_deadline, grace_time);
210 int is_after_deadline = gpr_time_cmp(now, connect_deadline) > 0;
211 if (gpr_time_cmp(now, finish_time) > 0) {
212 break;
213 }
214 gpr_log(GPR_DEBUG, "now=%d.%09d connect_deadline=%d.%09d",
215 now.tv_sec, now.tv_nsec, connect_deadline.tv_sec, connect_deadline.tv_nsec);
Craig Tiller9a576332015-06-17 10:21:49 -0700216 if (is_after_deadline &&
Craig Tillerbe952492015-08-25 16:59:00 -0700217 gpr_time_cmp(now, restart_verifying_time) <= 0) {
Craig Tillercb63a9b2015-05-13 09:52:36 -0700218 /* allow some slack before insisting that things be done */
219 } else {
Craig Tiller9a576332015-06-17 10:21:49 -0700220 GPR_ASSERT(g_connections_complete ==
221 connections_complete_before + is_after_deadline);
Craig Tillercb63a9b2015-05-13 09:52:36 -0700222 }
Craig Tiller4c06b822015-08-06 08:41:31 -0700223 grpc_pollset_work(&g_pollset, &worker, gpr_now(GPR_CLOCK_MONOTONIC),
224 GRPC_TIMEOUT_MILLIS_TO_DEADLINE(10));
Craig Tillercb63a9b2015-05-13 09:52:36 -0700225 }
226 gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
227
ctiller18b49ab2014-12-09 14:39:16 -0800228 close(svr_fd);
229 for (i = 0; i < NUM_CLIENT_CONNECTS; ++i) {
230 close(client_fd[i]);
231 }
232}
233
Craig Tiller9a576332015-06-17 10:21:49 -0700234static void destroy_pollset(void *p) { grpc_pollset_destroy(p); }
Craig Tillercb63a9b2015-05-13 09:52:36 -0700235
Craig Tiller8ad8a412015-02-25 08:36:40 -0800236int main(int argc, char **argv) {
237 grpc_test_init(argc, argv);
Craig Tillerbe952492015-08-25 16:59:00 -0700238 grpc_init();
Craig Tillerb1fa1d52015-05-11 10:27:53 -0700239 grpc_pollset_set_init(&g_pollset_set);
240 grpc_pollset_init(&g_pollset);
241 grpc_pollset_set_add_pollset(&g_pollset_set, &g_pollset);
ctiller18b49ab2014-12-09 14:39:16 -0800242 test_succeeds();
David Klempnerbaced4d2015-02-10 17:10:15 -0800243 gpr_log(GPR_ERROR, "End of first test");
ctiller18b49ab2014-12-09 14:39:16 -0800244 test_fails();
245 test_times_out();
Craig Tillerb1fa1d52015-05-11 10:27:53 -0700246 grpc_pollset_set_destroy(&g_pollset_set);
Craig Tillercb63a9b2015-05-13 09:52:36 -0700247 grpc_pollset_shutdown(&g_pollset, destroy_pollset, &g_pollset);
Craig Tillerbe952492015-08-25 16:59:00 -0700248 grpc_shutdown();
ctiller18b49ab2014-12-09 14:39:16 -0800249 return 0;
Craig Tiller190d3602015-02-18 09:23:38 -0800250}