Skip to content

fix(storage): resolve race conditions in archived generation tests - #3341

Open
mahendra-google wants to merge 1 commit into
GoogleCloudPlatform:mainfrom
mahendra-google:fix/file-archived-generation-tests-flakes
Open

fix(storage): resolve race conditions in archived generation tests#3341
mahendra-google wants to merge 1 commit into
GoogleCloudPlatform:mainfrom
mahendra-google:fix/file-archived-generation-tests-flakes

Conversation

@mahendra-google

Copy link
Copy Markdown
Contributor

This PR provides a fix to the issue and
resolves the test flakiness observed in the archived generation tests (such as CopyFileArchivedGenerationTest , ListFileArchivedGenerationTest and DeleteFileArchivedGenerationTest).

Previously, these tests were failing intermittently with 404 No such object or assertion errors (Expected: 2, Actual: 1).

Because the tests were creating, deleting objects immediately after enabling versioning on the bucket, GCS had not always propagated the versioning state, resulting in objects being permanently deleted instead of archived.

This PR removes bucket versioning toggling from generation tests and introduces BucketNameVersioned (shared versioned bucket) in the StorageFixture and utilized shared versioned bucket across all generation tests eliminating race conditions.

Introduce a pre-configured versioned bucket in the StorageFixture to eliminate
GCS metadata propagation delays and utilized shared versioned bucket across all generation tests
@mahendra-google
mahendra-google requested review from a team as code owners August 4, 2026 08:57
@product-auto-label product-auto-label Bot added api: storage Issues related to the Cloud Storage API. samples Issues that are directly related to samples. labels Aug 4, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors several integration tests—specifically CopyFileArchivedGenerationTest, DeleteFileArchivedGenerationTest, and ListFileArchivedGenerationTest—to use a shared, pre-configured versioned bucket (BucketNameVersioned) from the test fixture, eliminating the need to repeatedly enable and disable versioning within individual tests. It also cleans up unused sample variables and standardizes object name generation. The review feedback correctly identifies a performance issue in DeleteFileArchivedGenerationTest.cs where an IEnumerable is enumerated multiple times, causing redundant HTTP requests, and suggests materializing the sequence to avoid this.

Comment on lines +42 to +47
var objects = listFileArchivedGenerationSample.ListFileArchivedGeneration(_fixture.BucketNameVersioned);

Assert.Equal(2, objects.Count(a => a.Name == objectName));
Assert.Equal(2, objects.Count(a => a.Name == objectName));

// Get Generations
var testFiles = objects.Where(a => a.Name == objectName).ToList();
long? fileArchivedGeneration = testFiles[0].Generation;
long? fileCurrentGeneration = testFiles[1].Generation;
// Get Generations
var testFiles = objects.Where(a => a.Name == objectName).ToList();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The objects variable is an IEnumerable returned by ListFileArchivedGeneration, which is lazily evaluated. Calling objects.Count(...) and then objects.Where(...).ToList() causes the sequence to be enumerated twice, triggering multiple redundant HTTP requests to Google Cloud Storage. Materializing the sequence with .ToList() immediately avoids this double enumeration.

        var objects = listFileArchivedGenerationSample.ListFileArchivedGeneration(_fixture.BucketNameVersioned).ToList();

        // Get Generations
        var testFiles = objects.Where(a => a.Name == objectName).ToList();
        Assert.Equal(2, testFiles.Count);

objects = listFileArchivedGenerationSample.ListFileArchivedGeneration(_fixture.BucketNameGeneric);
Assert.Equal(1, objects.Count(a => a.Name == objectName));
objects = listFileArchivedGenerationSample.ListFileArchivedGeneration(_fixture.BucketNameVersioned);
Assert.Equal(1, objects.Count(a => a.Name == objectName));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the test fails during assertion, we are failing to cleanup the object versions.

Comment on lines +47 to +48
_fixture.CollectArchivedFiles(_fixture.BucketNameVersioned, objectName, testFiles[0].Generation);
_fixture.CollectArchivedFiles(_fixture.BucketNameVersioned, objectName, testFiles[1].Generation);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move these lines above the assertion


_fixture.CollectArchivedFiles(_fixture.BucketNameGeneric, objectName, fileArchivedGeneration);
_fixture.CollectArchivedFiles(_fixture.BucketNameGeneric, objectName, fileCurrentGeneration);
_fixture.CollectArchivedFiles(_fixture.BucketNameVersioned, objectName, fileArchivedGeneration);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move the collection of these generations to their respective locations. If second upload fails, we will fail to collect the first generation will not be collected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api: storage Issues related to the Cloud Storage API. samples Issues that are directly related to samples.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants