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/udp_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_number_of_reads = 0;
50 : static int g_number_of_bytes_read = 0;
51 :
52 11 : static void on_read(grpc_exec_ctx *exec_ctx, grpc_fd *emfd,
53 : grpc_server *server) {
54 : char read_buffer[512];
55 : ssize_t byte_count;
56 :
57 11 : gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
58 11 : byte_count = recv(emfd->fd, read_buffer, sizeof(read_buffer), 0);
59 :
60 11 : g_number_of_reads++;
61 11 : g_number_of_bytes_read += (int)byte_count;
62 :
63 11 : grpc_pollset_kick(&g_pollset, NULL);
64 11 : gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
65 11 : }
66 :
67 1 : static void test_no_op(void) {
68 1 : grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
69 1 : grpc_udp_server *s = grpc_udp_server_create();
70 1 : grpc_udp_server_destroy(&exec_ctx, s, NULL);
71 1 : grpc_exec_ctx_finish(&exec_ctx);
72 1 : }
73 :
74 1 : static void test_no_op_with_start(void) {
75 1 : grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
76 1 : grpc_udp_server *s = grpc_udp_server_create();
77 1 : LOG_TEST("test_no_op_with_start");
78 1 : grpc_udp_server_start(&exec_ctx, s, NULL, 0, NULL);
79 1 : grpc_udp_server_destroy(&exec_ctx, s, NULL);
80 1 : grpc_exec_ctx_finish(&exec_ctx);
81 1 : }
82 :
83 1 : static void test_no_op_with_port(void) {
84 1 : grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
85 : struct sockaddr_in addr;
86 1 : grpc_udp_server *s = grpc_udp_server_create();
87 1 : LOG_TEST("test_no_op_with_port");
88 :
89 1 : memset(&addr, 0, sizeof(addr));
90 1 : addr.sin_family = AF_INET;
91 1 : GPR_ASSERT(grpc_udp_server_add_port(s, (struct sockaddr *)&addr, sizeof(addr),
92 : on_read));
93 :
94 1 : grpc_udp_server_destroy(&exec_ctx, s, NULL);
95 1 : grpc_exec_ctx_finish(&exec_ctx);
96 1 : }
97 :
98 1 : static void test_no_op_with_port_and_start(void) {
99 1 : grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
100 : struct sockaddr_in addr;
101 1 : grpc_udp_server *s = grpc_udp_server_create();
102 1 : LOG_TEST("test_no_op_with_port_and_start");
103 :
104 1 : memset(&addr, 0, sizeof(addr));
105 1 : addr.sin_family = AF_INET;
106 1 : GPR_ASSERT(grpc_udp_server_add_port(s, (struct sockaddr *)&addr, sizeof(addr),
107 : on_read));
108 :
109 1 : grpc_udp_server_start(&exec_ctx, s, NULL, 0, NULL);
110 :
111 1 : grpc_udp_server_destroy(&exec_ctx, s, NULL);
112 1 : grpc_exec_ctx_finish(&exec_ctx);
113 1 : }
114 :
115 2 : static void test_receive(int number_of_clients) {
116 2 : grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
117 : struct sockaddr_storage addr;
118 2 : socklen_t addr_len = sizeof(addr);
119 : int clifd, svrfd;
120 2 : grpc_udp_server *s = grpc_udp_server_create();
121 : int i;
122 : int number_of_reads_before;
123 : gpr_timespec deadline;
124 : grpc_pollset *pollsets[1];
125 2 : LOG_TEST("test_receive");
126 2 : gpr_log(GPR_INFO, "clients=%d", number_of_clients);
127 :
128 2 : g_number_of_bytes_read = 0;
129 :
130 2 : memset(&addr, 0, sizeof(addr));
131 2 : addr.ss_family = AF_INET;
132 2 : GPR_ASSERT(
133 : grpc_udp_server_add_port(s, (struct sockaddr *)&addr, addr_len, on_read));
134 :
135 2 : svrfd = grpc_udp_server_get_fd(s, 0);
136 2 : GPR_ASSERT(svrfd >= 0);
137 2 : GPR_ASSERT(getsockname(svrfd, (struct sockaddr *)&addr, &addr_len) == 0);
138 2 : GPR_ASSERT(addr_len <= sizeof(addr));
139 :
140 2 : pollsets[0] = &g_pollset;
141 2 : grpc_udp_server_start(&exec_ctx, s, pollsets, 1, NULL);
142 :
143 2 : gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
144 :
145 13 : for (i = 0; i < number_of_clients; i++) {
146 11 : deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10);
147 :
148 11 : number_of_reads_before = g_number_of_reads;
149 : /* Create a socket, send a packet to the UDP server. */
150 11 : clifd = socket(addr.ss_family, SOCK_DGRAM, 0);
151 11 : GPR_ASSERT(clifd >= 0);
152 11 : GPR_ASSERT(connect(clifd, (struct sockaddr *)&addr, addr_len) == 0);
153 11 : GPR_ASSERT(5 == write(clifd, "hello", 5));
154 44 : while (g_number_of_reads == number_of_reads_before &&
155 11 : gpr_time_cmp(deadline, gpr_now(deadline.clock_type)) > 0) {
156 : grpc_pollset_worker worker;
157 11 : grpc_pollset_work(&exec_ctx, &g_pollset, &worker,
158 : gpr_now(GPR_CLOCK_MONOTONIC), deadline);
159 11 : gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
160 11 : grpc_exec_ctx_finish(&exec_ctx);
161 11 : gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
162 : }
163 11 : GPR_ASSERT(g_number_of_reads == number_of_reads_before + 1);
164 11 : close(clifd);
165 : }
166 2 : GPR_ASSERT(g_number_of_bytes_read == 5 * number_of_clients);
167 :
168 2 : gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
169 :
170 2 : grpc_udp_server_destroy(&exec_ctx, s, NULL);
171 2 : grpc_exec_ctx_finish(&exec_ctx);
172 2 : }
173 :
174 1 : static void destroy_pollset(grpc_exec_ctx *exec_ctx, void *p, int success) {
175 1 : grpc_pollset_destroy(p);
176 1 : }
177 :
178 1 : int main(int argc, char **argv) {
179 : grpc_closure destroyed;
180 1 : grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
181 1 : grpc_test_init(argc, argv);
182 1 : grpc_iomgr_init();
183 1 : grpc_pollset_init(&g_pollset);
184 :
185 1 : test_no_op();
186 1 : test_no_op_with_start();
187 1 : test_no_op_with_port();
188 1 : test_no_op_with_port_and_start();
189 1 : test_receive(1);
190 1 : test_receive(10);
191 :
192 1 : grpc_closure_init(&destroyed, destroy_pollset, &g_pollset);
193 1 : grpc_pollset_shutdown(&exec_ctx, &g_pollset, &destroyed);
194 1 : grpc_exec_ctx_finish(&exec_ctx);
195 1 : grpc_iomgr_shutdown();
196 1 : return 0;
197 : }
|