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_server.h"
35 : #include "src/core/iomgr/iomgr.h"
36 : #include <grpc/support/log.h>
37 : #include <grpc/support/sync.h>
38 : #include <grpc/support/time.h>
39 : #include "test/core/util/test_config.h"
40 :
41 : #include <sys/socket.h>
42 : #include <netinet/in.h>
43 : #include <string.h>
44 : #include <unistd.h>
45 :
46 : #define LOG_TEST(x) gpr_log(GPR_INFO, "%s", #x)
47 :
48 : static grpc_pollset g_pollset;
49 : static int g_nconnects = 0;
50 :
51 11 : static void on_connect(grpc_exec_ctx *exec_ctx, void *arg, grpc_endpoint *tcp) {
52 11 : grpc_endpoint_shutdown(exec_ctx, tcp);
53 11 : grpc_endpoint_destroy(exec_ctx, tcp);
54 :
55 11 : gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
56 11 : g_nconnects++;
57 11 : grpc_pollset_kick(&g_pollset, NULL);
58 11 : gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
59 11 : }
60 :
61 1 : static void test_no_op(void) {
62 1 : grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
63 1 : grpc_tcp_server *s = grpc_tcp_server_create();
64 1 : grpc_tcp_server_destroy(&exec_ctx, s, NULL);
65 1 : grpc_exec_ctx_finish(&exec_ctx);
66 1 : }
67 :
68 1 : static void test_no_op_with_start(void) {
69 1 : grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
70 1 : grpc_tcp_server *s = grpc_tcp_server_create();
71 1 : LOG_TEST("test_no_op_with_start");
72 1 : grpc_tcp_server_start(&exec_ctx, s, NULL, 0, on_connect, NULL);
73 1 : grpc_tcp_server_destroy(&exec_ctx, s, NULL);
74 1 : grpc_exec_ctx_finish(&exec_ctx);
75 1 : }
76 :
77 1 : static void test_no_op_with_port(void) {
78 1 : grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
79 : struct sockaddr_in addr;
80 1 : grpc_tcp_server *s = grpc_tcp_server_create();
81 1 : LOG_TEST("test_no_op_with_port");
82 :
83 1 : memset(&addr, 0, sizeof(addr));
84 1 : addr.sin_family = AF_INET;
85 1 : GPR_ASSERT(
86 : grpc_tcp_server_add_port(s, (struct sockaddr *)&addr, sizeof(addr)));
87 :
88 1 : grpc_tcp_server_destroy(&exec_ctx, s, NULL);
89 1 : grpc_exec_ctx_finish(&exec_ctx);
90 1 : }
91 :
92 1 : static void test_no_op_with_port_and_start(void) {
93 1 : grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
94 : struct sockaddr_in addr;
95 1 : grpc_tcp_server *s = grpc_tcp_server_create();
96 1 : LOG_TEST("test_no_op_with_port_and_start");
97 :
98 1 : memset(&addr, 0, sizeof(addr));
99 1 : addr.sin_family = AF_INET;
100 1 : GPR_ASSERT(
101 : grpc_tcp_server_add_port(s, (struct sockaddr *)&addr, sizeof(addr)));
102 :
103 1 : grpc_tcp_server_start(&exec_ctx, s, NULL, 0, on_connect, NULL);
104 :
105 1 : grpc_tcp_server_destroy(&exec_ctx, s, NULL);
106 1 : grpc_exec_ctx_finish(&exec_ctx);
107 1 : }
108 :
109 2 : static void test_connect(int n) {
110 2 : grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
111 : struct sockaddr_storage addr;
112 2 : socklen_t addr_len = sizeof(addr);
113 : int svrfd, clifd;
114 2 : grpc_tcp_server *s = grpc_tcp_server_create();
115 : int nconnects_before;
116 : gpr_timespec deadline;
117 : grpc_pollset *pollsets[1];
118 : int i;
119 2 : LOG_TEST("test_connect");
120 2 : gpr_log(GPR_INFO, "clients=%d", n);
121 :
122 2 : memset(&addr, 0, sizeof(addr));
123 2 : addr.ss_family = AF_INET;
124 2 : GPR_ASSERT(grpc_tcp_server_add_port(s, (struct sockaddr *)&addr, addr_len));
125 :
126 2 : svrfd = grpc_tcp_server_get_fd(s, 0);
127 2 : GPR_ASSERT(svrfd >= 0);
128 2 : GPR_ASSERT(getsockname(svrfd, (struct sockaddr *)&addr, &addr_len) == 0);
129 2 : GPR_ASSERT(addr_len <= sizeof(addr));
130 :
131 2 : pollsets[0] = &g_pollset;
132 2 : grpc_tcp_server_start(&exec_ctx, s, pollsets, 1, on_connect, NULL);
133 :
134 2 : gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
135 :
136 13 : for (i = 0; i < n; i++) {
137 11 : deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10);
138 :
139 11 : nconnects_before = g_nconnects;
140 11 : clifd = socket(addr.ss_family, SOCK_STREAM, 0);
141 11 : GPR_ASSERT(clifd >= 0);
142 11 : gpr_log(GPR_DEBUG, "start connect");
143 11 : GPR_ASSERT(connect(clifd, (struct sockaddr *)&addr, addr_len) == 0);
144 :
145 11 : gpr_log(GPR_DEBUG, "wait");
146 84 : while (g_nconnects == nconnects_before &&
147 31 : gpr_time_cmp(deadline, gpr_now(deadline.clock_type)) > 0) {
148 : grpc_pollset_worker worker;
149 31 : grpc_pollset_work(&exec_ctx, &g_pollset, &worker,
150 : gpr_now(GPR_CLOCK_MONOTONIC), deadline);
151 31 : gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
152 31 : grpc_exec_ctx_finish(&exec_ctx);
153 31 : gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
154 : }
155 11 : gpr_log(GPR_DEBUG, "wait done");
156 :
157 11 : GPR_ASSERT(g_nconnects == nconnects_before + 1);
158 11 : close(clifd);
159 : }
160 :
161 2 : gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
162 :
163 2 : grpc_tcp_server_destroy(&exec_ctx, s, NULL);
164 2 : grpc_exec_ctx_finish(&exec_ctx);
165 2 : }
166 :
167 1 : static void destroy_pollset(grpc_exec_ctx *exec_ctx, void *p, int success) {
168 1 : grpc_pollset_destroy(p);
169 1 : }
170 :
171 1 : int main(int argc, char **argv) {
172 : grpc_closure destroyed;
173 1 : grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
174 1 : grpc_test_init(argc, argv);
175 1 : grpc_iomgr_init();
176 1 : grpc_pollset_init(&g_pollset);
177 :
178 1 : test_no_op();
179 1 : test_no_op_with_start();
180 1 : test_no_op_with_port();
181 1 : test_no_op_with_port_and_start();
182 1 : test_connect(1);
183 1 : test_connect(10);
184 :
185 1 : grpc_closure_init(&destroyed, destroy_pollset, &g_pollset);
186 1 : grpc_pollset_shutdown(&exec_ctx, &g_pollset, &destroyed);
187 1 : grpc_exec_ctx_finish(&exec_ctx);
188 1 : grpc_iomgr_shutdown();
189 1 : return 0;
190 : }
|