diff --git a/build_autogenerated.yaml b/build_autogenerated.yaml index 42036748370f9..78d00abed1569 100644 --- a/build_autogenerated.yaml +++ b/build_autogenerated.yaml @@ -19705,6 +19705,7 @@ targets: build: test language: c++ headers: + - test/core/event_engine/delegating_event_engine.h - test/core/event_engine/event_engine_test_utils.h - test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.h - test/core/test_util/cmdline.h diff --git a/test/core/security/BUILD b/test/core/security/BUILD index ed139dd4ffb3e..d2f2d3adbdcdd 100644 --- a/test/core/security/BUILD +++ b/test/core/security/BUILD @@ -112,6 +112,7 @@ grpc_cc_test( "//:grpc", "//src/core:channel_args", "//src/core:gcp_service_account_identity_credentials", + "//test/core/event_engine:delegating_event_engine", "//test/core/event_engine:event_engine_test_utils", "//test/core/event_engine/fuzzing_event_engine", "//test/core/test_util:grpc_test_util", diff --git a/test/core/security/credentials_test.cc b/test/core/security/credentials_test.cc index 3731f5ca18941..c2a4cd7f0e0de 100644 --- a/test/core/security/credentials_test.cc +++ b/test/core/security/credentials_test.cc @@ -75,12 +75,15 @@ #include "src/core/util/json/json_reader.h" #include "src/core/util/string.h" #include "src/core/util/tmpfile.h" +#include "test/core/event_engine/delegating_event_engine.h" #include "test/core/event_engine/event_engine_test_utils.h" #include "test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.h" #include "test/core/test_util/test_config.h" namespace grpc_core { +using grpc_event_engine::experimental::DelegatingEventEngine; +using grpc_event_engine::experimental::EventEngine; using grpc_event_engine::experimental::FuzzingEventEngine; using internal::grpc_flush_cached_google_default_credentials; using internal::set_gce_tenancy_checker_for_testing; @@ -2459,12 +2462,28 @@ class TokenFetcherCredentialsTest : public ::testing::Test { std::atomic num_fetches_{0}; }; + class EventEngineWrapper : public DelegatingEventEngine { + public: + explicit EventEngineWrapper(TokenFetcherCredentialsTest* test) + : DelegatingEventEngine(test->event_engine_), test_(test) {} + + TaskHandle RunAfter(Duration when, + absl::AnyInvocable callback) override { + test_->run_after_duration_ = when; + return wrapped_ee()->RunAfter(when, std::move(callback)); + } + + private: + TokenFetcherCredentialsTest* test_; + }; + void SetUp() override { event_engine_ = std::make_shared( FuzzingEventEngine::Options(), fuzzing_event_engine::Actions()); + ee_wrapper_ = std::make_shared(this); grpc_timer_manager_set_start_threaded(false); grpc_init(); - creds_ = MakeRefCounted(event_engine_); + creds_ = MakeRefCounted(ee_wrapper_); } void TearDown() override { @@ -2472,6 +2491,7 @@ class TokenFetcherCredentialsTest : public ::testing::Test { event_engine_->TickUntilIdle(); event_engine_->UnsetGlobalHooks(); creds_.reset(); + grpc_event_engine::experimental::WaitForSingleOwner(std::move(ee_wrapper_)); grpc_event_engine::experimental::WaitForSingleOwner( std::move(event_engine_)); grpc_shutdown_blocking(); @@ -2484,7 +2504,9 @@ class TokenFetcherCredentialsTest : public ::testing::Test { } std::shared_ptr event_engine_; + std::shared_ptr ee_wrapper_; RefCountedPtr creds_; + absl::optional run_after_duration_; }; TEST_F(TokenFetcherCredentialsTest, Basic) { @@ -2566,11 +2588,6 @@ TEST_F(TokenFetcherCredentialsTest, Expires30SecondsEarly) { TEST_F(TokenFetcherCredentialsTest, FetchFails) { const absl::Status kExpectedError = absl::UnavailableError("bummer, dude"); - absl::optional run_after_duration; - event_engine_->SetRunAfterDurationCallback( - [&](FuzzingEventEngine::Duration duration) { - run_after_duration = duration; - }); ExecCtx exec_ctx; creds_->AddResult(kExpectedError); // First request will trigger a fetch, which will fail. @@ -2579,11 +2596,11 @@ TEST_F(TokenFetcherCredentialsTest, FetchFails) { state->RunRequestMetadataTest(creds_.get(), kTestUrlScheme, kTestAuthority, kTestPath); EXPECT_EQ(creds_->num_fetches(), 1); - while (!run_after_duration.has_value()) event_engine_->Tick(); + while (!run_after_duration_.has_value()) event_engine_->Tick(); // Make sure backoff was set for the right period. // This is 1 second (initial backoff) minus 1ms for the tick needed above. - EXPECT_EQ(run_after_duration, std::chrono::seconds(1)); - run_after_duration.reset(); + EXPECT_EQ(run_after_duration_, std::chrono::seconds(1)); + run_after_duration_.reset(); // Start a new call now, which will be queued and then eventually // resumed when the next fetch happens. state = RequestMetadataState::NewInstance( @@ -2604,11 +2621,6 @@ TEST_F(TokenFetcherCredentialsTest, FetchFails) { TEST_F(TokenFetcherCredentialsTest, Backoff) { const absl::Status kExpectedError = absl::UnavailableError("bummer, dude"); - absl::optional run_after_duration; - event_engine_->SetRunAfterDurationCallback( - [&](FuzzingEventEngine::Duration duration) { - run_after_duration = duration; - }); ExecCtx exec_ctx; creds_->AddResult(kExpectedError); // First request will trigger a fetch, which will fail. @@ -2617,10 +2629,10 @@ TEST_F(TokenFetcherCredentialsTest, Backoff) { state->RunRequestMetadataTest(creds_.get(), kTestUrlScheme, kTestAuthority, kTestPath); EXPECT_EQ(creds_->num_fetches(), 1); - while (!run_after_duration.has_value()) event_engine_->Tick(); + while (!run_after_duration_.has_value()) event_engine_->Tick(); // Make sure backoff was set for the right period. - EXPECT_EQ(run_after_duration, std::chrono::seconds(1)); - run_after_duration.reset(); + EXPECT_EQ(run_after_duration_, std::chrono::seconds(1)); + run_after_duration_.reset(); // Start a new call now, which will be queued and then eventually // resumed when the next fetch happens. state = RequestMetadataState::NewInstance(kExpectedError, "", @@ -2629,12 +2641,12 @@ TEST_F(TokenFetcherCredentialsTest, Backoff) { kTestPath); // Tick until the next fetch fails and the backoff timer starts again. creds_->AddResult(kExpectedError); - while (!run_after_duration.has_value()) event_engine_->Tick(); + while (!run_after_duration_.has_value()) event_engine_->Tick(); EXPECT_EQ(creds_->num_fetches(), 2); // The backoff time should be longer now. We account for jitter here. - EXPECT_EQ(run_after_duration, std::chrono::milliseconds(1600)) - << "actual: " << run_after_duration->count(); - run_after_duration.reset(); + EXPECT_EQ(run_after_duration_, std::chrono::milliseconds(1600)) + << "actual: " << run_after_duration_->count(); + run_after_duration_.reset(); // Start another new call to trigger another new fetch once the // backoff expires. state = RequestMetadataState::NewInstance(kExpectedError, "", @@ -2643,20 +2655,15 @@ TEST_F(TokenFetcherCredentialsTest, Backoff) { kTestPath); // Tick until the next fetch starts. creds_->AddResult(kExpectedError); - while (!run_after_duration.has_value()) event_engine_->Tick(); + while (!run_after_duration_.has_value()) event_engine_->Tick(); EXPECT_EQ(creds_->num_fetches(), 3); // Check backoff time again. - EXPECT_EQ(run_after_duration, std::chrono::milliseconds(2560)) - << "actual: " << run_after_duration->count(); + EXPECT_EQ(run_after_duration_, std::chrono::milliseconds(2560)) + << "actual: " << run_after_duration_->count(); } TEST_F(TokenFetcherCredentialsTest, FetchNotStartedAfterBackoffWithoutRpc) { const absl::Status kExpectedError = absl::UnavailableError("bummer, dude"); - absl::optional run_after_duration; - event_engine_->SetRunAfterDurationCallback( - [&](FuzzingEventEngine::Duration duration) { - run_after_duration = duration; - }); ExecCtx exec_ctx; creds_->AddResult(kExpectedError); // First request will trigger a fetch, which will fail. @@ -2665,10 +2672,10 @@ TEST_F(TokenFetcherCredentialsTest, FetchNotStartedAfterBackoffWithoutRpc) { state->RunRequestMetadataTest(creds_.get(), kTestUrlScheme, kTestAuthority, kTestPath); EXPECT_EQ(creds_->num_fetches(), 1); - while (!run_after_duration.has_value()) event_engine_->Tick(); + while (!run_after_duration_.has_value()) event_engine_->Tick(); // Make sure backoff was set for the right period. - EXPECT_EQ(run_after_duration, std::chrono::seconds(1)); - run_after_duration.reset(); + EXPECT_EQ(run_after_duration_, std::chrono::seconds(1)); + run_after_duration_.reset(); // Tick until the backoff expires. No new fetch should be started. event_engine_->TickUntilIdle(); EXPECT_EQ(creds_->num_fetches(), 1); @@ -2683,11 +2690,6 @@ TEST_F(TokenFetcherCredentialsTest, FetchNotStartedAfterBackoffWithoutRpc) { TEST_F(TokenFetcherCredentialsTest, ShutdownWhileBackoffTimerPending) { const absl::Status kExpectedError = absl::UnavailableError("bummer, dude"); - absl::optional run_after_duration; - event_engine_->SetRunAfterDurationCallback( - [&](FuzzingEventEngine::Duration duration) { - run_after_duration = duration; - }); ExecCtx exec_ctx; creds_->AddResult(kExpectedError); // First request will trigger a fetch, which will fail. @@ -2696,10 +2698,10 @@ TEST_F(TokenFetcherCredentialsTest, ShutdownWhileBackoffTimerPending) { state->RunRequestMetadataTest(creds_.get(), kTestUrlScheme, kTestAuthority, kTestPath); EXPECT_EQ(creds_->num_fetches(), 1); - while (!run_after_duration.has_value()) event_engine_->Tick(); + while (!run_after_duration_.has_value()) event_engine_->Tick(); // Make sure backoff was set for the right period. - EXPECT_EQ(run_after_duration, std::chrono::seconds(1)); - run_after_duration.reset(); + EXPECT_EQ(run_after_duration_, std::chrono::seconds(1)); + run_after_duration_.reset(); // Do nothing else. Make sure the creds shut down correctly. }