From 15184d30adff45b7caf4933a9657e54707f3cce4 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Mon, 13 Sep 2021 09:52:20 -0700 Subject: [PATCH] Fix injected abort error not recorded after injected delay (#27215) * Fix injected abort error not recorded after injected delay * Add the abort after delay test case * Make Kokoro's clang_format happy --- .../fault_injection/fault_injection_filter.cc | 4 +- test/cpp/end2end/xds_end2end_test.cc | 37 +++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/core/ext/filters/fault_injection/fault_injection_filter.cc b/src/core/ext/filters/fault_injection/fault_injection_filter.cc index f4d41486f36..d8d2bc171a3 100644 --- a/src/core/ext/filters/fault_injection/fault_injection_filter.cc +++ b/src/core/ext/filters/fault_injection/fault_injection_filter.cc @@ -456,8 +456,10 @@ void CallData::ResumeBatch(void* arg, grpc_error_handle error) { // Abort if needed. error = calld->MaybeAbort(); if (error != GRPC_ERROR_NONE) { + calld->abort_error_ = error; grpc_transport_stream_op_batch_finish_with_failure( - calld->delayed_batch_, error, calld->call_combiner_); + calld->delayed_batch_, GRPC_ERROR_REF(calld->abort_error_), + calld->call_combiner_); return; } // Chain to the next filter. diff --git a/test/cpp/end2end/xds_end2end_test.cc b/test/cpp/end2end/xds_end2end_test.cc index 8f4800561c8..813854e7e28 100644 --- a/test/cpp/end2end/xds_end2end_test.cc +++ b/test/cpp/end2end/xds_end2end_test.cc @@ -12359,6 +12359,43 @@ TEST_P(FaultInjectionTest, XdsFaultInjectionPercentageDelayViaHeaders) { ::testing::DoubleNear(kDelayRate, kErrorTolerance)); } +TEST_P(FaultInjectionTest, XdsFaultInjectionAbortAfterDelayForStreamCall) { + const uint32_t kFixedDelaySeconds = 1; + const uint32_t kRpcTimeoutMilliseconds = 100 * 1000; // 100s should not reach + SetNextResolution({}); + SetNextResolutionForLbChannelAllBalancers(); + // Create an EDS resource + AdsServiceImpl::EdsResourceArgs args({ + {"locality0", CreateEndpointsForBackends()}, + }); + balancers_[0]->ads_service()->SetEdsResource( + BuildEdsResource(args, DefaultEdsServiceName())); + // Construct the fault injection filter config + HTTPFault http_fault; + auto* abort_percentage = http_fault.mutable_abort()->mutable_percentage(); + abort_percentage->set_numerator(100); // Always inject ABORT! + abort_percentage->set_denominator(FractionalPercent::HUNDRED); + http_fault.mutable_abort()->set_grpc_status( + static_cast(StatusCode::ABORTED)); + auto* delay_percentage = http_fault.mutable_delay()->mutable_percentage(); + delay_percentage->set_numerator(100); // Always inject DELAY! + delay_percentage->set_denominator(FractionalPercent::HUNDRED); + auto* fixed_delay = http_fault.mutable_delay()->mutable_fixed_delay(); + fixed_delay->set_seconds(kFixedDelaySeconds); + // Config fault injection via different setup + SetFilterConfig(http_fault); + // Send a stream RPC and check its status code + ClientContext context; + context.set_deadline( + grpc_timeout_milliseconds_to_deadline(kRpcTimeoutMilliseconds)); + auto stream = stub_->BidiStream(&context); + stream->WritesDone(); + auto status = stream->Finish(); + EXPECT_EQ(StatusCode::ABORTED, status.error_code()) + << status.error_message() << ", " << status.error_details() << ", " + << context.debug_error_string(); +} + TEST_P(FaultInjectionTest, XdsFaultInjectionAlwaysDelayPercentageAbort) { const uint32_t kAbortPercentagePerHundred = 50; const double kAbortRate = kAbortPercentagePerHundred / 100.0;