1 //
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 <grpc/grpc.h>
22
23 #include <map>
24 #include <memory>
25 #include <utility>
26
27 #include "absl/status/status.h"
28 #include "gtest/gtest.h"
29 #include "src/core/lib/channel/channel_stack.h"
30 #include "src/core/lib/channel/channel_stack_builder_impl.h"
31 #include "src/core/lib/iomgr/closure.h"
32 #include "src/core/lib/iomgr/error.h"
33 #include "src/core/lib/iomgr/exec_ctx.h"
34 #include "test/core/test_util/test_config.h"
35
36 namespace grpc_core {
37 namespace testing {
38 namespace {
39
ChannelInitFunc(grpc_channel_element *,grpc_channel_element_args *)40 grpc_error_handle ChannelInitFunc(grpc_channel_element* /*elem*/,
41 grpc_channel_element_args* /*args*/) {
42 return absl::OkStatus();
43 }
44
CallInitFunc(grpc_call_element *,const grpc_call_element_args *)45 grpc_error_handle CallInitFunc(grpc_call_element* /*elem*/,
46 const grpc_call_element_args* /*args*/) {
47 return absl::OkStatus();
48 }
49
ChannelDestroyFunc(grpc_channel_element *)50 void ChannelDestroyFunc(grpc_channel_element* /*elem*/) {}
51
CallDestroyFunc(grpc_call_element *,const grpc_call_final_info *,grpc_closure *)52 void CallDestroyFunc(grpc_call_element* /*elem*/,
53 const grpc_call_final_info* /*final_info*/,
54 grpc_closure* /*ignored*/) {}
55
FilterNamed(absl::string_view name)56 const grpc_channel_filter* FilterNamed(absl::string_view name) {
57 static auto* filters =
58 new std::map<absl::string_view, const grpc_channel_filter*>;
59 auto it = filters->find(name);
60 if (it != filters->end()) return it->second;
61 static auto* name_factories =
62 new std::vector<std::unique_ptr<UniqueTypeName::Factory>>();
63 name_factories->emplace_back(std::make_unique<UniqueTypeName::Factory>(name));
64 auto unique_type_name = name_factories->back()->Create();
65 return filters
66 ->emplace(
67 name,
68 new grpc_channel_filter{
69 grpc_call_next_op, grpc_channel_next_op, 0, CallInitFunc,
70 grpc_call_stack_ignore_set_pollset_or_pollset_set,
71 CallDestroyFunc, 0, ChannelInitFunc,
72 [](grpc_channel_stack*, grpc_channel_element*) {},
73 ChannelDestroyFunc, grpc_channel_next_get_info, unique_type_name})
74 .first->second;
75 }
76
TEST(ChannelStackBuilder,UnknownTarget)77 TEST(ChannelStackBuilder, UnknownTarget) {
78 ChannelStackBuilderImpl builder("alpha-beta-gamma", GRPC_CLIENT_CHANNEL,
79 ChannelArgs());
80 EXPECT_EQ(builder.target(), "unknown");
81 }
82
TEST(ChannelStackBuilder,CanPrepend)83 TEST(ChannelStackBuilder, CanPrepend) {
84 ExecCtx exec_ctx;
85 ChannelStackBuilderImpl builder("alpha-beta-gamma", GRPC_CLIENT_CHANNEL,
86 ChannelArgs());
87 builder.PrependFilter(FilterNamed("filter1"));
88 builder.PrependFilter(FilterNamed("filter2"));
89 auto stack = builder.Build();
90 EXPECT_TRUE(stack.ok());
91 EXPECT_EQ((*stack)->count, 2);
92 EXPECT_EQ(grpc_channel_stack_element(stack->get(), 0)->filter,
93 FilterNamed("filter2"));
94 EXPECT_EQ(grpc_channel_stack_element(stack->get(), 1)->filter,
95 FilterNamed("filter1"));
96 }
97
TEST(ChannelStackBuilder,CanAppend)98 TEST(ChannelStackBuilder, CanAppend) {
99 ExecCtx exec_ctx;
100 ChannelStackBuilderImpl builder("alpha-beta-gamma", GRPC_CLIENT_CHANNEL,
101 ChannelArgs());
102 builder.AppendFilter(FilterNamed("filter1"));
103 builder.AppendFilter(FilterNamed("filter2"));
104 auto stack = builder.Build();
105 EXPECT_TRUE(stack.ok());
106 EXPECT_EQ((*stack)->count, 2);
107 EXPECT_EQ(grpc_channel_stack_element(stack->get(), 0)->filter,
108 FilterNamed("filter1"));
109 EXPECT_EQ(grpc_channel_stack_element(stack->get(), 1)->filter,
110 FilterNamed("filter2"));
111 }
112
113 } // namespace
114 } // namespace testing
115 } // namespace grpc_core
116
main(int argc,char ** argv)117 int main(int argc, char** argv) {
118 ::testing::InitGoogleTest(&argc, argv);
119 grpc::testing::TestEnvironment env(&argc, argv);
120 grpc_init();
121 int ret = RUN_ALL_TESTS();
122 grpc_shutdown();
123 return ret;
124 }
125