Skip to content

Commit 8cb7c98

Browse files
committed
add env var protection
1 parent c399e19 commit 8cb7c98

File tree

3 files changed

+100
-2
lines changed

3 files changed

+100
-2
lines changed

src/core/xds/grpc/xds_server_grpc.cc

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,6 @@ void GrpcXdsServer::JsonPostLoad(const Json& json, const JsonArgs& args,
143143
for (const Json& feature_json : array) {
144144
if (feature_json.type() == Json::Type::kString &&
145145
(feature_json.string() == kServerFeatureIgnoreResourceDeletion ||
146-
// FIXME: env var guard
147146
feature_json.string() == kServerFeatureFailOnDataErrors ||
148147
feature_json.string() ==
149148
kServerFeatureResourceTimerIsTransientFailure ||

src/core/xds/xds_client/xds_client.cc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ class XdsClient::XdsChannel::AdsCall final
211211
Duration timeout = ads_call_->xds_client()->request_timeout_;
212212
if (timeout == Duration::Zero()) {
213213
timeout =
214+
XdsDataErrorHandlingEnabled() &&
214215
ads_call_->xds_channel()->server_.ResourceTimerIsTransientFailure()
215216
? Duration::Seconds(30)
216217
: Duration::Seconds(15);
@@ -242,7 +243,8 @@ class XdsClient::XdsChannel::AdsCall final
242243
name_.authority, type_->type_url(), name_.key)
243244
<< "} from xds server";
244245
resource_seen_ = true;
245-
if (ads_call_->xds_channel()->server_
246+
if (XdsDataErrorHandlingEnabled() &&
247+
ads_call_->xds_channel()->server_
246248
.ResourceTimerIsTransientFailure()) {
247249
state.SetTransientError(absl::StrCat(
248250
"xDS server ", ads_call_->xds_channel()->server_uri(),

test/core/xds/xds_client_test.cc

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2966,7 +2966,104 @@ TEST_F(XdsClientTest, ResourceDoesNotExistUponTimeout) {
29662966
EXPECT_TRUE(stream->IsOrphaned());
29672967
}
29682968

2969+
TEST_F(XdsClientTest, ResourceTimerIsTransientErrorIgnoredUnlessEnabled) {
2970+
event_engine_->SetRunAfterDurationCallback(
2971+
[&](grpc_event_engine::experimental::EventEngine::Duration duration) {
2972+
grpc_event_engine::experimental::EventEngine::Duration expected =
2973+
std::chrono::seconds(15);
2974+
EXPECT_EQ(duration, expected)
2975+
<< "Expected: " << expected.count()
2976+
<< "\nActual: " << duration.count();
2977+
});
2978+
InitXdsClient(FakeXdsBootstrap::Builder().SetServers(
2979+
{FakeXdsBootstrap::FakeXdsServer(kDefaultXdsServerUrl, false, true)}));
2980+
// Start a watch for "foo1".
2981+
auto watcher = StartFooWatch("foo1");
2982+
// Watcher should initially not see any resource reported.
2983+
EXPECT_FALSE(watcher->HasEvent());
2984+
// Check metric data.
2985+
EXPECT_THAT(metrics_reporter_->resource_updates_valid(),
2986+
::testing::ElementsAre());
2987+
EXPECT_THAT(metrics_reporter_->resource_updates_invalid(),
2988+
::testing::ElementsAre());
2989+
EXPECT_THAT(GetResourceCounts(),
2990+
::testing::ElementsAre(::testing::Pair(
2991+
ResourceCountLabelsEq(XdsClient::kOldStyleAuthority,
2992+
XdsFooResourceType::Get()->type_url(),
2993+
"requested"),
2994+
1)));
2995+
// XdsClient should have created an ADS stream.
2996+
auto stream = WaitForAdsStream();
2997+
ASSERT_TRUE(stream != nullptr);
2998+
// XdsClient should have sent a subscription request on the ADS stream.
2999+
auto request = WaitForRequest(stream.get());
3000+
ASSERT_TRUE(request.has_value());
3001+
CheckRequest(*request, XdsFooResourceType::Get()->type_url(),
3002+
/*version_info=*/"", /*response_nonce=*/"",
3003+
/*error_detail=*/absl::OkStatus(),
3004+
/*resource_names=*/{"foo1"});
3005+
CheckRequestNode(*request); // Should be present on the first request.
3006+
// Do not send a response, but wait for the resource to be reported as
3007+
// not existing.
3008+
EXPECT_TRUE(watcher->WaitForDoesNotExist());
3009+
// Check metric data.
3010+
EXPECT_TRUE(metrics_reporter_->WaitForMetricsReporterData(
3011+
::testing::ElementsAre(), ::testing::ElementsAre(), ::testing::_));
3012+
EXPECT_THAT(GetResourceCounts(),
3013+
::testing::ElementsAre(::testing::Pair(
3014+
ResourceCountLabelsEq(XdsClient::kOldStyleAuthority,
3015+
XdsFooResourceType::Get()->type_url(),
3016+
"does_not_exist"),
3017+
1)));
3018+
// Start a new watcher for the same resource. It should immediately
3019+
// receive the same does-not-exist notification.
3020+
auto watcher2 = StartFooWatch("foo1");
3021+
EXPECT_TRUE(watcher2->WaitForDoesNotExist());
3022+
// Now server sends a response.
3023+
stream->SendMessageToClient(
3024+
ResponseBuilder(XdsFooResourceType::Get()->type_url())
3025+
.set_version_info("1")
3026+
.set_nonce("A")
3027+
.AddFooResource(XdsFooResource("foo1", 6))
3028+
.Serialize());
3029+
// XdsClient should have delivered the response to the watchers.
3030+
auto resource = watcher->WaitForNextResource();
3031+
ASSERT_NE(resource, nullptr);
3032+
EXPECT_EQ(resource->name, "foo1");
3033+
EXPECT_EQ(resource->value, 6);
3034+
resource = watcher2->WaitForNextResource();
3035+
ASSERT_NE(resource, nullptr);
3036+
EXPECT_EQ(resource->name, "foo1");
3037+
EXPECT_EQ(resource->value, 6);
3038+
// Check metric data.
3039+
EXPECT_TRUE(metrics_reporter_->WaitForMetricsReporterData(
3040+
::testing::ElementsAre(::testing::Pair(
3041+
::testing::Pair(kDefaultXdsServerUrl,
3042+
XdsFooResourceType::Get()->type_url()),
3043+
1)),
3044+
::testing::ElementsAre(), ::testing::_));
3045+
EXPECT_THAT(
3046+
GetResourceCounts(),
3047+
::testing::ElementsAre(::testing::Pair(
3048+
ResourceCountLabelsEq(XdsClient::kOldStyleAuthority,
3049+
XdsFooResourceType::Get()->type_url(), "acked"),
3050+
1)));
3051+
// XdsClient should have sent an ACK message to the xDS server.
3052+
request = WaitForRequest(stream.get());
3053+
ASSERT_TRUE(request.has_value());
3054+
CheckRequest(*request, XdsFooResourceType::Get()->type_url(),
3055+
/*version_info=*/"1", /*response_nonce=*/"A",
3056+
/*error_detail=*/absl::OkStatus(),
3057+
/*resource_names=*/{"foo1"});
3058+
// Cancel watch.
3059+
CancelFooWatch(watcher.get(), "foo1");
3060+
CancelFooWatch(watcher2.get(), "foo1");
3061+
EXPECT_TRUE(stream->IsOrphaned());
3062+
}
3063+
29693064
TEST_F(XdsClientTest, ResourceTimerIsTransientFailure) {
3065+
testing::ScopedEnvVar env_var("GRPC_EXPERIMENTAL_XDS_DATA_ERROR_HANDLING",
3066+
"true");
29703067
event_engine_->SetRunAfterDurationCallback(
29713068
[&](grpc_event_engine::experimental::EventEngine::Duration duration) {
29723069
grpc_event_engine::experimental::EventEngine::Duration expected =

0 commit comments

Comments
 (0)