Skip to content

test(creds,dentry_cache): fix portability of integration tests on non-allowlisted GCP projects#4745

Open
kislaykishore wants to merge 6 commits into
masterfrom
cred-test
Open

test(creds,dentry_cache): fix portability of integration tests on non-allowlisted GCP projects#4745
kislaykishore wants to merge 6 commits into
masterfrom
cred-test

Conversation

@kislaykishore
Copy link
Copy Markdown
Collaborator

@kislaykishore kislaykishore commented Jun 1, 2026

Description

The FUSE kernel driver can translate ESTALE to EIO on certain versions. Make tests more robust to handle it. Specifically:

  • Introduced a ValidateESTALEOrEIOError helper to accept both syscall.ESTALE ("stale file handle") and syscall.EIO ("input/output error"). This accounts for differences in how the Linux FUSE driver translates FUSE ESTALE errors to the userspace depending on the kernel environment/version. Updated the dentry_cache and notifier_tests to use the method.
  • Skip credentials-based tests on non-allowlisted projects.

Link to the issue in case of a bug fix.

b/518338525

Testing details

  1. Manual - Verified that executing the integration test suite via make e2e-test on a VM hosted in a non-allowlisted project successfully runs all portable tests and gracefully skips credentials-based tests without crashes. All run tests passed.
  2. Unit tests - N/A
  3. Integration tests - Verified that dentry_cache, mount_timeout, requester_pays_bucket, and managed_folders tests execute successfully.

Any backward incompatible change? If so, please explain.

No backward incompatible changes.

@kislaykishore kislaykishore requested review from a team and meet2mky as code owners June 1, 2026 06:09
@kislaykishore kislaykishore requested a review from charith87 June 1, 2026 06:09
@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request enhances the robustness and portability of the integration and end-to-end test suites. By implementing a project-aware skipping mechanism for credential-based tests and accounting for kernel-specific error translation differences, the changes ensure that the test suite can execute reliably across diverse GCP environments without triggering unnecessary failures or panics.

Highlights

  • Improved Test Portability: Centralized project allowlisting logic and introduced a helper to gracefully skip credential-dependent tests on non-allowlisted GCP projects.
  • Enhanced Error Validation: Added a new validation helper, ValidateESTALEOrEIOError, to handle variations in how different Linux kernels translate FUSE ESTALE errors.
  • Refactored Test Suites: Updated dentry_cache, managed_folders, mount_timeout, and requester_pays_bucket tests to utilize the new portability and error validation helpers.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@github-actions github-actions Bot added the remind-reviewers Auto remind reviewers in attention set for review post 24hrs of inactivity on PR. label Jun 1, 2026
Copy link
Copy Markdown
Contributor

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

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 updates integration tests to skip execution on non-allowlisted GCP projects and introduces a helper function ValidateESTALEOrEIOError to handle cases where the FUSE kernel driver translates ESTALE to EIO. The reviewer provided valuable feedback, suggesting the use of errors.Is instead of string matching for system errors, caching the GCP project ID to prevent redundant metadata server requests, and moving the allowlist check in managed_folders_test.go earlier in TestMain to avoid bypassing deferred cleanups and unnecessary client initialization.

Comment on lines +58 to +68
func ValidateESTALEOrEIOError(t *testing.T, err error) {
t.Helper()

require.Error(t, err)
// FUSE kernel driver can translate ESTALE to EIO (input/output error) on some operations/kernels.
// So we accept both "stale file handle" (ESTALE) and "input/output error" (EIO).
errMsg := err.Error()
if !strings.Contains(errMsg, syscall.ESTALE.Error()) && !strings.Contains(errMsg, syscall.EIO.Error()) {
t.Fatalf("Expected error to contain %q or %q. Got: %q", syscall.ESTALE.Error(), syscall.EIO.Error(), errMsg)
}
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

Using strings.Contains on err.Error() to check for specific system errors like syscall.ESTALE or syscall.EIO can be fragile. In Go, the idiomatic and robust way to assert wrapped system errors (such as those wrapped in os.PathError) is using errors.Is.

func ValidateESTALEOrEIOError(t *testing.T, err error) {
	t.Helper()

	require.Error(t, err)
	// FUSE kernel driver can translate ESTALE to EIO (input/output error) on some operations/kernels.
	// So we accept both "stale file handle" (ESTALE) and "input/output error" (EIO).
	if !errors.Is(err, syscall.ESTALE) && !errors.Is(err, syscall.EIO) {
		t.Fatalf("Expected error to be %v or %v. Got: %v", syscall.ESTALE, syscall.EIO, err)
	}
}

Comment on lines +44 to +54
func IsAllowlistedProject(ctx context.Context) bool {
id, err := metadata.ProjectIDWithContext(ctx)
if err != nil {
log.Printf("Error in fetching project id: %v", err)
return false
}
if strings.Contains(id, "cloudtop") {
return true
}
return slices.Contains(AllowlistedGcpProjects, id)
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

Every call to metadata.ProjectIDWithContext(ctx) performs an HTTP request to the local metadata server. Since IsAllowlistedProject is called first, and then projectID is called again during credential creation, this results in redundant network roundtrips.

We can cache the fetched project ID in a package-level variable to avoid these duplicate requests. Additionally, please update the projectID(ctx) function to use fetchProjectID(ctx) instead of calling metadata.ProjectIDWithContext(ctx) directly.

var (
	projectIDCache    string
	projectIDCacheErr error
	projectIDFetched  bool
)

func fetchProjectID(ctx context.Context) (string, error) {
	if !projectIDFetched {
		projectIDCache, projectIDCacheErr = metadata.ProjectIDWithContext(ctx)
		projectIDFetched = true
	}
	return projectIDCache, projectIDCacheErr
}

func IsAllowlistedProject(ctx context.Context) bool {
	id, err := fetchProjectID(ctx)
	if err != nil {
		log.Printf("Error in fetching project id: %v", err)
		return false
	}
	if strings.Contains(id, "cloudtop") {
		return true
	}
	return slices.Contains(AllowlistedGcpProjects, id)
}

Comment on lines +109 to +112
if !creds_tests.IsAllowlistedProject(testEnv.ctx) {
log.Printf("The active GCP project is not one of the allowlisted projects. Skipping managed folders tests.")
os.Exit(0)
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

This check is currently placed after the storage and control clients are created. If the project is not allowlisted, os.Exit(0) is called, which bypasses the deferred cleanup functions for those clients.

Additionally, initializing the clients is unnecessary if the tests are going to be skipped.

Consider moving this check to the beginning of TestMain (right after testEnv.cfg is initialized, around line 92), before the clients are created.

@kislaykishore kislaykishore added the execute-integration-tests Run only integration tests label Jun 1, 2026
@codecov
Copy link
Copy Markdown

codecov Bot commented Jun 1, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 0.00%. Comparing base (ea8a8e6) to head (e76684f).
⚠️ Report is 1 commits behind head on master.

Additional details and impacted files
@@      Coverage Diff       @@
##   master   #4745   +/-   ##
==============================
==============================

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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

Labels

execute-integration-tests Run only integration tests remind-reviewers Auto remind reviewers in attention set for review post 24hrs of inactivity on PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant