Imported Upstream version 1.41.0
[platform/upstream/grpc.git] / test / core / end2end / tests / filter_init_fails.cc
1 /*
2  *
3  * Copyright 2016 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 <limits.h>
20 #include <stdbool.h>
21 #include <stdio.h>
22 #include <string.h>
23
24 #include <grpc/byte_buffer.h>
25 #include <grpc/support/alloc.h>
26 #include <grpc/support/log.h>
27 #include <grpc/support/time.h>
28
29 #include "src/core/lib/channel/channel_stack_builder.h"
30 #include "src/core/lib/surface/channel_init.h"
31 #include "test/core/end2end/cq_verifier.h"
32 #include "test/core/end2end/end2end_tests.h"
33
34 enum { TIMEOUT = 200000 };
35
36 static bool g_enable_server_channel_filter = false;
37 static bool g_enable_client_channel_filter = false;
38 static bool g_enable_client_subchannel_filter = false;
39 static bool g_channel_filter_init_failure = false;
40
41 static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
42
43 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
44                                             const char* test_name,
45                                             grpc_channel_args* client_args,
46                                             grpc_channel_args* server_args) {
47   grpc_end2end_test_fixture f;
48   gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name);
49   f = config.create_fixture(client_args, server_args);
50   config.init_server(&f, server_args);
51   config.init_client(&f, client_args);
52   return f;
53 }
54
55 static gpr_timespec n_seconds_from_now(int n) {
56   return grpc_timeout_seconds_to_deadline(n);
57 }
58
59 static gpr_timespec five_seconds_from_now(void) {
60   return n_seconds_from_now(5);
61 }
62
63 static void drain_cq(grpc_completion_queue* cq) {
64   grpc_event ev;
65   do {
66     ev = grpc_completion_queue_next(cq, five_seconds_from_now(), nullptr);
67   } while (ev.type != GRPC_QUEUE_SHUTDOWN);
68 }
69
70 static void shutdown_server(grpc_end2end_test_fixture* f) {
71   if (!f->server) return;
72   grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
73   GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
74                                          grpc_timeout_seconds_to_deadline(5),
75                                          nullptr)
76                  .type == GRPC_OP_COMPLETE);
77   grpc_server_destroy(f->server);
78   f->server = nullptr;
79 }
80
81 static void shutdown_client(grpc_end2end_test_fixture* f) {
82   if (!f->client) return;
83   grpc_channel_destroy(f->client);
84   f->client = nullptr;
85 }
86
87 static void end_test(grpc_end2end_test_fixture* f) {
88   shutdown_server(f);
89   shutdown_client(f);
90
91   grpc_completion_queue_shutdown(f->cq);
92   drain_cq(f->cq);
93   grpc_completion_queue_destroy(f->cq);
94   grpc_completion_queue_destroy(f->shutdown_cq);
95 }
96
97 // Simple request via a SERVER_CHANNEL filter that always fails to
98 // initialize the call.
99 static void test_server_channel_filter(grpc_end2end_test_config config) {
100   grpc_call* c;
101   grpc_call* s;
102   grpc_slice request_payload_slice =
103       grpc_slice_from_copied_string("hello world");
104   grpc_byte_buffer* request_payload =
105       grpc_raw_byte_buffer_create(&request_payload_slice, 1);
106   grpc_end2end_test_fixture f =
107       begin_test(config, "filter_init_fails", nullptr, nullptr);
108   cq_verifier* cqv = cq_verifier_create(f.cq);
109   grpc_op ops[6];
110   grpc_op* op;
111   grpc_metadata_array initial_metadata_recv;
112   grpc_metadata_array trailing_metadata_recv;
113   grpc_metadata_array request_metadata_recv;
114   grpc_byte_buffer* request_payload_recv = nullptr;
115   grpc_call_details call_details;
116   grpc_status_code status;
117   grpc_call_error error;
118   grpc_slice details;
119
120   gpr_timespec deadline = five_seconds_from_now();
121   c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
122                                grpc_slice_from_static_string("/foo"), nullptr,
123                                deadline, nullptr);
124   GPR_ASSERT(c);
125
126   grpc_metadata_array_init(&initial_metadata_recv);
127   grpc_metadata_array_init(&trailing_metadata_recv);
128   grpc_metadata_array_init(&request_metadata_recv);
129   grpc_call_details_init(&call_details);
130
131   memset(ops, 0, sizeof(ops));
132   op = ops;
133   op->op = GRPC_OP_SEND_INITIAL_METADATA;
134   op->data.send_initial_metadata.count = 0;
135   op->data.send_initial_metadata.metadata = nullptr;
136   op->flags = 0;
137   op->reserved = nullptr;
138   op++;
139   op->op = GRPC_OP_SEND_MESSAGE;
140   op->data.send_message.send_message = request_payload;
141   op->flags = 0;
142   op->reserved = nullptr;
143   op++;
144   op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
145   op->flags = 0;
146   op->reserved = nullptr;
147   op++;
148   op->op = GRPC_OP_RECV_INITIAL_METADATA;
149   op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
150   op->flags = 0;
151   op->reserved = nullptr;
152   op++;
153   op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
154   op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
155   op->data.recv_status_on_client.status = &status;
156   op->data.recv_status_on_client.status_details = &details;
157   op->flags = 0;
158   op->reserved = nullptr;
159   op++;
160   error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1),
161                                 nullptr);
162   GPR_ASSERT(GRPC_CALL_OK == error);
163
164   error =
165       grpc_server_request_call(f.server, &s, &call_details,
166                                &request_metadata_recv, f.cq, f.cq, tag(101));
167   GPR_ASSERT(GRPC_CALL_OK == error);
168
169   CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
170   cq_verify(cqv);
171
172   if (g_channel_filter_init_failure) {
173     // Inproc channel returns invalid_argument and other clients return
174     // unavailable.
175     // Windows with sockpair returns unknown.
176     GPR_ASSERT(status == GRPC_STATUS_UNKNOWN ||
177                status == GRPC_STATUS_UNAVAILABLE ||
178                status == GRPC_STATUS_INVALID_ARGUMENT);
179   } else {
180     GPR_ASSERT(status == GRPC_STATUS_PERMISSION_DENIED);
181     GPR_ASSERT(0 == grpc_slice_str_cmp(details, "access denied"));
182   }
183
184   grpc_slice_unref(details);
185   grpc_metadata_array_destroy(&initial_metadata_recv);
186   grpc_metadata_array_destroy(&trailing_metadata_recv);
187   grpc_metadata_array_destroy(&request_metadata_recv);
188   grpc_call_details_destroy(&call_details);
189
190   grpc_call_unref(c);
191
192   cq_verifier_destroy(cqv);
193
194   grpc_byte_buffer_destroy(request_payload);
195   grpc_byte_buffer_destroy(request_payload_recv);
196
197   end_test(&f);
198   config.tear_down_data(&f);
199 }
200
201 // Simple request via a CLIENT_CHANNEL or CLIENT_DIRECT_CHANNEL filter
202 // that always fails to initialize the call.
203 static void test_client_channel_filter(grpc_end2end_test_config config) {
204   grpc_call* c;
205   grpc_slice request_payload_slice =
206       grpc_slice_from_copied_string("hello world");
207   grpc_byte_buffer* request_payload =
208       grpc_raw_byte_buffer_create(&request_payload_slice, 1);
209   gpr_timespec deadline = five_seconds_from_now();
210   grpc_end2end_test_fixture f =
211       begin_test(config, "filter_init_fails", nullptr, nullptr);
212   cq_verifier* cqv = cq_verifier_create(f.cq);
213   grpc_op ops[6];
214   grpc_op* op;
215   grpc_metadata_array initial_metadata_recv;
216   grpc_metadata_array trailing_metadata_recv;
217   grpc_metadata_array request_metadata_recv;
218   grpc_byte_buffer* request_payload_recv = nullptr;
219   grpc_call_details call_details;
220   grpc_status_code status;
221   grpc_call_error error;
222   grpc_slice details;
223
224   c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
225                                grpc_slice_from_static_string("/foo"), nullptr,
226                                deadline, nullptr);
227   GPR_ASSERT(c);
228
229   grpc_metadata_array_init(&initial_metadata_recv);
230   grpc_metadata_array_init(&trailing_metadata_recv);
231   grpc_metadata_array_init(&request_metadata_recv);
232   grpc_call_details_init(&call_details);
233
234   memset(ops, 0, sizeof(ops));
235   op = ops;
236   op->op = GRPC_OP_SEND_INITIAL_METADATA;
237   op->data.send_initial_metadata.count = 0;
238   op->data.send_initial_metadata.metadata = nullptr;
239   op->flags = 0;
240   op->reserved = nullptr;
241   op++;
242   op->op = GRPC_OP_SEND_MESSAGE;
243   op->data.send_message.send_message = request_payload;
244   op->flags = 0;
245   op->reserved = nullptr;
246   op++;
247   op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
248   op->flags = 0;
249   op->reserved = nullptr;
250   op++;
251   op->op = GRPC_OP_RECV_INITIAL_METADATA;
252   op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
253   op->flags = 0;
254   op->reserved = nullptr;
255   op++;
256   op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
257   op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
258   op->data.recv_status_on_client.status = &status;
259   op->data.recv_status_on_client.status_details = &details;
260   op->flags = 0;
261   op->reserved = nullptr;
262   op++;
263   error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1),
264                                 nullptr);
265   GPR_ASSERT(GRPC_CALL_OK == error);
266
267   CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
268   cq_verify(cqv);
269
270   if (g_channel_filter_init_failure) {
271     GPR_ASSERT(status == GRPC_STATUS_INVALID_ARGUMENT);
272   } else {
273     GPR_ASSERT(status == GRPC_STATUS_PERMISSION_DENIED);
274     GPR_ASSERT(0 == grpc_slice_str_cmp(details, "access denied"));
275   }
276
277   grpc_slice_unref(details);
278   grpc_metadata_array_destroy(&initial_metadata_recv);
279   grpc_metadata_array_destroy(&trailing_metadata_recv);
280   grpc_metadata_array_destroy(&request_metadata_recv);
281   grpc_call_details_destroy(&call_details);
282
283   grpc_call_unref(c);
284
285   cq_verifier_destroy(cqv);
286
287   grpc_byte_buffer_destroy(request_payload);
288   grpc_byte_buffer_destroy(request_payload_recv);
289
290   end_test(&f);
291   config.tear_down_data(&f);
292 }
293
294 // Simple request via a CLIENT_SUBCHANNEL filter that always fails to
295 // initialize the call.
296 static void test_client_subchannel_filter(grpc_end2end_test_config config) {
297   grpc_call* c;
298   grpc_slice request_payload_slice =
299       grpc_slice_from_copied_string("hello world");
300   grpc_byte_buffer* request_payload =
301       grpc_raw_byte_buffer_create(&request_payload_slice, 1);
302   gpr_timespec deadline = five_seconds_from_now();
303   grpc_end2end_test_fixture f =
304       begin_test(config, "filter_init_fails", nullptr, nullptr);
305   cq_verifier* cqv = cq_verifier_create(f.cq);
306   grpc_op ops[6];
307   grpc_op* op;
308   grpc_metadata_array initial_metadata_recv;
309   grpc_metadata_array trailing_metadata_recv;
310   grpc_metadata_array request_metadata_recv;
311   grpc_byte_buffer* request_payload_recv = nullptr;
312   grpc_call_details call_details;
313   grpc_status_code status;
314   grpc_call_error error;
315   grpc_slice details;
316
317   c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
318                                grpc_slice_from_static_string("/foo"), nullptr,
319                                deadline, nullptr);
320   GPR_ASSERT(c);
321
322   grpc_metadata_array_init(&initial_metadata_recv);
323   grpc_metadata_array_init(&trailing_metadata_recv);
324   grpc_metadata_array_init(&request_metadata_recv);
325   grpc_call_details_init(&call_details);
326
327   memset(ops, 0, sizeof(ops));
328   op = ops;
329   op->op = GRPC_OP_SEND_INITIAL_METADATA;
330   op->data.send_initial_metadata.count = 0;
331   op->data.send_initial_metadata.metadata = nullptr;
332   op->flags = 0;
333   op->reserved = nullptr;
334   op++;
335   op->op = GRPC_OP_SEND_MESSAGE;
336   op->data.send_message.send_message = request_payload;
337   op->flags = 0;
338   op->reserved = nullptr;
339   op++;
340   op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
341   op->flags = 0;
342   op->reserved = nullptr;
343   op++;
344   op->op = GRPC_OP_RECV_INITIAL_METADATA;
345   op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
346   op->flags = 0;
347   op->reserved = nullptr;
348   op++;
349   op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
350   op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
351   op->data.recv_status_on_client.status = &status;
352   op->data.recv_status_on_client.status_details = &details;
353   op->flags = 0;
354   op->reserved = nullptr;
355   op++;
356
357   error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1),
358                                 nullptr);
359   GPR_ASSERT(GRPC_CALL_OK == error);
360
361   CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
362   cq_verify(cqv);
363
364   if (g_channel_filter_init_failure) {
365     GPR_ASSERT(status == GRPC_STATUS_UNAVAILABLE);
366   } else {
367     GPR_ASSERT(status == GRPC_STATUS_PERMISSION_DENIED);
368     GPR_ASSERT(0 == grpc_slice_str_cmp(details, "access denied"));
369   }
370
371   // Reset and create a new call.  (The first call uses a different code
372   // path in client_channel.c than subsequent calls on the same channel,
373   // and we need to test both.)
374   grpc_call_unref(c);
375   status = GRPC_STATUS_OK;
376   grpc_slice_unref(details);
377   details = grpc_empty_slice();
378
379   c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
380                                grpc_slice_from_static_string("/foo"), nullptr,
381                                deadline, nullptr);
382   GPR_ASSERT(c);
383
384   error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(2),
385                                 nullptr);
386   GPR_ASSERT(GRPC_CALL_OK == error);
387
388   CQ_EXPECT_COMPLETION(cqv, tag(2), 1);
389   cq_verify(cqv);
390
391   if (g_channel_filter_init_failure) {
392     GPR_ASSERT(status == GRPC_STATUS_UNAVAILABLE);
393   } else {
394     GPR_ASSERT(status == GRPC_STATUS_PERMISSION_DENIED);
395     GPR_ASSERT(0 == grpc_slice_str_cmp(details, "access denied"));
396   }
397
398   grpc_slice_unref(details);
399   grpc_metadata_array_destroy(&initial_metadata_recv);
400   grpc_metadata_array_destroy(&trailing_metadata_recv);
401   grpc_metadata_array_destroy(&request_metadata_recv);
402   grpc_call_details_destroy(&call_details);
403
404   grpc_call_unref(c);
405
406   cq_verifier_destroy(cqv);
407
408   grpc_byte_buffer_destroy(request_payload);
409   grpc_byte_buffer_destroy(request_payload_recv);
410
411   end_test(&f);
412   config.tear_down_data(&f);
413 }
414
415 /*******************************************************************************
416  * Test filter - always fails to initialize a call
417  */
418
419 static grpc_error_handle init_call_elem(
420     grpc_call_element* /*elem*/, const grpc_call_element_args* /*args*/) {
421   return grpc_error_set_int(
422       GRPC_ERROR_CREATE_FROM_STATIC_STRING("access denied"),
423       GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_PERMISSION_DENIED);
424 }
425
426 static void destroy_call_elem(grpc_call_element* /*elem*/,
427                               const grpc_call_final_info* /*final_info*/,
428                               grpc_closure* /*ignored*/) {}
429
430 static grpc_error_handle init_channel_elem(
431     grpc_channel_element* /*elem*/, grpc_channel_element_args* /*args*/) {
432   if (g_channel_filter_init_failure) {
433     return grpc_error_set_int(
434         GRPC_ERROR_CREATE_FROM_STATIC_STRING("Test channel filter init error"),
435         GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_INVALID_ARGUMENT);
436   }
437   return GRPC_ERROR_NONE;
438 }
439
440 static void destroy_channel_elem(grpc_channel_element* /*elem*/) {}
441
442 static const grpc_channel_filter test_filter = {
443     grpc_call_next_op,
444     grpc_channel_next_op,
445     0,
446     init_call_elem,
447     grpc_call_stack_ignore_set_pollset_or_pollset_set,
448     destroy_call_elem,
449     0,
450     init_channel_elem,
451     destroy_channel_elem,
452     grpc_channel_next_get_info,
453     "filter_init_fails"};
454
455 /*******************************************************************************
456  * Registration
457  */
458
459 static bool maybe_add_server_channel_filter(grpc_channel_stack_builder* builder,
460                                             void* /*arg*/) {
461   if (g_enable_server_channel_filter) {
462     // Want to add the filter as close to the end as possible, to make
463     // sure that all of the filters work well together.  However, we
464     // can't add it at the very end, because the connected channel filter
465     // must be the last one.  So we add it right before the last one.
466     grpc_channel_stack_builder_iterator* it =
467         grpc_channel_stack_builder_create_iterator_at_last(builder);
468     GPR_ASSERT(grpc_channel_stack_builder_move_prev(it));
469     const bool retval = grpc_channel_stack_builder_add_filter_before(
470         it, &test_filter, nullptr, nullptr);
471     grpc_channel_stack_builder_iterator_destroy(it);
472     return retval;
473   } else {
474     return true;
475   }
476 }
477
478 static bool maybe_add_client_channel_filter(grpc_channel_stack_builder* builder,
479                                             void* /*arg*/) {
480   if (g_enable_client_channel_filter) {
481     // Want to add the filter as close to the end as possible, to make
482     // sure that all of the filters work well together.  However, we
483     // can't add it at the very end, because the connected channel filter
484     // must be the last one.  So we add it right before the last one.
485     grpc_channel_stack_builder_iterator* it =
486         grpc_channel_stack_builder_create_iterator_at_last(builder);
487     GPR_ASSERT(grpc_channel_stack_builder_move_prev(it));
488     const bool retval = grpc_channel_stack_builder_add_filter_before(
489         it, &test_filter, nullptr, nullptr);
490     grpc_channel_stack_builder_iterator_destroy(it);
491     return retval;
492   } else {
493     return true;
494   }
495 }
496
497 static bool maybe_add_client_subchannel_filter(
498     grpc_channel_stack_builder* builder, void* /*arg*/) {
499   if (g_enable_client_subchannel_filter) {
500     // Want to add the filter as close to the end as possible, to make
501     // sure that all of the filters work well together.  However, we
502     // can't add it at the very end, because the client channel filter
503     // must be the last one.  So we add it right before the last one.
504     grpc_channel_stack_builder_iterator* it =
505         grpc_channel_stack_builder_create_iterator_at_last(builder);
506     GPR_ASSERT(grpc_channel_stack_builder_move_prev(it));
507     const bool retval = grpc_channel_stack_builder_add_filter_before(
508         it, &test_filter, nullptr, nullptr);
509     grpc_channel_stack_builder_iterator_destroy(it);
510     return retval;
511   } else {
512     return true;
513   }
514 }
515
516 static void init_plugin(void) {
517   grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, INT_MAX,
518                                    maybe_add_server_channel_filter, nullptr);
519   grpc_channel_init_register_stage(GRPC_CLIENT_CHANNEL, INT_MAX,
520                                    maybe_add_client_channel_filter, nullptr);
521   grpc_channel_init_register_stage(GRPC_CLIENT_SUBCHANNEL, INT_MAX,
522                                    maybe_add_client_subchannel_filter, nullptr);
523   grpc_channel_init_register_stage(GRPC_CLIENT_DIRECT_CHANNEL, INT_MAX,
524                                    maybe_add_client_channel_filter, nullptr);
525 }
526
527 static void destroy_plugin(void) {}
528
529 static void filter_init_fails_internal(grpc_end2end_test_config config) {
530   gpr_log(GPR_INFO, "Testing SERVER_CHANNEL filter.");
531   g_enable_server_channel_filter = true;
532   test_server_channel_filter(config);
533   g_enable_server_channel_filter = false;
534   gpr_log(GPR_INFO, "Testing CLIENT_CHANNEL / CLIENT_DIRECT_CHANNEL filter.");
535   g_enable_client_channel_filter = true;
536   test_client_channel_filter(config);
537   g_enable_client_channel_filter = false;
538   // If the client handshake completes before the server handshake and the
539   // client is able to send application data before the server handshake
540   // completes, then testing the CLIENT_SUBCHANNEL filter will cause the server
541   // to freeze waiting for the final handshake message from the client. This
542   // handshake message will never arrive because it would have been sent with
543   // the first application data message, which failed because of the filter.
544   if ((config.feature_mask & FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL) &&
545       !(config.feature_mask &
546         FEATURE_MASK_DOES_NOT_SUPPORT_CLIENT_HANDSHAKE_COMPLETE_FIRST)) {
547     gpr_log(GPR_INFO, "Testing CLIENT_SUBCHANNEL filter.");
548     g_enable_client_subchannel_filter = true;
549     test_client_subchannel_filter(config);
550     g_enable_client_subchannel_filter = false;
551   }
552 }
553
554 void filter_init_fails(grpc_end2end_test_config config) {
555   filter_init_fails_internal(config);
556   gpr_log(GPR_INFO, "Testing with channel filter init error");
557   g_channel_filter_init_failure = true;
558   filter_init_fails_internal(config);
559   g_channel_filter_init_failure = false;
560 }
561
562 void filter_init_fails_pre_init(void) {
563   grpc_register_plugin(init_plugin, destroy_plugin);
564 }