blob: 945f7c1bdcb9c82fc297edae2bc27253e117ac42 [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
82 memset(&addr, 0, sizeof(addr));
83 addr.sin_family = AF_INET;
84
85 /* create a dummy server */
86 svr_fd = socket(AF_INET, SOCK_STREAM, 0);
87 GPR_ASSERT(svr_fd >= 0);
88 GPR_ASSERT(0 == bind(svr_fd, (struct sockaddr *)&addr, addr_len));
89 GPR_ASSERT(0 == listen(svr_fd, 1));
90
Craig Tillercb63a9b2015-05-13 09:52:36 -070091 gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
92 connections_complete_before = g_connections_complete;
93 gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
94
ctiller18b49ab2014-12-09 14:39:16 -080095 /* connect to it */
96 GPR_ASSERT(getsockname(svr_fd, (struct sockaddr *)&addr, &addr_len) == 0);
Craig Tillercb63a9b2015-05-13 09:52:36 -070097 grpc_tcp_client_connect(must_succeed, NULL, &g_pollset_set, (struct sockaddr *)&addr, addr_len,
ctiller18b49ab2014-12-09 14:39:16 -080098 gpr_inf_future);
99
100 /* await the connection */
101 do {
102 addr_len = sizeof(addr);
103 r = accept(svr_fd, (struct sockaddr *)&addr, &addr_len);
104 } while (r == -1 && errno == EINTR);
105 GPR_ASSERT(r >= 0);
106 close(r);
107
Craig Tillercb63a9b2015-05-13 09:52:36 -0700108 gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
109
110 while (g_connections_complete == connections_complete_before) {
111 grpc_pollset_work(&g_pollset, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5));
112 }
113
114 gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
ctiller18b49ab2014-12-09 14:39:16 -0800115}
116
Craig Tiller32946d32015-01-15 11:37:30 -0800117void test_fails(void) {
ctiller18b49ab2014-12-09 14:39:16 -0800118 struct sockaddr_in addr;
119 socklen_t addr_len = sizeof(addr);
Craig Tillercb63a9b2015-05-13 09:52:36 -0700120 int connections_complete_before;
ctiller18b49ab2014-12-09 14:39:16 -0800121
122 memset(&addr, 0, sizeof(addr));
123 addr.sin_family = AF_INET;
124
Craig Tillercb63a9b2015-05-13 09:52:36 -0700125 gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
126 connections_complete_before = g_connections_complete;
127 gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
128
ctiller18b49ab2014-12-09 14:39:16 -0800129 /* connect to a broken address */
Craig Tillercb63a9b2015-05-13 09:52:36 -0700130 grpc_tcp_client_connect(must_fail, NULL, &g_pollset_set, (struct sockaddr *)&addr, addr_len,
ctiller18b49ab2014-12-09 14:39:16 -0800131 gpr_inf_future);
132
Craig Tillercb63a9b2015-05-13 09:52:36 -0700133 gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
134
ctiller18b49ab2014-12-09 14:39:16 -0800135 /* wait for the connection callback to finish */
Craig Tillercb63a9b2015-05-13 09:52:36 -0700136 while (g_connections_complete == connections_complete_before) {
137 grpc_pollset_work(&g_pollset, test_deadline());
138 }
139
140 gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
ctiller18b49ab2014-12-09 14:39:16 -0800141}
142
Craig Tiller32946d32015-01-15 11:37:30 -0800143void test_times_out(void) {
ctiller18b49ab2014-12-09 14:39:16 -0800144 struct sockaddr_in addr;
145 socklen_t addr_len = sizeof(addr);
146 int svr_fd;
147#define NUM_CLIENT_CONNECTS 10
148 int client_fd[NUM_CLIENT_CONNECTS];
149 int i;
150 int r;
Craig Tillercb63a9b2015-05-13 09:52:36 -0700151 int connections_complete_before;
ctiller18b49ab2014-12-09 14:39:16 -0800152 gpr_timespec connect_deadline;
153
ctiller18b49ab2014-12-09 14:39:16 -0800154 memset(&addr, 0, sizeof(addr));
155 addr.sin_family = AF_INET;
156
157 /* create a dummy server */
158 svr_fd = socket(AF_INET, SOCK_STREAM, 0);
159 GPR_ASSERT(svr_fd >= 0);
160 GPR_ASSERT(0 == bind(svr_fd, (struct sockaddr *)&addr, addr_len));
161 GPR_ASSERT(0 == listen(svr_fd, 1));
162 /* Get its address */
163 GPR_ASSERT(getsockname(svr_fd, (struct sockaddr *)&addr, &addr_len) == 0);
164
165 /* tie up the listen buffer, which is somewhat arbitrarily sized. */
166 for (i = 0; i < NUM_CLIENT_CONNECTS; ++i) {
Craig Tiller5d8fbe22015-01-21 16:33:54 -0800167 client_fd[i] = socket(AF_INET, SOCK_STREAM, 0);
Yang Gao5fd0d292015-01-26 00:19:48 -0800168 grpc_set_socket_nonblocking(client_fd[i], 1);
ctiller18b49ab2014-12-09 14:39:16 -0800169 do {
170 r = connect(client_fd[i], (struct sockaddr *)&addr, addr_len);
171 } while (r == -1 && errno == EINTR);
172 GPR_ASSERT(r < 0);
173 GPR_ASSERT(errno == EWOULDBLOCK || errno == EINPROGRESS);
174 }
175
176 /* connect to dummy server address */
177
Craig Tiller8ad8a412015-02-25 08:36:40 -0800178 connect_deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(1);
ctiller18b49ab2014-12-09 14:39:16 -0800179
Craig Tillercb63a9b2015-05-13 09:52:36 -0700180 gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
181 connections_complete_before = g_connections_complete;
182 gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
ctiller18b49ab2014-12-09 14:39:16 -0800183
Craig Tillercb63a9b2015-05-13 09:52:36 -0700184 grpc_tcp_client_connect(must_fail, NULL, &g_pollset_set, (struct sockaddr *)&addr, addr_len,
185 connect_deadline);
186
187 /* Make sure the event doesn't trigger early */
188 gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
189 while (gpr_time_cmp(gpr_time_add(connect_deadline, gpr_time_from_seconds(2)), gpr_now()) > 0) {
190 int is_after_deadline = gpr_time_cmp(connect_deadline, gpr_now()) <= 0;
191 if (is_after_deadline && gpr_time_cmp(gpr_time_add(connect_deadline, gpr_time_from_seconds(1)), gpr_now()) > 0) {
192 /* allow some slack before insisting that things be done */
193 } else {
194 GPR_ASSERT(g_connections_complete == connections_complete_before + is_after_deadline);
195 }
196 grpc_pollset_work(&g_pollset, GRPC_TIMEOUT_MILLIS_TO_DEADLINE(10));
197 }
198 gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
199
ctiller18b49ab2014-12-09 14:39:16 -0800200 close(svr_fd);
201 for (i = 0; i < NUM_CLIENT_CONNECTS; ++i) {
202 close(client_fd[i]);
203 }
204}
205
Craig Tillercb63a9b2015-05-13 09:52:36 -0700206static void destroy_pollset(void *p) {
207 grpc_pollset_destroy(p);
208}
209
Craig Tiller8ad8a412015-02-25 08:36:40 -0800210int main(int argc, char **argv) {
211 grpc_test_init(argc, argv);
ctiller18b49ab2014-12-09 14:39:16 -0800212 grpc_iomgr_init();
Craig Tillerb1fa1d52015-05-11 10:27:53 -0700213 grpc_pollset_set_init(&g_pollset_set);
214 grpc_pollset_init(&g_pollset);
215 grpc_pollset_set_add_pollset(&g_pollset_set, &g_pollset);
ctiller18b49ab2014-12-09 14:39:16 -0800216 test_succeeds();
David Klempnerbaced4d2015-02-10 17:10:15 -0800217 gpr_log(GPR_ERROR, "End of first test");
ctiller18b49ab2014-12-09 14:39:16 -0800218 test_fails();
219 test_times_out();
Craig Tillerb1fa1d52015-05-11 10:27:53 -0700220 grpc_pollset_set_destroy(&g_pollset_set);
Craig Tillercb63a9b2015-05-13 09:52:36 -0700221 grpc_pollset_shutdown(&g_pollset, destroy_pollset, &g_pollset);
ctiller18b49ab2014-12-09 14:39:16 -0800222 grpc_iomgr_shutdown();
223 return 0;
Craig Tiller190d3602015-02-18 09:23:38 -0800224}