|
|
|
@ -91,6 +91,7 @@ |
|
|
|
|
#include "src/proto/grpc/testing/xds/v3/listener.grpc.pb.h" |
|
|
|
|
#include "src/proto/grpc/testing/xds/v3/lrs.grpc.pb.h" |
|
|
|
|
#include "src/proto/grpc/testing/xds/v3/route.grpc.pb.h" |
|
|
|
|
#include "src/proto/grpc/testing/xds/v3/router.grpc.pb.h" |
|
|
|
|
#include "src/proto/grpc/testing/xds/v3/tls.grpc.pb.h" |
|
|
|
|
|
|
|
|
|
namespace grpc { |
|
|
|
@ -1580,6 +1581,13 @@ class XdsEnd2endTest : public ::testing::TestWithParam<TestType> { |
|
|
|
|
// Initialize default xDS resources.
|
|
|
|
|
// Construct LDS resource.
|
|
|
|
|
default_listener_.set_name(kServerName); |
|
|
|
|
HttpConnectionManager http_connection_manager; |
|
|
|
|
auto* filter = http_connection_manager.add_http_filters(); |
|
|
|
|
filter->set_name("router"); |
|
|
|
|
filter->mutable_typed_config()->PackFrom( |
|
|
|
|
envoy::extensions::filters::http::router::v3::Router()); |
|
|
|
|
default_listener_.mutable_api_listener()->mutable_api_listener()->PackFrom( |
|
|
|
|
http_connection_manager); |
|
|
|
|
// Construct RDS resource.
|
|
|
|
|
default_route_config_.set_name(kDefaultRouteConfigurationName); |
|
|
|
|
auto* virtual_host = default_route_config_.add_virtual_hosts(); |
|
|
|
@ -1985,6 +1993,10 @@ class XdsEnd2endTest : public ::testing::TestWithParam<TestType> { |
|
|
|
|
static Listener BuildListener(const RouteConfiguration& route_config) { |
|
|
|
|
HttpConnectionManager http_connection_manager; |
|
|
|
|
*(http_connection_manager.mutable_route_config()) = route_config; |
|
|
|
|
auto* filter = http_connection_manager.add_http_filters(); |
|
|
|
|
filter->set_name("router"); |
|
|
|
|
filter->mutable_typed_config()->PackFrom( |
|
|
|
|
envoy::extensions::filters::http::router::v3::Router()); |
|
|
|
|
Listener listener; |
|
|
|
|
listener.set_name(kServerName); |
|
|
|
|
listener.mutable_api_listener()->mutable_api_listener()->PackFrom( |
|
|
|
@ -2603,6 +2615,8 @@ TEST_P(XdsResolverOnlyTest, RestartsRequestsUponReconnection) { |
|
|
|
|
// Manually configure use of RDS.
|
|
|
|
|
auto listener = default_listener_; |
|
|
|
|
HttpConnectionManager http_connection_manager; |
|
|
|
|
listener.mutable_api_listener()->mutable_api_listener()->UnpackTo( |
|
|
|
|
&http_connection_manager); |
|
|
|
|
auto* rds = http_connection_manager.mutable_rds(); |
|
|
|
|
rds->set_route_config_name(kDefaultRouteConfigurationName); |
|
|
|
|
rds->mutable_config_source()->mutable_ads(); |
|
|
|
@ -3004,7 +3018,7 @@ TEST_P(LdsTest, NoApiListener) { |
|
|
|
|
SetNextResolution({}); |
|
|
|
|
SetNextResolutionForLbChannelAllBalancers(); |
|
|
|
|
CheckRpcSendFailure(); |
|
|
|
|
const auto& response_state = |
|
|
|
|
const auto response_state = |
|
|
|
|
balancers_[0]->ads_service()->lds_response_state(); |
|
|
|
|
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); |
|
|
|
|
EXPECT_THAT( |
|
|
|
@ -3017,6 +3031,8 @@ TEST_P(LdsTest, NoApiListener) { |
|
|
|
|
TEST_P(LdsTest, WrongRouteSpecifier) { |
|
|
|
|
auto listener = default_listener_; |
|
|
|
|
HttpConnectionManager http_connection_manager; |
|
|
|
|
listener.mutable_api_listener()->mutable_api_listener()->UnpackTo( |
|
|
|
|
&http_connection_manager); |
|
|
|
|
http_connection_manager.mutable_scoped_routes(); |
|
|
|
|
listener.mutable_api_listener()->mutable_api_listener()->PackFrom( |
|
|
|
|
http_connection_manager); |
|
|
|
@ -3024,7 +3040,7 @@ TEST_P(LdsTest, WrongRouteSpecifier) { |
|
|
|
|
SetNextResolution({}); |
|
|
|
|
SetNextResolutionForLbChannelAllBalancers(); |
|
|
|
|
CheckRpcSendFailure(); |
|
|
|
|
const auto& response_state = |
|
|
|
|
const auto response_state = |
|
|
|
|
balancers_[0]->ads_service()->lds_response_state(); |
|
|
|
|
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); |
|
|
|
|
EXPECT_THAT( |
|
|
|
@ -3038,6 +3054,8 @@ TEST_P(LdsTest, WrongRouteSpecifier) { |
|
|
|
|
TEST_P(LdsTest, RdsMissingConfigSource) { |
|
|
|
|
auto listener = default_listener_; |
|
|
|
|
HttpConnectionManager http_connection_manager; |
|
|
|
|
listener.mutable_api_listener()->mutable_api_listener()->UnpackTo( |
|
|
|
|
&http_connection_manager); |
|
|
|
|
http_connection_manager.mutable_rds()->set_route_config_name( |
|
|
|
|
kDefaultRouteConfigurationName); |
|
|
|
|
listener.mutable_api_listener()->mutable_api_listener()->PackFrom( |
|
|
|
@ -3046,7 +3064,7 @@ TEST_P(LdsTest, RdsMissingConfigSource) { |
|
|
|
|
SetNextResolution({}); |
|
|
|
|
SetNextResolutionForLbChannelAllBalancers(); |
|
|
|
|
CheckRpcSendFailure(); |
|
|
|
|
const auto& response_state = |
|
|
|
|
const auto response_state = |
|
|
|
|
balancers_[0]->ads_service()->lds_response_state(); |
|
|
|
|
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); |
|
|
|
|
EXPECT_THAT(response_state.error_message, |
|
|
|
@ -3059,6 +3077,8 @@ TEST_P(LdsTest, RdsMissingConfigSource) { |
|
|
|
|
TEST_P(LdsTest, RdsConfigSourceDoesNotSpecifyAds) { |
|
|
|
|
auto listener = default_listener_; |
|
|
|
|
HttpConnectionManager http_connection_manager; |
|
|
|
|
listener.mutable_api_listener()->mutable_api_listener()->UnpackTo( |
|
|
|
|
&http_connection_manager); |
|
|
|
|
auto* rds = http_connection_manager.mutable_rds(); |
|
|
|
|
rds->set_route_config_name(kDefaultRouteConfigurationName); |
|
|
|
|
rds->mutable_config_source()->mutable_self(); |
|
|
|
@ -3068,7 +3088,7 @@ TEST_P(LdsTest, RdsConfigSourceDoesNotSpecifyAds) { |
|
|
|
|
SetNextResolution({}); |
|
|
|
|
SetNextResolutionForLbChannelAllBalancers(); |
|
|
|
|
CheckRpcSendFailure(); |
|
|
|
|
const auto& response_state = |
|
|
|
|
const auto response_state = |
|
|
|
|
balancers_[0]->ads_service()->lds_response_state(); |
|
|
|
|
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); |
|
|
|
|
EXPECT_THAT( |
|
|
|
@ -3096,7 +3116,7 @@ TEST_P(LdsTest, MultipleBadResources) { |
|
|
|
|
EchoResponse response; |
|
|
|
|
grpc::Status status = stub2->Echo(&context, request, &response); |
|
|
|
|
EXPECT_FALSE(status.ok()); |
|
|
|
|
const auto& response_state = |
|
|
|
|
const auto response_state = |
|
|
|
|
balancers_[0]->ads_service()->lds_response_state(); |
|
|
|
|
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); |
|
|
|
|
EXPECT_THAT( |
|
|
|
@ -3109,6 +3129,196 @@ TEST_P(LdsTest, MultipleBadResources) { |
|
|
|
|
": Listener has neither address nor ApiListener")))); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// TODO(roth): Remove this test when we remove the
|
|
|
|
|
// GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION environment variable guard.
|
|
|
|
|
TEST_P(LdsTest, HttpFiltersEnabled) { |
|
|
|
|
gpr_setenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION", "true"); |
|
|
|
|
SetNextResolutionForLbChannelAllBalancers(); |
|
|
|
|
AdsServiceImpl::EdsResourceArgs args({ |
|
|
|
|
{"locality0", GetBackendPorts()}, |
|
|
|
|
}); |
|
|
|
|
balancers_[0]->ads_service()->SetEdsResource( |
|
|
|
|
BuildEdsResource(args, DefaultEdsServiceName())); |
|
|
|
|
WaitForAllBackends(); |
|
|
|
|
gpr_unsetenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Test that we fail RPCs if there is no router filter.
|
|
|
|
|
TEST_P(LdsTest, FailRpcsIfNoHttpRouterFilter) { |
|
|
|
|
gpr_setenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION", "true"); |
|
|
|
|
SetNextResolutionForLbChannelAllBalancers(); |
|
|
|
|
auto listener = default_listener_; |
|
|
|
|
HttpConnectionManager http_connection_manager; |
|
|
|
|
listener.mutable_api_listener()->mutable_api_listener()->UnpackTo( |
|
|
|
|
&http_connection_manager); |
|
|
|
|
http_connection_manager.clear_http_filters(); |
|
|
|
|
listener.mutable_api_listener()->mutable_api_listener()->PackFrom( |
|
|
|
|
http_connection_manager); |
|
|
|
|
SetListenerAndRouteConfiguration(0, listener, default_route_config_); |
|
|
|
|
AdsServiceImpl::EdsResourceArgs args({ |
|
|
|
|
{"locality0", GetBackendPorts()}, |
|
|
|
|
}); |
|
|
|
|
balancers_[0]->ads_service()->SetEdsResource( |
|
|
|
|
BuildEdsResource(args, DefaultEdsServiceName())); |
|
|
|
|
Status status = SendRpc(); |
|
|
|
|
EXPECT_EQ(status.error_code(), StatusCode::UNAVAILABLE); |
|
|
|
|
EXPECT_EQ(status.error_message(), "no xDS HTTP router filter configured"); |
|
|
|
|
// Wait until xDS server sees ACK.
|
|
|
|
|
while (balancers_[0]->ads_service()->lds_response_state().state == |
|
|
|
|
AdsServiceImpl::ResponseState::SENT) { |
|
|
|
|
CheckRpcSendFailure(); |
|
|
|
|
} |
|
|
|
|
const auto response_state = |
|
|
|
|
balancers_[0]->ads_service()->lds_response_state(); |
|
|
|
|
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::ACKED); |
|
|
|
|
gpr_unsetenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// TODO(lidiz): As part of adding the fault injection filter, add a test
|
|
|
|
|
// that we ignore filters after the router filter.
|
|
|
|
|
|
|
|
|
|
// Test that we NACK empty filter names.
|
|
|
|
|
TEST_P(LdsTest, RejectsEmptyHttpFilterName) { |
|
|
|
|
gpr_setenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION", "true"); |
|
|
|
|
auto listener = default_listener_; |
|
|
|
|
HttpConnectionManager http_connection_manager; |
|
|
|
|
listener.mutable_api_listener()->mutable_api_listener()->UnpackTo( |
|
|
|
|
&http_connection_manager); |
|
|
|
|
auto* filter = http_connection_manager.add_http_filters(); |
|
|
|
|
filter->mutable_typed_config()->PackFrom(Listener()); |
|
|
|
|
listener.mutable_api_listener()->mutable_api_listener()->PackFrom( |
|
|
|
|
http_connection_manager); |
|
|
|
|
SetListenerAndRouteConfiguration(0, listener, default_route_config_); |
|
|
|
|
SetNextResolution({}); |
|
|
|
|
SetNextResolutionForLbChannelAllBalancers(); |
|
|
|
|
// Wait until xDS server sees NACK.
|
|
|
|
|
do { |
|
|
|
|
CheckRpcSendFailure(); |
|
|
|
|
} while (balancers_[0]->ads_service()->lds_response_state().state == |
|
|
|
|
AdsServiceImpl::ResponseState::SENT); |
|
|
|
|
const auto response_state = |
|
|
|
|
balancers_[0]->ads_service()->lds_response_state(); |
|
|
|
|
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); |
|
|
|
|
EXPECT_THAT(response_state.error_message, |
|
|
|
|
::testing::HasSubstr("empty filter name at index 1")); |
|
|
|
|
gpr_unsetenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Test that we NACK duplicate HTTP filter names.
|
|
|
|
|
TEST_P(LdsTest, RejectsDuplicateHttpFilterName) { |
|
|
|
|
gpr_setenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION", "true"); |
|
|
|
|
auto listener = default_listener_; |
|
|
|
|
HttpConnectionManager http_connection_manager; |
|
|
|
|
listener.mutable_api_listener()->mutable_api_listener()->UnpackTo( |
|
|
|
|
&http_connection_manager); |
|
|
|
|
*http_connection_manager.add_http_filters() = |
|
|
|
|
http_connection_manager.http_filters(0); |
|
|
|
|
listener.mutable_api_listener()->mutable_api_listener()->PackFrom( |
|
|
|
|
http_connection_manager); |
|
|
|
|
SetListenerAndRouteConfiguration(0, listener, default_route_config_); |
|
|
|
|
SetNextResolution({}); |
|
|
|
|
SetNextResolutionForLbChannelAllBalancers(); |
|
|
|
|
// Wait until xDS server sees NACK.
|
|
|
|
|
do { |
|
|
|
|
CheckRpcSendFailure(); |
|
|
|
|
} while (balancers_[0]->ads_service()->lds_response_state().state == |
|
|
|
|
AdsServiceImpl::ResponseState::SENT); |
|
|
|
|
const auto response_state = |
|
|
|
|
balancers_[0]->ads_service()->lds_response_state(); |
|
|
|
|
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); |
|
|
|
|
EXPECT_THAT(response_state.error_message, |
|
|
|
|
::testing::HasSubstr("duplicate HTTP filter name: router")); |
|
|
|
|
gpr_unsetenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Test that we NACK unknown filter types.
|
|
|
|
|
TEST_P(LdsTest, RejectsUnknownHttpFilterType) { |
|
|
|
|
gpr_setenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION", "true"); |
|
|
|
|
auto listener = default_listener_; |
|
|
|
|
HttpConnectionManager http_connection_manager; |
|
|
|
|
listener.mutable_api_listener()->mutable_api_listener()->UnpackTo( |
|
|
|
|
&http_connection_manager); |
|
|
|
|
auto* filter = http_connection_manager.add_http_filters(); |
|
|
|
|
filter->set_name("unknown"); |
|
|
|
|
filter->mutable_typed_config()->PackFrom(Listener()); |
|
|
|
|
listener.mutable_api_listener()->mutable_api_listener()->PackFrom( |
|
|
|
|
http_connection_manager); |
|
|
|
|
SetListenerAndRouteConfiguration(0, listener, default_route_config_); |
|
|
|
|
SetNextResolution({}); |
|
|
|
|
SetNextResolutionForLbChannelAllBalancers(); |
|
|
|
|
// Wait until xDS server sees NACK.
|
|
|
|
|
do { |
|
|
|
|
CheckRpcSendFailure(); |
|
|
|
|
} while (balancers_[0]->ads_service()->lds_response_state().state == |
|
|
|
|
AdsServiceImpl::ResponseState::SENT); |
|
|
|
|
const auto response_state = |
|
|
|
|
balancers_[0]->ads_service()->lds_response_state(); |
|
|
|
|
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); |
|
|
|
|
EXPECT_THAT(response_state.error_message, |
|
|
|
|
::testing::HasSubstr("no filter registered for config type " |
|
|
|
|
"envoy.config.listener.v3.Listener")); |
|
|
|
|
gpr_unsetenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Test that we ignore optional unknown filter types.
|
|
|
|
|
TEST_P(LdsTest, IgnoresOptionalUnknownHttpFilterType) { |
|
|
|
|
gpr_setenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION", "true"); |
|
|
|
|
auto listener = default_listener_; |
|
|
|
|
HttpConnectionManager http_connection_manager; |
|
|
|
|
listener.mutable_api_listener()->mutable_api_listener()->UnpackTo( |
|
|
|
|
&http_connection_manager); |
|
|
|
|
auto* filter = http_connection_manager.add_http_filters(); |
|
|
|
|
filter->set_name("unknown"); |
|
|
|
|
filter->mutable_typed_config()->PackFrom(Listener()); |
|
|
|
|
filter->set_is_optional(true); |
|
|
|
|
listener.mutable_api_listener()->mutable_api_listener()->PackFrom( |
|
|
|
|
http_connection_manager); |
|
|
|
|
SetListenerAndRouteConfiguration(0, listener, default_route_config_); |
|
|
|
|
AdsServiceImpl::EdsResourceArgs args({ |
|
|
|
|
{"locality0", GetBackendPorts()}, |
|
|
|
|
}); |
|
|
|
|
balancers_[0]->ads_service()->SetEdsResource( |
|
|
|
|
BuildEdsResource(args, DefaultEdsServiceName())); |
|
|
|
|
SetNextResolutionForLbChannelAllBalancers(); |
|
|
|
|
WaitForAllBackends(); |
|
|
|
|
EXPECT_EQ(balancers_[0]->ads_service()->lds_response_state().state, |
|
|
|
|
AdsServiceImpl::ResponseState::ACKED); |
|
|
|
|
gpr_unsetenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Test that we NACK unparseable filter configs.
|
|
|
|
|
TEST_P(LdsTest, RejectsUnparseableHttpFilterType) { |
|
|
|
|
gpr_setenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION", "true"); |
|
|
|
|
auto listener = default_listener_; |
|
|
|
|
HttpConnectionManager http_connection_manager; |
|
|
|
|
listener.mutable_api_listener()->mutable_api_listener()->UnpackTo( |
|
|
|
|
&http_connection_manager); |
|
|
|
|
auto* filter = http_connection_manager.add_http_filters(); |
|
|
|
|
filter->set_name("unknown"); |
|
|
|
|
filter->mutable_typed_config()->PackFrom(listener); |
|
|
|
|
filter->mutable_typed_config()->set_type_url( |
|
|
|
|
"type.googleapis.com/envoy.extensions.filters.http.router.v3.Router"); |
|
|
|
|
listener.mutable_api_listener()->mutable_api_listener()->PackFrom( |
|
|
|
|
http_connection_manager); |
|
|
|
|
SetListenerAndRouteConfiguration(0, listener, default_route_config_); |
|
|
|
|
SetNextResolution({}); |
|
|
|
|
SetNextResolutionForLbChannelAllBalancers(); |
|
|
|
|
// Wait until xDS server sees NACK.
|
|
|
|
|
do { |
|
|
|
|
CheckRpcSendFailure(); |
|
|
|
|
} while (balancers_[0]->ads_service()->lds_response_state().state == |
|
|
|
|
AdsServiceImpl::ResponseState::SENT); |
|
|
|
|
const auto response_state = |
|
|
|
|
balancers_[0]->ads_service()->lds_response_state(); |
|
|
|
|
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); |
|
|
|
|
EXPECT_THAT( |
|
|
|
|
response_state.error_message, |
|
|
|
|
::testing::HasSubstr( |
|
|
|
|
"filter config for type " |
|
|
|
|
"envoy.extensions.filters.http.router.v3.Router failed to parse")); |
|
|
|
|
gpr_unsetenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
using LdsRdsTest = BasicTest; |
|
|
|
|
|
|
|
|
|
// Tests that LDS client should send an ACK upon correct LDS response (with
|
|
|
|
@ -3160,7 +3370,7 @@ TEST_P(LdsRdsTest, NoMatchedDomain) { |
|
|
|
|
CheckRpcSendFailure(); |
|
|
|
|
// Do a bit of polling, to allow the ACK to get to the ADS server.
|
|
|
|
|
channel_->WaitForConnected(grpc_timeout_milliseconds_to_deadline(100)); |
|
|
|
|
const auto& response_state = RouteConfigurationResponseState(0); |
|
|
|
|
const auto response_state = RouteConfigurationResponseState(0); |
|
|
|
|
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::ACKED); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -3207,7 +3417,7 @@ TEST_P(LdsRdsTest, RouteMatchHasQueryParameters) { |
|
|
|
|
SetNextResolution({}); |
|
|
|
|
SetNextResolutionForLbChannelAllBalancers(); |
|
|
|
|
CheckRpcSendFailure(); |
|
|
|
|
const auto& response_state = RouteConfigurationResponseState(0); |
|
|
|
|
const auto response_state = RouteConfigurationResponseState(0); |
|
|
|
|
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); |
|
|
|
|
EXPECT_THAT(response_state.error_message, |
|
|
|
|
::testing::HasSubstr("No valid routes specified.")); |
|
|
|
@ -3226,7 +3436,7 @@ TEST_P(LdsRdsTest, RouteMatchHasValidPrefixEmptyOrSingleSlash) { |
|
|
|
|
SetNextResolution({}); |
|
|
|
|
SetNextResolutionForLbChannelAllBalancers(); |
|
|
|
|
(void)SendRpc(); |
|
|
|
|
const auto& response_state = RouteConfigurationResponseState(0); |
|
|
|
|
const auto response_state = RouteConfigurationResponseState(0); |
|
|
|
|
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::ACKED); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -3240,7 +3450,7 @@ TEST_P(LdsRdsTest, RouteMatchHasInvalidPrefixNoLeadingSlash) { |
|
|
|
|
SetNextResolution({}); |
|
|
|
|
SetNextResolutionForLbChannelAllBalancers(); |
|
|
|
|
CheckRpcSendFailure(); |
|
|
|
|
const auto& response_state = RouteConfigurationResponseState(0); |
|
|
|
|
const auto response_state = RouteConfigurationResponseState(0); |
|
|
|
|
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); |
|
|
|
|
EXPECT_THAT(response_state.error_message, |
|
|
|
|
::testing::HasSubstr("No valid routes specified.")); |
|
|
|
@ -3256,7 +3466,7 @@ TEST_P(LdsRdsTest, RouteMatchHasInvalidPrefixExtraContent) { |
|
|
|
|
SetNextResolution({}); |
|
|
|
|
SetNextResolutionForLbChannelAllBalancers(); |
|
|
|
|
CheckRpcSendFailure(); |
|
|
|
|
const auto& response_state = RouteConfigurationResponseState(0); |
|
|
|
|
const auto response_state = RouteConfigurationResponseState(0); |
|
|
|
|
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); |
|
|
|
|
EXPECT_THAT(response_state.error_message, |
|
|
|
|
::testing::HasSubstr("No valid routes specified.")); |
|
|
|
@ -3272,7 +3482,7 @@ TEST_P(LdsRdsTest, RouteMatchHasInvalidPrefixDoubleSlash) { |
|
|
|
|
SetNextResolution({}); |
|
|
|
|
SetNextResolutionForLbChannelAllBalancers(); |
|
|
|
|
CheckRpcSendFailure(); |
|
|
|
|
const auto& response_state = RouteConfigurationResponseState(0); |
|
|
|
|
const auto response_state = RouteConfigurationResponseState(0); |
|
|
|
|
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); |
|
|
|
|
EXPECT_THAT(response_state.error_message, |
|
|
|
|
::testing::HasSubstr("No valid routes specified.")); |
|
|
|
@ -3288,7 +3498,7 @@ TEST_P(LdsRdsTest, RouteMatchHasInvalidPathEmptyPath) { |
|
|
|
|
SetNextResolution({}); |
|
|
|
|
SetNextResolutionForLbChannelAllBalancers(); |
|
|
|
|
CheckRpcSendFailure(); |
|
|
|
|
const auto& response_state = RouteConfigurationResponseState(0); |
|
|
|
|
const auto response_state = RouteConfigurationResponseState(0); |
|
|
|
|
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); |
|
|
|
|
EXPECT_THAT(response_state.error_message, |
|
|
|
|
::testing::HasSubstr("No valid routes specified.")); |
|
|
|
@ -3304,7 +3514,7 @@ TEST_P(LdsRdsTest, RouteMatchHasInvalidPathNoLeadingSlash) { |
|
|
|
|
SetNextResolution({}); |
|
|
|
|
SetNextResolutionForLbChannelAllBalancers(); |
|
|
|
|
CheckRpcSendFailure(); |
|
|
|
|
const auto& response_state = RouteConfigurationResponseState(0); |
|
|
|
|
const auto response_state = RouteConfigurationResponseState(0); |
|
|
|
|
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); |
|
|
|
|
EXPECT_THAT(response_state.error_message, |
|
|
|
|
::testing::HasSubstr("No valid routes specified.")); |
|
|
|
@ -3320,7 +3530,7 @@ TEST_P(LdsRdsTest, RouteMatchHasInvalidPathTooManySlashes) { |
|
|
|
|
SetNextResolution({}); |
|
|
|
|
SetNextResolutionForLbChannelAllBalancers(); |
|
|
|
|
CheckRpcSendFailure(); |
|
|
|
|
const auto& response_state = RouteConfigurationResponseState(0); |
|
|
|
|
const auto response_state = RouteConfigurationResponseState(0); |
|
|
|
|
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); |
|
|
|
|
EXPECT_THAT(response_state.error_message, |
|
|
|
|
::testing::HasSubstr("No valid routes specified.")); |
|
|
|
@ -3336,7 +3546,7 @@ TEST_P(LdsRdsTest, RouteMatchHasInvalidPathOnlyOneSlash) { |
|
|
|
|
SetNextResolution({}); |
|
|
|
|
SetNextResolutionForLbChannelAllBalancers(); |
|
|
|
|
CheckRpcSendFailure(); |
|
|
|
|
const auto& response_state = RouteConfigurationResponseState(0); |
|
|
|
|
const auto response_state = RouteConfigurationResponseState(0); |
|
|
|
|
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); |
|
|
|
|
EXPECT_THAT(response_state.error_message, |
|
|
|
|
::testing::HasSubstr("No valid routes specified.")); |
|
|
|
@ -3352,7 +3562,7 @@ TEST_P(LdsRdsTest, RouteMatchHasInvalidPathMissingService) { |
|
|
|
|
SetNextResolution({}); |
|
|
|
|
SetNextResolutionForLbChannelAllBalancers(); |
|
|
|
|
CheckRpcSendFailure(); |
|
|
|
|
const auto& response_state = RouteConfigurationResponseState(0); |
|
|
|
|
const auto response_state = RouteConfigurationResponseState(0); |
|
|
|
|
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); |
|
|
|
|
EXPECT_THAT(response_state.error_message, |
|
|
|
|
::testing::HasSubstr("No valid routes specified.")); |
|
|
|
@ -3368,7 +3578,7 @@ TEST_P(LdsRdsTest, RouteMatchHasInvalidPathMissingMethod) { |
|
|
|
|
SetNextResolution({}); |
|
|
|
|
SetNextResolutionForLbChannelAllBalancers(); |
|
|
|
|
CheckRpcSendFailure(); |
|
|
|
|
const auto& response_state = RouteConfigurationResponseState(0); |
|
|
|
|
const auto response_state = RouteConfigurationResponseState(0); |
|
|
|
|
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); |
|
|
|
|
EXPECT_THAT(response_state.error_message, |
|
|
|
|
::testing::HasSubstr("No valid routes specified.")); |
|
|
|
@ -3385,7 +3595,7 @@ TEST_P(LdsRdsTest, RouteMatchHasInvalidPathRegex) { |
|
|
|
|
SetNextResolution({}); |
|
|
|
|
SetNextResolutionForLbChannelAllBalancers(); |
|
|
|
|
CheckRpcSendFailure(); |
|
|
|
|
const auto& response_state = RouteConfigurationResponseState(0); |
|
|
|
|
const auto response_state = RouteConfigurationResponseState(0); |
|
|
|
|
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); |
|
|
|
|
EXPECT_THAT(response_state.error_message, |
|
|
|
|
::testing::HasSubstr( |
|
|
|
@ -3401,7 +3611,7 @@ TEST_P(LdsRdsTest, RouteHasNoRouteAction) { |
|
|
|
|
SetNextResolution({}); |
|
|
|
|
SetNextResolutionForLbChannelAllBalancers(); |
|
|
|
|
CheckRpcSendFailure(); |
|
|
|
|
const auto& response_state = RouteConfigurationResponseState(0); |
|
|
|
|
const auto response_state = RouteConfigurationResponseState(0); |
|
|
|
|
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); |
|
|
|
|
EXPECT_THAT(response_state.error_message, |
|
|
|
|
::testing::HasSubstr("No RouteAction found in route.")); |
|
|
|
@ -3419,7 +3629,7 @@ TEST_P(LdsRdsTest, RouteActionClusterHasEmptyClusterName) { |
|
|
|
|
SetNextResolution({}); |
|
|
|
|
SetNextResolutionForLbChannelAllBalancers(); |
|
|
|
|
CheckRpcSendFailure(); |
|
|
|
|
const auto& response_state = RouteConfigurationResponseState(0); |
|
|
|
|
const auto response_state = RouteConfigurationResponseState(0); |
|
|
|
|
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); |
|
|
|
|
EXPECT_THAT( |
|
|
|
|
response_state.error_message, |
|
|
|
@ -3447,7 +3657,7 @@ TEST_P(LdsRdsTest, RouteActionWeightedTargetHasIncorrectTotalWeightSet) { |
|
|
|
|
SetNextResolution({}); |
|
|
|
|
SetNextResolutionForLbChannelAllBalancers(); |
|
|
|
|
CheckRpcSendFailure(); |
|
|
|
|
const auto& response_state = RouteConfigurationResponseState(0); |
|
|
|
|
const auto response_state = RouteConfigurationResponseState(0); |
|
|
|
|
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); |
|
|
|
|
EXPECT_THAT(response_state.error_message, |
|
|
|
|
::testing::HasSubstr( |
|
|
|
@ -3474,7 +3684,7 @@ TEST_P(LdsRdsTest, RouteActionWeightedClusterHasZeroTotalWeight) { |
|
|
|
|
SetNextResolution({}); |
|
|
|
|
SetNextResolutionForLbChannelAllBalancers(); |
|
|
|
|
CheckRpcSendFailure(); |
|
|
|
|
const auto& response_state = RouteConfigurationResponseState(0); |
|
|
|
|
const auto response_state = RouteConfigurationResponseState(0); |
|
|
|
|
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); |
|
|
|
|
EXPECT_THAT( |
|
|
|
|
response_state.error_message, |
|
|
|
@ -3502,7 +3712,7 @@ TEST_P(LdsRdsTest, RouteActionWeightedTargetClusterHasEmptyClusterName) { |
|
|
|
|
SetNextResolution({}); |
|
|
|
|
SetNextResolutionForLbChannelAllBalancers(); |
|
|
|
|
CheckRpcSendFailure(); |
|
|
|
|
const auto& response_state = RouteConfigurationResponseState(0); |
|
|
|
|
const auto response_state = RouteConfigurationResponseState(0); |
|
|
|
|
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); |
|
|
|
|
EXPECT_THAT( |
|
|
|
|
response_state.error_message, |
|
|
|
@ -3530,7 +3740,7 @@ TEST_P(LdsRdsTest, RouteActionWeightedTargetClusterHasNoWeight) { |
|
|
|
|
SetNextResolution({}); |
|
|
|
|
SetNextResolutionForLbChannelAllBalancers(); |
|
|
|
|
CheckRpcSendFailure(); |
|
|
|
|
const auto& response_state = RouteConfigurationResponseState(0); |
|
|
|
|
const auto response_state = RouteConfigurationResponseState(0); |
|
|
|
|
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); |
|
|
|
|
EXPECT_THAT(response_state.error_message, |
|
|
|
|
::testing::HasSubstr( |
|
|
|
@ -3550,7 +3760,7 @@ TEST_P(LdsRdsTest, RouteHeaderMatchInvalidRegex) { |
|
|
|
|
SetNextResolution({}); |
|
|
|
|
SetNextResolutionForLbChannelAllBalancers(); |
|
|
|
|
CheckRpcSendFailure(); |
|
|
|
|
const auto& response_state = RouteConfigurationResponseState(0); |
|
|
|
|
const auto response_state = RouteConfigurationResponseState(0); |
|
|
|
|
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); |
|
|
|
|
EXPECT_THAT( |
|
|
|
|
response_state.error_message, |
|
|
|
@ -3572,7 +3782,7 @@ TEST_P(LdsRdsTest, RouteHeaderMatchInvalidRange) { |
|
|
|
|
SetNextResolution({}); |
|
|
|
|
SetNextResolutionForLbChannelAllBalancers(); |
|
|
|
|
CheckRpcSendFailure(); |
|
|
|
|
const auto& response_state = RouteConfigurationResponseState(0); |
|
|
|
|
const auto response_state = RouteConfigurationResponseState(0); |
|
|
|
|
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); |
|
|
|
|
EXPECT_THAT( |
|
|
|
|
response_state.error_message, |
|
|
|
@ -4634,6 +4844,8 @@ TEST_P(LdsRdsTest, XdsRoutingApplyXdsTimeout) { |
|
|
|
|
// Construct listener.
|
|
|
|
|
auto listener = default_listener_; |
|
|
|
|
HttpConnectionManager http_connection_manager; |
|
|
|
|
listener.mutable_api_listener()->mutable_api_listener()->UnpackTo( |
|
|
|
|
&http_connection_manager); |
|
|
|
|
// Set up HTTP max_stream_duration of 3.5 seconds
|
|
|
|
|
auto* duration = |
|
|
|
|
http_connection_manager.mutable_common_http_protocol_options() |
|
|
|
@ -4772,6 +4984,8 @@ TEST_P(LdsRdsTest, XdsRoutingHttpTimeoutDisabled) { |
|
|
|
|
// Construct listener.
|
|
|
|
|
auto listener = default_listener_; |
|
|
|
|
HttpConnectionManager http_connection_manager; |
|
|
|
|
listener.mutable_api_listener()->mutable_api_listener()->UnpackTo( |
|
|
|
|
&http_connection_manager); |
|
|
|
|
// Set up HTTP max_stream_duration of 3.5 seconds
|
|
|
|
|
auto* duration = |
|
|
|
|
http_connection_manager.mutable_common_http_protocol_options() |
|
|
|
@ -4837,6 +5051,8 @@ TEST_P(LdsRdsTest, XdsRoutingApplyApplicationTimeoutWhenXdsTimeoutExplicit0) { |
|
|
|
|
// Construct listener.
|
|
|
|
|
auto listener = default_listener_; |
|
|
|
|
HttpConnectionManager http_connection_manager; |
|
|
|
|
listener.mutable_api_listener()->mutable_api_listener()->UnpackTo( |
|
|
|
|
&http_connection_manager); |
|
|
|
|
// Set up HTTP max_stream_duration of 3.5 seconds
|
|
|
|
|
auto* duration = |
|
|
|
|
http_connection_manager.mutable_common_http_protocol_options() |
|
|
|
@ -4910,14 +5126,16 @@ TEST_P(LdsRdsTest, XdsRoutingApplyApplicationTimeoutWhenHttpTimeoutExplicit0) { |
|
|
|
|
{"locality0", {g_port_saver->GetPort()}}, |
|
|
|
|
}); |
|
|
|
|
balancers_[0]->ads_service()->SetEdsResource(BuildEdsResource(args)); |
|
|
|
|
auto listener = default_listener_; |
|
|
|
|
HttpConnectionManager http_connection_manager; |
|
|
|
|
listener.mutable_api_listener()->mutable_api_listener()->UnpackTo( |
|
|
|
|
&http_connection_manager); |
|
|
|
|
// Set up HTTP max_stream_duration to be explicit 0
|
|
|
|
|
auto* duration = |
|
|
|
|
http_connection_manager.mutable_common_http_protocol_options() |
|
|
|
|
->mutable_max_stream_duration(); |
|
|
|
|
duration->set_seconds(0); |
|
|
|
|
duration->set_nanos(0); |
|
|
|
|
auto listener = default_listener_; |
|
|
|
|
listener.mutable_api_listener()->mutable_api_listener()->PackFrom( |
|
|
|
|
http_connection_manager); |
|
|
|
|
// Set listener and route config.
|
|
|
|
@ -5043,7 +5261,7 @@ TEST_P(LdsRdsTest, XdsRoutingHeadersMatching) { |
|
|
|
|
EXPECT_EQ(0, backends_[1]->backend_service()->request_count()); |
|
|
|
|
EXPECT_EQ(kNumEcho1Rpcs, backends_[1]->backend_service1()->request_count()); |
|
|
|
|
EXPECT_EQ(0, backends_[1]->backend_service2()->request_count()); |
|
|
|
|
const auto& response_state = RouteConfigurationResponseState(0); |
|
|
|
|
const auto response_state = RouteConfigurationResponseState(0); |
|
|
|
|
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::ACKED); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -5090,7 +5308,7 @@ TEST_P(LdsRdsTest, XdsRoutingHeadersMatchingSpecialHeaderContentType) { |
|
|
|
|
CheckRpcSendOk(kNumEchoRpcs); |
|
|
|
|
EXPECT_EQ(kNumEchoRpcs, backends_[0]->backend_service()->request_count()); |
|
|
|
|
EXPECT_EQ(0, backends_[1]->backend_service()->request_count()); |
|
|
|
|
const auto& response_state = RouteConfigurationResponseState(0); |
|
|
|
|
const auto response_state = RouteConfigurationResponseState(0); |
|
|
|
|
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::ACKED); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -5158,7 +5376,7 @@ TEST_P(LdsRdsTest, XdsRoutingHeadersMatchingSpecialCasesToIgnore) { |
|
|
|
|
EXPECT_EQ(kNumEchoRpcs, backends_[0]->backend_service()->request_count()); |
|
|
|
|
EXPECT_EQ(0, backends_[1]->backend_service()->request_count()); |
|
|
|
|
EXPECT_EQ(0, backends_[2]->backend_service()->request_count()); |
|
|
|
|
const auto& response_state = RouteConfigurationResponseState(0); |
|
|
|
|
const auto response_state = RouteConfigurationResponseState(0); |
|
|
|
|
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::ACKED); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -5215,7 +5433,7 @@ TEST_P(LdsRdsTest, XdsRoutingRuntimeFractionMatching) { |
|
|
|
|
(1 - kErrorTolerance)), |
|
|
|
|
::testing::Le(static_cast<double>(kNumRpcs) * 25 / 100 * |
|
|
|
|
(1 + kErrorTolerance)))); |
|
|
|
|
const auto& response_state = RouteConfigurationResponseState(0); |
|
|
|
|
const auto response_state = RouteConfigurationResponseState(0); |
|
|
|
|
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::ACKED); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -5314,7 +5532,7 @@ TEST_P(LdsRdsTest, XdsRoutingHeadersMatchingUnmatchCases) { |
|
|
|
|
EXPECT_EQ(kNumEchoRpcs, backends_[0]->backend_service()->request_count()); |
|
|
|
|
EXPECT_EQ(kNumEcho1Rpcs, backends_[0]->backend_service1()->request_count()); |
|
|
|
|
EXPECT_EQ(0, backends_[0]->backend_service2()->request_count()); |
|
|
|
|
const auto& response_state = RouteConfigurationResponseState(0); |
|
|
|
|
const auto response_state = RouteConfigurationResponseState(0); |
|
|
|
|
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::ACKED); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -5381,6 +5599,253 @@ TEST_P(LdsRdsTest, XdsRoutingChangeRoutesWithoutChangingClusters) { |
|
|
|
|
EXPECT_EQ(1, backends_[1]->backend_service2()->request_count()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Test that we NACK unknown filter types in VirtualHost.
|
|
|
|
|
TEST_P(LdsRdsTest, RejectsUnknownHttpFilterTypeInVirtualHost) { |
|
|
|
|
if (GetParam().use_v2()) return; // Filters supported in v3 only.
|
|
|
|
|
gpr_setenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION", "true"); |
|
|
|
|
RouteConfiguration route_config = default_route_config_; |
|
|
|
|
auto* per_filter_config = |
|
|
|
|
route_config.mutable_virtual_hosts(0)->mutable_typed_per_filter_config(); |
|
|
|
|
(*per_filter_config)["unknown"].PackFrom(Listener()); |
|
|
|
|
SetListenerAndRouteConfiguration(0, default_listener_, route_config); |
|
|
|
|
SetNextResolution({}); |
|
|
|
|
SetNextResolutionForLbChannelAllBalancers(); |
|
|
|
|
// Wait until xDS server sees NACK.
|
|
|
|
|
do { |
|
|
|
|
CheckRpcSendFailure(); |
|
|
|
|
} while (RouteConfigurationResponseState(0).state == |
|
|
|
|
AdsServiceImpl::ResponseState::SENT); |
|
|
|
|
const auto response_state = RouteConfigurationResponseState(0); |
|
|
|
|
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); |
|
|
|
|
EXPECT_THAT(response_state.error_message, |
|
|
|
|
::testing::HasSubstr("no filter registered for config type " |
|
|
|
|
"envoy.config.listener.v3.Listener")); |
|
|
|
|
gpr_unsetenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Test that we ignore optional unknown filter types in VirtualHost.
|
|
|
|
|
TEST_P(LdsRdsTest, IgnoresOptionalUnknownHttpFilterTypeInVirtualHost) { |
|
|
|
|
if (GetParam().use_v2()) return; // Filters supported in v3 only.
|
|
|
|
|
gpr_setenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION", "true"); |
|
|
|
|
RouteConfiguration route_config = default_route_config_; |
|
|
|
|
auto* per_filter_config = |
|
|
|
|
route_config.mutable_virtual_hosts(0)->mutable_typed_per_filter_config(); |
|
|
|
|
::envoy::config::route::v3::FilterConfig filter_config; |
|
|
|
|
filter_config.mutable_config()->PackFrom(Listener()); |
|
|
|
|
filter_config.set_is_optional(true); |
|
|
|
|
(*per_filter_config)["unknown"].PackFrom(filter_config); |
|
|
|
|
SetListenerAndRouteConfiguration(0, default_listener_, route_config); |
|
|
|
|
AdsServiceImpl::EdsResourceArgs args({ |
|
|
|
|
{"locality0", GetBackendPorts()}, |
|
|
|
|
}); |
|
|
|
|
balancers_[0]->ads_service()->SetEdsResource( |
|
|
|
|
BuildEdsResource(args, DefaultEdsServiceName())); |
|
|
|
|
SetNextResolution({}); |
|
|
|
|
SetNextResolutionForLbChannelAllBalancers(); |
|
|
|
|
WaitForAllBackends(); |
|
|
|
|
EXPECT_EQ(RouteConfigurationResponseState(0).state, |
|
|
|
|
AdsServiceImpl::ResponseState::ACKED); |
|
|
|
|
gpr_unsetenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Test that we NACK unparseable filter types in VirtualHost.
|
|
|
|
|
TEST_P(LdsRdsTest, RejectsUnparseableHttpFilterTypeInVirtualHost) { |
|
|
|
|
if (GetParam().use_v2()) return; // Filters supported in v3 only.
|
|
|
|
|
gpr_setenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION", "true"); |
|
|
|
|
RouteConfiguration route_config = default_route_config_; |
|
|
|
|
auto* per_filter_config = |
|
|
|
|
route_config.mutable_virtual_hosts(0)->mutable_typed_per_filter_config(); |
|
|
|
|
(*per_filter_config)["unknown"].PackFrom( |
|
|
|
|
envoy::extensions::filters::http::router::v3::Router()); |
|
|
|
|
SetListenerAndRouteConfiguration(0, default_listener_, route_config); |
|
|
|
|
SetNextResolution({}); |
|
|
|
|
SetNextResolutionForLbChannelAllBalancers(); |
|
|
|
|
// Wait until xDS server sees NACK.
|
|
|
|
|
do { |
|
|
|
|
CheckRpcSendFailure(); |
|
|
|
|
} while (RouteConfigurationResponseState(0).state == |
|
|
|
|
AdsServiceImpl::ResponseState::SENT); |
|
|
|
|
const auto response_state = RouteConfigurationResponseState(0); |
|
|
|
|
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); |
|
|
|
|
EXPECT_THAT( |
|
|
|
|
response_state.error_message, |
|
|
|
|
::testing::HasSubstr("router filter does not support config override")); |
|
|
|
|
gpr_unsetenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Test that we NACK unknown filter types in Route.
|
|
|
|
|
TEST_P(LdsRdsTest, RejectsUnknownHttpFilterTypeInRoute) { |
|
|
|
|
if (GetParam().use_v2()) return; // Filters supported in v3 only.
|
|
|
|
|
gpr_setenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION", "true"); |
|
|
|
|
RouteConfiguration route_config = default_route_config_; |
|
|
|
|
auto* per_filter_config = route_config.mutable_virtual_hosts(0) |
|
|
|
|
->mutable_routes(0) |
|
|
|
|
->mutable_typed_per_filter_config(); |
|
|
|
|
(*per_filter_config)["unknown"].PackFrom(Listener()); |
|
|
|
|
SetListenerAndRouteConfiguration(0, default_listener_, route_config); |
|
|
|
|
SetNextResolution({}); |
|
|
|
|
SetNextResolutionForLbChannelAllBalancers(); |
|
|
|
|
// Wait until xDS server sees NACK.
|
|
|
|
|
do { |
|
|
|
|
CheckRpcSendFailure(); |
|
|
|
|
} while (RouteConfigurationResponseState(0).state == |
|
|
|
|
AdsServiceImpl::ResponseState::SENT); |
|
|
|
|
const auto response_state = RouteConfigurationResponseState(0); |
|
|
|
|
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); |
|
|
|
|
EXPECT_THAT(response_state.error_message, |
|
|
|
|
::testing::HasSubstr("no filter registered for config type " |
|
|
|
|
"envoy.config.listener.v3.Listener")); |
|
|
|
|
gpr_unsetenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Test that we ignore optional unknown filter types in Route.
|
|
|
|
|
TEST_P(LdsRdsTest, IgnoresOptionalUnknownHttpFilterTypeInRoute) { |
|
|
|
|
if (GetParam().use_v2()) return; // Filters supported in v3 only.
|
|
|
|
|
gpr_setenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION", "true"); |
|
|
|
|
RouteConfiguration route_config = default_route_config_; |
|
|
|
|
auto* per_filter_config = route_config.mutable_virtual_hosts(0) |
|
|
|
|
->mutable_routes(0) |
|
|
|
|
->mutable_typed_per_filter_config(); |
|
|
|
|
::envoy::config::route::v3::FilterConfig filter_config; |
|
|
|
|
filter_config.mutable_config()->PackFrom(Listener()); |
|
|
|
|
filter_config.set_is_optional(true); |
|
|
|
|
(*per_filter_config)["unknown"].PackFrom(filter_config); |
|
|
|
|
SetListenerAndRouteConfiguration(0, default_listener_, route_config); |
|
|
|
|
AdsServiceImpl::EdsResourceArgs args({ |
|
|
|
|
{"locality0", GetBackendPorts()}, |
|
|
|
|
}); |
|
|
|
|
balancers_[0]->ads_service()->SetEdsResource( |
|
|
|
|
BuildEdsResource(args, DefaultEdsServiceName())); |
|
|
|
|
SetNextResolution({}); |
|
|
|
|
SetNextResolutionForLbChannelAllBalancers(); |
|
|
|
|
WaitForAllBackends(); |
|
|
|
|
EXPECT_EQ(RouteConfigurationResponseState(0).state, |
|
|
|
|
AdsServiceImpl::ResponseState::ACKED); |
|
|
|
|
gpr_unsetenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Test that we NACK unparseable filter types in Route.
|
|
|
|
|
TEST_P(LdsRdsTest, RejectsUnparseableHttpFilterTypeInRoute) { |
|
|
|
|
if (GetParam().use_v2()) return; // Filters supported in v3 only.
|
|
|
|
|
gpr_setenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION", "true"); |
|
|
|
|
RouteConfiguration route_config = default_route_config_; |
|
|
|
|
auto* per_filter_config = route_config.mutable_virtual_hosts(0) |
|
|
|
|
->mutable_routes(0) |
|
|
|
|
->mutable_typed_per_filter_config(); |
|
|
|
|
(*per_filter_config)["unknown"].PackFrom( |
|
|
|
|
envoy::extensions::filters::http::router::v3::Router()); |
|
|
|
|
SetListenerAndRouteConfiguration(0, default_listener_, route_config); |
|
|
|
|
SetNextResolution({}); |
|
|
|
|
SetNextResolutionForLbChannelAllBalancers(); |
|
|
|
|
// Wait until xDS server sees NACK.
|
|
|
|
|
do { |
|
|
|
|
CheckRpcSendFailure(); |
|
|
|
|
} while (RouteConfigurationResponseState(0).state == |
|
|
|
|
AdsServiceImpl::ResponseState::SENT); |
|
|
|
|
const auto response_state = RouteConfigurationResponseState(0); |
|
|
|
|
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); |
|
|
|
|
EXPECT_THAT( |
|
|
|
|
response_state.error_message, |
|
|
|
|
::testing::HasSubstr("router filter does not support config override")); |
|
|
|
|
gpr_unsetenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Test that we NACK unknown filter types in ClusterWeight.
|
|
|
|
|
TEST_P(LdsRdsTest, RejectsUnknownHttpFilterTypeInClusterWeight) { |
|
|
|
|
if (GetParam().use_v2()) return; // Filters supported in v3 only.
|
|
|
|
|
gpr_setenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION", "true"); |
|
|
|
|
RouteConfiguration route_config = default_route_config_; |
|
|
|
|
auto* cluster_weight = route_config.mutable_virtual_hosts(0) |
|
|
|
|
->mutable_routes(0) |
|
|
|
|
->mutable_route() |
|
|
|
|
->mutable_weighted_clusters() |
|
|
|
|
->add_clusters(); |
|
|
|
|
cluster_weight->set_name(kDefaultClusterName); |
|
|
|
|
cluster_weight->mutable_weight()->set_value(100); |
|
|
|
|
auto* per_filter_config = cluster_weight->mutable_typed_per_filter_config(); |
|
|
|
|
(*per_filter_config)["unknown"].PackFrom(Listener()); |
|
|
|
|
SetListenerAndRouteConfiguration(0, default_listener_, route_config); |
|
|
|
|
SetNextResolution({}); |
|
|
|
|
SetNextResolutionForLbChannelAllBalancers(); |
|
|
|
|
// Wait until xDS server sees NACK.
|
|
|
|
|
do { |
|
|
|
|
CheckRpcSendFailure(); |
|
|
|
|
} while (RouteConfigurationResponseState(0).state == |
|
|
|
|
AdsServiceImpl::ResponseState::SENT); |
|
|
|
|
const auto response_state = RouteConfigurationResponseState(0); |
|
|
|
|
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); |
|
|
|
|
EXPECT_THAT(response_state.error_message, |
|
|
|
|
::testing::HasSubstr("no filter registered for config type " |
|
|
|
|
"envoy.config.listener.v3.Listener")); |
|
|
|
|
gpr_unsetenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Test that we ignore optional unknown filter types in ClusterWeight.
|
|
|
|
|
TEST_P(LdsRdsTest, IgnoresOptionalUnknownHttpFilterTypeInClusterWeight) { |
|
|
|
|
if (GetParam().use_v2()) return; // Filters supported in v3 only.
|
|
|
|
|
gpr_setenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION", "true"); |
|
|
|
|
RouteConfiguration route_config = default_route_config_; |
|
|
|
|
auto* cluster_weight = route_config.mutable_virtual_hosts(0) |
|
|
|
|
->mutable_routes(0) |
|
|
|
|
->mutable_route() |
|
|
|
|
->mutable_weighted_clusters() |
|
|
|
|
->add_clusters(); |
|
|
|
|
cluster_weight->set_name(kDefaultClusterName); |
|
|
|
|
cluster_weight->mutable_weight()->set_value(100); |
|
|
|
|
auto* per_filter_config = cluster_weight->mutable_typed_per_filter_config(); |
|
|
|
|
::envoy::config::route::v3::FilterConfig filter_config; |
|
|
|
|
filter_config.mutable_config()->PackFrom(Listener()); |
|
|
|
|
filter_config.set_is_optional(true); |
|
|
|
|
(*per_filter_config)["unknown"].PackFrom(filter_config); |
|
|
|
|
SetListenerAndRouteConfiguration(0, default_listener_, route_config); |
|
|
|
|
AdsServiceImpl::EdsResourceArgs args({ |
|
|
|
|
{"locality0", GetBackendPorts()}, |
|
|
|
|
}); |
|
|
|
|
balancers_[0]->ads_service()->SetEdsResource( |
|
|
|
|
BuildEdsResource(args, DefaultEdsServiceName())); |
|
|
|
|
SetNextResolution({}); |
|
|
|
|
SetNextResolutionForLbChannelAllBalancers(); |
|
|
|
|
WaitForAllBackends(); |
|
|
|
|
EXPECT_EQ(RouteConfigurationResponseState(0).state, |
|
|
|
|
AdsServiceImpl::ResponseState::ACKED); |
|
|
|
|
gpr_unsetenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Test that we NACK unparseable filter types in ClusterWeight.
|
|
|
|
|
TEST_P(LdsRdsTest, RejectsUnparseableHttpFilterTypeInClusterWeight) { |
|
|
|
|
if (GetParam().use_v2()) return; // Filters supported in v3 only.
|
|
|
|
|
gpr_setenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION", "true"); |
|
|
|
|
RouteConfiguration route_config = default_route_config_; |
|
|
|
|
auto* cluster_weight = route_config.mutable_virtual_hosts(0) |
|
|
|
|
->mutable_routes(0) |
|
|
|
|
->mutable_route() |
|
|
|
|
->mutable_weighted_clusters() |
|
|
|
|
->add_clusters(); |
|
|
|
|
cluster_weight->set_name(kDefaultClusterName); |
|
|
|
|
cluster_weight->mutable_weight()->set_value(100); |
|
|
|
|
auto* per_filter_config = cluster_weight->mutable_typed_per_filter_config(); |
|
|
|
|
(*per_filter_config)["unknown"].PackFrom( |
|
|
|
|
envoy::extensions::filters::http::router::v3::Router()); |
|
|
|
|
SetListenerAndRouteConfiguration(0, default_listener_, route_config); |
|
|
|
|
SetNextResolution({}); |
|
|
|
|
SetNextResolutionForLbChannelAllBalancers(); |
|
|
|
|
// Wait until xDS server sees NACK.
|
|
|
|
|
do { |
|
|
|
|
CheckRpcSendFailure(); |
|
|
|
|
} while (RouteConfigurationResponseState(0).state == |
|
|
|
|
AdsServiceImpl::ResponseState::SENT); |
|
|
|
|
const auto response_state = RouteConfigurationResponseState(0); |
|
|
|
|
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); |
|
|
|
|
EXPECT_THAT( |
|
|
|
|
response_state.error_message, |
|
|
|
|
::testing::HasSubstr("router filter does not support config override")); |
|
|
|
|
gpr_unsetenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// TODO(lidiz): As part of adding the fault injection filter, add tests
|
|
|
|
|
// for overriding filter configs in the typed_per_filter_config fields in
|
|
|
|
|
// each of VirtualHost, Route, and ClusterWeight.
|
|
|
|
|
|
|
|
|
|
using CdsTest = BasicTest; |
|
|
|
|
|
|
|
|
|
// Tests that CDS client should send an ACK upon correct CDS response.
|
|
|
|
@ -5590,7 +6055,7 @@ TEST_P(CdsTest, LogicalDNSClusterTypeDisabled) { |
|
|
|
|
SetNextResolution({}); |
|
|
|
|
SetNextResolutionForLbChannelAllBalancers(); |
|
|
|
|
CheckRpcSendFailure(); |
|
|
|
|
const auto& response_state = |
|
|
|
|
const auto response_state = |
|
|
|
|
balancers_[0]->ads_service()->cds_response_state(); |
|
|
|
|
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); |
|
|
|
|
EXPECT_THAT(response_state.error_message, |
|
|
|
@ -5612,7 +6077,7 @@ TEST_P(CdsTest, AggregateClusterTypeDisabled) { |
|
|
|
|
SetNextResolution({}); |
|
|
|
|
SetNextResolutionForLbChannelAllBalancers(); |
|
|
|
|
CheckRpcSendFailure(); |
|
|
|
|
const auto& response_state = |
|
|
|
|
const auto response_state = |
|
|
|
|
balancers_[0]->ads_service()->cds_response_state(); |
|
|
|
|
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); |
|
|
|
|
EXPECT_THAT(response_state.error_message, |
|
|
|
@ -5628,7 +6093,7 @@ TEST_P(CdsTest, UnsupportedClusterType) { |
|
|
|
|
SetNextResolution({}); |
|
|
|
|
SetNextResolutionForLbChannelAllBalancers(); |
|
|
|
|
CheckRpcSendFailure(); |
|
|
|
|
const auto& response_state = |
|
|
|
|
const auto response_state = |
|
|
|
|
balancers_[0]->ads_service()->cds_response_state(); |
|
|
|
|
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); |
|
|
|
|
EXPECT_THAT(response_state.error_message, |
|
|
|
@ -5655,7 +6120,7 @@ TEST_P(CdsTest, MultipleBadResources) { |
|
|
|
|
SetNextResolution({}); |
|
|
|
|
SetNextResolutionForLbChannelAllBalancers(); |
|
|
|
|
CheckRpcSendFailure(); |
|
|
|
|
const auto& response_state = |
|
|
|
|
const auto response_state = |
|
|
|
|
balancers_[0]->ads_service()->cds_response_state(); |
|
|
|
|
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); |
|
|
|
|
EXPECT_THAT(response_state.error_message, |
|
|
|
@ -5675,7 +6140,7 @@ TEST_P(CdsTest, WrongEdsConfig) { |
|
|
|
|
SetNextResolution({}); |
|
|
|
|
SetNextResolutionForLbChannelAllBalancers(); |
|
|
|
|
CheckRpcSendFailure(); |
|
|
|
|
const auto& response_state = |
|
|
|
|
const auto response_state = |
|
|
|
|
balancers_[0]->ads_service()->cds_response_state(); |
|
|
|
|
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); |
|
|
|
|
EXPECT_THAT(response_state.error_message, |
|
|
|
@ -5691,7 +6156,7 @@ TEST_P(CdsTest, WrongLbPolicy) { |
|
|
|
|
SetNextResolution({}); |
|
|
|
|
SetNextResolutionForLbChannelAllBalancers(); |
|
|
|
|
CheckRpcSendFailure(); |
|
|
|
|
const auto& response_state = |
|
|
|
|
const auto response_state = |
|
|
|
|
balancers_[0]->ads_service()->cds_response_state(); |
|
|
|
|
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); |
|
|
|
|
EXPECT_THAT(response_state.error_message, |
|
|
|
@ -5707,7 +6172,7 @@ TEST_P(CdsTest, WrongLrsServer) { |
|
|
|
|
SetNextResolution({}); |
|
|
|
|
SetNextResolutionForLbChannelAllBalancers(); |
|
|
|
|
CheckRpcSendFailure(); |
|
|
|
|
const auto& response_state = |
|
|
|
|
const auto response_state = |
|
|
|
|
balancers_[0]->ads_service()->cds_response_state(); |
|
|
|
|
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); |
|
|
|
|
EXPECT_THAT(response_state.error_message, |
|
|
|
@ -5875,7 +6340,7 @@ TEST_P(XdsSecurityTest, |
|
|
|
|
transport_socket->set_name("envoy.transport_sockets.tls"); |
|
|
|
|
balancers_[0]->ads_service()->SetCdsResource(cluster); |
|
|
|
|
CheckRpcSendFailure(); |
|
|
|
|
const auto& response_state = |
|
|
|
|
const auto response_state = |
|
|
|
|
balancers_[0]->ads_service()->cds_response_state(); |
|
|
|
|
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); |
|
|
|
|
EXPECT_THAT(response_state.error_message, |
|
|
|
@ -5898,7 +6363,7 @@ TEST_P( |
|
|
|
|
transport_socket->mutable_typed_config()->PackFrom(upstream_tls_context); |
|
|
|
|
balancers_[0]->ads_service()->SetCdsResource(cluster); |
|
|
|
|
CheckRpcSendFailure(); |
|
|
|
|
const auto& response_state = |
|
|
|
|
const auto response_state = |
|
|
|
|
balancers_[0]->ads_service()->cds_response_state(); |
|
|
|
|
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); |
|
|
|
|
EXPECT_THAT(response_state.error_message, |
|
|
|
@ -5920,7 +6385,7 @@ TEST_P( |
|
|
|
|
transport_socket->mutable_typed_config()->PackFrom(upstream_tls_context); |
|
|
|
|
balancers_[0]->ads_service()->SetCdsResource(cluster); |
|
|
|
|
CheckRpcSendFailure(); |
|
|
|
|
const auto& response_state = |
|
|
|
|
const auto response_state = |
|
|
|
|
balancers_[0]->ads_service()->cds_response_state(); |
|
|
|
|
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); |
|
|
|
|
EXPECT_THAT(response_state.error_message, |
|
|
|
@ -5950,7 +6415,7 @@ TEST_P(XdsSecurityTest, RegexSanMatcherDoesNotAllowIgnoreCase) { |
|
|
|
|
transport_socket->mutable_typed_config()->PackFrom(upstream_tls_context); |
|
|
|
|
balancers_[0]->ads_service()->SetCdsResource(cluster); |
|
|
|
|
CheckRpcSendFailure(); |
|
|
|
|
const auto& response_state = |
|
|
|
|
const auto response_state = |
|
|
|
|
balancers_[0]->ads_service()->cds_response_state(); |
|
|
|
|
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); |
|
|
|
|
EXPECT_THAT(response_state.error_message, |
|
|
|
@ -6379,7 +6844,7 @@ TEST_P(XdsEnabledServerTest, BadLdsUpdateNoApiListenerNorAddress) { |
|
|
|
|
listener.add_filter_chains(); |
|
|
|
|
balancers_[0]->ads_service()->SetLdsResource(listener); |
|
|
|
|
CheckRpcSendFailure(1, RpcOptions().set_wait_for_ready(true)); |
|
|
|
|
const auto& response_state = |
|
|
|
|
const auto response_state = |
|
|
|
|
balancers_[0]->ads_service()->lds_response_state(); |
|
|
|
|
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); |
|
|
|
|
EXPECT_THAT( |
|
|
|
@ -6403,7 +6868,7 @@ TEST_P(XdsEnabledServerTest, BadLdsUpdateBothApiListenerAndAddress) { |
|
|
|
|
listener.mutable_api_listener(); |
|
|
|
|
balancers_[0]->ads_service()->SetLdsResource(listener); |
|
|
|
|
CheckRpcSendFailure(1, RpcOptions().set_wait_for_ready(true)); |
|
|
|
|
const auto& response_state = |
|
|
|
|
const auto response_state = |
|
|
|
|
balancers_[0]->ads_service()->lds_response_state(); |
|
|
|
|
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); |
|
|
|
|
EXPECT_THAT( |
|
|
|
@ -6663,7 +7128,7 @@ TEST_P(XdsServerSecurityTest, TlsConfigurationWithoutRootProviderInstance) { |
|
|
|
|
transport_socket->mutable_typed_config()->PackFrom(downstream_tls_context); |
|
|
|
|
balancers_[0]->ads_service()->SetLdsResource(listener); |
|
|
|
|
CheckRpcSendFailure(1, RpcOptions().set_wait_for_ready(true)); |
|
|
|
|
const auto& response_state = |
|
|
|
|
const auto response_state = |
|
|
|
|
balancers_[0]->ads_service()->lds_response_state(); |
|
|
|
|
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); |
|
|
|
|
EXPECT_THAT(response_state.error_message, |
|
|
|
@ -6926,7 +7391,7 @@ TEST_P(EdsTest, NacksSparsePriorityList) { |
|
|
|
|
}); |
|
|
|
|
balancers_[0]->ads_service()->SetEdsResource(BuildEdsResource(args)); |
|
|
|
|
CheckRpcSendFailure(); |
|
|
|
|
const auto& response_state = |
|
|
|
|
const auto response_state = |
|
|
|
|
balancers_[0]->ads_service()->eds_response_state(); |
|
|
|
|
EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); |
|
|
|
|
EXPECT_THAT(response_state.error_message, |
|
|
|
|