Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(111)

Side by Side Diff: third_party/grpc/test/core/iomgr/endpoint_tests.c

Issue 1932353002: Initial checkin of gRPC to third_party/ Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 *
3 * Copyright 2015-2016, 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 "test/core/iomgr/endpoint_tests.h"
35
36 #include <sys/types.h>
37
38 #include <grpc/support/alloc.h>
39 #include <grpc/support/log.h>
40 #include <grpc/support/slice.h>
41 #include <grpc/support/time.h>
42 #include <grpc/support/useful.h>
43 #include "test/core/util/test_config.h"
44
45 /*
46 General test notes:
47
48 All tests which write data into an endpoint write i%256 into byte i, which
49 is verified by readers.
50
51 In general there are a few interesting things to vary which may lead to
52 exercising different codepaths in an implementation:
53 1. Total amount of data written to the endpoint
54 2. Size of slice allocations
55 3. Amount of data we read from or write to the endpoint at once
56
57 The tests here tend to parameterize these where applicable.
58
59 */
60
61 static gpr_mu *g_mu;
62 static grpc_pollset *g_pollset;
63
64 size_t count_slices(gpr_slice *slices, size_t nslices, int *current_data) {
65 size_t num_bytes = 0;
66 size_t i;
67 size_t j;
68 unsigned char *buf;
69 for (i = 0; i < nslices; ++i) {
70 buf = GPR_SLICE_START_PTR(slices[i]);
71 for (j = 0; j < GPR_SLICE_LENGTH(slices[i]); ++j) {
72 GPR_ASSERT(buf[j] == *current_data);
73 *current_data = (*current_data + 1) % 256;
74 }
75 num_bytes += GPR_SLICE_LENGTH(slices[i]);
76 }
77 return num_bytes;
78 }
79
80 static grpc_endpoint_test_fixture begin_test(grpc_endpoint_test_config config,
81 const char *test_name,
82 size_t slice_size) {
83 gpr_log(GPR_INFO, "%s/%s", test_name, config.name);
84 return config.create_fixture(slice_size);
85 }
86
87 static void end_test(grpc_endpoint_test_config config) { config.clean_up(); }
88
89 static gpr_slice *allocate_blocks(size_t num_bytes, size_t slice_size,
90 size_t *num_blocks, uint8_t *current_data) {
91 size_t nslices = num_bytes / slice_size + (num_bytes % slice_size ? 1 : 0);
92 gpr_slice *slices = malloc(sizeof(gpr_slice) * nslices);
93 size_t num_bytes_left = num_bytes;
94 size_t i;
95 size_t j;
96 unsigned char *buf;
97 *num_blocks = nslices;
98
99 for (i = 0; i < nslices; ++i) {
100 slices[i] = gpr_slice_malloc(slice_size > num_bytes_left ? num_bytes_left
101 : slice_size);
102 num_bytes_left -= GPR_SLICE_LENGTH(slices[i]);
103 buf = GPR_SLICE_START_PTR(slices[i]);
104 for (j = 0; j < GPR_SLICE_LENGTH(slices[i]); ++j) {
105 buf[j] = *current_data;
106 (*current_data)++;
107 }
108 }
109 GPR_ASSERT(num_bytes_left == 0);
110 return slices;
111 }
112
113 struct read_and_write_test_state {
114 grpc_endpoint *read_ep;
115 grpc_endpoint *write_ep;
116 size_t target_bytes;
117 size_t bytes_read;
118 size_t current_write_size;
119 size_t bytes_written;
120 int current_read_data;
121 uint8_t current_write_data;
122 int read_done;
123 int write_done;
124 gpr_slice_buffer incoming;
125 gpr_slice_buffer outgoing;
126 grpc_closure done_read;
127 grpc_closure done_write;
128 };
129
130 static void read_and_write_test_read_handler(grpc_exec_ctx *exec_ctx,
131 void *data, bool success) {
132 struct read_and_write_test_state *state = data;
133
134 state->bytes_read += count_slices(
135 state->incoming.slices, state->incoming.count, &state->current_read_data);
136 if (state->bytes_read == state->target_bytes || !success) {
137 gpr_log(GPR_INFO, "Read handler done");
138 gpr_mu_lock(g_mu);
139 state->read_done = 1 + success;
140 grpc_pollset_kick(g_pollset, NULL);
141 gpr_mu_unlock(g_mu);
142 } else if (success) {
143 grpc_endpoint_read(exec_ctx, state->read_ep, &state->incoming,
144 &state->done_read);
145 }
146 }
147
148 static void read_and_write_test_write_handler(grpc_exec_ctx *exec_ctx,
149 void *data, bool success) {
150 struct read_and_write_test_state *state = data;
151 gpr_slice *slices = NULL;
152 size_t nslices;
153
154 if (success) {
155 state->bytes_written += state->current_write_size;
156 if (state->target_bytes - state->bytes_written <
157 state->current_write_size) {
158 state->current_write_size = state->target_bytes - state->bytes_written;
159 }
160 if (state->current_write_size != 0) {
161 slices = allocate_blocks(state->current_write_size, 8192, &nslices,
162 &state->current_write_data);
163 gpr_slice_buffer_reset_and_unref(&state->outgoing);
164 gpr_slice_buffer_addn(&state->outgoing, slices, nslices);
165 grpc_endpoint_write(exec_ctx, state->write_ep, &state->outgoing,
166 &state->done_write);
167 free(slices);
168 return;
169 }
170 }
171
172 gpr_log(GPR_INFO, "Write handler done");
173 gpr_mu_lock(g_mu);
174 state->write_done = 1 + success;
175 grpc_pollset_kick(g_pollset, NULL);
176 gpr_mu_unlock(g_mu);
177 }
178
179 /* Do both reading and writing using the grpc_endpoint API.
180
181 This also includes a test of the shutdown behavior.
182 */
183 static void read_and_write_test(grpc_endpoint_test_config config,
184 size_t num_bytes, size_t write_size,
185 size_t slice_size, int shutdown) {
186 struct read_and_write_test_state state;
187 gpr_timespec deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(20);
188 grpc_endpoint_test_fixture f =
189 begin_test(config, "read_and_write_test", slice_size);
190 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
191 gpr_log(GPR_DEBUG, "num_bytes=%d write_size=%d slice_size=%d shutdown=%d",
192 num_bytes, write_size, slice_size, shutdown);
193
194 if (shutdown) {
195 gpr_log(GPR_INFO, "Start read and write shutdown test");
196 } else {
197 gpr_log(GPR_INFO, "Start read and write test with %d bytes, slice size %d",
198 num_bytes, slice_size);
199 }
200
201 state.read_ep = f.client_ep;
202 state.write_ep = f.server_ep;
203 state.target_bytes = num_bytes;
204 state.bytes_read = 0;
205 state.current_write_size = write_size;
206 state.bytes_written = 0;
207 state.read_done = 0;
208 state.write_done = 0;
209 state.current_read_data = 0;
210 state.current_write_data = 0;
211 grpc_closure_init(&state.done_read, read_and_write_test_read_handler, &state);
212 grpc_closure_init(&state.done_write, read_and_write_test_write_handler,
213 &state);
214 gpr_slice_buffer_init(&state.outgoing);
215 gpr_slice_buffer_init(&state.incoming);
216
217 /* Get started by pretending an initial write completed */
218 /* NOTE: Sets up initial conditions so we can have the same write handler
219 for the first iteration as for later iterations. It does the right thing
220 even when bytes_written is unsigned. */
221 state.bytes_written -= state.current_write_size;
222 read_and_write_test_write_handler(&exec_ctx, &state, 1);
223 grpc_exec_ctx_finish(&exec_ctx);
224
225 grpc_endpoint_read(&exec_ctx, state.read_ep, &state.incoming,
226 &state.done_read);
227
228 if (shutdown) {
229 gpr_log(GPR_DEBUG, "shutdown read");
230 grpc_endpoint_shutdown(&exec_ctx, state.read_ep);
231 gpr_log(GPR_DEBUG, "shutdown write");
232 grpc_endpoint_shutdown(&exec_ctx, state.write_ep);
233 }
234 grpc_exec_ctx_finish(&exec_ctx);
235
236 gpr_mu_lock(g_mu);
237 while (!state.read_done || !state.write_done) {
238 grpc_pollset_worker *worker = NULL;
239 GPR_ASSERT(gpr_time_cmp(gpr_now(GPR_CLOCK_MONOTONIC), deadline) < 0);
240 grpc_pollset_work(&exec_ctx, g_pollset, &worker,
241 gpr_now(GPR_CLOCK_MONOTONIC), deadline);
242 }
243 gpr_mu_unlock(g_mu);
244 grpc_exec_ctx_finish(&exec_ctx);
245
246 end_test(config);
247 gpr_slice_buffer_destroy(&state.outgoing);
248 gpr_slice_buffer_destroy(&state.incoming);
249 grpc_endpoint_destroy(&exec_ctx, state.read_ep);
250 grpc_endpoint_destroy(&exec_ctx, state.write_ep);
251 grpc_exec_ctx_finish(&exec_ctx);
252 }
253
254 void grpc_endpoint_tests(grpc_endpoint_test_config config,
255 grpc_pollset *pollset, gpr_mu *mu) {
256 size_t i;
257 g_pollset = pollset;
258 g_mu = mu;
259 read_and_write_test(config, 10000000, 100000, 8192, 0);
260 read_and_write_test(config, 1000000, 100000, 1, 0);
261 read_and_write_test(config, 100000000, 100000, 1, 1);
262 for (i = 1; i < 1000; i = GPR_MAX(i + 1, i * 5 / 4)) {
263 read_and_write_test(config, 40320, i, i, 0);
264 }
265 g_pollset = NULL;
266 }
OLDNEW
« no previous file with comments | « third_party/grpc/test/core/iomgr/endpoint_tests.h ('k') | third_party/grpc/test/core/iomgr/fd_conservation_posix_test.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698