Test: drop the npm install from the AgentLoader discovery integration fixture - #276
Open
AmaadMartin wants to merge 1 commit into
Conversation
…y fixture The discovery suite never spawns a subprocess: it constructs AgentLoader in-process and calls listApps()/listAgents()/getAppFile(). esbuild and Node both resolve @google/adk and @google/adk-devtools from the workspace-root node_modules, whose symlinks point at the same core/ and dev/ the fixture's file: deps did, so materialising ~600 packages into the fixture was pure waste on every CI job on every OS. Deleting the fixture package.json is required to remove the install, and it changes which manifest getTypeFromPackageJson() finds: the walk now reaches the repository root, which declares "type": "module", so the fixture compiles to .mjs/esm instead of .cjs/cjs. A new assertion on the compiled artifact's extension pins that. Removing the install also stops preloadAgents() stat-ing every top-level entry of a fixture node_modules, and makes the suite runnable offline.
This was referenced Jul 30, 2026
Open
Open
Open
This was referenced Aug 6, 2026
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
Closes: #issue_number
Related: #issue_number
Problem: The
integrationVitest project runs 14 separatenpm installinvocations inside test fixture directories, each materialising ~600 packages, on all three OSes of the validation matrix. One of those 14 is pure waste: theAgentLoader discovery and loading integrationsuite intests/integration/app_loader/app_loader_test.tsnever spawns a subprocess. It constructsAgentLoaderin-process and callslistApps()/listAgents()/getAppFile(). esbuild (insideAgentFile.load()) and Node both resolve@google/adkand@google/adk-devtoolsfrom the workspace-rootnode_modules, whichnpm workspacespopulates with@google/adk -> ./coreand@google/adk-devtools -> ./devsymlinks — the same physical targets the fixture'sfile:deps pointed at. Installing them again into the fixture buys nothing, costs ~600 package materialisations plus a full recursive teardown per CI job per OS, and additionally forcesAgentLoader.preloadAgents()tostatevery top-level entry of the fixture's ownnode_modules.Solution: Delete the install, and with it
tests/integration/app_loader/discovery/package.json— the manifest exists only to carry thefile:deps, and it is the thing that makesnpm installmeaningful there. The fixture's four sources are untouched.Deleting that manifest has one non-obvious consequence, which is the reason for the new assertion.
getFileModuleType()(dev/src/utils/agent_loader.ts:574) delegates a.tsentry togetTypeFromPackageJson(), which walks up to the firstpackage.jsonand returnsESMiff it declares"type": "module". Previously the walk stopped at the fixture's own manifest, which has no"type"field, so artifacts compiled to.cjswithformat: 'cjs'. Now the walk continues pastdiscovery/,app_loader/,integration/andtests/(none of which have apackage.json) and reaches the repository root, which declares"type": "module"— so artifacts compile to.mjswithformat: 'esm'. That path is not exotic; it is already exercised in CI by theagent_loader/import_meta_urlandskills/script_jsfixtures, both of which declare"type": "module".linkProjectNodeModules()likewise now resolves to the repository-rootnode_modulesinstead of the fixture's, which is a strict superset.The suite's assertions are unchanged in meaning: still 2 apps and 4 agents-or-apps. Neither the deleted
package.json(not a JS entry point) nor the fixturenode_modules(a directory with noapp.*/agent.*inside it) ever contributed to those counts.Scope notes:
tests/is touched, andcoverage.includeinvitest.config.tscovers onlycore/src,dev/srcandintegrations/src, so coverage and its thresholds are unaffected.vitest.config.tsor anywhere else. The discoverybeforeAllloses its explicit hook timeout only because its body is now a single synchronous constructor call; theafterAllkeepsFIXTURE_HOOK_TIMEOUT_MSexactly as it was.package.jsonand their install:getFileModuleType()reads their"type"field, and thebuild_setupsuite exists precisely to prove the published package layout resolves from a consumer project.@ts-expect-error,@ts-ignore,eslint-disable,any,as any) — none was needed.Collision check (required by the contribution workflow, recorded here):
tests/integration/app_loader/discovery/at all, so the change in this PR is unclaimed.fix/flaky-install-bound-integration-suites) does already land the cheap-install work that would otherwise have been part of this change: it centralisesnpm install --prefer-offline --no-audit --no-fundbehindinstallFixtureProject()intests/integration/fixture_project.tsand applies it to all four install-bound suites. Rather than ship a second, competing copy of that helper, this PR is stacked on Fix: stabilise install-bound and server-spawning integration suites #218 and contributes only the part Fix: stabilise install-bound and server-spawning integration suites #218 does not do — removing the fourteenth install entirely. Fix: stop the agent_loader and build_setup integration suites from timing out on their fixture npm install #257 lands the same three flags as a local constant in two of the four files, and is a subset of Fix: stabilise install-bound and server-spawning integration suites #218.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.
This is a test-infrastructure change: the integration suite is the test for it, and no unit test is added. A unit test that mocked
child_processto assert an install did not happen would assert the mock, not the behaviour. The behavioural consequence is instead pinned by a real assertion inside the suite (see the mutation proof below).Targeted runs only (never the whole repo suite), Linux, Node v22.22.0, on the exact commit pushed:
Discovery suite, no fixture install and no network state. From a clean tree with the fixture's
node_modules/package-lock.jsonremoved:→
Test Files 1 passed (1),Tests 3 passed | 3 skipped (6).All four install-bound suites (the four files Fix: stabilise install-bound and server-spawning integration suites #218 touches, to confirm nothing regressed underneath the stack):
→
Test Files 4 passed (4),Tests 30 passed | 4 skipped (34),Duration 480.92s.git status --porcelainclean afterwards.Static checks.
npm run lint→ clean.npm run format:check→All matched files use Prettier code style!.npm run ts:checkfails identically with and without this diff — I captured its full output on the stack base and on this commit anddiffreports them byte-identical, so the failures are pre-existing (they are the subject of separate PRs) and none of them names a file in this diff.Prove the test can fail (mutation). The new assertion is the regression guard for the whole change, so it was run against the unmutated pre-change state:
Mutation: restore
tests/integration/app_loader/discovery/package.jsonwith its original contents (git show HEAD:...), leaving everything else as-is.Result — the new assertion FAILS:
Mutation reverted (
rmthe restored manifest) →Tests 3 passed, green again.Measured effect (Linux, directional — not CI numbers):
app_loader_test.ts -t 'AgentLoader discovery'Duration 96.74sDuration 27.22sapp_loader_test.ts(whole file, 6 tests)Duration 302.93sDuration 225.59sBoth "before" figures were taken on the stack base (this change stashed) in the same session, so they already include #218's cheap-install flags; the delta is attributable to removing the install, not to the flags.
Manual End-to-End (E2E) Tests:
All five steps were run and produced exactly the output above.
CI status: absent — validated locally instead.
validation.yamltriggers onpull_request: branches: [main], and this is a stacked PR whose base isfix/flaky-install-bound-integration-suites, so therun-testsmatrix never fires (onlyauto-assignruns, which is not validation). Everything below was therefore run locally on the exact pushed commit1f70b67e, with a clean working tree:npm run buildnpm run lintnpm run format:checkAll matched files use Prettier code style!npx vitest run --project integration tests/integration/app_loader/app_loader_test.tsTest Files 1 passed (1),Tests 6 passed (6),Duration 247.67sgit status --porcelainafterwardsls tests/integration/app_loader/discoveryservice_alpha service_beta standalone_agent.ts standalone_app.tsnpm run ts:checkis the one red check, and it is red identically on the stack base — its output is byte-identical with and without this diff.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.