blob: 21bb29097223844da24bed175693ed7b8054659c [file] [log] [blame]
ctiller18b49ab2014-12-09 14:39:16 -08001/*
2 *
Craig Tiller6169d5f2016-03-31 07:46:18 -07003 * 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
Craig Tiller9533d042016-03-25 17:11:06 -070034#include "src/core/lib/iomgr/tcp_client.h"
ctiller18b49ab2014-12-09 14:39:16 -080035
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>
Craig Tillera8be91b2016-02-19 16:22:44 -080043#include <grpc/support/alloc.h>
ctiller18b49ab2014-12-09 14:39:16 -080044#include <grpc/support/log.h>
45#include <grpc/support/time.h>
Craig Tillerbe952492015-08-25 16:59:00 -070046
Craig Tiller9533d042016-03-25 17:11:06 -070047#include "src/core/lib/iomgr/iomgr.h"
Craig Tiller8a034482016-03-28 16:09:04 -070048#include "src/core/lib/iomgr/pollset_set.h"
Craig Tiller9533d042016-03-25 17:11:06 -070049#include "src/core/lib/iomgr/socket_utils_posix.h"
50#include "src/core/lib/iomgr/timer.h"
Craig Tiller8ad8a412015-02-25 08:36:40 -080051#include "test/core/util/test_config.h"
ctiller18b49ab2014-12-09 14:39:16 -080052
Craig Tillera75d18a2016-02-25 08:45:00 -080053static grpc_pollset_set *g_pollset_set;
Craig Tiller85371a22016-02-25 13:55:13 -080054static gpr_mu *g_mu;
Craig Tillera8be91b2016-02-19 16:22:44 -080055static grpc_pollset *g_pollset;
Craig Tillercb63a9b2015-05-13 09:52:36 -070056static int g_connections_complete = 0;
Craig Tillerdfff1b82015-09-21 14:39:57 -070057static grpc_endpoint *g_connecting = NULL;
Craig Tillerb1fa1d52015-05-11 10:27:53 -070058
Craig Tillera82950e2015-09-22 12:33:20 -070059static gpr_timespec test_deadline(void) {
Robbie Shadeca7effc2017-01-17 09:14:29 -050060 return grpc_timeout_seconds_to_deadline(10);
ctiller18b49ab2014-12-09 14:39:16 -080061}
62
Craig Tillera82950e2015-09-22 12:33:20 -070063static void finish_connection() {
Craig Tiller85371a22016-02-25 13:55:13 -080064 gpr_mu_lock(g_mu);
Craig Tillercb63a9b2015-05-13 09:52:36 -070065 g_connections_complete++;
Craig Tiller1aee5362016-05-07 11:26:50 -070066 GPR_ASSERT(
67 GRPC_LOG_IF_ERROR("pollset_kick", grpc_pollset_kick(g_pollset, NULL)));
Craig Tiller85371a22016-02-25 13:55:13 -080068 gpr_mu_unlock(g_mu);
Craig Tillercb63a9b2015-05-13 09:52:36 -070069}
70
Craig Tillerf707d622016-05-06 14:26:12 -070071static void must_succeed(grpc_exec_ctx *exec_ctx, void *arg,
72 grpc_error *error) {
Craig Tillera82950e2015-09-22 12:33:20 -070073 GPR_ASSERT(g_connecting != NULL);
Craig Tillerf707d622016-05-06 14:26:12 -070074 GPR_ASSERT(error == GRPC_ERROR_NONE);
Craig Tillercda759d2017-01-27 11:37:37 -080075 grpc_endpoint_shutdown(exec_ctx, g_connecting,
76 GRPC_ERROR_CREATE("must_succeed called"));
Craig Tillera82950e2015-09-22 12:33:20 -070077 grpc_endpoint_destroy(exec_ctx, g_connecting);
Craig Tillerdfff1b82015-09-21 14:39:57 -070078 g_connecting = NULL;
Craig Tillera82950e2015-09-22 12:33:20 -070079 finish_connection();
ctiller18b49ab2014-12-09 14:39:16 -080080}
81
Craig Tillerf707d622016-05-06 14:26:12 -070082static void must_fail(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
Craig Tillera82950e2015-09-22 12:33:20 -070083 GPR_ASSERT(g_connecting == NULL);
Craig Tillerf707d622016-05-06 14:26:12 -070084 GPR_ASSERT(error != GRPC_ERROR_NONE);
Craig Tillera82950e2015-09-22 12:33:20 -070085 finish_connection();
ctiller18b49ab2014-12-09 14:39:16 -080086}
87
Craig Tillera82950e2015-09-22 12:33:20 -070088void test_succeeds(void) {
murgatroid997871f732016-09-23 13:49:05 -070089 grpc_resolved_address resolved_addr;
90 struct sockaddr_in *addr = (struct sockaddr_in *)resolved_addr.addr;
ctiller18b49ab2014-12-09 14:39:16 -080091 int svr_fd;
92 int r;
Craig Tillercb63a9b2015-05-13 09:52:36 -070093 int connections_complete_before;
Craig Tillerdfff1b82015-09-21 14:39:57 -070094 grpc_closure done;
Craig Tillerf5768a62015-09-22 10:54:34 -070095 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
ctiller18b49ab2014-12-09 14:39:16 -080096
Craig Tillera82950e2015-09-22 12:33:20 -070097 gpr_log(GPR_DEBUG, "test_succeeds");
Craig Tillere9593352015-07-15 07:35:09 -070098
murgatroid997871f732016-09-23 13:49:05 -070099 memset(&resolved_addr, 0, sizeof(resolved_addr));
100 resolved_addr.len = sizeof(struct sockaddr_in);
101 addr->sin_family = AF_INET;
ctiller18b49ab2014-12-09 14:39:16 -0800102
103 /* create a dummy server */
Craig Tillera82950e2015-09-22 12:33:20 -0700104 svr_fd = socket(AF_INET, SOCK_STREAM, 0);
105 GPR_ASSERT(svr_fd >= 0);
murgatroid99dedb9232016-09-26 13:54:04 -0700106 GPR_ASSERT(
107 0 == bind(svr_fd, (struct sockaddr *)addr, (socklen_t)resolved_addr.len));
Craig Tillera82950e2015-09-22 12:33:20 -0700108 GPR_ASSERT(0 == listen(svr_fd, 1));
ctiller18b49ab2014-12-09 14:39:16 -0800109
Craig Tiller85371a22016-02-25 13:55:13 -0800110 gpr_mu_lock(g_mu);
Craig Tillercb63a9b2015-05-13 09:52:36 -0700111 connections_complete_before = g_connections_complete;
Craig Tiller85371a22016-02-25 13:55:13 -0800112 gpr_mu_unlock(g_mu);
Craig Tillercb63a9b2015-05-13 09:52:36 -0700113
ctiller18b49ab2014-12-09 14:39:16 -0800114 /* connect to it */
murgatroid99dedb9232016-09-26 13:54:04 -0700115 GPR_ASSERT(getsockname(svr_fd, (struct sockaddr *)addr,
116 (socklen_t *)&resolved_addr.len) == 0);
Craig Tiller91031da2016-12-28 15:44:25 -0800117 grpc_closure_init(&done, must_succeed, NULL, grpc_schedule_on_exec_ctx);
Craig Tiller30ff60e2016-09-23 14:54:27 -0700118 grpc_tcp_client_connect(&exec_ctx, &done, &g_connecting, g_pollset_set, NULL,
murgatroid997871f732016-09-23 13:49:05 -0700119 &resolved_addr, gpr_inf_future(GPR_CLOCK_REALTIME));
ctiller18b49ab2014-12-09 14:39:16 -0800120
121 /* await the connection */
Craig Tillera82950e2015-09-22 12:33:20 -0700122 do {
murgatroid997871f732016-09-23 13:49:05 -0700123 resolved_addr.len = sizeof(addr);
murgatroid99a4601922016-10-12 13:19:40 -0700124 r = accept(svr_fd, (struct sockaddr *)addr,
125 (socklen_t *)&resolved_addr.len);
Craig Tillera82950e2015-09-22 12:33:20 -0700126 } while (r == -1 && errno == EINTR);
127 GPR_ASSERT(r >= 0);
128 close(r);
ctiller18b49ab2014-12-09 14:39:16 -0800129
Craig Tiller85371a22016-02-25 13:55:13 -0800130 gpr_mu_lock(g_mu);
Craig Tillercb63a9b2015-05-13 09:52:36 -0700131
Craig Tillera82950e2015-09-22 12:33:20 -0700132 while (g_connections_complete == connections_complete_before) {
Craig Tillerd0a8ae12016-02-18 08:01:19 -0800133 grpc_pollset_worker *worker = NULL;
Craig Tiller1aee5362016-05-07 11:26:50 -0700134 GPR_ASSERT(GRPC_LOG_IF_ERROR(
135 "pollset_work",
136 grpc_pollset_work(&exec_ctx, g_pollset, &worker,
137 gpr_now(GPR_CLOCK_MONOTONIC),
Robbie Shadeca7effc2017-01-17 09:14:29 -0500138 grpc_timeout_seconds_to_deadline(5))));
Craig Tiller85371a22016-02-25 13:55:13 -0800139 gpr_mu_unlock(g_mu);
Craig Tiller311445f2016-02-18 07:31:39 -0800140 grpc_exec_ctx_flush(&exec_ctx);
Craig Tiller85371a22016-02-25 13:55:13 -0800141 gpr_mu_lock(g_mu);
Craig Tillera82950e2015-09-22 12:33:20 -0700142 }
Craig Tillercb63a9b2015-05-13 09:52:36 -0700143
Craig Tiller85371a22016-02-25 13:55:13 -0800144 gpr_mu_unlock(g_mu);
Craig Tiller311445f2016-02-18 07:31:39 -0800145
146 grpc_exec_ctx_finish(&exec_ctx);
ctiller18b49ab2014-12-09 14:39:16 -0800147}
148
Craig Tillera82950e2015-09-22 12:33:20 -0700149void test_fails(void) {
murgatroid997871f732016-09-23 13:49:05 -0700150 grpc_resolved_address resolved_addr;
151 struct sockaddr_in *addr = (struct sockaddr_in *)resolved_addr.addr;
Craig Tillercb63a9b2015-05-13 09:52:36 -0700152 int connections_complete_before;
Craig Tillerdfff1b82015-09-21 14:39:57 -0700153 grpc_closure done;
Craig Tillerf5768a62015-09-22 10:54:34 -0700154 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
ctiller18b49ab2014-12-09 14:39:16 -0800155
Craig Tillera82950e2015-09-22 12:33:20 -0700156 gpr_log(GPR_DEBUG, "test_fails");
Craig Tillere9593352015-07-15 07:35:09 -0700157
murgatroid997871f732016-09-23 13:49:05 -0700158 memset(&resolved_addr, 0, sizeof(resolved_addr));
159 resolved_addr.len = sizeof(struct sockaddr_in);
160 addr->sin_family = AF_INET;
ctiller18b49ab2014-12-09 14:39:16 -0800161
Craig Tiller85371a22016-02-25 13:55:13 -0800162 gpr_mu_lock(g_mu);
Craig Tillercb63a9b2015-05-13 09:52:36 -0700163 connections_complete_before = g_connections_complete;
Craig Tiller85371a22016-02-25 13:55:13 -0800164 gpr_mu_unlock(g_mu);
Craig Tillercb63a9b2015-05-13 09:52:36 -0700165
ctiller18b49ab2014-12-09 14:39:16 -0800166 /* connect to a broken address */
Craig Tiller91031da2016-12-28 15:44:25 -0800167 grpc_closure_init(&done, must_fail, NULL, grpc_schedule_on_exec_ctx);
Craig Tiller30ff60e2016-09-23 14:54:27 -0700168 grpc_tcp_client_connect(&exec_ctx, &done, &g_connecting, g_pollset_set, NULL,
murgatroid997871f732016-09-23 13:49:05 -0700169 &resolved_addr, gpr_inf_future(GPR_CLOCK_REALTIME));
ctiller18b49ab2014-12-09 14:39:16 -0800170
Craig Tiller85371a22016-02-25 13:55:13 -0800171 gpr_mu_lock(g_mu);
Craig Tillercb63a9b2015-05-13 09:52:36 -0700172
ctiller18b49ab2014-12-09 14:39:16 -0800173 /* wait for the connection callback to finish */
Craig Tillera82950e2015-09-22 12:33:20 -0700174 while (g_connections_complete == connections_complete_before) {
Craig Tillerd0a8ae12016-02-18 08:01:19 -0800175 grpc_pollset_worker *worker = NULL;
Craig Tiller311445f2016-02-18 07:31:39 -0800176 gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC);
177 gpr_timespec polling_deadline = test_deadline();
178 if (!grpc_timer_check(&exec_ctx, now, &polling_deadline)) {
Craig Tiller1aee5362016-05-07 11:26:50 -0700179 GPR_ASSERT(GRPC_LOG_IF_ERROR(
180 "pollset_work", grpc_pollset_work(&exec_ctx, g_pollset, &worker, now,
181 polling_deadline)));
Craig Tiller311445f2016-02-18 07:31:39 -0800182 }
Craig Tiller85371a22016-02-25 13:55:13 -0800183 gpr_mu_unlock(g_mu);
Craig Tiller311445f2016-02-18 07:31:39 -0800184 grpc_exec_ctx_flush(&exec_ctx);
Craig Tiller85371a22016-02-25 13:55:13 -0800185 gpr_mu_lock(g_mu);
Craig Tillera82950e2015-09-22 12:33:20 -0700186 }
Craig Tillercb63a9b2015-05-13 09:52:36 -0700187
Craig Tiller85371a22016-02-25 13:55:13 -0800188 gpr_mu_unlock(g_mu);
Craig Tiller311445f2016-02-18 07:31:39 -0800189 grpc_exec_ctx_finish(&exec_ctx);
ctiller18b49ab2014-12-09 14:39:16 -0800190}
191
Craig Tillerf707d622016-05-06 14:26:12 -0700192static void destroy_pollset(grpc_exec_ctx *exec_ctx, void *p,
193 grpc_error *error) {
Craig Tillera82950e2015-09-22 12:33:20 -0700194 grpc_pollset_destroy(p);
Craig Tillerdfff1b82015-09-21 14:39:57 -0700195}
Craig Tillercb63a9b2015-05-13 09:52:36 -0700196
Craig Tillera82950e2015-09-22 12:33:20 -0700197int main(int argc, char **argv) {
Craig Tillerdfff1b82015-09-21 14:39:57 -0700198 grpc_closure destroyed;
Craig Tillerf5768a62015-09-22 10:54:34 -0700199 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Craig Tillera82950e2015-09-22 12:33:20 -0700200 grpc_test_init(argc, argv);
201 grpc_init();
Craig Tillera75d18a2016-02-25 08:45:00 -0800202 g_pollset_set = grpc_pollset_set_create();
Yuchen Zeng47de64c2017-02-22 19:04:38 -0800203 g_pollset = gpr_zalloc(grpc_pollset_size());
Craig Tillera8be91b2016-02-19 16:22:44 -0800204 grpc_pollset_init(g_pollset, &g_mu);
Craig Tillera75d18a2016-02-25 08:45:00 -0800205 grpc_pollset_set_add_pollset(&exec_ctx, g_pollset_set, g_pollset);
Craig Tillera82950e2015-09-22 12:33:20 -0700206 grpc_exec_ctx_finish(&exec_ctx);
207 test_succeeds();
208 gpr_log(GPR_ERROR, "End of first test");
209 test_fails();
Craig Tiller9e5ac1b2017-02-14 22:25:50 -0800210 grpc_pollset_set_destroy(&exec_ctx, g_pollset_set);
Craig Tillerd4654562017-01-03 08:45:56 -0800211 grpc_closure_init(&destroyed, destroy_pollset, g_pollset,
212 grpc_schedule_on_exec_ctx);
Craig Tillera8be91b2016-02-19 16:22:44 -0800213 grpc_pollset_shutdown(&exec_ctx, g_pollset, &destroyed);
Craig Tillera82950e2015-09-22 12:33:20 -0700214 grpc_exec_ctx_finish(&exec_ctx);
215 grpc_shutdown();
Craig Tillera8be91b2016-02-19 16:22:44 -0800216 gpr_free(g_pollset);
ctiller18b49ab2014-12-09 14:39:16 -0800217 return 0;
Craig Tiller190d3602015-02-18 09:23:38 -0800218}