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