Skip to content

Commit

Permalink
fix credentials_test
Browse files Browse the repository at this point in the history
  • Loading branch information
markdroth committed Sep 17, 2024
1 parent c1de4fe commit b539a46
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 40 deletions.
1 change: 1 addition & 0 deletions build_autogenerated.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions test/core/security/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
82 changes: 42 additions & 40 deletions test/core/security/credentials_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -2459,19 +2462,36 @@ class TokenFetcherCredentialsTest : public ::testing::Test {
std::atomic<size_t> num_fetches_{0};
};

class EventEngineWrapper : public DelegatingEventEngine {
public:
explicit EventEngineWrapper(TokenFetcherCredentialsTest* test)
: DelegatingEventEngine(test->event_engine_), test_(test) {}

TaskHandle RunAfter(Duration when,
absl::AnyInvocable<void()> 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>(
FuzzingEventEngine::Options(), fuzzing_event_engine::Actions());
ee_wrapper_ = std::make_shared<EventEngineWrapper>(this);
grpc_timer_manager_set_start_threaded(false);
grpc_init();
creds_ = MakeRefCounted<TestTokenFetcherCredentials>(event_engine_);
creds_ = MakeRefCounted<TestTokenFetcherCredentials>(ee_wrapper_);
}

void TearDown() override {
event_engine_->FuzzingDone();
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();
Expand All @@ -2484,7 +2504,9 @@ class TokenFetcherCredentialsTest : public ::testing::Test {
}

std::shared_ptr<FuzzingEventEngine> event_engine_;
std::shared_ptr<EventEngineWrapper> ee_wrapper_;
RefCountedPtr<TestTokenFetcherCredentials> creds_;
absl::optional<EventEngine::Duration> run_after_duration_;
};

TEST_F(TokenFetcherCredentialsTest, Basic) {
Expand Down Expand Up @@ -2566,11 +2588,6 @@ TEST_F(TokenFetcherCredentialsTest, Expires30SecondsEarly) {

TEST_F(TokenFetcherCredentialsTest, FetchFails) {
const absl::Status kExpectedError = absl::UnavailableError("bummer, dude");
absl::optional<FuzzingEventEngine::Duration> 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.
Expand All @@ -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(
Expand All @@ -2604,11 +2621,6 @@ TEST_F(TokenFetcherCredentialsTest, FetchFails) {

TEST_F(TokenFetcherCredentialsTest, Backoff) {
const absl::Status kExpectedError = absl::UnavailableError("bummer, dude");
absl::optional<FuzzingEventEngine::Duration> 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.
Expand All @@ -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, "",
Expand All @@ -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, "",
Expand All @@ -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<FuzzingEventEngine::Duration> 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.
Expand All @@ -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);
Expand All @@ -2683,11 +2690,6 @@ TEST_F(TokenFetcherCredentialsTest, FetchNotStartedAfterBackoffWithoutRpc) {

TEST_F(TokenFetcherCredentialsTest, ShutdownWhileBackoffTimerPending) {
const absl::Status kExpectedError = absl::UnavailableError("bummer, dude");
absl::optional<FuzzingEventEngine::Duration> 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.
Expand All @@ -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.
}

Expand Down

0 comments on commit b539a46

Please sign in to comment.