blob: 1571f6ec0966b5393fa37fe8cf2555b2556ee1c7 [file] [log] [blame]
David Garcia Quintas243fe9d2017-08-24 14:16:37 -07001/*
2 *
3 * Copyright 2017 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 "src/core/lib/channel/channel_stack_builder.h"
20
21#include <limits.h>
22#include <string.h>
23
24#include <grpc/support/alloc.h>
25#include <grpc/support/log.h>
26#include <grpc/support/string_util.h>
27
28#include "src/core/lib/slice/slice_internal.h"
29#include "src/core/lib/surface/channel_init.h"
30#include "test/core/util/test_config.h"
31
Craig Tillerbaa14a92017-11-03 09:09:36 -070032static grpc_error* channel_init_func(grpc_exec_ctx* exec_ctx,
33 grpc_channel_element* elem,
34 grpc_channel_element_args* args) {
David Garcia Quintas243fe9d2017-08-24 14:16:37 -070035 return GRPC_ERROR_NONE;
36}
37
Craig Tillerbaa14a92017-11-03 09:09:36 -070038static grpc_error* call_init_func(grpc_exec_ctx* exec_ctx,
39 grpc_call_element* elem,
40 const grpc_call_element_args* args) {
David Garcia Quintas243fe9d2017-08-24 14:16:37 -070041 return GRPC_ERROR_NONE;
42}
43
Craig Tillerbaa14a92017-11-03 09:09:36 -070044static void channel_destroy_func(grpc_exec_ctx* exec_ctx,
45 grpc_channel_element* elem) {}
David Garcia Quintas243fe9d2017-08-24 14:16:37 -070046
Craig Tillerbaa14a92017-11-03 09:09:36 -070047static void call_destroy_func(grpc_exec_ctx* exec_ctx, grpc_call_element* elem,
48 const grpc_call_final_info* final_info,
49 grpc_closure* ignored) {}
David Garcia Quintas243fe9d2017-08-24 14:16:37 -070050
Craig Tillerbaa14a92017-11-03 09:09:36 -070051static void call_func(grpc_exec_ctx* exec_ctx, grpc_call_element* elem,
52 grpc_transport_stream_op_batch* op) {}
David Garcia Quintas243fe9d2017-08-24 14:16:37 -070053
Craig Tillerbaa14a92017-11-03 09:09:36 -070054static void channel_func(grpc_exec_ctx* exec_ctx, grpc_channel_element* elem,
55 grpc_transport_op* op) {
David Garcia Quintas243fe9d2017-08-24 14:16:37 -070056 if (op->disconnect_with_error != GRPC_ERROR_NONE) {
57 GRPC_ERROR_UNREF(op->disconnect_with_error);
58 }
59 GRPC_CLOSURE_SCHED(exec_ctx, op->on_consumed, GRPC_ERROR_NONE);
60}
61
David Garcia Quintas243fe9d2017-08-24 14:16:37 -070062bool g_replacement_fn_called = false;
63bool g_original_fn_called = false;
Craig Tillerbaa14a92017-11-03 09:09:36 -070064void set_arg_once_fn(grpc_channel_stack* channel_stack,
65 grpc_channel_element* elem, void* arg) {
Yash Tibrewal40422d52017-11-06 14:39:17 -080066 bool* called = static_cast<bool*>(arg);
David Garcia Quintas243fe9d2017-08-24 14:16:37 -070067 // Make sure this function is only called once per arg.
68 GPR_ASSERT(*called == false);
69 *called = true;
70}
71
72static void test_channel_stack_builder_filter_replace(void) {
Craig Tillerbaa14a92017-11-03 09:09:36 -070073 grpc_channel* channel =
David Garcia Quintas243fe9d2017-08-24 14:16:37 -070074 grpc_insecure_channel_create("target name isn't used", NULL, NULL);
75 GPR_ASSERT(channel != NULL);
76 // Make sure the high priority filter has been created.
77 GPR_ASSERT(g_replacement_fn_called);
78 // ... and that the low priority one hasn't.
79 GPR_ASSERT(!g_original_fn_called);
80 grpc_channel_destroy(channel);
81}
82
83const grpc_channel_filter replacement_filter = {
84 call_func,
85 channel_func,
86 0,
87 call_init_func,
88 grpc_call_stack_ignore_set_pollset_or_pollset_set,
89 call_destroy_func,
90 0,
91 channel_init_func,
92 channel_destroy_func,
David Garcia Quintas243fe9d2017-08-24 14:16:37 -070093 grpc_channel_next_get_info,
94 "filter_name"};
95
96const grpc_channel_filter original_filter = {
97 call_func,
98 channel_func,
99 0,
100 call_init_func,
101 grpc_call_stack_ignore_set_pollset_or_pollset_set,
102 call_destroy_func,
103 0,
104 channel_init_func,
105 channel_destroy_func,
David Garcia Quintas243fe9d2017-08-24 14:16:37 -0700106 grpc_channel_next_get_info,
107 "filter_name"};
108
Craig Tillerbaa14a92017-11-03 09:09:36 -0700109static bool add_replacement_filter(grpc_exec_ctx* exec_ctx,
110 grpc_channel_stack_builder* builder,
111 void* arg) {
Yash Tibrewal40422d52017-11-06 14:39:17 -0800112 const grpc_channel_filter* filter =
113 static_cast<const grpc_channel_filter*>(arg);
David Garcia Quintas243fe9d2017-08-24 14:16:37 -0700114 // Get rid of any other version of the filter, as determined by having the
115 // same name.
116 GPR_ASSERT(grpc_channel_stack_builder_remove_filter(builder, filter->name));
117 return grpc_channel_stack_builder_prepend_filter(
118 builder, filter, set_arg_once_fn, &g_replacement_fn_called);
119}
120
Craig Tillerbaa14a92017-11-03 09:09:36 -0700121static bool add_original_filter(grpc_exec_ctx* exec_ctx,
122 grpc_channel_stack_builder* builder,
123 void* arg) {
David Garcia Quintas243fe9d2017-08-24 14:16:37 -0700124 return grpc_channel_stack_builder_prepend_filter(
Craig Tillerbaa14a92017-11-03 09:09:36 -0700125 builder, (const grpc_channel_filter*)arg, set_arg_once_fn,
David Garcia Quintas243fe9d2017-08-24 14:16:37 -0700126 &g_original_fn_called);
127}
128
129static void init_plugin(void) {
130 grpc_channel_init_register_stage(GRPC_CLIENT_CHANNEL, INT_MAX,
131 add_original_filter,
Craig Tillerbaa14a92017-11-03 09:09:36 -0700132 (void*)&original_filter);
David Garcia Quintas243fe9d2017-08-24 14:16:37 -0700133 grpc_channel_init_register_stage(GRPC_CLIENT_CHANNEL, INT_MAX,
134 add_replacement_filter,
Craig Tillerbaa14a92017-11-03 09:09:36 -0700135 (void*)&replacement_filter);
David Garcia Quintas243fe9d2017-08-24 14:16:37 -0700136}
137
138static void destroy_plugin(void) {}
139
Craig Tillerbaa14a92017-11-03 09:09:36 -0700140int main(int argc, char** argv) {
David Garcia Quintas243fe9d2017-08-24 14:16:37 -0700141 grpc_test_init(argc, argv);
142 grpc_register_plugin(init_plugin, destroy_plugin);
143 grpc_init();
144 test_channel_stack_builder_filter_replace();
145 grpc_shutdown();
146 return 0;
147}