blob: e937912d5f1c00781cd6d743775ae3e4c549c4ce [file] [log] [blame]
Craig Tiller4e6247a2017-01-05 10:17:01 -08001/*
2 *
3 * Copyright 2017, 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/end2end/end2end_tests.h"
35
36#include <stdio.h>
37#include <string.h>
38
39#include <grpc/byte_buffer.h>
40#include <grpc/support/alloc.h>
41#include <grpc/support/log.h>
42#include <grpc/support/time.h>
43#include <grpc/support/useful.h>
44#include "test/core/end2end/cq_verifier.h"
45
46static void *tag(intptr_t t) { return (void *)t; }
47
48static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
49 const char *test_name,
50 grpc_channel_args *client_args,
51 grpc_channel_args *server_args) {
52 grpc_end2end_test_fixture f;
Robbie Shade55a046a2017-01-25 15:14:28 -050053 gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name);
Craig Tiller4e6247a2017-01-05 10:17:01 -080054 f = config.create_fixture(client_args, server_args);
55 config.init_server(&f, server_args);
56 config.init_client(&f, client_args);
57 return f;
58}
59
Chris Evansed2a5472017-03-27 17:34:51 -050060static gpr_timespec n_seconds_from_now(int n) {
Robbie Shadeca7effc2017-01-17 09:14:29 -050061 return grpc_timeout_seconds_to_deadline(n);
Craig Tiller4e6247a2017-01-05 10:17:01 -080062}
63
Chris Evansed2a5472017-03-27 17:34:51 -050064static gpr_timespec five_seconds_from_now(void) {
65 return n_seconds_from_now(5);
66}
Craig Tiller4e6247a2017-01-05 10:17:01 -080067
68static void drain_cq(grpc_completion_queue *cq) {
69 grpc_event ev;
70 do {
Chris Evansed2a5472017-03-27 17:34:51 -050071 ev = grpc_completion_queue_next(cq, five_seconds_from_now(), NULL);
Craig Tiller4e6247a2017-01-05 10:17:01 -080072 } while (ev.type != GRPC_QUEUE_SHUTDOWN);
73}
74
75static void shutdown_server(grpc_end2end_test_fixture *f) {
76 if (!f->server) return;
Sree Kuchibhotla321881d2017-02-27 11:25:28 -080077 grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
78 GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
79 grpc_timeout_seconds_to_deadline(5),
80 NULL)
Craig Tiller4e6247a2017-01-05 10:17:01 -080081 .type == GRPC_OP_COMPLETE);
82 grpc_server_destroy(f->server);
83 f->server = NULL;
84}
85
86static void shutdown_client(grpc_end2end_test_fixture *f) {
87 if (!f->client) return;
88 grpc_channel_destroy(f->client);
89 f->client = NULL;
90}
91
92static void end_test(grpc_end2end_test_fixture *f) {
93 shutdown_server(f);
94 shutdown_client(f);
95
96 grpc_completion_queue_shutdown(f->cq);
97 drain_cq(f->cq);
98 grpc_completion_queue_destroy(f->cq);
Sree Kuchibhotla321881d2017-02-27 11:25:28 -080099 grpc_completion_queue_destroy(f->shutdown_cq);
Craig Tiller4e6247a2017-01-05 10:17:01 -0800100}
101
102/* Client sends a request with payload, server reads then returns status. */
103static void test_invoke_request_with_payload(grpc_end2end_test_config config) {
104 grpc_call *c;
105 grpc_call *s;
106 grpc_slice request_payload_slice1 =
107 grpc_slice_from_copied_string("hello world");
108 grpc_byte_buffer *request_payload1 =
109 grpc_raw_byte_buffer_create(&request_payload_slice1, 1);
110 grpc_slice request_payload_slice2 = grpc_slice_from_copied_string("abc123");
111 grpc_byte_buffer *request_payload2 =
112 grpc_raw_byte_buffer_create(&request_payload_slice2, 1);
Craig Tiller4e6247a2017-01-05 10:17:01 -0800113 grpc_end2end_test_fixture f =
114 begin_test(config, "test_invoke_request_with_payload", NULL, NULL);
115 cq_verifier *cqv = cq_verifier_create(f.cq);
116 grpc_op ops[6];
117 grpc_op *op;
118 grpc_metadata_array initial_metadata_recv;
119 grpc_metadata_array trailing_metadata_recv;
120 grpc_metadata_array request_metadata_recv;
121 grpc_byte_buffer *request_payload_recv1 = NULL;
122 grpc_byte_buffer *request_payload_recv2 = NULL;
123 grpc_call_details call_details;
124 grpc_status_code status;
125 grpc_call_error error;
Craig Tiller7c70b6c2017-01-23 07:48:42 -0800126 grpc_slice details = grpc_empty_slice();
Craig Tiller4e6247a2017-01-05 10:17:01 -0800127 int was_cancelled = 2;
128
Chris Evansed2a5472017-03-27 17:34:51 -0500129 gpr_timespec deadline = five_seconds_from_now();
Craig Tiller4e6247a2017-01-05 10:17:01 -0800130 c = grpc_channel_create_call(
Craig Tiller7c70b6c2017-01-23 07:48:42 -0800131 f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
132 grpc_slice_from_static_string("/foo"),
133 get_host_override_slice("foo.test.google.fr:1234", config), deadline,
Craig Tiller4e6247a2017-01-05 10:17:01 -0800134 NULL);
135 GPR_ASSERT(c);
136
137 grpc_metadata_array_init(&initial_metadata_recv);
138 grpc_metadata_array_init(&trailing_metadata_recv);
139 grpc_metadata_array_init(&request_metadata_recv);
140 grpc_call_details_init(&call_details);
141
142 memset(ops, 0, sizeof(ops));
143 op = ops;
144 op->op = GRPC_OP_SEND_INITIAL_METADATA;
145 op->data.send_initial_metadata.count = 0;
146 op++;
147 error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), NULL);
148 GPR_ASSERT(GRPC_CALL_OK == error);
149
150 memset(ops, 0, sizeof(ops));
151 op = ops;
152 op->op = GRPC_OP_RECV_INITIAL_METADATA;
Mark D. Roth435f9f22017-01-25 12:53:54 -0800153 op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
Craig Tiller4e6247a2017-01-05 10:17:01 -0800154 op->flags = 0;
155 op->reserved = NULL;
156 op++;
157 error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(2), NULL);
158 GPR_ASSERT(GRPC_CALL_OK == error);
159
160 GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(
161 f.server, &s, &call_details,
162 &request_metadata_recv, f.cq, f.cq, tag(101)));
163 CQ_EXPECT_COMPLETION(cqv, tag(1), true); /* send message is buffered */
164 CQ_EXPECT_COMPLETION(cqv, tag(101), true);
165 cq_verify(cqv);
166
167 memset(ops, 0, sizeof(ops));
168 op = ops;
169 op->op = GRPC_OP_SEND_MESSAGE;
Mark D. Roth435f9f22017-01-25 12:53:54 -0800170 op->data.send_message.send_message = request_payload1;
Craig Tiller4e6247a2017-01-05 10:17:01 -0800171 op->flags = GRPC_WRITE_BUFFER_HINT;
172 op++;
173 error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(3), NULL);
174 GPR_ASSERT(GRPC_CALL_OK == error);
175
176 memset(ops, 0, sizeof(ops));
177 op = ops;
178 op->op = GRPC_OP_SEND_INITIAL_METADATA;
179 op->data.send_initial_metadata.count = 0;
180 op++;
181 error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), NULL);
182 GPR_ASSERT(GRPC_CALL_OK == error);
183
184 /* recv message should not succeed yet - it's buffered at the client still */
185 memset(ops, 0, sizeof(ops));
186 op = ops;
187 op->op = GRPC_OP_RECV_MESSAGE;
Mark D. Roth435f9f22017-01-25 12:53:54 -0800188 op->data.recv_message.recv_message = &request_payload_recv1;
Craig Tiller4e6247a2017-01-05 10:17:01 -0800189 op++;
190 error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), NULL);
191 GPR_ASSERT(GRPC_CALL_OK == error);
192
193 CQ_EXPECT_COMPLETION(cqv, tag(2), true);
194 CQ_EXPECT_COMPLETION(cqv, tag(3), true);
195 CQ_EXPECT_COMPLETION(cqv, tag(102), true);
196 cq_verify(cqv);
197
198 /* send another message, this time not buffered */
199 memset(ops, 0, sizeof(ops));
200 op = ops;
201 op->op = GRPC_OP_SEND_MESSAGE;
Mark D. Roth435f9f22017-01-25 12:53:54 -0800202 op->data.send_message.send_message = request_payload2;
Craig Tiller4e6247a2017-01-05 10:17:01 -0800203 op->flags = 0;
204 op++;
205 error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(4), NULL);
206 GPR_ASSERT(GRPC_CALL_OK == error);
207
208 /* now the first send should match up with the first recv */
209 CQ_EXPECT_COMPLETION(cqv, tag(103), true);
210 CQ_EXPECT_COMPLETION(cqv, tag(4), true);
211 cq_verify(cqv);
212
213 /* and the next recv should be ready immediately also */
214 memset(ops, 0, sizeof(ops));
215 op = ops;
216 op->op = GRPC_OP_RECV_MESSAGE;
Mark D. Roth435f9f22017-01-25 12:53:54 -0800217 op->data.recv_message.recv_message = &request_payload_recv2;
Craig Tiller4e6247a2017-01-05 10:17:01 -0800218 op++;
219 error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(104), NULL);
220 GPR_ASSERT(GRPC_CALL_OK == error);
221
222 CQ_EXPECT_COMPLETION(cqv, tag(104), true);
223 cq_verify(cqv);
224
225 memset(ops, 0, sizeof(ops));
226 op = ops;
227 op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
228 op->flags = 0;
229 op->reserved = NULL;
230 op++;
231 op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
232 op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
233 op->data.recv_status_on_client.status = &status;
234 op->data.recv_status_on_client.status_details = &details;
Craig Tiller4e6247a2017-01-05 10:17:01 -0800235 op->flags = 0;
236 op->reserved = NULL;
237 op++;
238 error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(4), NULL);
239
240 memset(ops, 0, sizeof(ops));
241 op = ops;
242 op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
243 op->data.recv_close_on_server.cancelled = &was_cancelled;
244 op->flags = 0;
245 op->reserved = NULL;
246 op++;
247 op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
248 op->data.send_status_from_server.trailing_metadata_count = 0;
249 op->data.send_status_from_server.status = GRPC_STATUS_OK;
Craig Tiller7c70b6c2017-01-23 07:48:42 -0800250 grpc_slice status_details = grpc_slice_from_static_string("xyz");
251 op->data.send_status_from_server.status_details = &status_details;
Craig Tiller4e6247a2017-01-05 10:17:01 -0800252 op->flags = 0;
253 op->reserved = NULL;
254 op++;
255 error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(105), NULL);
256 GPR_ASSERT(GRPC_CALL_OK == error);
257
258 CQ_EXPECT_COMPLETION(cqv, tag(105), 1);
259 CQ_EXPECT_COMPLETION(cqv, tag(4), 1);
260 cq_verify(cqv);
261
262 GPR_ASSERT(status == GRPC_STATUS_OK);
Craig Tiller7c70b6c2017-01-23 07:48:42 -0800263 GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
264 GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
Craig Tiller4e6247a2017-01-05 10:17:01 -0800265 validate_host_override_string("foo.test.google.fr:1234", call_details.host,
266 config);
267 GPR_ASSERT(was_cancelled == 0);
268 GPR_ASSERT(byte_buffer_eq_string(request_payload_recv1, "hello world"));
269 GPR_ASSERT(byte_buffer_eq_string(request_payload_recv2, "abc123"));
270
Craig Tiller7c70b6c2017-01-23 07:48:42 -0800271 grpc_slice_unref(details);
Craig Tiller4e6247a2017-01-05 10:17:01 -0800272 grpc_metadata_array_destroy(&initial_metadata_recv);
273 grpc_metadata_array_destroy(&trailing_metadata_recv);
274 grpc_metadata_array_destroy(&request_metadata_recv);
275 grpc_call_details_destroy(&call_details);
276
277 grpc_call_destroy(c);
278 grpc_call_destroy(s);
279
280 cq_verifier_destroy(cqv);
281
282 grpc_byte_buffer_destroy(request_payload1);
283 grpc_byte_buffer_destroy(request_payload_recv1);
284 grpc_byte_buffer_destroy(request_payload2);
285 grpc_byte_buffer_destroy(request_payload_recv2);
286
287 end_test(&f);
288 config.tear_down_data(&f);
289}
290
291void write_buffering(grpc_end2end_test_config config) {
292 test_invoke_request_with_payload(config);
293}
294
295void write_buffering_pre_init(void) {}