1 /*
2 *
3 * Copyright 2015 gRPC authors.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19 #include "test/core/end2end/end2end_tests.h"
20
21 #include <stdio.h>
22 #include <string.h>
23
24 #include <grpc/byte_buffer.h>
25 #include <grpc/byte_buffer_reader.h>
26 #include <grpc/compression.h>
27 #include <grpc/support/alloc.h>
28 #include <grpc/support/log.h>
29 #include <grpc/support/string_util.h>
30 #include <grpc/support/time.h>
31
32 #include "src/core/lib/channel/channel_args.h"
33 #include "src/core/lib/compression/compression_args.h"
34 #include "src/core/lib/surface/call.h"
35 #include "src/core/lib/surface/call_test_only.h"
36 #include "src/core/lib/transport/static_metadata.h"
37 #include "test/core/end2end/cq_verifier.h"
38
tag(intptr_t t)39 static void* tag(intptr_t t) { return (void*)t; }
40
begin_test(grpc_end2end_test_config config,const char * test_name,grpc_channel_args * client_args,grpc_channel_args * server_args,bool decompress_in_core)41 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
42 const char* test_name,
43 grpc_channel_args* client_args,
44 grpc_channel_args* server_args,
45 bool decompress_in_core) {
46 grpc_end2end_test_fixture f;
47 gpr_log(GPR_INFO, "Running test: %s%s/%s", test_name,
48 decompress_in_core ? "" : "_with_decompression_disabled",
49 config.name);
50 f = config.create_fixture(client_args, server_args);
51 config.init_server(&f, server_args);
52 config.init_client(&f, client_args);
53 return f;
54 }
55
n_seconds_from_now(int n)56 static gpr_timespec n_seconds_from_now(int n) {
57 return grpc_timeout_seconds_to_deadline(n);
58 }
59
five_seconds_from_now(void)60 static gpr_timespec five_seconds_from_now(void) {
61 return n_seconds_from_now(5);
62 }
63
drain_cq(grpc_completion_queue * cq)64 static void drain_cq(grpc_completion_queue* cq) {
65 grpc_event ev;
66 do {
67 ev = grpc_completion_queue_next(cq, five_seconds_from_now(), nullptr);
68 } while (ev.type != GRPC_QUEUE_SHUTDOWN);
69 }
70
shutdown_server(grpc_end2end_test_fixture * f)71 static void shutdown_server(grpc_end2end_test_fixture* f) {
72 if (!f->server) return;
73 grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
74 GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
75 grpc_timeout_seconds_to_deadline(5),
76 nullptr)
77 .type == GRPC_OP_COMPLETE);
78 grpc_server_destroy(f->server);
79 f->server = nullptr;
80 }
81
shutdown_client(grpc_end2end_test_fixture * f)82 static void shutdown_client(grpc_end2end_test_fixture* f) {
83 if (!f->client) return;
84 grpc_channel_destroy(f->client);
85 f->client = nullptr;
86 }
87
end_test(grpc_end2end_test_fixture * f)88 static void end_test(grpc_end2end_test_fixture* f) {
89 shutdown_server(f);
90 shutdown_client(f);
91
92 grpc_completion_queue_shutdown(f->cq);
93 drain_cq(f->cq);
94 grpc_completion_queue_destroy(f->cq);
95 grpc_completion_queue_destroy(f->shutdown_cq);
96 }
97
request_for_disabled_algorithm(grpc_end2end_test_config config,const char * test_name,uint32_t send_flags_bitmask,grpc_compression_algorithm algorithm_to_disable,grpc_compression_algorithm requested_client_compression_algorithm,grpc_status_code expected_error,grpc_metadata * client_metadata,bool decompress_in_core)98 static void request_for_disabled_algorithm(
99 grpc_end2end_test_config config, const char* test_name,
100 uint32_t send_flags_bitmask,
101 grpc_compression_algorithm algorithm_to_disable,
102 grpc_compression_algorithm requested_client_compression_algorithm,
103 grpc_status_code expected_error, grpc_metadata* client_metadata,
104 bool decompress_in_core) {
105 grpc_call* c;
106 grpc_call* s;
107 grpc_slice request_payload_slice;
108 grpc_byte_buffer* request_payload;
109 grpc_channel_args* client_args;
110 grpc_channel_args* server_args;
111 grpc_end2end_test_fixture f;
112 grpc_op ops[6];
113 grpc_op* op;
114 grpc_metadata_array initial_metadata_recv;
115 grpc_metadata_array trailing_metadata_recv;
116 grpc_metadata_array request_metadata_recv;
117 grpc_byte_buffer* request_payload_recv = nullptr;
118 grpc_call_details call_details;
119 grpc_status_code status;
120 grpc_call_error error;
121 grpc_slice details;
122 int was_cancelled = 2;
123 cq_verifier* cqv;
124 char str[1024];
125
126 memset(str, 'x', 1023);
127 str[1023] = '\0';
128 request_payload_slice = grpc_slice_from_copied_string(str);
129 request_payload = grpc_raw_byte_buffer_create(&request_payload_slice, 1);
130
131 client_args = grpc_channel_args_set_channel_default_compression_algorithm(
132 nullptr, requested_client_compression_algorithm);
133 server_args = grpc_channel_args_set_channel_default_compression_algorithm(
134 nullptr, GRPC_COMPRESS_NONE);
135 server_args = grpc_channel_args_compression_algorithm_set_state(
136 &server_args, algorithm_to_disable, false);
137 if (!decompress_in_core) {
138 grpc_arg disable_decompression_in_core_arg =
139 grpc_channel_arg_integer_create(
140 const_cast<char*>(GRPC_ARG_ENABLE_PER_MESSAGE_DECOMPRESSION), 0);
141 grpc_channel_args* old_client_args = client_args;
142 grpc_channel_args* old_server_args = server_args;
143 client_args = grpc_channel_args_copy_and_add(
144 client_args, &disable_decompression_in_core_arg, 1);
145 server_args = grpc_channel_args_copy_and_add(
146 server_args, &disable_decompression_in_core_arg, 1);
147 grpc_channel_args_destroy(old_client_args);
148 grpc_channel_args_destroy(old_server_args);
149 }
150
151 f = begin_test(config, test_name, client_args, server_args,
152 decompress_in_core);
153 cqv = cq_verifier_create(f.cq);
154
155 gpr_timespec deadline = five_seconds_from_now();
156 c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
157 grpc_slice_from_static_string("/foo"), nullptr,
158 deadline, nullptr);
159 GPR_ASSERT(c);
160
161 grpc_metadata_array_init(&initial_metadata_recv);
162 grpc_metadata_array_init(&trailing_metadata_recv);
163 grpc_metadata_array_init(&request_metadata_recv);
164 grpc_call_details_init(&call_details);
165
166 error =
167 grpc_server_request_call(f.server, &s, &call_details,
168 &request_metadata_recv, f.cq, f.cq, tag(101));
169 GPR_ASSERT(GRPC_CALL_OK == error);
170
171 memset(ops, 0, sizeof(ops));
172 op = ops;
173 op->op = GRPC_OP_SEND_INITIAL_METADATA;
174 if (client_metadata != nullptr) {
175 op->data.send_initial_metadata.count = 1;
176 op->data.send_initial_metadata.metadata = client_metadata;
177 } else {
178 op->data.send_initial_metadata.count = 0;
179 }
180 op->flags = 0;
181 op->reserved = nullptr;
182 op++;
183 op->op = GRPC_OP_SEND_MESSAGE;
184 op->data.send_message.send_message = request_payload;
185 op->flags = send_flags_bitmask;
186 op->reserved = nullptr;
187 op++;
188 op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
189 op->flags = 0;
190 op->reserved = nullptr;
191 op++;
192 op->op = GRPC_OP_RECV_INITIAL_METADATA;
193 op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
194 op->flags = 0;
195 op->reserved = nullptr;
196 op++;
197 op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
198 op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
199 op->data.recv_status_on_client.status = &status;
200 op->data.recv_status_on_client.status_details = &details;
201 op->flags = 0;
202 op->reserved = nullptr;
203 op++;
204 error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1),
205 nullptr);
206 GPR_ASSERT(GRPC_CALL_OK == error);
207
208 CQ_EXPECT_COMPLETION(cqv, tag(101), true);
209 CQ_EXPECT_COMPLETION(cqv, tag(1), true);
210 cq_verify(cqv);
211
212 op = ops;
213 op->op = GRPC_OP_SEND_INITIAL_METADATA;
214 op->data.send_initial_metadata.count = 0;
215 op->flags = 0;
216 op->reserved = nullptr;
217 op++;
218 op->op = GRPC_OP_RECV_MESSAGE;
219 op->data.recv_message.recv_message = &request_payload_recv;
220 op->flags = 0;
221 op->reserved = nullptr;
222 op++;
223 error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102),
224 nullptr);
225 GPR_ASSERT(GRPC_CALL_OK == error);
226
227 CQ_EXPECT_COMPLETION(cqv, tag(102), false);
228
229 op = ops;
230 op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
231 op->data.recv_close_on_server.cancelled = &was_cancelled;
232 op->flags = 0;
233 op->reserved = nullptr;
234 op++;
235 error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(103),
236 nullptr);
237 GPR_ASSERT(GRPC_CALL_OK == error);
238
239 CQ_EXPECT_COMPLETION(cqv, tag(103), true);
240 cq_verify(cqv);
241
242 /* call was cancelled (closed) ... */
243 GPR_ASSERT(was_cancelled != 0);
244 /* with a certain error */
245 GPR_ASSERT(status == expected_error);
246
247 const char* algo_name = nullptr;
248 GPR_ASSERT(grpc_compression_algorithm_name(algorithm_to_disable, &algo_name));
249 char* expected_details = nullptr;
250 gpr_asprintf(&expected_details, "Compression algorithm '%s' is disabled.",
251 algo_name);
252 /* and we expect a specific reason for it */
253 GPR_ASSERT(0 == grpc_slice_str_cmp(details, expected_details));
254 gpr_free(expected_details);
255 GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
256
257 grpc_slice_unref(details);
258 grpc_metadata_array_destroy(&initial_metadata_recv);
259 grpc_metadata_array_destroy(&trailing_metadata_recv);
260 grpc_metadata_array_destroy(&request_metadata_recv);
261 grpc_call_details_destroy(&call_details);
262
263 grpc_call_unref(c);
264 grpc_call_unref(s);
265
266 cq_verifier_destroy(cqv);
267
268 grpc_slice_unref(request_payload_slice);
269 grpc_byte_buffer_destroy(request_payload);
270 grpc_byte_buffer_destroy(request_payload_recv);
271 grpc_channel_args_destroy(client_args);
272 grpc_channel_args_destroy(server_args);
273 end_test(&f);
274 config.tear_down_data(&f);
275 }
276
request_with_payload_template_inner(grpc_end2end_test_config config,const char * test_name,uint32_t client_send_flags_bitmask,grpc_compression_algorithm default_client_channel_compression_algorithm,grpc_compression_algorithm default_server_channel_compression_algorithm,grpc_compression_algorithm expected_algorithm_from_client,grpc_compression_algorithm expected_algorithm_from_server,grpc_metadata * client_init_metadata,bool set_server_level,grpc_compression_level server_compression_level,bool send_message_before_initial_metadata,bool decompress_in_core)277 static void request_with_payload_template_inner(
278 grpc_end2end_test_config config, const char* test_name,
279 uint32_t client_send_flags_bitmask,
280 grpc_compression_algorithm default_client_channel_compression_algorithm,
281 grpc_compression_algorithm default_server_channel_compression_algorithm,
282 grpc_compression_algorithm expected_algorithm_from_client,
283 grpc_compression_algorithm expected_algorithm_from_server,
284 grpc_metadata* client_init_metadata, bool set_server_level,
285 grpc_compression_level server_compression_level,
286 bool send_message_before_initial_metadata, bool decompress_in_core) {
287 grpc_call* c;
288 grpc_call* s;
289 grpc_slice request_payload_slice;
290 grpc_byte_buffer* request_payload = nullptr;
291 grpc_channel_args* client_args;
292 grpc_channel_args* server_args;
293 grpc_end2end_test_fixture f;
294 grpc_op ops[6];
295 grpc_op* op;
296 grpc_metadata_array initial_metadata_recv;
297 grpc_metadata_array trailing_metadata_recv;
298 grpc_metadata_array request_metadata_recv;
299 grpc_byte_buffer* request_payload_recv = nullptr;
300 grpc_byte_buffer* response_payload;
301 grpc_byte_buffer* response_payload_recv;
302 grpc_call_details call_details;
303 grpc_status_code status;
304 grpc_call_error error;
305 grpc_slice details;
306 int was_cancelled = 2;
307 cq_verifier* cqv;
308 char request_str[1024];
309 char response_str[1024];
310
311 memset(request_str, 'x', 1023);
312 request_str[1023] = '\0';
313
314 memset(response_str, 'y', 1023);
315 response_str[1023] = '\0';
316
317 request_payload_slice = grpc_slice_from_copied_string(request_str);
318 grpc_slice response_payload_slice =
319 grpc_slice_from_copied_string(response_str);
320
321 client_args = grpc_channel_args_set_channel_default_compression_algorithm(
322 nullptr, default_client_channel_compression_algorithm);
323 server_args = grpc_channel_args_set_channel_default_compression_algorithm(
324 nullptr, default_server_channel_compression_algorithm);
325 if (!decompress_in_core) {
326 grpc_arg disable_decompression_in_core_arg =
327 grpc_channel_arg_integer_create(
328 const_cast<char*>(GRPC_ARG_ENABLE_PER_MESSAGE_DECOMPRESSION), 0);
329 grpc_channel_args* old_client_args = client_args;
330 grpc_channel_args* old_server_args = server_args;
331 client_args = grpc_channel_args_copy_and_add(
332 client_args, &disable_decompression_in_core_arg, 1);
333 server_args = grpc_channel_args_copy_and_add(
334 server_args, &disable_decompression_in_core_arg, 1);
335 grpc_channel_args_destroy(old_client_args);
336 grpc_channel_args_destroy(old_server_args);
337 }
338 f = begin_test(config, test_name, client_args, server_args,
339 decompress_in_core);
340 cqv = cq_verifier_create(f.cq);
341
342 gpr_timespec deadline = five_seconds_from_now();
343 c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
344 grpc_slice_from_static_string("/foo"), nullptr,
345 deadline, nullptr);
346 GPR_ASSERT(c);
347
348 grpc_metadata_array_init(&initial_metadata_recv);
349 grpc_metadata_array_init(&trailing_metadata_recv);
350 grpc_metadata_array_init(&request_metadata_recv);
351 grpc_call_details_init(&call_details);
352
353 if (send_message_before_initial_metadata) {
354 request_payload = grpc_raw_byte_buffer_create(&request_payload_slice, 1);
355 memset(ops, 0, sizeof(ops));
356 op = ops;
357 op->op = GRPC_OP_SEND_MESSAGE;
358 op->data.send_message.send_message = request_payload;
359 op->flags = client_send_flags_bitmask;
360 op->reserved = nullptr;
361 op++;
362 error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(2),
363 nullptr);
364 GPR_ASSERT(GRPC_CALL_OK == error);
365 CQ_EXPECT_COMPLETION(cqv, tag(2), true);
366 }
367 memset(ops, 0, sizeof(ops));
368 op = ops;
369 op->op = GRPC_OP_SEND_INITIAL_METADATA;
370 if (client_init_metadata != nullptr) {
371 op->data.send_initial_metadata.count = 1;
372 op->data.send_initial_metadata.metadata = client_init_metadata;
373 } else {
374 op->data.send_initial_metadata.count = 0;
375 }
376 op->flags = 0;
377 op->reserved = nullptr;
378 op++;
379 op->op = GRPC_OP_RECV_INITIAL_METADATA;
380 op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
381 op->flags = 0;
382 op->reserved = nullptr;
383 op++;
384 op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
385 op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
386 op->data.recv_status_on_client.status = &status;
387 op->data.recv_status_on_client.status_details = &details;
388 op->flags = 0;
389 op->reserved = nullptr;
390 op++;
391 error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1),
392 nullptr);
393 GPR_ASSERT(GRPC_CALL_OK == error);
394
395 error =
396 grpc_server_request_call(f.server, &s, &call_details,
397 &request_metadata_recv, f.cq, f.cq, tag(100));
398 GPR_ASSERT(GRPC_CALL_OK == error);
399 CQ_EXPECT_COMPLETION(cqv, tag(100), true);
400 cq_verify(cqv);
401
402 GPR_ASSERT(GPR_BITCOUNT(grpc_call_test_only_get_encodings_accepted_by_peer(
403 s)) == GRPC_COMPRESS_ALGORITHMS_COUNT);
404 GPR_ASSERT(GPR_BITGET(grpc_call_test_only_get_encodings_accepted_by_peer(s),
405 GRPC_COMPRESS_NONE) != 0);
406 GPR_ASSERT(GPR_BITGET(grpc_call_test_only_get_encodings_accepted_by_peer(s),
407 GRPC_COMPRESS_DEFLATE) != 0);
408 GPR_ASSERT(GPR_BITGET(grpc_call_test_only_get_encodings_accepted_by_peer(s),
409 GRPC_COMPRESS_GZIP) != 0);
410 memset(ops, 0, sizeof(ops));
411 op = ops;
412 op->op = GRPC_OP_SEND_INITIAL_METADATA;
413 op->data.send_initial_metadata.count = 0;
414 if (set_server_level) {
415 op->data.send_initial_metadata.maybe_compression_level.is_set = true;
416 op->data.send_initial_metadata.maybe_compression_level.level =
417 server_compression_level;
418 }
419 op->flags = 0;
420 op->reserved = nullptr;
421 op++;
422 op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
423 op->data.recv_close_on_server.cancelled = &was_cancelled;
424 op->flags = 0;
425 op->reserved = nullptr;
426 op++;
427 error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(101),
428 nullptr);
429 GPR_ASSERT(GRPC_CALL_OK == error);
430 for (int i = 0; i < 2; i++) {
431 response_payload = grpc_raw_byte_buffer_create(&response_payload_slice, 1);
432
433 if (i > 0 || !send_message_before_initial_metadata) {
434 request_payload = grpc_raw_byte_buffer_create(&request_payload_slice, 1);
435 memset(ops, 0, sizeof(ops));
436 op = ops;
437 op->op = GRPC_OP_SEND_MESSAGE;
438 op->data.send_message.send_message = request_payload;
439 op->flags = client_send_flags_bitmask;
440 op->reserved = nullptr;
441 op++;
442 error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops),
443 tag(2), nullptr);
444 GPR_ASSERT(GRPC_CALL_OK == error);
445 CQ_EXPECT_COMPLETION(cqv, tag(2), 1);
446 }
447
448 memset(ops, 0, sizeof(ops));
449 op = ops;
450 op->op = GRPC_OP_RECV_MESSAGE;
451 op->data.recv_message.recv_message = &request_payload_recv;
452 op->flags = 0;
453 op->reserved = nullptr;
454 op++;
455 error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops),
456 tag(102), nullptr);
457 GPR_ASSERT(GRPC_CALL_OK == error);
458
459 CQ_EXPECT_COMPLETION(cqv, tag(102), 1);
460 cq_verify(cqv);
461
462 GPR_ASSERT(request_payload_recv->type == GRPC_BB_RAW);
463 GPR_ASSERT(byte_buffer_eq_string(request_payload_recv, request_str));
464 GPR_ASSERT(request_payload_recv->data.raw.compression ==
465 (decompress_in_core ? GRPC_COMPRESS_NONE
466 : expected_algorithm_from_client));
467
468 memset(ops, 0, sizeof(ops));
469 op = ops;
470 op->op = GRPC_OP_SEND_MESSAGE;
471 op->data.send_message.send_message = response_payload;
472 op->flags = 0;
473 op->reserved = nullptr;
474 op++;
475 error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops),
476 tag(103), nullptr);
477 GPR_ASSERT(GRPC_CALL_OK == error);
478
479 memset(ops, 0, sizeof(ops));
480 op = ops;
481 op->op = GRPC_OP_RECV_MESSAGE;
482 op->data.recv_message.recv_message = &response_payload_recv;
483 op->flags = 0;
484 op->reserved = nullptr;
485 op++;
486 error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(3),
487 nullptr);
488 GPR_ASSERT(GRPC_CALL_OK == error);
489
490 CQ_EXPECT_COMPLETION(cqv, tag(103), 1);
491 CQ_EXPECT_COMPLETION(cqv, tag(3), 1);
492 cq_verify(cqv);
493
494 GPR_ASSERT(response_payload_recv->type == GRPC_BB_RAW);
495 GPR_ASSERT(byte_buffer_eq_string(response_payload_recv, response_str));
496 if (server_compression_level > GRPC_COMPRESS_LEVEL_NONE) {
497 const grpc_compression_algorithm algo_for_server_level =
498 grpc_call_compression_for_level(s, server_compression_level);
499 GPR_ASSERT(
500 response_payload_recv->data.raw.compression ==
501 (decompress_in_core ? GRPC_COMPRESS_NONE : algo_for_server_level));
502 } else {
503 GPR_ASSERT(response_payload_recv->data.raw.compression ==
504 (decompress_in_core ? GRPC_COMPRESS_NONE
505 : expected_algorithm_from_server));
506 }
507
508 grpc_byte_buffer_destroy(request_payload);
509 grpc_byte_buffer_destroy(response_payload);
510 grpc_byte_buffer_destroy(request_payload_recv);
511 grpc_byte_buffer_destroy(response_payload_recv);
512 }
513 grpc_slice_unref(request_payload_slice);
514 grpc_slice_unref(response_payload_slice);
515
516 memset(ops, 0, sizeof(ops));
517 op = ops;
518 op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
519 op->flags = 0;
520 op->reserved = nullptr;
521 op++;
522 error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(4),
523 nullptr);
524 GPR_ASSERT(GRPC_CALL_OK == error);
525
526 memset(ops, 0, sizeof(ops));
527 op = ops;
528 op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
529 op->data.send_status_from_server.trailing_metadata_count = 0;
530 op->data.send_status_from_server.status = GRPC_STATUS_OK;
531 grpc_slice status_details = grpc_slice_from_static_string("xyz");
532 op->data.send_status_from_server.status_details = &status_details;
533 op->flags = 0;
534 op->reserved = nullptr;
535 op++;
536 error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(104),
537 nullptr);
538 GPR_ASSERT(GRPC_CALL_OK == error);
539
540 CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
541 CQ_EXPECT_COMPLETION(cqv, tag(4), 1);
542 CQ_EXPECT_COMPLETION(cqv, tag(101), 1);
543 CQ_EXPECT_COMPLETION(cqv, tag(104), 1);
544 cq_verify(cqv);
545
546 GPR_ASSERT(status == GRPC_STATUS_OK);
547 GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
548 GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
549 GPR_ASSERT(was_cancelled == 0);
550
551 grpc_slice_unref(details);
552 grpc_metadata_array_destroy(&initial_metadata_recv);
553 grpc_metadata_array_destroy(&trailing_metadata_recv);
554 grpc_metadata_array_destroy(&request_metadata_recv);
555 grpc_call_details_destroy(&call_details);
556
557 grpc_call_unref(c);
558 grpc_call_unref(s);
559
560 cq_verifier_destroy(cqv);
561 grpc_channel_args_destroy(client_args);
562 grpc_channel_args_destroy(server_args);
563 end_test(&f);
564 config.tear_down_data(&f);
565 }
566
request_with_payload_template(grpc_end2end_test_config config,const char * test_name,uint32_t client_send_flags_bitmask,grpc_compression_algorithm default_client_channel_compression_algorithm,grpc_compression_algorithm default_server_channel_compression_algorithm,grpc_compression_algorithm expected_algorithm_from_client,grpc_compression_algorithm expected_algorithm_from_server,grpc_metadata * client_init_metadata,bool set_server_level,grpc_compression_level server_compression_level,bool send_message_before_initial_metadata)567 static void request_with_payload_template(
568 grpc_end2end_test_config config, const char* test_name,
569 uint32_t client_send_flags_bitmask,
570 grpc_compression_algorithm default_client_channel_compression_algorithm,
571 grpc_compression_algorithm default_server_channel_compression_algorithm,
572 grpc_compression_algorithm expected_algorithm_from_client,
573 grpc_compression_algorithm expected_algorithm_from_server,
574 grpc_metadata* client_init_metadata, bool set_server_level,
575 grpc_compression_level server_compression_level,
576 bool send_message_before_initial_metadata) {
577 request_with_payload_template_inner(
578 config, test_name, client_send_flags_bitmask,
579 default_client_channel_compression_algorithm,
580 default_server_channel_compression_algorithm,
581 expected_algorithm_from_client, expected_algorithm_from_server,
582 client_init_metadata, set_server_level, server_compression_level,
583 send_message_before_initial_metadata, false);
584 request_with_payload_template_inner(
585 config, test_name, client_send_flags_bitmask,
586 default_client_channel_compression_algorithm,
587 default_server_channel_compression_algorithm,
588 expected_algorithm_from_client, expected_algorithm_from_server,
589 client_init_metadata, set_server_level, server_compression_level,
590 send_message_before_initial_metadata, true);
591 }
592
test_invoke_request_with_exceptionally_uncompressed_payload(grpc_end2end_test_config config)593 static void test_invoke_request_with_exceptionally_uncompressed_payload(
594 grpc_end2end_test_config config) {
595 request_with_payload_template(
596 config, "test_invoke_request_with_exceptionally_uncompressed_payload",
597 GRPC_WRITE_NO_COMPRESS, GRPC_COMPRESS_GZIP, GRPC_COMPRESS_GZIP,
598 GRPC_COMPRESS_NONE, GRPC_COMPRESS_GZIP, nullptr, false,
599 /* ignored */ GRPC_COMPRESS_LEVEL_NONE, false);
600 }
601
test_invoke_request_with_uncompressed_payload(grpc_end2end_test_config config)602 static void test_invoke_request_with_uncompressed_payload(
603 grpc_end2end_test_config config) {
604 request_with_payload_template(
605 config, "test_invoke_request_with_uncompressed_payload", 0,
606 GRPC_COMPRESS_NONE, GRPC_COMPRESS_NONE, GRPC_COMPRESS_NONE,
607 GRPC_COMPRESS_NONE, nullptr, false,
608 /* ignored */ GRPC_COMPRESS_LEVEL_NONE, false);
609 }
610
test_invoke_request_with_compressed_payload(grpc_end2end_test_config config)611 static void test_invoke_request_with_compressed_payload(
612 grpc_end2end_test_config config) {
613 request_with_payload_template(
614 config, "test_invoke_request_with_compressed_payload", 0,
615 GRPC_COMPRESS_GZIP, GRPC_COMPRESS_GZIP, GRPC_COMPRESS_GZIP,
616 GRPC_COMPRESS_GZIP, nullptr, false,
617 /* ignored */ GRPC_COMPRESS_LEVEL_NONE, false);
618 }
619
test_invoke_request_with_send_message_before_initial_metadata(grpc_end2end_test_config config)620 static void test_invoke_request_with_send_message_before_initial_metadata(
621 grpc_end2end_test_config config) {
622 request_with_payload_template(
623 config, "test_invoke_request_with_compressed_payload", 0,
624 GRPC_COMPRESS_GZIP, GRPC_COMPRESS_GZIP, GRPC_COMPRESS_GZIP,
625 GRPC_COMPRESS_GZIP, nullptr, false,
626 /* ignored */ GRPC_COMPRESS_LEVEL_NONE, true);
627 }
628
test_invoke_request_with_server_level(grpc_end2end_test_config config)629 static void test_invoke_request_with_server_level(
630 grpc_end2end_test_config config) {
631 request_with_payload_template(
632 config, "test_invoke_request_with_server_level", 0, GRPC_COMPRESS_NONE,
633 GRPC_COMPRESS_NONE, GRPC_COMPRESS_NONE, GRPC_COMPRESS_NONE /* ignored */,
634 nullptr, true, GRPC_COMPRESS_LEVEL_HIGH, false);
635 }
636
test_invoke_request_with_compressed_payload_md_override(grpc_end2end_test_config config)637 static void test_invoke_request_with_compressed_payload_md_override(
638 grpc_end2end_test_config config) {
639 grpc_metadata gzip_compression_override;
640 grpc_metadata identity_compression_override;
641
642 gzip_compression_override.key = GRPC_MDSTR_GRPC_INTERNAL_ENCODING_REQUEST;
643 gzip_compression_override.value = grpc_slice_from_static_string("gzip");
644 memset(&gzip_compression_override.internal_data, 0,
645 sizeof(gzip_compression_override.internal_data));
646
647 identity_compression_override.key = GRPC_MDSTR_GRPC_INTERNAL_ENCODING_REQUEST;
648 identity_compression_override.value =
649 grpc_slice_from_static_string("identity");
650 memset(&identity_compression_override.internal_data, 0,
651 sizeof(identity_compression_override.internal_data));
652
653 /* Channel default NONE (aka IDENTITY), call override to GZIP */
654 request_with_payload_template(
655 config, "test_invoke_request_with_compressed_payload_md_override_1", 0,
656 GRPC_COMPRESS_NONE, GRPC_COMPRESS_NONE, GRPC_COMPRESS_GZIP,
657 GRPC_COMPRESS_NONE, &gzip_compression_override, false,
658 /*ignored*/ GRPC_COMPRESS_LEVEL_NONE, false);
659
660 /* Channel default DEFLATE, call override to GZIP */
661 request_with_payload_template(
662 config, "test_invoke_request_with_compressed_payload_md_override_2", 0,
663 GRPC_COMPRESS_DEFLATE, GRPC_COMPRESS_NONE, GRPC_COMPRESS_GZIP,
664 GRPC_COMPRESS_NONE, &gzip_compression_override, false,
665 /*ignored*/ GRPC_COMPRESS_LEVEL_NONE, false);
666
667 /* Channel default DEFLATE, call override to NONE (aka IDENTITY) */
668 request_with_payload_template(
669 config, "test_invoke_request_with_compressed_payload_md_override_3", 0,
670 GRPC_COMPRESS_DEFLATE, GRPC_COMPRESS_NONE, GRPC_COMPRESS_NONE,
671 GRPC_COMPRESS_NONE, &identity_compression_override, false,
672 /*ignored*/ GRPC_COMPRESS_LEVEL_NONE, false);
673 }
674
test_invoke_request_with_disabled_algorithm(grpc_end2end_test_config config)675 static void test_invoke_request_with_disabled_algorithm(
676 grpc_end2end_test_config config) {
677 request_for_disabled_algorithm(config,
678 "test_invoke_request_with_disabled_algorithm",
679 0, GRPC_COMPRESS_GZIP, GRPC_COMPRESS_GZIP,
680 GRPC_STATUS_UNIMPLEMENTED, nullptr, false);
681 request_for_disabled_algorithm(config,
682 "test_invoke_request_with_disabled_algorithm",
683 0, GRPC_COMPRESS_GZIP, GRPC_COMPRESS_GZIP,
684 GRPC_STATUS_UNIMPLEMENTED, nullptr, true);
685 }
686
compressed_payload(grpc_end2end_test_config config)687 void compressed_payload(grpc_end2end_test_config config) {
688 test_invoke_request_with_exceptionally_uncompressed_payload(config);
689 test_invoke_request_with_uncompressed_payload(config);
690 test_invoke_request_with_compressed_payload(config);
691 test_invoke_request_with_send_message_before_initial_metadata(config);
692 test_invoke_request_with_server_level(config);
693 test_invoke_request_with_compressed_payload_md_override(config);
694 test_invoke_request_with_disabled_algorithm(config);
695 }
696
compressed_payload_pre_init(void)697 void compressed_payload_pre_init(void) {}
698