Fix: make cli_create_test hermetic against ambient GOOGLE_CLOUD_* env vars (duplicate of #569) - #576
Open
AmaadMartin wants to merge 1 commit into
Open
Fix: make cli_create_test hermetic against ambient GOOGLE_CLOUD_* env vars (duplicate of #569)#576AmaadMartin wants to merge 1 commit into
AmaadMartin wants to merge 1 commit into
Conversation
… vars getGcpProject()/getGcpRegion() return process.env.GOOGLE_CLOUD_PROJECT / GOOGLE_CLOUD_LOCATION before they ever reach the mocked execSync, so a developer who exports those vars saw "should handle Vertex AI selection with gcloud defaults" fail with their real project id. The node:child_process mock was never the gap; the unstubbed env read was. Pin both vars to undefined in beforeEach and add vi.unstubAllEnvs() to afterEach, mirroring dev/test/cli/cli_deploy_agent_engine_test.ts. Also cover the two previously untested ambient-input paths: env vars winning over the gcloud lookup, and the empty default when the lookup throws. Test-only; dev/src is byte-identical. Coverage of cli_create.ts rises 91.78 -> 93.71 statements and 82.81 -> 86.56 branches.
AmaadMartin
pushed a commit
that referenced
this pull request
Aug 4, 2026
* fix(artifacts): isolate in-memory composite keys * test(artifacts): cover storage key boundaries * refactor(artifacts): encode in-memory key segments
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Please ensure you have read the contribution guide before creating a pull request.
Link to Issue or Description of Change
No public GitHub issue is associated with this change.
Problem:
dev/test/cli/cli_create_test.tsis not hermetic. The testcreateAgent > Interactive Mode > should handle Vertex AI selection with gcloud defaultsasserts that the project prompt is seeded with the stubbed valuegcloud-project, but on any machine that exportsGOOGLE_CLOUD_PROJECTitreceives that machine's real project id instead and fails:
The root cause is not an unstubbed
gcloudshell-out —node:child_processis already fully mocked at
cli_create_test.ts:35-45, and that mock iseffective. The leak is one level earlier:
getGcpProject()(
dev/src/cli/cli_create.ts:103-116) andgetGcpRegion()(118-131) eachshort-circuit on an environment variable before reaching
execSync, andnothing pinned those variables. Adding more
execSyncstubbing would havechanged nothing. This makes
npm run test:unitred for environment-dependentreasons, which trains contributors to ignore local failures.
Solution: Pin the two variables to
undefinedin the existingbeforeEach(file-level, so the whole file stays hermetic if another test later exercises
the Vertex path) and add
vi.unstubAllEnvs()to the existingafterEach.vi.stubEnv(name, undefined)deletes the variable for the test, which letsif (process.env.GOOGLE_CLOUD_PROJECT)fall through to the already-mockedexecSync. The teardown mirrors the sibling CLI test atdev/test/cli/cli_deploy_agent_engine_test.ts:241-247;vitest.config.tsdoesnot set
unstubEnvs, so the explicit teardown is required rather than optional.Two new tests cover the ambient-input paths that were previously untested: env
vars winning over the
gcloudlookup, and the empty default when the lookupthrows.
Deliberate scope decisions:
dev/src/is byte-identical tomain.process.envalready is the injection seam and
vi.stubEnvis the supported way to driveit, so threading a
readGcpDefaultscallback throughAgentCreationOptionsorexporting the helpers purely for the test would add production surface with no
production caller.
initialValue: 'gcloud-project'and theGOOGLE_CLOUD_PROJECT=gcloud-project.envassertion are untouched — thatpair is the regression signal for the Vertex path. Only the fixture (the
ambient environment) was pinned; no assertion was relaxed and no test deleted.
vitest.config.tsuntouched. Repo-wideunstubEnvsis a separate concern(see Fix: scrub ADK environment variables from unit test runs #302 / Fix: make env-var stubbing hermetic across the test suite (vitest unstubEnvs + ambient-env coverage) #281) and out of scope here.
Testing Plan
Please describe the tests that you ran to verify your changes. This is required for all PRs that are not small documentation or typo fixes.
Unit Tests:
[x] I have added or updated unit tests for my change.
[x] All unit tests pass locally.
Targeted run, under both ambient conditions — 11 tests before, 13 after:
Coverage of the code under test (
--coverage.include='dev/src/cli/cli_create.ts')rises from 91.78% → 93.71% statements and 82.81% → 86.56% branches,
newly covering the
GOOGLE_CLOUD_PROJECT/GOOGLE_CLOUD_LOCATIONearlyreturns and both
catchfallbacks. Functions remain 100%.Proof each test can fail (mutation testing). Every new test was run against
unfixed code and confirmed to FAIL. Mutations were applied one at a time and the
source restored byte-identically after each:
vi.stubEnvlines, ran with the env varsexported →
should handle Vertex AI selection with gcloud defaultsfails:- "initialValue": "gcloud-project"/+ "initialValue": "some-real-project"(the region prompt leaks
us-central1in the same run).if (process.env.GOOGLE_CLOUD_PROJECT) { return ... }block fromgetGcpProject→should prefer ambient Google Cloud env vars over gcloud configfails on the load-bearing assertion:AssertionError: expected "spy" to not be called at all, but actually been called 1 times. Result:Tests 1 failed | 12 passed (13).getGcpProject'scatchto return'mutant-default'instead of''→should seed empty defaults when the gcloud lookup failsfails:- "initialValue": ""/+ "initialValue": "mutant-default". Result:Tests 1 failed | 12 passed (13).expect(execSync).not.toHaveBeenCalled()is the load-bearing assertion: it pinsthe precedence (env short-circuits before the shell-out), which is the exact
behaviour that caused this bug.
Manual End-to-End (E2E) Tests:
Please provide instructions on how to manually test your changes, including any necessary setup or configuration.
No E2E test is applicable — this is a unit-test hermeticity fix with no
production change and no cross-package surface. To verify manually, run the file
under all three ambient configurations and confirm 13/13 each time:
npm run buildsucceeds andnpx eslint dev/test/cli/cli_create_test.tsisclean. Note on
npm run ts:check: it exits non-zero on this branch, but it doesso identically on unmodified
main(verified by stashing this change), witherrors spread across pre-existing
core/test/**files.cli_create_test.tsisnot among the files it reports, so this pre-existing breakage is neither caused
nor worsened here, and fixing it repo-wide is out of scope.
Checklist
[x] I have read the CONTRIBUTING.md document.
[x] I have performed a self-review of my own code.
[x] I have commented my code, particularly in hard-to-understand areas.
[x] I have added tests that prove my fix is effective or that my feature works.
[x] New and existing unit tests pass locally with my changes.