xds_end2end_test: Move RLS tests to their own file (#29290)
* move some code around * remove num_backends parameter from XdsEnd2endTest * remove use_xds_enabled_server param from XdsEnd2endTest * remove xds_resource_does_not_exist_timeout_ms param from XdsEnd2endTest * remove client_load_reporting_interval_seconds param from XdsEnd2endTest * start moving CreateAndStartBackends() into individual tests * finish moving CreateAndStartBackends() into individual tests * remove unused variable * remove SetEdsResourceWithDelay * fix test flake * clang-tidy * clang-format * move test framework to its own library * fix build * clang-format * fix windows build * rename TestType to XdsTestType * move BackendServiceImpl inside of BackendServerThread * clang-format * move AdminServerThread to CSDS test suite * move RLS tests to their own file * remove unnecessary deps * generate_projectspull/29332/head^2
parent
1a983ed013
commit
214e3f3622
6 changed files with 641 additions and 326 deletions
@ -0,0 +1,361 @@ |
||||
// Copyright 2017 gRPC authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
#include <memory> |
||||
|
||||
#include <gmock/gmock.h> |
||||
#include <gtest/gtest.h> |
||||
|
||||
#include "absl/memory/memory.h" |
||||
#include "absl/strings/str_cat.h" |
||||
|
||||
#include "src/core/ext/filters/client_channel/backup_poller.h" |
||||
#include "src/core/lib/gpr/env.h" |
||||
#include "src/proto/grpc/lookup/v1/rls.grpc.pb.h" |
||||
#include "src/proto/grpc/lookup/v1/rls.pb.h" |
||||
#include "src/proto/grpc/lookup/v1/rls_config.pb.h" |
||||
#include "test/cpp/end2end/rls_server.h" |
||||
#include "test/cpp/end2end/xds/xds_end2end_test_lib.h" |
||||
|
||||
namespace grpc { |
||||
namespace testing { |
||||
namespace { |
||||
|
||||
using ::grpc::lookup::v1::RouteLookupClusterSpecifier; |
||||
using ::grpc::lookup::v1::RouteLookupConfig; |
||||
|
||||
constexpr char kRlsTestKey[] = "test_key"; |
||||
constexpr char kRlsTestKey1[] = "key1"; |
||||
constexpr char kRlsTestValue[] = "test_value"; |
||||
constexpr char kRlsHostKey[] = "host_key"; |
||||
constexpr char kRlsServiceKey[] = "service_key"; |
||||
constexpr char kRlsServiceValue[] = "grpc.testing.EchoTestService"; |
||||
constexpr char kRlsMethodKey[] = "method_key"; |
||||
constexpr char kRlsMethodValue[] = "Echo"; |
||||
constexpr char kRlsConstantKey[] = "constant_key"; |
||||
constexpr char kRlsConstantValue[] = "constant_value"; |
||||
constexpr char kRlsClusterSpecifierPluginInstanceName[] = "rls_plugin_instance"; |
||||
|
||||
class RlsTest : public XdsEnd2endTest { |
||||
protected: |
||||
class RlsServerThread : public ServerThread { |
||||
public: |
||||
explicit RlsServerThread(XdsEnd2endTest* test_obj) |
||||
: ServerThread(test_obj, /*use_xds_enabled_server=*/false), |
||||
rls_service_(new RlsServiceImpl()) {} |
||||
|
||||
RlsServiceImpl* rls_service() { return rls_service_.get(); } |
||||
|
||||
private: |
||||
const char* Type() override { return "Rls"; } |
||||
|
||||
void RegisterAllServices(ServerBuilder* builder) override { |
||||
builder->RegisterService(rls_service_.get()); |
||||
} |
||||
|
||||
void StartAllServices() override { rls_service_->Start(); } |
||||
|
||||
void ShutdownAllServices() override { rls_service_->Shutdown(); } |
||||
|
||||
std::shared_ptr<RlsServiceImpl> rls_service_; |
||||
}; |
||||
|
||||
RlsTest() { |
||||
rls_server_ = absl::make_unique<RlsServerThread>(this); |
||||
rls_server_->Start(); |
||||
} |
||||
|
||||
void TearDown() override { |
||||
rls_server_->Shutdown(); |
||||
XdsEnd2endTest::TearDown(); |
||||
} |
||||
|
||||
std::unique_ptr<RlsServerThread> rls_server_; |
||||
}; |
||||
|
||||
// Test both with and without RDS.
|
||||
INSTANTIATE_TEST_SUITE_P( |
||||
XdsTest, RlsTest, |
||||
::testing::Values(XdsTestType(), XdsTestType().set_enable_rds_testing(), |
||||
// Also test with xDS v2.
|
||||
XdsTestType().set_enable_rds_testing().set_use_v2()), |
||||
&XdsTestType::Name); |
||||
|
||||
TEST_P(RlsTest, XdsRoutingClusterSpecifierPlugin) { |
||||
ScopedExperimentalEnvVar env_var("GRPC_EXPERIMENTAL_XDS_RLS_LB"); |
||||
CreateAndStartBackends(2); |
||||
const char* kNewClusterName = "new_cluster"; |
||||
const char* kNewEdsServiceName = "new_eds_service_name"; |
||||
const size_t kNumEchoRpcs = 5; |
||||
// Populate new EDS resources.
|
||||
EdsResourceArgs args({ |
||||
{"locality0", CreateEndpointsForBackends(0, 1)}, |
||||
}); |
||||
EdsResourceArgs args1({ |
||||
{"locality0", CreateEndpointsForBackends(1, 2)}, |
||||
}); |
||||
balancer_->ads_service()->SetEdsResource(BuildEdsResource(args)); |
||||
balancer_->ads_service()->SetEdsResource( |
||||
BuildEdsResource(args1, kNewEdsServiceName)); |
||||
// Populate new CDS resources.
|
||||
Cluster new_cluster = default_cluster_; |
||||
new_cluster.set_name(kNewClusterName); |
||||
new_cluster.mutable_eds_cluster_config()->set_service_name( |
||||
kNewEdsServiceName); |
||||
balancer_->ads_service()->SetCdsResource(new_cluster); |
||||
// Prepare the RLSLookupConfig and configure all the keys; change route
|
||||
// configurations to use cluster specifier plugin.
|
||||
rls_server_->rls_service()->SetResponse( |
||||
BuildRlsRequest({{kRlsTestKey, kRlsTestValue}, |
||||
{kRlsHostKey, kServerName}, |
||||
{kRlsServiceKey, kRlsServiceValue}, |
||||
{kRlsMethodKey, kRlsMethodValue}, |
||||
{kRlsConstantKey, kRlsConstantValue}}), |
||||
BuildRlsResponse({kNewClusterName})); |
||||
RouteLookupConfig route_lookup_config; |
||||
auto* key_builder = route_lookup_config.add_grpc_keybuilders(); |
||||
auto* name = key_builder->add_names(); |
||||
name->set_service(kRlsServiceValue); |
||||
name->set_method(kRlsMethodValue); |
||||
auto* header = key_builder->add_headers(); |
||||
header->set_key(kRlsTestKey); |
||||
header->add_names(kRlsTestKey1); |
||||
header->add_names("key2"); |
||||
auto* extra_keys = key_builder->mutable_extra_keys(); |
||||
extra_keys->set_host(kRlsHostKey); |
||||
extra_keys->set_service(kRlsServiceKey); |
||||
extra_keys->set_method(kRlsMethodKey); |
||||
(*key_builder->mutable_constant_keys())[kRlsConstantKey] = kRlsConstantValue; |
||||
route_lookup_config.set_lookup_service( |
||||
absl::StrCat("localhost:", rls_server_->port())); |
||||
route_lookup_config.set_cache_size_bytes(5000); |
||||
RouteLookupClusterSpecifier rls; |
||||
*rls.mutable_route_lookup_config() = std::move(route_lookup_config); |
||||
RouteConfiguration new_route_config = default_route_config_; |
||||
auto* plugin = new_route_config.add_cluster_specifier_plugins(); |
||||
plugin->mutable_extension()->set_name(kRlsClusterSpecifierPluginInstanceName); |
||||
plugin->mutable_extension()->mutable_typed_config()->PackFrom(rls); |
||||
auto* default_route = |
||||
new_route_config.mutable_virtual_hosts(0)->mutable_routes(0); |
||||
default_route->mutable_route()->set_cluster_specifier_plugin( |
||||
kRlsClusterSpecifierPluginInstanceName); |
||||
SetRouteConfiguration(balancer_.get(), new_route_config); |
||||
auto rpc_options = RpcOptions().set_metadata({{kRlsTestKey1, kRlsTestValue}}); |
||||
WaitForAllBackends(1, 2, WaitForBackendOptions(), rpc_options); |
||||
CheckRpcSendOk(kNumEchoRpcs, rpc_options); |
||||
// Make sure RPCs all go to the correct backend.
|
||||
EXPECT_EQ(kNumEchoRpcs, backends_[1]->backend_service()->request_count()); |
||||
} |
||||
|
||||
TEST_P(RlsTest, XdsRoutingClusterSpecifierPluginNacksUndefinedSpecifier) { |
||||
ScopedExperimentalEnvVar env_var("GRPC_EXPERIMENTAL_XDS_RLS_LB"); |
||||
RouteConfiguration new_route_config = default_route_config_; |
||||
auto* default_route = |
||||
new_route_config.mutable_virtual_hosts(0)->mutable_routes(0); |
||||
// Set Cluster Specifier Plugin to something that does not exist.
|
||||
default_route->mutable_route()->set_cluster_specifier_plugin( |
||||
kRlsClusterSpecifierPluginInstanceName); |
||||
SetRouteConfiguration(balancer_.get(), new_route_config); |
||||
const auto response_state = WaitForRdsNack(); |
||||
ASSERT_TRUE(response_state.has_value()) << "timed out waiting for NACK"; |
||||
EXPECT_THAT(response_state->error_message, |
||||
::testing::HasSubstr(absl::StrCat( |
||||
"RouteAction cluster contains cluster specifier plugin " |
||||
"name not configured: ", |
||||
kRlsClusterSpecifierPluginInstanceName))); |
||||
} |
||||
|
||||
TEST_P(RlsTest, XdsRoutingClusterSpecifierPluginNacksDuplicateSpecifier) { |
||||
ScopedExperimentalEnvVar env_var("GRPC_EXPERIMENTAL_XDS_RLS_LB"); |
||||
// Prepare the RLSLookupConfig: change route configurations to use cluster
|
||||
// specifier plugin.
|
||||
RouteLookupConfig route_lookup_config; |
||||
auto* key_builder = route_lookup_config.add_grpc_keybuilders(); |
||||
auto* name = key_builder->add_names(); |
||||
name->set_service(kRlsServiceValue); |
||||
name->set_method(kRlsMethodValue); |
||||
auto* header = key_builder->add_headers(); |
||||
header->set_key(kRlsTestKey); |
||||
header->add_names(kRlsTestKey1); |
||||
route_lookup_config.set_lookup_service( |
||||
absl::StrCat("localhost:", rls_server_->port())); |
||||
route_lookup_config.set_cache_size_bytes(5000); |
||||
RouteLookupClusterSpecifier rls; |
||||
*rls.mutable_route_lookup_config() = std::move(route_lookup_config); |
||||
RouteConfiguration new_route_config = default_route_config_; |
||||
auto* plugin = new_route_config.add_cluster_specifier_plugins(); |
||||
plugin->mutable_extension()->set_name(kRlsClusterSpecifierPluginInstanceName); |
||||
plugin->mutable_extension()->mutable_typed_config()->PackFrom(rls); |
||||
auto* duplicate_plugin = new_route_config.add_cluster_specifier_plugins(); |
||||
duplicate_plugin->mutable_extension()->set_name( |
||||
kRlsClusterSpecifierPluginInstanceName); |
||||
duplicate_plugin->mutable_extension()->mutable_typed_config()->PackFrom(rls); |
||||
auto* default_route = |
||||
new_route_config.mutable_virtual_hosts(0)->mutable_routes(0); |
||||
default_route->mutable_route()->set_cluster_specifier_plugin( |
||||
kRlsClusterSpecifierPluginInstanceName); |
||||
SetRouteConfiguration(balancer_.get(), new_route_config); |
||||
const auto response_state = WaitForRdsNack(); |
||||
ASSERT_TRUE(response_state.has_value()) << "timed out waiting for NACK"; |
||||
EXPECT_THAT(response_state->error_message, |
||||
::testing::HasSubstr(absl::StrCat( |
||||
"Duplicated definition of cluster_specifier_plugin ", |
||||
kRlsClusterSpecifierPluginInstanceName))); |
||||
} |
||||
|
||||
TEST_P(RlsTest, |
||||
XdsRoutingClusterSpecifierPluginNacksUnknownSpecifierProtoNotOptional) { |
||||
ScopedExperimentalEnvVar env_var("GRPC_EXPERIMENTAL_XDS_RLS_LB"); |
||||
// Prepare the RLSLookupConfig: change route configurations to use cluster
|
||||
// specifier plugin.
|
||||
RouteLookupConfig route_lookup_config; |
||||
RouteConfiguration new_route_config = default_route_config_; |
||||
auto* plugin = new_route_config.add_cluster_specifier_plugins(); |
||||
plugin->mutable_extension()->set_name(kRlsClusterSpecifierPluginInstanceName); |
||||
// Instead of grpc.lookup.v1.RouteLookupClusterSpecifier, let's say we
|
||||
// mistakenly packed the inner RouteLookupConfig instead.
|
||||
plugin->mutable_extension()->mutable_typed_config()->PackFrom( |
||||
route_lookup_config); |
||||
auto* default_route = |
||||
new_route_config.mutable_virtual_hosts(0)->mutable_routes(0); |
||||
default_route->mutable_route()->set_cluster_specifier_plugin( |
||||
kRlsClusterSpecifierPluginInstanceName); |
||||
SetRouteConfiguration(balancer_.get(), new_route_config); |
||||
const auto response_state = WaitForRdsNack(); |
||||
ASSERT_TRUE(response_state.has_value()) << "timed out waiting for NACK"; |
||||
EXPECT_THAT(response_state->error_message, |
||||
::testing::HasSubstr("Unknown ClusterSpecifierPlugin type " |
||||
"grpc.lookup.v1.RouteLookupConfig")); |
||||
} |
||||
|
||||
TEST_P(RlsTest, |
||||
XdsRoutingClusterSpecifierPluginIgnoreUnknownSpecifierProtoOptional) { |
||||
ScopedExperimentalEnvVar env_var("GRPC_EXPERIMENTAL_XDS_RLS_LB"); |
||||
CreateAndStartBackends(1); |
||||
EdsResourceArgs args({{"locality0", CreateEndpointsForBackends()}}); |
||||
balancer_->ads_service()->SetEdsResource(BuildEdsResource(args)); |
||||
// Prepare the RLSLookupConfig: change route configurations to use cluster
|
||||
// specifier plugin.
|
||||
RouteLookupConfig route_lookup_config; |
||||
RouteConfiguration new_route_config = default_route_config_; |
||||
auto* plugin = new_route_config.add_cluster_specifier_plugins(); |
||||
plugin->mutable_extension()->set_name(kRlsClusterSpecifierPluginInstanceName); |
||||
// Instead of grpc.lookup.v1.RouteLookupClusterSpecifier, let's say we
|
||||
// mistakenly packed the inner RouteLookupConfig instead.
|
||||
plugin->mutable_extension()->mutable_typed_config()->PackFrom( |
||||
route_lookup_config); |
||||
plugin->set_is_optional(true); |
||||
auto* route = new_route_config.mutable_virtual_hosts(0)->mutable_routes(0); |
||||
route->mutable_route()->set_cluster_specifier_plugin( |
||||
kRlsClusterSpecifierPluginInstanceName); |
||||
auto* default_route = new_route_config.mutable_virtual_hosts(0)->add_routes(); |
||||
default_route->mutable_match()->set_prefix(""); |
||||
default_route->mutable_route()->set_cluster(kDefaultClusterName); |
||||
SetRouteConfiguration(balancer_.get(), new_route_config); |
||||
// Ensure we ignore the cluster specifier plugin and send traffic according to
|
||||
// the default route.
|
||||
WaitForAllBackends(); |
||||
} |
||||
|
||||
TEST_P(RlsTest, XdsRoutingRlsClusterSpecifierPluginNacksRequiredMatch) { |
||||
ScopedExperimentalEnvVar env_var("GRPC_EXPERIMENTAL_XDS_RLS_LB"); |
||||
// Prepare the RLSLookupConfig and configure all the keys; add required_match
|
||||
// field which should not be there.
|
||||
RouteLookupConfig route_lookup_config; |
||||
auto* key_builder = route_lookup_config.add_grpc_keybuilders(); |
||||
auto* name = key_builder->add_names(); |
||||
name->set_service(kRlsServiceValue); |
||||
name->set_method(kRlsMethodValue); |
||||
auto* header = key_builder->add_headers(); |
||||
header->set_key(kRlsTestKey); |
||||
header->add_names(kRlsTestKey1); |
||||
header->set_required_match(true); |
||||
route_lookup_config.set_lookup_service( |
||||
absl::StrCat("localhost:", rls_server_->port())); |
||||
route_lookup_config.set_cache_size_bytes(5000); |
||||
RouteLookupClusterSpecifier rls; |
||||
*rls.mutable_route_lookup_config() = std::move(route_lookup_config); |
||||
RouteConfiguration new_route_config = default_route_config_; |
||||
auto* plugin = new_route_config.add_cluster_specifier_plugins(); |
||||
plugin->mutable_extension()->set_name(kRlsClusterSpecifierPluginInstanceName); |
||||
plugin->mutable_extension()->mutable_typed_config()->PackFrom(rls); |
||||
auto* default_route = |
||||
new_route_config.mutable_virtual_hosts(0)->mutable_routes(0); |
||||
default_route->mutable_route()->set_cluster_specifier_plugin( |
||||
kRlsClusterSpecifierPluginInstanceName); |
||||
SetRouteConfiguration(balancer_.get(), new_route_config); |
||||
const auto response_state = WaitForRdsNack(); |
||||
ASSERT_TRUE(response_state.has_value()) << "timed out waiting for NACK"; |
||||
EXPECT_THAT( |
||||
response_state->error_message, |
||||
::testing::HasSubstr("field:requiredMatch error:must not be present")); |
||||
} |
||||
|
||||
TEST_P(RlsTest, XdsRoutingClusterSpecifierPluginDisabled) { |
||||
CreateAndStartBackends(1); |
||||
// Populate new EDS resources.
|
||||
EdsResourceArgs args({{"locality0", CreateEndpointsForBackends()}}); |
||||
balancer_->ads_service()->SetEdsResource(BuildEdsResource(args)); |
||||
// Prepare the RLSLookupConfig and configure all the keys; change route
|
||||
// configurations to use cluster specifier plugin.
|
||||
RouteLookupConfig route_lookup_config; |
||||
auto* key_builder = route_lookup_config.add_grpc_keybuilders(); |
||||
auto* name = key_builder->add_names(); |
||||
name->set_service(kRlsServiceValue); |
||||
name->set_method(kRlsMethodValue); |
||||
auto* header = key_builder->add_headers(); |
||||
header->set_key(kRlsTestKey); |
||||
header->add_names(kRlsTestKey1); |
||||
route_lookup_config.set_lookup_service( |
||||
absl::StrCat("localhost:", rls_server_->port())); |
||||
route_lookup_config.set_cache_size_bytes(5000); |
||||
RouteLookupClusterSpecifier rls; |
||||
*rls.mutable_route_lookup_config() = std::move(route_lookup_config); |
||||
RouteConfiguration new_route_config = default_route_config_; |
||||
auto* plugin = new_route_config.add_cluster_specifier_plugins(); |
||||
plugin->mutable_extension()->set_name(kRlsClusterSpecifierPluginInstanceName); |
||||
plugin->mutable_extension()->mutable_typed_config()->PackFrom(rls); |
||||
auto* route = new_route_config.mutable_virtual_hosts(0)->mutable_routes(0); |
||||
route->mutable_route()->set_cluster_specifier_plugin( |
||||
kRlsClusterSpecifierPluginInstanceName); |
||||
auto* default_route = new_route_config.mutable_virtual_hosts(0)->add_routes(); |
||||
default_route->mutable_match()->set_prefix(""); |
||||
default_route->mutable_route()->set_cluster(kDefaultClusterName); |
||||
SetRouteConfiguration(balancer_.get(), new_route_config); |
||||
// Ensure we ignore the cluster specifier plugin and send traffic according to
|
||||
// the default route.
|
||||
auto rpc_options = RpcOptions().set_metadata({{kRlsTestKey1, kRlsTestValue}}); |
||||
WaitForAllBackends(0, 1, WaitForBackendOptions(), rpc_options); |
||||
} |
||||
|
||||
} // namespace
|
||||
} // namespace testing
|
||||
} // namespace grpc
|
||||
|
||||
int main(int argc, char** argv) { |
||||
grpc::testing::TestEnvironment env(&argc, argv); |
||||
::testing::InitGoogleTest(&argc, argv); |
||||
// Make the backup poller poll very frequently in order to pick up
|
||||
// updates from all the subchannels's FDs.
|
||||
GPR_GLOBAL_CONFIG_SET(grpc_client_channel_backup_poll_interval_ms, 1); |
||||
#if TARGET_OS_IPHONE |
||||
// Workaround Apple CFStream bug
|
||||
gpr_setenv("grpc_cfstream", "0"); |
||||
#endif |
||||
grpc_init(); |
||||
const auto result = RUN_ALL_TESTS(); |
||||
grpc_shutdown(); |
||||
return result; |
||||
} |
Loading…
Reference in new issue