blob: 637886a7383b40ca3e8aa3c051f6d5240c3aa739 [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
42#include "src/core/iomgr/iomgr.h"
Craig Tiller5d8fbe22015-01-21 16:33:54 -080043#include "src/core/iomgr/socket_utils_posix.h"
ctiller18b49ab2014-12-09 14:39:16 -080044#include <grpc/support/log.h>
45#include <grpc/support/time.h>
Craig Tiller8ad8a412015-02-25 08:36:40 -080046#include "test/core/util/test_config.h"
ctiller18b49ab2014-12-09 14:39:16 -080047
Craig Tillerb1fa1d52015-05-11 10:27:53 -070048static grpc_pollset_set g_pollset_set;
49static grpc_pollset g_pollset;
Craig Tillercb63a9b2015-05-13 09:52:36 -070050static int g_connections_complete = 0;
Craig Tillerb1fa1d52015-05-11 10:27:53 -070051
Craig Tiller32946d32015-01-15 11:37:30 -080052static gpr_timespec test_deadline(void) {
Craig Tiller8ad8a412015-02-25 08:36:40 -080053 return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10);
ctiller18b49ab2014-12-09 14:39:16 -080054}
55
Craig Tillercb63a9b2015-05-13 09:52:36 -070056static void finish_connection() {
57 gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
58 g_connections_complete++;
59 grpc_pollset_kick(&g_pollset);
60 gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
61}
62
ctiller18b49ab2014-12-09 14:39:16 -080063static void must_succeed(void *arg, grpc_endpoint *tcp) {
64 GPR_ASSERT(tcp);
65 grpc_endpoint_shutdown(tcp);
66 grpc_endpoint_destroy(tcp);
Craig Tillercb63a9b2015-05-13 09:52:36 -070067 finish_connection();
ctiller18b49ab2014-12-09 14:39:16 -080068}
69
70static void must_fail(void *arg, grpc_endpoint *tcp) {
71 GPR_ASSERT(!tcp);
Craig Tillercb63a9b2015-05-13 09:52:36 -070072 finish_connection();
ctiller18b49ab2014-12-09 14:39:16 -080073}
74
Craig Tiller32946d32015-01-15 11:37:30 -080075void test_succeeds(void) {
ctiller18b49ab2014-12-09 14:39:16 -080076 struct sockaddr_in addr;
77 socklen_t addr_len = sizeof(addr);
78 int svr_fd;
79 int r;
Craig Tillercb63a9b2015-05-13 09:52:36 -070080 int connections_complete_before;
ctiller18b49ab2014-12-09 14:39:16 -080081
Craig Tillere9593352015-07-15 07:35:09 -070082 gpr_log(GPR_DEBUG, "test_succeeds");
83
ctiller18b49ab2014-12-09 14:39:16 -080084 memset(&addr, 0, sizeof(addr));
85 addr.sin_family = AF_INET;
86
87 /* create a dummy server */
88 svr_fd = socket(AF_INET, SOCK_STREAM, 0);
89 GPR_ASSERT(svr_fd >= 0);
90 GPR_ASSERT(0 == bind(svr_fd, (struct sockaddr *)&addr, addr_len));
91 GPR_ASSERT(0 == listen(svr_fd, 1));
92
Craig Tillercb63a9b2015-05-13 09:52:36 -070093 gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
94 connections_complete_before = g_connections_complete;
95 gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
96
ctiller18b49ab2014-12-09 14:39:16 -080097 /* connect to it */
98 GPR_ASSERT(getsockname(svr_fd, (struct sockaddr *)&addr, &addr_len) == 0);
Craig Tiller9a576332015-06-17 10:21:49 -070099 grpc_tcp_client_connect(must_succeed, NULL, &g_pollset_set,
Craig Tiller143e7bf2015-07-13 08:41:49 -0700100 (struct sockaddr *)&addr, addr_len,
101 gpr_inf_future(GPR_CLOCK_REALTIME));
ctiller18b49ab2014-12-09 14:39:16 -0800102
103 /* await the connection */
104 do {
105 addr_len = sizeof(addr);
106 r = accept(svr_fd, (struct sockaddr *)&addr, &addr_len);
107 } while (r == -1 && errno == EINTR);
108 GPR_ASSERT(r >= 0);
109 close(r);
110
Craig Tillercb63a9b2015-05-13 09:52:36 -0700111 gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
112
113 while (g_connections_complete == connections_complete_before) {
114 grpc_pollset_work(&g_pollset, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5));
115 }
116
117 gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
ctiller18b49ab2014-12-09 14:39:16 -0800118}
119
Craig Tiller32946d32015-01-15 11:37:30 -0800120void test_fails(void) {
ctiller18b49ab2014-12-09 14:39:16 -0800121 struct sockaddr_in addr;
122 socklen_t addr_len = sizeof(addr);
Craig Tillercb63a9b2015-05-13 09:52:36 -0700123 int connections_complete_before;
ctiller18b49ab2014-12-09 14:39:16 -0800124
Craig Tillere9593352015-07-15 07:35:09 -0700125 gpr_log(GPR_DEBUG, "test_fails");
126
ctiller18b49ab2014-12-09 14:39:16 -0800127 memset(&addr, 0, sizeof(addr));
128 addr.sin_family = AF_INET;
129
Craig Tillercb63a9b2015-05-13 09:52:36 -0700130 gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
131 connections_complete_before = g_connections_complete;
132 gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
133
ctiller18b49ab2014-12-09 14:39:16 -0800134 /* connect to a broken address */
Craig Tiller9a576332015-06-17 10:21:49 -0700135 grpc_tcp_client_connect(must_fail, NULL, &g_pollset_set,
Craig Tiller143e7bf2015-07-13 08:41:49 -0700136 (struct sockaddr *)&addr, addr_len,
137 gpr_inf_future(GPR_CLOCK_REALTIME));
ctiller18b49ab2014-12-09 14:39:16 -0800138
Craig Tillercb63a9b2015-05-13 09:52:36 -0700139 gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
140
ctiller18b49ab2014-12-09 14:39:16 -0800141 /* wait for the connection callback to finish */
Craig Tillercb63a9b2015-05-13 09:52:36 -0700142 while (g_connections_complete == connections_complete_before) {
143 grpc_pollset_work(&g_pollset, test_deadline());
144 }
145
146 gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
ctiller18b49ab2014-12-09 14:39:16 -0800147}
148
Craig Tiller32946d32015-01-15 11:37:30 -0800149void test_times_out(void) {
ctiller18b49ab2014-12-09 14:39:16 -0800150 struct sockaddr_in addr;
151 socklen_t addr_len = sizeof(addr);
152 int svr_fd;
Craig Tillere9593352015-07-15 07:35:09 -0700153#define NUM_CLIENT_CONNECTS 100
ctiller18b49ab2014-12-09 14:39:16 -0800154 int client_fd[NUM_CLIENT_CONNECTS];
155 int i;
156 int r;
Craig Tillercb63a9b2015-05-13 09:52:36 -0700157 int connections_complete_before;
ctiller18b49ab2014-12-09 14:39:16 -0800158 gpr_timespec connect_deadline;
159
Craig Tillere9593352015-07-15 07:35:09 -0700160 gpr_log(GPR_DEBUG, "test_times_out");
161
ctiller18b49ab2014-12-09 14:39:16 -0800162 memset(&addr, 0, sizeof(addr));
163 addr.sin_family = AF_INET;
164
165 /* create a dummy server */
166 svr_fd = socket(AF_INET, SOCK_STREAM, 0);
167 GPR_ASSERT(svr_fd >= 0);
168 GPR_ASSERT(0 == bind(svr_fd, (struct sockaddr *)&addr, addr_len));
169 GPR_ASSERT(0 == listen(svr_fd, 1));
170 /* Get its address */
171 GPR_ASSERT(getsockname(svr_fd, (struct sockaddr *)&addr, &addr_len) == 0);
172
173 /* tie up the listen buffer, which is somewhat arbitrarily sized. */
174 for (i = 0; i < NUM_CLIENT_CONNECTS; ++i) {
Craig Tiller5d8fbe22015-01-21 16:33:54 -0800175 client_fd[i] = socket(AF_INET, SOCK_STREAM, 0);
Yang Gao5fd0d292015-01-26 00:19:48 -0800176 grpc_set_socket_nonblocking(client_fd[i], 1);
ctiller18b49ab2014-12-09 14:39:16 -0800177 do {
178 r = connect(client_fd[i], (struct sockaddr *)&addr, addr_len);
179 } while (r == -1 && errno == EINTR);
180 GPR_ASSERT(r < 0);
181 GPR_ASSERT(errno == EWOULDBLOCK || errno == EINPROGRESS);
182 }
183
184 /* connect to dummy server address */
185
Craig Tiller8ad8a412015-02-25 08:36:40 -0800186 connect_deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(1);
ctiller18b49ab2014-12-09 14:39:16 -0800187
Craig Tillercb63a9b2015-05-13 09:52:36 -0700188 gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
189 connections_complete_before = g_connections_complete;
190 gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
ctiller18b49ab2014-12-09 14:39:16 -0800191
Craig Tiller9a576332015-06-17 10:21:49 -0700192 grpc_tcp_client_connect(must_fail, NULL, &g_pollset_set,
193 (struct sockaddr *)&addr, addr_len, connect_deadline);
Craig Tillercb63a9b2015-05-13 09:52:36 -0700194
195 /* Make sure the event doesn't trigger early */
196 gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
Craig Tiller58bbc862015-07-13 09:51:17 -0700197 while (gpr_time_cmp(gpr_time_add(connect_deadline,
198 gpr_time_from_seconds(2, GPR_TIMESPAN)),
Craig Tillerf3756c12015-07-01 17:21:01 -0700199 gpr_now(GPR_CLOCK_REALTIME)) > 0) {
Craig Tillerf1bff012015-07-06 11:20:50 -0700200 int is_after_deadline =
201 gpr_time_cmp(connect_deadline, gpr_now(GPR_CLOCK_REALTIME)) <= 0;
Craig Tiller9a576332015-06-17 10:21:49 -0700202 if (is_after_deadline &&
Craig Tiller58bbc862015-07-13 09:51:17 -0700203 gpr_time_cmp(gpr_time_add(connect_deadline,
204 gpr_time_from_seconds(1, GPR_TIMESPAN)),
Craig Tillerf3756c12015-07-01 17:21:01 -0700205 gpr_now(GPR_CLOCK_REALTIME)) > 0) {
Craig Tillercb63a9b2015-05-13 09:52:36 -0700206 /* allow some slack before insisting that things be done */
207 } else {
Craig Tiller9a576332015-06-17 10:21:49 -0700208 GPR_ASSERT(g_connections_complete ==
209 connections_complete_before + is_after_deadline);
Craig Tillercb63a9b2015-05-13 09:52:36 -0700210 }
211 grpc_pollset_work(&g_pollset, GRPC_TIMEOUT_MILLIS_TO_DEADLINE(10));
212 }
213 gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
214
ctiller18b49ab2014-12-09 14:39:16 -0800215 close(svr_fd);
216 for (i = 0; i < NUM_CLIENT_CONNECTS; ++i) {
217 close(client_fd[i]);
218 }
219}
220
Craig Tiller9a576332015-06-17 10:21:49 -0700221static void destroy_pollset(void *p) { grpc_pollset_destroy(p); }
Craig Tillercb63a9b2015-05-13 09:52:36 -0700222
Craig Tiller8ad8a412015-02-25 08:36:40 -0800223int main(int argc, char **argv) {
224 grpc_test_init(argc, argv);
ctiller18b49ab2014-12-09 14:39:16 -0800225 grpc_iomgr_init();
Craig Tillerb1fa1d52015-05-11 10:27:53 -0700226 grpc_pollset_set_init(&g_pollset_set);
227 grpc_pollset_init(&g_pollset);
228 grpc_pollset_set_add_pollset(&g_pollset_set, &g_pollset);
ctiller18b49ab2014-12-09 14:39:16 -0800229 test_succeeds();
David Klempnerbaced4d2015-02-10 17:10:15 -0800230 gpr_log(GPR_ERROR, "End of first test");
ctiller18b49ab2014-12-09 14:39:16 -0800231 test_fails();
232 test_times_out();
Craig Tillerb1fa1d52015-05-11 10:27:53 -0700233 grpc_pollset_set_destroy(&g_pollset_set);
Craig Tillercb63a9b2015-05-13 09:52:36 -0700234 grpc_pollset_shutdown(&g_pollset, destroy_pollset, &g_pollset);
ctiller18b49ab2014-12-09 14:39:16 -0800235 grpc_iomgr_shutdown();
236 return 0;
Craig Tiller190d3602015-02-18 09:23:38 -0800237}