Merge pull request #24683 from donnadionne/protect_timeout

Protect timeout feature under a flag and added testing.
pull/24719/head
donnadionne 4 years ago committed by GitHub
commit ae55be3fff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 40
      src/core/ext/xds/xds_api.cc
  2. 97
      test/cpp/end2end/xds_end2end_test.cc

@ -88,6 +88,17 @@
namespace grpc_core { namespace grpc_core {
// TODO (donnadionne): Check to see if timeout is enabled, this will be
// removed once timeout feature is fully integration-tested and enabled by
// default.
bool XdsTimeoutEnabled() {
char* value = gpr_getenv("GRPC_XDS_EXPERIMENTAL_ENABLE_TIMEOUT");
bool parsed_value;
bool parse_succeeded = gpr_parse_bool_value(value, &parsed_value);
gpr_free(value);
return parse_succeeded && parsed_value;
}
// //
// XdsApi::Route::Matchers::PathMatcher // XdsApi::Route::Matchers::PathMatcher
// //
@ -1129,7 +1140,7 @@ grpc_error* RouteActionParse(const envoy_config_route_v3_Route* route_msg,
// No cluster or weighted_clusters found in RouteAction, ignore this route. // No cluster or weighted_clusters found in RouteAction, ignore this route.
*ignore_route = true; *ignore_route = true;
} }
if (!*ignore_route) { if (XdsTimeoutEnabled() && !*ignore_route) {
const envoy_config_route_v3_RouteAction_MaxStreamDuration* const envoy_config_route_v3_RouteAction_MaxStreamDuration*
max_stream_duration = max_stream_duration =
envoy_config_route_v3_RouteAction_max_stream_duration(route_action); envoy_config_route_v3_RouteAction_max_stream_duration(route_action);
@ -1278,18 +1289,21 @@ grpc_error* LdsResponseParse(
return GRPC_ERROR_CREATE_FROM_STATIC_STRING( return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"Could not parse HttpConnectionManager config from ApiListener"); "Could not parse HttpConnectionManager config from ApiListener");
} }
// Obtain max_stream_duration from Http Protocol Options. if (XdsTimeoutEnabled()) {
const envoy_config_core_v3_HttpProtocolOptions* options = // Obtain max_stream_duration from Http Protocol Options.
envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_common_http_protocol_options( const envoy_config_core_v3_HttpProtocolOptions* options =
http_connection_manager); envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_common_http_protocol_options(
if (options != nullptr) { http_connection_manager);
const google_protobuf_Duration* duration = if (options != nullptr) {
envoy_config_core_v3_HttpProtocolOptions_max_stream_duration(options); const google_protobuf_Duration* duration =
if (duration != nullptr) { envoy_config_core_v3_HttpProtocolOptions_max_stream_duration(
lds_update.http_max_stream_duration.seconds = options);
google_protobuf_Duration_seconds(duration); if (duration != nullptr) {
lds_update.http_max_stream_duration.nanos = lds_update.http_max_stream_duration.seconds =
google_protobuf_Duration_nanos(duration); google_protobuf_Duration_seconds(duration);
lds_update.http_max_stream_duration.nanos =
google_protobuf_Duration_nanos(duration);
}
} }
} }
// Found inlined route_config. Parse it to find the cluster_name. // Found inlined route_config. Parse it to find the cluster_name.

@ -4251,6 +4251,7 @@ TEST_P(LdsRdsTest, XdsRoutingApplyXdsTimeout) {
// TODO(https://github.com/grpc/grpc/issues/24549): TSAN won't work here. // TODO(https://github.com/grpc/grpc/issues/24549): TSAN won't work here.
if (BuiltUnderAsan() || BuiltUnderTsan()) return; if (BuiltUnderAsan() || BuiltUnderTsan()) return;
gpr_setenv("GRPC_XDS_EXPERIMENTAL_ENABLE_TIMEOUT", "true");
const int64_t kTimeoutNano = 500000000; const int64_t kTimeoutNano = 500000000;
const int64_t kTimeoutGrpcTimeoutHeaderMaxSecond = 1; const int64_t kTimeoutGrpcTimeoutHeaderMaxSecond = 1;
const int64_t kTimeoutMaxStreamDurationSecond = 2; const int64_t kTimeoutMaxStreamDurationSecond = 2;
@ -4393,9 +4394,100 @@ TEST_P(LdsRdsTest, XdsRoutingApplyXdsTimeout) {
kTimeoutHttpMaxStreamDurationSecond * 1000000000 + kTimeoutNano); kTimeoutHttpMaxStreamDurationSecond * 1000000000 + kTimeoutNano);
EXPECT_LT(ellapsed_nano_seconds.count(), EXPECT_LT(ellapsed_nano_seconds.count(),
kTimeoutApplicationSecond * 1000000000); kTimeoutApplicationSecond * 1000000000);
gpr_unsetenv("GRPC_XDS_EXPERIMENTAL_ENABLE_TIMEOUT");
}
TEST_P(LdsRdsTest, XdsRoutingXdsTimeoutDisabled) {
const int64_t kTimeoutMillis = 500;
const int64_t kTimeoutNano = kTimeoutMillis * 1000000;
const int64_t kTimeoutGrpcTimeoutHeaderMaxSecond = 1;
const int64_t kTimeoutApplicationSecond = 4;
SetNextResolution({});
SetNextResolutionForLbChannelAllBalancers();
// Populate new EDS resources.
AdsServiceImpl::EdsResourceArgs args({
{"locality0", {g_port_saver->GetPort()}},
});
balancers_[0]->ads_service()->SetEdsResource(BuildEdsResource(args));
RouteConfiguration new_route_config =
balancers_[0]->ads_service()->default_route_config();
// route 1: Set grpc_timeout_header_max of 1.5
auto* route1 = new_route_config.mutable_virtual_hosts(0)->mutable_routes(0);
auto* max_stream_duration =
route1->mutable_route()->mutable_max_stream_duration();
auto* duration = max_stream_duration->mutable_grpc_timeout_header_max();
duration->set_seconds(kTimeoutGrpcTimeoutHeaderMaxSecond);
duration->set_nanos(kTimeoutNano);
SetRouteConfiguration(0, new_route_config);
// Test grpc_timeout_header_max of 1.5 seconds is not applied
gpr_timespec t0 = gpr_now(GPR_CLOCK_MONOTONIC);
gpr_timespec est_timeout_time = gpr_time_add(
t0, gpr_time_from_millis(
kTimeoutGrpcTimeoutHeaderMaxSecond * 1000 + kTimeoutMillis,
GPR_TIMESPAN));
CheckRpcSendFailure(1,
RpcOptions()
.set_rpc_service(SERVICE_ECHO1)
.set_rpc_method(METHOD_ECHO1)
.set_wait_for_ready(true)
.set_timeout_ms(kTimeoutApplicationSecond * 1000),
StatusCode::DEADLINE_EXCEEDED);
gpr_timespec timeout_time = gpr_now(GPR_CLOCK_MONOTONIC);
EXPECT_GT(gpr_time_cmp(timeout_time, est_timeout_time), 0);
}
TEST_P(LdsRdsTest, XdsRoutingHttpTimeoutDisabled) {
const int64_t kTimeoutMillis = 500;
const int64_t kTimeoutNano = kTimeoutMillis * 1000000;
const int64_t kTimeoutHttpMaxStreamDurationSecond = 3;
const int64_t kTimeoutApplicationSecond = 4;
SetNextResolution({});
SetNextResolutionForLbChannelAllBalancers();
// Populate new EDS resources.
AdsServiceImpl::EdsResourceArgs args({
{"locality0", {g_port_saver->GetPort()}},
});
HttpConnectionManager http_connection_manager;
// Set up HTTP max_stream_duration of 3.5 seconds
auto* duration =
http_connection_manager.mutable_common_http_protocol_options()
->mutable_max_stream_duration();
duration->set_seconds(kTimeoutHttpMaxStreamDurationSecond);
duration->set_nanos(kTimeoutNano);
RouteConfiguration new_route_config =
balancers_[0]->ads_service()->default_route_config();
if (GetParam().enable_rds_testing()) {
auto* rds = http_connection_manager.mutable_rds();
rds->set_route_config_name(kDefaultRouteConfigurationName);
rds->mutable_config_source()->mutable_ads();
auto listener = balancers_[0]->ads_service()->default_listener();
listener.mutable_api_listener()->mutable_api_listener()->PackFrom(
http_connection_manager);
balancers_[0]->ads_service()->SetLdsResource(listener);
SetRouteConfiguration(0, new_route_config);
} else {
*http_connection_manager.mutable_route_config() = new_route_config;
auto listener = balancers_[0]->ads_service()->default_listener();
listener.mutable_api_listener()->mutable_api_listener()->PackFrom(
http_connection_manager);
balancers_[0]->ads_service()->SetLdsResource(listener);
}
// Test http_stream_duration of 3.5 seconds is not applied
auto t0 = gpr_now(GPR_CLOCK_MONOTONIC);
auto est_timeout_time = gpr_time_add(
t0, gpr_time_from_millis(
kTimeoutHttpMaxStreamDurationSecond * 1000 + kTimeoutMillis,
GPR_TIMESPAN));
CheckRpcSendFailure(1,
RpcOptions().set_wait_for_ready(true).set_timeout_ms(
kTimeoutApplicationSecond * 1000),
StatusCode::DEADLINE_EXCEEDED);
auto timeout_time = gpr_now(GPR_CLOCK_MONOTONIC);
EXPECT_GT(gpr_time_cmp(timeout_time, est_timeout_time), 0);
} }
TEST_P(LdsRdsTest, XdsRoutingApplyApplicationTimeoutWhenXdsTimeoutExplicit0) { TEST_P(LdsRdsTest, XdsRoutingApplyApplicationTimeoutWhenXdsTimeoutExplicit0) {
gpr_setenv("GRPC_XDS_EXPERIMENTAL_ENABLE_TIMEOUT", "true");
const int64_t kTimeoutNano = 500000000; const int64_t kTimeoutNano = 500000000;
const int64_t kTimeoutMaxStreamDurationSecond = 2; const int64_t kTimeoutMaxStreamDurationSecond = 2;
const int64_t kTimeoutHttpMaxStreamDurationSecond = 3; const int64_t kTimeoutHttpMaxStreamDurationSecond = 3;
@ -4505,9 +4597,11 @@ TEST_P(LdsRdsTest, XdsRoutingApplyApplicationTimeoutWhenXdsTimeoutExplicit0) {
system_clock::now() - t0); system_clock::now() - t0);
EXPECT_GT(ellapsed_nano_seconds.count(), EXPECT_GT(ellapsed_nano_seconds.count(),
kTimeoutApplicationSecond * 1000000000); kTimeoutApplicationSecond * 1000000000);
gpr_unsetenv("GRPC_XDS_EXPERIMENTAL_ENABLE_TIMEOUT");
} }
TEST_P(LdsRdsTest, XdsRoutingApplyApplicationTimeoutWhenHttpTimeoutExplicit0) { TEST_P(LdsRdsTest, XdsRoutingApplyApplicationTimeoutWhenHttpTimeoutExplicit0) {
gpr_setenv("GRPC_XDS_EXPERIMENTAL_ENABLE_TIMEOUT", "true");
const int64_t kTimeoutApplicationSecond = 4; const int64_t kTimeoutApplicationSecond = 4;
SetNextResolution({}); SetNextResolution({});
SetNextResolutionForLbChannelAllBalancers(); SetNextResolutionForLbChannelAllBalancers();
@ -4552,11 +4646,13 @@ TEST_P(LdsRdsTest, XdsRoutingApplyApplicationTimeoutWhenHttpTimeoutExplicit0) {
t0); t0);
EXPECT_GT(ellapsed_nano_seconds.count(), EXPECT_GT(ellapsed_nano_seconds.count(),
kTimeoutApplicationSecond * 1000000000); kTimeoutApplicationSecond * 1000000000);
gpr_unsetenv("GRPC_XDS_EXPERIMENTAL_ENABLE_TIMEOUT");
} }
// Test to ensure application-specified deadline won't be affected when // Test to ensure application-specified deadline won't be affected when
// the xDS config does not specify a timeout. // the xDS config does not specify a timeout.
TEST_P(LdsRdsTest, XdsRoutingWithOnlyApplicationTimeout) { TEST_P(LdsRdsTest, XdsRoutingWithOnlyApplicationTimeout) {
gpr_setenv("GRPC_XDS_EXPERIMENTAL_ENABLE_TIMEOUT", "true");
const int64_t kTimeoutApplicationSecond = 4; const int64_t kTimeoutApplicationSecond = 4;
SetNextResolution({}); SetNextResolution({});
SetNextResolutionForLbChannelAllBalancers(); SetNextResolutionForLbChannelAllBalancers();
@ -4575,6 +4671,7 @@ TEST_P(LdsRdsTest, XdsRoutingWithOnlyApplicationTimeout) {
t0); t0);
EXPECT_GT(ellapsed_nano_seconds.count(), EXPECT_GT(ellapsed_nano_seconds.count(),
kTimeoutApplicationSecond * 1000000000); kTimeoutApplicationSecond * 1000000000);
gpr_unsetenv("GRPC_XDS_EXPERIMENTAL_ENABLE_TIMEOUT");
} }
TEST_P(LdsRdsTest, XdsRoutingHeadersMatching) { TEST_P(LdsRdsTest, XdsRoutingHeadersMatching) {

Loading…
Cancel
Save