Line data Source code
1 : /*
2 : *
3 : * Copyright 2015, Google Inc.
4 : * 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 <grpc/grpc.h>
43 : #include <grpc/support/log.h>
44 : #include <grpc/support/time.h>
45 :
46 : #include "src/core/iomgr/iomgr.h"
47 : #include "src/core/iomgr/socket_utils_posix.h"
48 : #include "test/core/util/test_config.h"
49 :
50 : static grpc_pollset_set g_pollset_set;
51 : static grpc_pollset g_pollset;
52 : static int g_connections_complete = 0;
53 : static grpc_endpoint *g_connecting = NULL;
54 :
55 1 : static gpr_timespec test_deadline(void) {
56 1 : return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10);
57 : }
58 :
59 3 : static void finish_connection() {
60 3 : gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
61 3 : g_connections_complete++;
62 3 : grpc_pollset_kick(&g_pollset, NULL);
63 3 : gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
64 3 : }
65 :
66 1 : static void must_succeed(grpc_exec_ctx *exec_ctx, void *arg, int success) {
67 1 : GPR_ASSERT(g_connecting != NULL);
68 1 : GPR_ASSERT(success);
69 1 : grpc_endpoint_shutdown(exec_ctx, g_connecting);
70 1 : grpc_endpoint_destroy(exec_ctx, g_connecting);
71 1 : g_connecting = NULL;
72 1 : finish_connection();
73 1 : }
74 :
75 2 : static void must_fail(grpc_exec_ctx *exec_ctx, void *arg, int success) {
76 2 : GPR_ASSERT(g_connecting == NULL);
77 2 : GPR_ASSERT(!success);
78 2 : finish_connection();
79 2 : }
80 :
81 1 : void test_succeeds(void) {
82 : struct sockaddr_in addr;
83 1 : socklen_t addr_len = sizeof(addr);
84 : int svr_fd;
85 : int r;
86 : int connections_complete_before;
87 : grpc_closure done;
88 1 : grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
89 :
90 1 : gpr_log(GPR_DEBUG, "test_succeeds");
91 :
92 1 : memset(&addr, 0, sizeof(addr));
93 1 : addr.sin_family = AF_INET;
94 :
95 : /* create a dummy server */
96 1 : svr_fd = socket(AF_INET, SOCK_STREAM, 0);
97 1 : GPR_ASSERT(svr_fd >= 0);
98 1 : GPR_ASSERT(0 == bind(svr_fd, (struct sockaddr *)&addr, addr_len));
99 1 : GPR_ASSERT(0 == listen(svr_fd, 1));
100 :
101 1 : gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
102 1 : connections_complete_before = g_connections_complete;
103 1 : gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
104 :
105 : /* connect to it */
106 1 : GPR_ASSERT(getsockname(svr_fd, (struct sockaddr *)&addr, &addr_len) == 0);
107 1 : grpc_closure_init(&done, must_succeed, NULL);
108 1 : grpc_tcp_client_connect(&exec_ctx, &done, &g_connecting, &g_pollset_set,
109 : (struct sockaddr *)&addr, addr_len,
110 : gpr_inf_future(GPR_CLOCK_REALTIME));
111 :
112 : /* await the connection */
113 : do {
114 1 : addr_len = sizeof(addr);
115 1 : r = accept(svr_fd, (struct sockaddr *)&addr, &addr_len);
116 1 : } while (r == -1 && errno == EINTR);
117 1 : GPR_ASSERT(r >= 0);
118 1 : close(r);
119 :
120 1 : gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
121 :
122 3 : while (g_connections_complete == connections_complete_before) {
123 : grpc_pollset_worker worker;
124 1 : grpc_pollset_work(&exec_ctx, &g_pollset, &worker,
125 : gpr_now(GPR_CLOCK_MONOTONIC),
126 1 : GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5));
127 1 : gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
128 1 : grpc_exec_ctx_finish(&exec_ctx);
129 1 : gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
130 : }
131 :
132 1 : gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
133 1 : }
134 :
135 1 : void test_fails(void) {
136 : struct sockaddr_in addr;
137 1 : socklen_t addr_len = sizeof(addr);
138 : int connections_complete_before;
139 : grpc_closure done;
140 1 : grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
141 :
142 1 : gpr_log(GPR_DEBUG, "test_fails");
143 :
144 1 : memset(&addr, 0, sizeof(addr));
145 1 : addr.sin_family = AF_INET;
146 :
147 1 : gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
148 1 : connections_complete_before = g_connections_complete;
149 1 : gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
150 :
151 : /* connect to a broken address */
152 1 : grpc_closure_init(&done, must_fail, NULL);
153 1 : grpc_tcp_client_connect(&exec_ctx, &done, &g_connecting, &g_pollset_set,
154 : (struct sockaddr *)&addr, addr_len,
155 : gpr_inf_future(GPR_CLOCK_REALTIME));
156 :
157 1 : gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
158 :
159 : /* wait for the connection callback to finish */
160 3 : while (g_connections_complete == connections_complete_before) {
161 : grpc_pollset_worker worker;
162 1 : grpc_pollset_work(&exec_ctx, &g_pollset, &worker,
163 : gpr_now(GPR_CLOCK_MONOTONIC), test_deadline());
164 1 : gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
165 1 : grpc_exec_ctx_finish(&exec_ctx);
166 1 : gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
167 : }
168 :
169 1 : gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
170 1 : }
171 :
172 1 : void test_times_out(void) {
173 : struct sockaddr_in addr;
174 1 : socklen_t addr_len = sizeof(addr);
175 : int svr_fd;
176 : #define NUM_CLIENT_CONNECTS 100
177 : int client_fd[NUM_CLIENT_CONNECTS];
178 : int i;
179 : int r;
180 : int connections_complete_before;
181 : gpr_timespec connect_deadline;
182 : grpc_closure done;
183 1 : grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
184 :
185 1 : gpr_log(GPR_DEBUG, "test_times_out");
186 :
187 1 : memset(&addr, 0, sizeof(addr));
188 1 : addr.sin_family = AF_INET;
189 :
190 : /* create a dummy server */
191 1 : svr_fd = socket(AF_INET, SOCK_STREAM, 0);
192 1 : GPR_ASSERT(svr_fd >= 0);
193 1 : GPR_ASSERT(0 == bind(svr_fd, (struct sockaddr *)&addr, addr_len));
194 1 : GPR_ASSERT(0 == listen(svr_fd, 1));
195 : /* Get its address */
196 1 : GPR_ASSERT(getsockname(svr_fd, (struct sockaddr *)&addr, &addr_len) == 0);
197 :
198 : /* tie up the listen buffer, which is somewhat arbitrarily sized. */
199 101 : for (i = 0; i < NUM_CLIENT_CONNECTS; ++i) {
200 100 : client_fd[i] = socket(AF_INET, SOCK_STREAM, 0);
201 100 : grpc_set_socket_nonblocking(client_fd[i], 1);
202 : do {
203 100 : r = connect(client_fd[i], (struct sockaddr *)&addr, addr_len);
204 100 : } while (r == -1 && errno == EINTR);
205 100 : GPR_ASSERT(r < 0);
206 100 : GPR_ASSERT(errno == EWOULDBLOCK || errno == EINPROGRESS);
207 : }
208 :
209 : /* connect to dummy server address */
210 :
211 1 : connect_deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(1);
212 :
213 1 : gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
214 1 : connections_complete_before = g_connections_complete;
215 1 : gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
216 :
217 1 : grpc_closure_init(&done, must_fail, NULL);
218 1 : grpc_tcp_client_connect(&exec_ctx, &done, &g_connecting, &g_pollset_set,
219 : (struct sockaddr *)&addr, addr_len, connect_deadline);
220 :
221 : /* Make sure the event doesn't trigger early */
222 1 : gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
223 : for (;;) {
224 : grpc_pollset_worker worker;
225 598 : gpr_timespec now = gpr_now(connect_deadline.clock_type);
226 598 : gpr_timespec continue_verifying_time =
227 : gpr_time_from_seconds(5, GPR_TIMESPAN);
228 598 : gpr_timespec grace_time = gpr_time_from_seconds(3, GPR_TIMESPAN);
229 598 : gpr_timespec finish_time =
230 : gpr_time_add(connect_deadline, continue_verifying_time);
231 598 : gpr_timespec restart_verifying_time =
232 : gpr_time_add(connect_deadline, grace_time);
233 598 : int is_after_deadline = gpr_time_cmp(now, connect_deadline) > 0;
234 598 : if (gpr_time_cmp(now, finish_time) > 0) {
235 1 : break;
236 : }
237 597 : gpr_log(GPR_DEBUG, "now=%d.%09d connect_deadline=%d.%09d", now.tv_sec,
238 : now.tv_nsec, connect_deadline.tv_sec, connect_deadline.tv_nsec);
239 597 : if (is_after_deadline && gpr_time_cmp(now, restart_verifying_time) <= 0) {
240 : /* allow some slack before insisting that things be done */
241 : } else {
242 297 : GPR_ASSERT(g_connections_complete ==
243 : connections_complete_before + is_after_deadline);
244 : }
245 597 : grpc_pollset_work(&exec_ctx, &g_pollset, &worker,
246 : gpr_now(GPR_CLOCK_MONOTONIC),
247 597 : GRPC_TIMEOUT_MILLIS_TO_DEADLINE(10));
248 597 : gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
249 597 : grpc_exec_ctx_finish(&exec_ctx);
250 597 : gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
251 597 : }
252 1 : gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
253 :
254 1 : close(svr_fd);
255 101 : for (i = 0; i < NUM_CLIENT_CONNECTS; ++i) {
256 100 : close(client_fd[i]);
257 : }
258 1 : }
259 :
260 1 : static void destroy_pollset(grpc_exec_ctx *exec_ctx, void *p, int success) {
261 1 : grpc_pollset_destroy(p);
262 1 : }
263 :
264 1 : int main(int argc, char **argv) {
265 : grpc_closure destroyed;
266 1 : grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
267 1 : grpc_test_init(argc, argv);
268 1 : grpc_init();
269 1 : grpc_pollset_set_init(&g_pollset_set);
270 1 : grpc_pollset_init(&g_pollset);
271 1 : grpc_pollset_set_add_pollset(&exec_ctx, &g_pollset_set, &g_pollset);
272 1 : grpc_exec_ctx_finish(&exec_ctx);
273 1 : test_succeeds();
274 1 : gpr_log(GPR_ERROR, "End of first test");
275 1 : test_fails();
276 1 : test_times_out();
277 1 : grpc_pollset_set_destroy(&g_pollset_set);
278 1 : grpc_closure_init(&destroyed, destroy_pollset, &g_pollset);
279 1 : grpc_pollset_shutdown(&exec_ctx, &g_pollset, &destroyed);
280 1 : grpc_exec_ctx_finish(&exec_ctx);
281 1 : grpc_shutdown();
282 1 : return 0;
283 : }
|