|
|
|
@ -596,11 +596,10 @@ class XdsFederationTest : public XdsEnd2endTest { |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// Get bootstrap from env var, so that there's a global XdsClient.
|
|
|
|
|
// Runs with and without RDS.
|
|
|
|
|
// Runs with RDS so that we know all resource types work properly.
|
|
|
|
|
INSTANTIATE_TEST_SUITE_P( |
|
|
|
|
XdsTest, XdsFederationTest, |
|
|
|
|
::testing::Values( |
|
|
|
|
XdsTestType().set_bootstrap_source(XdsTestType::kBootstrapFromEnvVar), |
|
|
|
|
XdsTestType() |
|
|
|
|
.set_bootstrap_source(XdsTestType::kBootstrapFromEnvVar) |
|
|
|
|
.set_enable_rds_testing()), |
|
|
|
@ -808,6 +807,185 @@ TEST_P(XdsFederationTest, FederationTargetAuthorityWithResourceTemplate) { |
|
|
|
|
EXPECT_EQ(1U, backends_[1]->backend_service()->request_count()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
TEST_P(XdsFederationTest, TargetUriAuthorityUnknown) { |
|
|
|
|
ScopedExperimentalEnvVar env_var("GRPC_EXPERIMENTAL_XDS_FEDERATION"); |
|
|
|
|
const char* kAuthority = "xds.example.com"; |
|
|
|
|
const char* kNewServerName = "whee%/server.example.com"; |
|
|
|
|
const char* kNewListenerTemplate = |
|
|
|
|
"xdstp://xds.example.com/envoy.config.listener.v3.Listener/" |
|
|
|
|
"client/%s?psm_project_id=1234"; |
|
|
|
|
BootstrapBuilder builder = BootstrapBuilder(); |
|
|
|
|
builder.AddAuthority( |
|
|
|
|
kAuthority, absl::StrCat("localhost:", grpc_pick_unused_port_or_die()), |
|
|
|
|
kNewListenerTemplate); |
|
|
|
|
InitClient(builder); |
|
|
|
|
auto channel2 = CreateChannel( |
|
|
|
|
/*failover_timeout_ms=*/0, kNewServerName, "xds.unknown.com"); |
|
|
|
|
auto stub2 = grpc::testing::EchoTestService::NewStub(channel2); |
|
|
|
|
ClientContext context; |
|
|
|
|
EchoRequest request; |
|
|
|
|
request.set_message(kRequestMessage); |
|
|
|
|
EchoResponse response; |
|
|
|
|
grpc::Status status = stub2->Echo(&context, request, &response); |
|
|
|
|
EXPECT_EQ(status.error_code(), StatusCode::UNAVAILABLE); |
|
|
|
|
EXPECT_EQ(status.error_message(), |
|
|
|
|
"Invalid target URI -- authority not found for xds.unknown.com"); |
|
|
|
|
ASSERT_EQ(GRPC_CHANNEL_TRANSIENT_FAILURE, channel2->GetState(false)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
TEST_P(XdsFederationTest, RdsResourceNameAuthorityUnknown) { |
|
|
|
|
ScopedExperimentalEnvVar env_var("GRPC_EXPERIMENTAL_XDS_FEDERATION"); |
|
|
|
|
const char* kAuthority = "xds.example.com"; |
|
|
|
|
const char* kNewServerName = "whee%/server.example.com"; |
|
|
|
|
const char* kNewListenerTemplate = |
|
|
|
|
"xdstp://xds.example.com/envoy.config.listener.v3.Listener/" |
|
|
|
|
"client/%s?psm_project_id=1234"; |
|
|
|
|
const char* kNewListenerName = |
|
|
|
|
"xdstp://xds.example.com/envoy.config.listener.v3.Listener/" |
|
|
|
|
"client/whee%25/server.example.com?psm_project_id=1234"; |
|
|
|
|
const char* kNewRouteConfigName = |
|
|
|
|
"xdstp://xds.unknown.com/envoy.config.route.v3.RouteConfiguration/" |
|
|
|
|
"new_route_config_name"; |
|
|
|
|
BootstrapBuilder builder = BootstrapBuilder(); |
|
|
|
|
builder.AddAuthority(kAuthority, |
|
|
|
|
absl::StrCat("localhost:", authority_balancer_->port()), |
|
|
|
|
kNewListenerTemplate); |
|
|
|
|
InitClient(builder); |
|
|
|
|
// New RouteConfig
|
|
|
|
|
RouteConfiguration new_route_config = default_route_config_; |
|
|
|
|
new_route_config.set_name(kNewRouteConfigName); |
|
|
|
|
// New Listener
|
|
|
|
|
Listener listener = default_listener_; |
|
|
|
|
listener.set_name(kNewListenerName); |
|
|
|
|
SetListenerAndRouteConfiguration(authority_balancer_.get(), listener, |
|
|
|
|
new_route_config); |
|
|
|
|
// Channel should report TRANSIENT_FAILURE.
|
|
|
|
|
auto channel2 = |
|
|
|
|
CreateChannel(/*failover_timeout_ms=*/0, kNewServerName, kAuthority); |
|
|
|
|
auto stub2 = grpc::testing::EchoTestService::NewStub(channel2); |
|
|
|
|
ClientContext context; |
|
|
|
|
EchoRequest request; |
|
|
|
|
request.set_message(kRequestMessage); |
|
|
|
|
EchoResponse response; |
|
|
|
|
grpc::Status status = stub2->Echo(&context, request, &response); |
|
|
|
|
EXPECT_EQ(status.error_code(), StatusCode::UNAVAILABLE); |
|
|
|
|
EXPECT_EQ(status.error_message(), |
|
|
|
|
absl::StrCat( |
|
|
|
|
kNewRouteConfigName, |
|
|
|
|
": UNAVAILABLE: authority \"xds.unknown.com\" not present in " |
|
|
|
|
"bootstrap config")); |
|
|
|
|
ASSERT_EQ(GRPC_CHANNEL_TRANSIENT_FAILURE, channel2->GetState(false)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
TEST_P(XdsFederationTest, CdsResourceNameAuthorityUnknown) { |
|
|
|
|
ScopedExperimentalEnvVar env_var("GRPC_EXPERIMENTAL_XDS_FEDERATION"); |
|
|
|
|
const char* kAuthority = "xds.example.com"; |
|
|
|
|
const char* kNewServerName = "whee%/server.example.com"; |
|
|
|
|
const char* kNewListenerTemplate = |
|
|
|
|
"xdstp://xds.example.com/envoy.config.listener.v3.Listener/" |
|
|
|
|
"client/%s?psm_project_id=1234"; |
|
|
|
|
const char* kNewListenerName = |
|
|
|
|
"xdstp://xds.example.com/envoy.config.listener.v3.Listener/" |
|
|
|
|
"client/whee%25/server.example.com?psm_project_id=1234"; |
|
|
|
|
const char* kNewRouteConfigName = |
|
|
|
|
"xdstp://xds.example.com/envoy.config.route.v3.RouteConfiguration/" |
|
|
|
|
"new_route_config_name"; |
|
|
|
|
const char* kNewClusterName = |
|
|
|
|
"xdstp://xds.unknown.com/envoy.config.cluster.v3.Cluster/" |
|
|
|
|
"cluster_name"; |
|
|
|
|
BootstrapBuilder builder = BootstrapBuilder(); |
|
|
|
|
builder.AddAuthority(kAuthority, |
|
|
|
|
absl::StrCat("localhost:", authority_balancer_->port()), |
|
|
|
|
kNewListenerTemplate); |
|
|
|
|
InitClient(builder); |
|
|
|
|
// New Route
|
|
|
|
|
RouteConfiguration new_route_config = default_route_config_; |
|
|
|
|
new_route_config.set_name(kNewRouteConfigName); |
|
|
|
|
new_route_config.mutable_virtual_hosts(0) |
|
|
|
|
->mutable_routes(0) |
|
|
|
|
->mutable_route() |
|
|
|
|
->set_cluster(kNewClusterName); |
|
|
|
|
// New Listener
|
|
|
|
|
Listener listener = default_listener_; |
|
|
|
|
listener.set_name(kNewListenerName); |
|
|
|
|
SetListenerAndRouteConfiguration(authority_balancer_.get(), listener, |
|
|
|
|
new_route_config); |
|
|
|
|
// Channel should report TRANSIENT_FAILURE.
|
|
|
|
|
auto channel2 = |
|
|
|
|
CreateChannel(/*failover_timeout_ms=*/0, kNewServerName, kAuthority); |
|
|
|
|
auto stub2 = grpc::testing::EchoTestService::NewStub(channel2); |
|
|
|
|
ClientContext context; |
|
|
|
|
EchoRequest request; |
|
|
|
|
request.set_message(kRequestMessage); |
|
|
|
|
EchoResponse response; |
|
|
|
|
grpc::Status status = stub2->Echo(&context, request, &response); |
|
|
|
|
EXPECT_EQ(status.error_code(), StatusCode::UNAVAILABLE); |
|
|
|
|
EXPECT_EQ(status.error_message(), |
|
|
|
|
absl::StrCat( |
|
|
|
|
kNewClusterName, |
|
|
|
|
": UNAVAILABLE: authority \"xds.unknown.com\" not present in " |
|
|
|
|
"bootstrap config")); |
|
|
|
|
ASSERT_EQ(GRPC_CHANNEL_TRANSIENT_FAILURE, channel2->GetState(false)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
TEST_P(XdsFederationTest, EdsResourceNameAuthorityUnknown) { |
|
|
|
|
ScopedExperimentalEnvVar env_var("GRPC_EXPERIMENTAL_XDS_FEDERATION"); |
|
|
|
|
const char* kAuthority = "xds.example.com"; |
|
|
|
|
const char* kNewServerName = "whee%/server.example.com"; |
|
|
|
|
const char* kNewListenerTemplate = |
|
|
|
|
"xdstp://xds.example.com/envoy.config.listener.v3.Listener/" |
|
|
|
|
"client/%s?psm_project_id=1234"; |
|
|
|
|
const char* kNewListenerName = |
|
|
|
|
"xdstp://xds.example.com/envoy.config.listener.v3.Listener/" |
|
|
|
|
"client/whee%25/server.example.com?psm_project_id=1234"; |
|
|
|
|
const char* kNewRouteConfigName = |
|
|
|
|
"xdstp://xds.example.com/envoy.config.route.v3.RouteConfiguration/" |
|
|
|
|
"new_route_config_name"; |
|
|
|
|
const char* kNewEdsServiceName = |
|
|
|
|
"xdstp://xds.unknown.com/envoy.config.endpoint.v3.ClusterLoadAssignment/" |
|
|
|
|
"edsservice_name"; |
|
|
|
|
const char* kNewClusterName = |
|
|
|
|
"xdstp://xds.example.com/envoy.config.cluster.v3.Cluster/" |
|
|
|
|
"cluster_name"; |
|
|
|
|
BootstrapBuilder builder = BootstrapBuilder(); |
|
|
|
|
builder.AddAuthority(kAuthority, |
|
|
|
|
absl::StrCat("localhost:", authority_balancer_->port()), |
|
|
|
|
kNewListenerTemplate); |
|
|
|
|
InitClient(builder); |
|
|
|
|
// New cluster
|
|
|
|
|
Cluster new_cluster = default_cluster_; |
|
|
|
|
new_cluster.set_name(kNewClusterName); |
|
|
|
|
new_cluster.mutable_eds_cluster_config()->set_service_name( |
|
|
|
|
kNewEdsServiceName); |
|
|
|
|
authority_balancer_->ads_service()->SetCdsResource(new_cluster); |
|
|
|
|
// New Route
|
|
|
|
|
RouteConfiguration new_route_config = default_route_config_; |
|
|
|
|
new_route_config.set_name(kNewRouteConfigName); |
|
|
|
|
new_route_config.mutable_virtual_hosts(0) |
|
|
|
|
->mutable_routes(0) |
|
|
|
|
->mutable_route() |
|
|
|
|
->set_cluster(kNewClusterName); |
|
|
|
|
// New Listener
|
|
|
|
|
Listener listener = default_listener_; |
|
|
|
|
listener.set_name(kNewListenerName); |
|
|
|
|
SetListenerAndRouteConfiguration(authority_balancer_.get(), listener, |
|
|
|
|
new_route_config); |
|
|
|
|
// Channel should report TRANSIENT_FAILURE.
|
|
|
|
|
auto channel2 = |
|
|
|
|
CreateChannel(/*failover_timeout_ms=*/0, kNewServerName, kAuthority); |
|
|
|
|
auto stub2 = grpc::testing::EchoTestService::NewStub(channel2); |
|
|
|
|
ClientContext context; |
|
|
|
|
EchoRequest request; |
|
|
|
|
request.set_message(kRequestMessage); |
|
|
|
|
EchoResponse response; |
|
|
|
|
grpc::Status status = stub2->Echo(&context, request, &response); |
|
|
|
|
EXPECT_EQ(status.error_code(), StatusCode::UNAVAILABLE); |
|
|
|
|
// TODO(roth): Improve this error message as part of
|
|
|
|
|
// https://github.com/grpc/grpc/issues/22883.
|
|
|
|
|
EXPECT_EQ(status.error_message(), "no ready priority"); |
|
|
|
|
ASSERT_EQ(GRPC_CHANNEL_TRANSIENT_FAILURE, channel2->GetState(false)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Setting server_listener_resource_name_template to start with "xdstp:" and
|
|
|
|
|
// look up xds server under an authority map.
|
|
|
|
|
TEST_P(XdsFederationTest, FederationServer) { |
|
|
|
|