3 * Copyright 2016 gRPC authors.
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
24 #include <grpc/byte_buffer.h>
25 #include <grpc/support/alloc.h>
26 #include <grpc/support/log.h>
27 #include <grpc/support/time.h>
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"
34 enum { TIMEOUT = 200000 };
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;
41 static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
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);
55 static gpr_timespec n_seconds_from_now(int n) {
56 return grpc_timeout_seconds_to_deadline(n);
59 static gpr_timespec five_seconds_from_now(void) {
60 return n_seconds_from_now(5);
63 static void drain_cq(grpc_completion_queue* cq) {
66 ev = grpc_completion_queue_next(cq, five_seconds_from_now(), nullptr);
67 } while (ev.type != GRPC_QUEUE_SHUTDOWN);
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),
76 .type == GRPC_OP_COMPLETE);
77 grpc_server_destroy(f->server);
81 static void shutdown_client(grpc_end2end_test_fixture* f) {
82 if (!f->client) return;
83 grpc_channel_destroy(f->client);
87 static void end_test(grpc_end2end_test_fixture* f) {
91 grpc_completion_queue_shutdown(f->cq);
93 grpc_completion_queue_destroy(f->cq);
94 grpc_completion_queue_destroy(f->shutdown_cq);
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) {
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);
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;
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,
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);
131 memset(ops, 0, sizeof(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;
137 op->reserved = nullptr;
139 op->op = GRPC_OP_SEND_MESSAGE;
140 op->data.send_message.send_message = request_payload;
142 op->reserved = nullptr;
144 op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
146 op->reserved = nullptr;
148 op->op = GRPC_OP_RECV_INITIAL_METADATA;
149 op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
151 op->reserved = nullptr;
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;
158 op->reserved = nullptr;
160 error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1),
162 GPR_ASSERT(GRPC_CALL_OK == 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);
169 CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
172 if (g_channel_filter_init_failure) {
173 // Inproc channel returns invalid_argument and other clients return
175 // Windows with sockpair returns unknown.
176 GPR_ASSERT(status == GRPC_STATUS_UNKNOWN ||
177 status == GRPC_STATUS_UNAVAILABLE ||
178 status == GRPC_STATUS_INVALID_ARGUMENT);
180 GPR_ASSERT(status == GRPC_STATUS_PERMISSION_DENIED);
181 GPR_ASSERT(0 == grpc_slice_str_cmp(details, "access denied"));
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);
192 cq_verifier_destroy(cqv);
194 grpc_byte_buffer_destroy(request_payload);
195 grpc_byte_buffer_destroy(request_payload_recv);
198 config.tear_down_data(&f);
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) {
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);
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;
224 c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
225 grpc_slice_from_static_string("/foo"), nullptr,
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);
234 memset(ops, 0, sizeof(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;
240 op->reserved = nullptr;
242 op->op = GRPC_OP_SEND_MESSAGE;
243 op->data.send_message.send_message = request_payload;
245 op->reserved = nullptr;
247 op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
249 op->reserved = nullptr;
251 op->op = GRPC_OP_RECV_INITIAL_METADATA;
252 op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
254 op->reserved = nullptr;
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;
261 op->reserved = nullptr;
263 error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1),
265 GPR_ASSERT(GRPC_CALL_OK == error);
267 CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
270 if (g_channel_filter_init_failure) {
271 GPR_ASSERT(status == GRPC_STATUS_INVALID_ARGUMENT);
273 GPR_ASSERT(status == GRPC_STATUS_PERMISSION_DENIED);
274 GPR_ASSERT(0 == grpc_slice_str_cmp(details, "access denied"));
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);
285 cq_verifier_destroy(cqv);
287 grpc_byte_buffer_destroy(request_payload);
288 grpc_byte_buffer_destroy(request_payload_recv);
291 config.tear_down_data(&f);
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) {
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);
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;
317 c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
318 grpc_slice_from_static_string("/foo"), nullptr,
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);
327 memset(ops, 0, sizeof(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;
333 op->reserved = nullptr;
335 op->op = GRPC_OP_SEND_MESSAGE;
336 op->data.send_message.send_message = request_payload;
338 op->reserved = nullptr;
340 op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
342 op->reserved = nullptr;
344 op->op = GRPC_OP_RECV_INITIAL_METADATA;
345 op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
347 op->reserved = nullptr;
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;
354 op->reserved = nullptr;
357 error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1),
359 GPR_ASSERT(GRPC_CALL_OK == error);
361 CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
364 if (g_channel_filter_init_failure) {
365 GPR_ASSERT(status == GRPC_STATUS_UNAVAILABLE);
367 GPR_ASSERT(status == GRPC_STATUS_PERMISSION_DENIED);
368 GPR_ASSERT(0 == grpc_slice_str_cmp(details, "access denied"));
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.)
375 status = GRPC_STATUS_OK;
376 grpc_slice_unref(details);
377 details = grpc_empty_slice();
379 c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
380 grpc_slice_from_static_string("/foo"), nullptr,
384 error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(2),
386 GPR_ASSERT(GRPC_CALL_OK == error);
388 CQ_EXPECT_COMPLETION(cqv, tag(2), 1);
391 if (g_channel_filter_init_failure) {
392 GPR_ASSERT(status == GRPC_STATUS_UNAVAILABLE);
394 GPR_ASSERT(status == GRPC_STATUS_PERMISSION_DENIED);
395 GPR_ASSERT(0 == grpc_slice_str_cmp(details, "access denied"));
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);
406 cq_verifier_destroy(cqv);
408 grpc_byte_buffer_destroy(request_payload);
409 grpc_byte_buffer_destroy(request_payload_recv);
412 config.tear_down_data(&f);
415 /*******************************************************************************
416 * Test filter - always fails to initialize a call
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);
426 static void destroy_call_elem(grpc_call_element* /*elem*/,
427 const grpc_call_final_info* /*final_info*/,
428 grpc_closure* /*ignored*/) {}
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);
437 return GRPC_ERROR_NONE;
440 static void destroy_channel_elem(grpc_channel_element* /*elem*/) {}
442 static const grpc_channel_filter test_filter = {
444 grpc_channel_next_op,
447 grpc_call_stack_ignore_set_pollset_or_pollset_set,
451 destroy_channel_elem,
452 grpc_channel_next_get_info,
453 "filter_init_fails"};
455 /*******************************************************************************
459 static bool maybe_add_server_channel_filter(grpc_channel_stack_builder* builder,
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);
478 static bool maybe_add_client_channel_filter(grpc_channel_stack_builder* builder,
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);
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);
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);
527 static void destroy_plugin(void) {}
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;
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;
562 void filter_init_fails_pre_init(void) {
563 grpc_register_plugin(init_plugin, destroy_plugin);