18 #include <gmock/gmock.h>
19 #include <gtest/gtest.h>
21 #include "absl/memory/memory.h"
22 #include "absl/strings/str_cat.h"
26 #include "src/proto/grpc/lookup/v1/rls.grpc.pb.h"
27 #include "src/proto/grpc/lookup/v1/rls.pb.h"
28 #include "src/proto/grpc/lookup/v1/rls_config.pb.h"
36 using ::grpc::lookup::v1::RouteLookupClusterSpecifier;
37 using ::grpc::lookup::v1::RouteLookupConfig;
39 constexpr
char kRlsTestKey[] =
"test_key";
40 constexpr
char kRlsTestKey1[] =
"key1";
41 constexpr
char kRlsTestValue[] =
"test_value";
42 constexpr
char kRlsHostKey[] =
"host_key";
43 constexpr
char kRlsServiceKey[] =
"service_key";
44 constexpr
char kRlsServiceValue[] =
"grpc.testing.EchoTestService";
45 constexpr
char kRlsMethodKey[] =
"method_key";
46 constexpr
char kRlsMethodValue[] =
"Echo";
47 constexpr
char kRlsConstantKey[] =
"constant_key";
48 constexpr
char kRlsConstantValue[] =
"constant_value";
49 constexpr
char kRlsClusterSpecifierPluginInstanceName[] =
"rls_plugin_instance";
51 class RlsTest :
public XdsEnd2endTest {
53 class RlsServerThread :
public ServerThread {
55 explicit RlsServerThread(XdsEnd2endTest* test_obj)
56 : ServerThread(test_obj,
false),
59 RlsServiceImpl* rls_service() {
return rls_service_.get(); }
62 const char*
Type()
override {
return "Rls"; }
64 void RegisterAllServices(ServerBuilder*
builder)
override {
68 void StartAllServices()
override {
rls_service_->Start(); }
70 void ShutdownAllServices()
override {
rls_service_->Shutdown(); }
76 rls_server_ = absl::make_unique<RlsServerThread>(
this);
80 void TearDown()
override {
91 ::
testing::Values(XdsTestType(), XdsTestType().set_enable_rds_testing(),
93 XdsTestType().set_enable_rds_testing().set_use_v2()),
96 TEST_P(RlsTest, XdsRoutingClusterSpecifierPlugin) {
97 ScopedExperimentalEnvVar
env_var(
"GRPC_EXPERIMENTAL_XDS_RLS_LB");
98 CreateAndStartBackends(2);
99 const char* kNewClusterName =
"new_cluster";
100 const char* kNewEdsServiceName =
"new_eds_service_name";
101 const size_t kNumEchoRpcs = 5;
103 EdsResourceArgs
args({
104 {
"locality0", CreateEndpointsForBackends(0, 1)},
106 EdsResourceArgs args1({
107 {
"locality0", CreateEndpointsForBackends(1, 2)},
109 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
110 balancer_->ads_service()->SetEdsResource(
111 BuildEdsResource(args1, kNewEdsServiceName));
113 Cluster new_cluster = default_cluster_;
114 new_cluster.set_name(kNewClusterName);
115 new_cluster.mutable_eds_cluster_config()->set_service_name(
117 balancer_->ads_service()->SetCdsResource(new_cluster);
122 {kRlsHostKey, kServerName},
123 {kRlsServiceKey, kRlsServiceValue},
124 {kRlsMethodKey, kRlsMethodValue},
125 {kRlsConstantKey, kRlsConstantValue}}),
127 RouteLookupConfig route_lookup_config;
128 auto* key_builder = route_lookup_config.add_grpc_keybuilders();
129 auto*
name = key_builder->add_names();
130 name->set_service(kRlsServiceValue);
131 name->set_method(kRlsMethodValue);
132 auto*
header = key_builder->add_headers();
133 header->set_key(kRlsTestKey);
134 header->add_names(kRlsTestKey1);
135 header->add_names(
"key2");
136 auto* extra_keys = key_builder->mutable_extra_keys();
137 extra_keys->set_host(kRlsHostKey);
138 extra_keys->set_service(kRlsServiceKey);
139 extra_keys->set_method(kRlsMethodKey);
140 (*key_builder->mutable_constant_keys())[kRlsConstantKey] = kRlsConstantValue;
141 route_lookup_config.set_lookup_service(
143 route_lookup_config.set_cache_size_bytes(5000);
144 RouteLookupClusterSpecifier rls;
145 *rls.mutable_route_lookup_config() =
std::move(route_lookup_config);
146 RouteConfiguration new_route_config = default_route_config_;
147 auto* plugin = new_route_config.add_cluster_specifier_plugins();
148 plugin->mutable_extension()->set_name(kRlsClusterSpecifierPluginInstanceName);
149 plugin->mutable_extension()->mutable_typed_config()->PackFrom(rls);
150 auto* default_route =
151 new_route_config.mutable_virtual_hosts(0)->mutable_routes(0);
152 default_route->mutable_route()->set_cluster_specifier_plugin(
153 kRlsClusterSpecifierPluginInstanceName);
154 SetRouteConfiguration(balancer_.get(), new_route_config);
155 auto rpc_options = RpcOptions().set_metadata({{kRlsTestKey1, kRlsTestValue}});
157 WaitForBackendOptions(), rpc_options);
163 TEST_P(RlsTest, XdsRoutingClusterSpecifierPluginNacksUndefinedSpecifier) {
164 ScopedExperimentalEnvVar
env_var(
"GRPC_EXPERIMENTAL_XDS_RLS_LB");
165 RouteConfiguration new_route_config = default_route_config_;
166 auto* default_route =
167 new_route_config.mutable_virtual_hosts(0)->mutable_routes(0);
169 default_route->mutable_route()->set_cluster_specifier_plugin(
170 kRlsClusterSpecifierPluginInstanceName);
171 SetRouteConfiguration(balancer_.get(), new_route_config);
173 ASSERT_TRUE(response_state.has_value()) <<
"timed out waiting for NACK";
176 "RouteAction cluster contains cluster specifier plugin "
177 "name not configured: ",
178 kRlsClusterSpecifierPluginInstanceName)));
181 TEST_P(RlsTest, XdsRoutingClusterSpecifierPluginNacksDuplicateSpecifier) {
182 ScopedExperimentalEnvVar
env_var(
"GRPC_EXPERIMENTAL_XDS_RLS_LB");
185 RouteLookupConfig route_lookup_config;
186 auto* key_builder = route_lookup_config.add_grpc_keybuilders();
187 auto*
name = key_builder->add_names();
188 name->set_service(kRlsServiceValue);
189 name->set_method(kRlsMethodValue);
190 auto*
header = key_builder->add_headers();
191 header->set_key(kRlsTestKey);
192 header->add_names(kRlsTestKey1);
193 route_lookup_config.set_lookup_service(
195 route_lookup_config.set_cache_size_bytes(5000);
196 RouteLookupClusterSpecifier rls;
197 *rls.mutable_route_lookup_config() =
std::move(route_lookup_config);
198 RouteConfiguration new_route_config = default_route_config_;
199 auto* plugin = new_route_config.add_cluster_specifier_plugins();
200 plugin->mutable_extension()->set_name(kRlsClusterSpecifierPluginInstanceName);
201 plugin->mutable_extension()->mutable_typed_config()->PackFrom(rls);
202 auto* duplicate_plugin = new_route_config.add_cluster_specifier_plugins();
203 duplicate_plugin->mutable_extension()->set_name(
204 kRlsClusterSpecifierPluginInstanceName);
205 duplicate_plugin->mutable_extension()->mutable_typed_config()->PackFrom(rls);
206 auto* default_route =
207 new_route_config.mutable_virtual_hosts(0)->mutable_routes(0);
208 default_route->mutable_route()->set_cluster_specifier_plugin(
209 kRlsClusterSpecifierPluginInstanceName);
210 SetRouteConfiguration(balancer_.get(), new_route_config);
212 ASSERT_TRUE(response_state.has_value()) <<
"timed out waiting for NACK";
215 "Duplicated definition of cluster_specifier_plugin ",
216 kRlsClusterSpecifierPluginInstanceName)));
220 XdsRoutingClusterSpecifierPluginNacksUnknownSpecifierProtoNotOptional) {
221 ScopedExperimentalEnvVar
env_var(
"GRPC_EXPERIMENTAL_XDS_RLS_LB");
224 RouteLookupConfig route_lookup_config;
225 RouteConfiguration new_route_config = default_route_config_;
226 auto* plugin = new_route_config.add_cluster_specifier_plugins();
227 plugin->mutable_extension()->set_name(kRlsClusterSpecifierPluginInstanceName);
230 plugin->mutable_extension()->mutable_typed_config()->PackFrom(
231 route_lookup_config);
232 auto* default_route =
233 new_route_config.mutable_virtual_hosts(0)->mutable_routes(0);
234 default_route->mutable_route()->set_cluster_specifier_plugin(
235 kRlsClusterSpecifierPluginInstanceName);
236 SetRouteConfiguration(balancer_.get(), new_route_config);
238 ASSERT_TRUE(response_state.has_value()) <<
"timed out waiting for NACK";
241 "grpc.lookup.v1.RouteLookupConfig"));
245 XdsRoutingClusterSpecifierPluginIgnoreUnknownSpecifierProtoOptional) {
246 ScopedExperimentalEnvVar
env_var(
"GRPC_EXPERIMENTAL_XDS_RLS_LB");
247 CreateAndStartBackends(1);
248 EdsResourceArgs
args({{
"locality0", CreateEndpointsForBackends()}});
249 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
252 RouteLookupConfig route_lookup_config;
253 RouteConfiguration new_route_config = default_route_config_;
254 auto* plugin = new_route_config.add_cluster_specifier_plugins();
255 plugin->mutable_extension()->set_name(kRlsClusterSpecifierPluginInstanceName);
258 plugin->mutable_extension()->mutable_typed_config()->PackFrom(
259 route_lookup_config);
260 plugin->set_is_optional(
true);
261 auto*
route = new_route_config.mutable_virtual_hosts(0)->mutable_routes(0);
262 route->mutable_route()->set_cluster_specifier_plugin(
263 kRlsClusterSpecifierPluginInstanceName);
264 auto* default_route = new_route_config.mutable_virtual_hosts(0)->add_routes();
265 default_route->mutable_match()->set_prefix(
"");
266 default_route->mutable_route()->set_cluster(kDefaultClusterName);
267 SetRouteConfiguration(balancer_.get(), new_route_config);
273 TEST_P(RlsTest, XdsRoutingRlsClusterSpecifierPluginNacksRequiredMatch) {
274 ScopedExperimentalEnvVar
env_var(
"GRPC_EXPERIMENTAL_XDS_RLS_LB");
277 RouteLookupConfig route_lookup_config;
278 auto* key_builder = route_lookup_config.add_grpc_keybuilders();
279 auto*
name = key_builder->add_names();
280 name->set_service(kRlsServiceValue);
281 name->set_method(kRlsMethodValue);
282 auto*
header = key_builder->add_headers();
283 header->set_key(kRlsTestKey);
284 header->add_names(kRlsTestKey1);
285 header->set_required_match(
true);
286 route_lookup_config.set_lookup_service(
288 route_lookup_config.set_cache_size_bytes(5000);
289 RouteLookupClusterSpecifier rls;
290 *rls.mutable_route_lookup_config() =
std::move(route_lookup_config);
291 RouteConfiguration new_route_config = default_route_config_;
292 auto* plugin = new_route_config.add_cluster_specifier_plugins();
293 plugin->mutable_extension()->set_name(kRlsClusterSpecifierPluginInstanceName);
294 plugin->mutable_extension()->mutable_typed_config()->PackFrom(rls);
295 auto* default_route =
296 new_route_config.mutable_virtual_hosts(0)->mutable_routes(0);
297 default_route->mutable_route()->set_cluster_specifier_plugin(
298 kRlsClusterSpecifierPluginInstanceName);
299 SetRouteConfiguration(balancer_.get(), new_route_config);
301 ASSERT_TRUE(response_state.has_value()) <<
"timed out waiting for NACK";
303 response_state->error_message,
307 TEST_P(RlsTest, XdsRoutingClusterSpecifierPluginDisabled) {
308 CreateAndStartBackends(1);
310 EdsResourceArgs
args({{
"locality0", CreateEndpointsForBackends()}});
311 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
314 RouteLookupConfig route_lookup_config;
315 auto* key_builder = route_lookup_config.add_grpc_keybuilders();
316 auto*
name = key_builder->add_names();
317 name->set_service(kRlsServiceValue);
318 name->set_method(kRlsMethodValue);
319 auto*
header = key_builder->add_headers();
320 header->set_key(kRlsTestKey);
321 header->add_names(kRlsTestKey1);
322 route_lookup_config.set_lookup_service(
324 route_lookup_config.set_cache_size_bytes(5000);
325 RouteLookupClusterSpecifier rls;
326 *rls.mutable_route_lookup_config() =
std::move(route_lookup_config);
327 RouteConfiguration new_route_config = default_route_config_;
328 auto* plugin = new_route_config.add_cluster_specifier_plugins();
329 plugin->mutable_extension()->set_name(kRlsClusterSpecifierPluginInstanceName);
330 plugin->mutable_extension()->mutable_typed_config()->PackFrom(rls);
331 auto*
route = new_route_config.mutable_virtual_hosts(0)->mutable_routes(0);
332 route->mutable_route()->set_cluster_specifier_plugin(
333 kRlsClusterSpecifierPluginInstanceName);
334 auto* default_route = new_route_config.mutable_virtual_hosts(0)->add_routes();
335 default_route->mutable_match()->set_prefix(
"");
336 default_route->mutable_route()->set_cluster(kDefaultClusterName);
337 SetRouteConfiguration(balancer_.get(), new_route_config);
340 auto rpc_options = RpcOptions().set_metadata({{kRlsTestKey1, kRlsTestValue}});
342 WaitForBackendOptions(), rpc_options);
349 int main(
int argc,
char** argv) {