1 //
2 // Copyright 2022 gRPC authors.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 #include <grpc/grpc.h>
18
19 #include <memory>
20
21 #include "absl/status/status.h"
22 #include "absl/status/statusor.h"
23 #include "gtest/gtest.h"
24 #include "src/core/client_channel/client_channel_service_config.h"
25 #include "src/core/lib/channel/channel_args.h"
26 #include "src/core/load_balancing/xds/xds_override_host.h"
27 #include "src/core/service_config/service_config.h"
28 #include "src/core/service_config/service_config_impl.h"
29 #include "src/core/util/ref_counted_ptr.h"
30 #include "src/core/xds/grpc/xds_health_status.h"
31 #include "test/core/test_util/test_config.h"
32
33 namespace grpc_core {
34 namespace testing {
35 namespace {
36
37 using internal::ClientChannelGlobalParsedConfig;
38 using internal::ClientChannelServiceConfigParser;
39
TEST(XdsOverrideHostConfigParsingTest,ValidConfig)40 TEST(XdsOverrideHostConfigParsingTest, ValidConfig) {
41 const char* service_config_json =
42 "{\n"
43 " \"loadBalancingConfig\":[{\n"
44 " \"xds_override_host_experimental\":{\n"
45 " \"clusterName\": \"foo\",\n"
46 " \"childPolicy\":[\n"
47 " {\"grpclb\":{}}\n"
48 " ]\n"
49 " }\n"
50 " }]\n"
51 "}\n";
52 auto service_config =
53 ServiceConfigImpl::Create(ChannelArgs(), service_config_json);
54 ASSERT_TRUE(service_config.ok()) << service_config.status();
55 EXPECT_NE(*service_config, nullptr);
56 auto global_config = static_cast<ClientChannelGlobalParsedConfig*>(
57 (*service_config)
58 ->GetGlobalParsedConfig(
59 ClientChannelServiceConfigParser::ParserIndex()));
60 ASSERT_NE(global_config, nullptr);
61 auto lb_config = global_config->parsed_lb_config();
62 ASSERT_NE(lb_config, nullptr);
63 ASSERT_EQ(lb_config->name(), XdsOverrideHostLbConfig::Name());
64 auto* override_host_lb_config =
65 static_cast<XdsOverrideHostLbConfig*>(lb_config.get());
66 EXPECT_EQ(override_host_lb_config->cluster_name(), "foo");
67 ASSERT_NE(override_host_lb_config->child_config(), nullptr);
68 EXPECT_EQ(override_host_lb_config->child_config()->name(), "grpclb");
69 }
70
TEST(XdsOverrideHostConfigParsingTest,ValidConfigWithRR)71 TEST(XdsOverrideHostConfigParsingTest, ValidConfigWithRR) {
72 const char* service_config_json =
73 "{\n"
74 " \"loadBalancingConfig\":[{\n"
75 " \"xds_override_host_experimental\":{\n"
76 " \"clusterName\": \"foo\",\n"
77 " \"childPolicy\":[\n"
78 " {\"round_robin\":{}}\n"
79 " ]\n"
80 " }\n"
81 " }]\n"
82 "}\n";
83 auto service_config =
84 ServiceConfigImpl::Create(ChannelArgs(), service_config_json);
85 ASSERT_TRUE(service_config.ok());
86 EXPECT_NE(*service_config, nullptr);
87 auto global_config = static_cast<ClientChannelGlobalParsedConfig*>(
88 (*service_config)
89 ->GetGlobalParsedConfig(
90 ClientChannelServiceConfigParser::ParserIndex()));
91 ASSERT_NE(global_config, nullptr);
92 auto lb_config = global_config->parsed_lb_config();
93 ASSERT_NE(lb_config, nullptr);
94 ASSERT_EQ(lb_config->name(), XdsOverrideHostLbConfig::Name());
95 auto* override_host_lb_config =
96 static_cast<XdsOverrideHostLbConfig*>(lb_config.get());
97 EXPECT_EQ(override_host_lb_config->cluster_name(), "foo");
98 ASSERT_NE(override_host_lb_config->child_config(), nullptr);
99 EXPECT_EQ(override_host_lb_config->child_config()->name(), "round_robin");
100 }
101
TEST(XdsOverrideHostConfigParsingTest,MissingClusterName)102 TEST(XdsOverrideHostConfigParsingTest, MissingClusterName) {
103 const char* service_config_json =
104 "{\n"
105 " \"loadBalancingConfig\":[{\n"
106 " \"xds_override_host_experimental\":{\n"
107 " \"childPolicy\":[\n"
108 " {\"round_robin\":{}}\n"
109 " ]\n"
110 " }\n"
111 " }]\n"
112 "}\n";
113 auto service_config =
114 ServiceConfigImpl::Create(ChannelArgs(), service_config_json);
115 ASSERT_FALSE(service_config.ok());
116 EXPECT_EQ(service_config.status(),
117 absl::InvalidArgumentError(
118 "errors validating service config: [field:loadBalancingConfig "
119 "error:errors validating xds_override_host LB policy config: "
120 "[field:clusterName error:field not present]]"));
121 }
122
TEST(XdsOverrideHostConfigParsingTest,ReportsMissingChildPolicyField)123 TEST(XdsOverrideHostConfigParsingTest, ReportsMissingChildPolicyField) {
124 const char* service_config_json =
125 "{\n"
126 " \"loadBalancingConfig\":[{\n"
127 " \"xds_override_host_experimental\":{\n"
128 " \"clusterName\": \"foo\"\n"
129 " }\n"
130 " }]\n"
131 "}\n";
132 auto service_config =
133 ServiceConfigImpl::Create(ChannelArgs(), service_config_json);
134 ASSERT_FALSE(service_config.ok());
135 EXPECT_EQ(service_config.status(),
136 absl::InvalidArgumentError(
137 "errors validating service config: [field:loadBalancingConfig "
138 "error:errors validating xds_override_host LB policy config: "
139 "[field:childPolicy error:field not present]]"));
140 }
141
TEST(XdsOverrideHostConfigParsingTest,ReportsChildPolicyShouldBeArray)142 TEST(XdsOverrideHostConfigParsingTest, ReportsChildPolicyShouldBeArray) {
143 const char* service_config_json =
144 "{\n"
145 " \"loadBalancingConfig\":[{\n"
146 " \"xds_override_host_experimental\":{\n"
147 " \"clusterName\": \"foo\",\n"
148 " \"childPolicy\":{\n"
149 " \"grpclb\":{}\n"
150 " }\n"
151 " }\n"
152 " }]\n"
153 "}\n";
154 auto service_config =
155 ServiceConfigImpl::Create(ChannelArgs(), service_config_json);
156 ASSERT_FALSE(service_config.ok()) << service_config.status();
157 EXPECT_EQ(service_config.status(),
158 absl::InvalidArgumentError(
159 "errors validating service config: [field:loadBalancingConfig "
160 "error:errors validating xds_override_host LB policy config: "
161 "[field:childPolicy error:type should be array]]"));
162 }
163
TEST(XdsOverrideHostConfigParsingTest,ReportsEmptyChildPolicyArray)164 TEST(XdsOverrideHostConfigParsingTest, ReportsEmptyChildPolicyArray) {
165 const char* service_config_json =
166 "{\n"
167 " \"loadBalancingConfig\":[{\n"
168 " \"xds_override_host_experimental\":{\n"
169 " \"clusterName\": \"foo\",\n"
170 " \"childPolicy\":[\n"
171 " ]\n"
172 " }\n"
173 " }]\n"
174 "}\n";
175 auto service_config =
176 ServiceConfigImpl::Create(ChannelArgs(), service_config_json);
177 ASSERT_FALSE(service_config.ok()) << service_config.status();
178 EXPECT_EQ(service_config.status(),
179 absl::InvalidArgumentError(
180 "errors validating service config: [field:loadBalancingConfig "
181 "error:errors validating xds_override_host LB policy config: "
182 "[field:childPolicy error:No known policies in list: ]]"));
183 }
184
185 } // namespace
186 } // namespace testing
187 } // namespace grpc_core
188
main(int argc,char ** argv)189 int main(int argc, char** argv) {
190 ::testing::InitGoogleTest(&argc, argv);
191 grpc::testing::TestEnvironment env(&argc, argv);
192 grpc_init();
193 auto result = RUN_ALL_TESTS();
194 grpc_shutdown();
195 return result;
196 }
197