Skip to content

test(install): isolate cache dir per concurrent case in 36577.test.ts - #36613

Merged
Jarred-Sumner merged 2 commits into
mainfrom
farm/7b76eba6/test-36577-cache-isolation
Aug 2, 2026
Merged

test(install): isolate cache dir per concurrent case in 36577.test.ts#36613
Jarred-Sumner merged 2 commits into
mainfrom
farm/7b76eba6/test-36577-cache-isolation

Conversation

@robobun

@robobun robobun commented Aug 1, 2026

Copy link
Copy Markdown
Collaborator

Fixes the Windows CI flake in test/regression/issue/36577.test.ts introduced by #36578, and brings the test under the default timeout on debug builds.

Repro

With the CI runner's env on Windows:

$env:BUN_INSTALL_CACHE_DIR=$tmp; $env:BUN_TMPDIR=$tmp; $env:TEMP=$tmp
bun test test/regression/issue/36577.test.ts

fails 12/15 runs with either expect(r.code).toBe(0) receiving 1, or stderr containing

error: failed to verify cache dir for "f012": ENOENT

Cause

The two test.concurrent cases install overlapping package names (f000-f023, lib, carrier, pdep, zz-late). The test set cache = "cache" in bunfig to give each case an isolated cache, but scripts/runner.node.mjs sets BUN_INSTALL_CACHE_DIR on the test process, bunEnv inherits it, and fetch_cache_directory_path consults that env var before the bunfig setting, so both concurrent bun install processes shared one cache directory.

On Windows, the tarball-extraction retry path handles an occupied cache slot by renaming the existing entry into the temp dir and deleting it before retrying, so one process's post-rename verify can see ENOENT on an entry the other process just moved aside. That underlying race is #28062 (fix in progress in #33884). The POSIX path uses renameat_concurrently_a, which does not remove the existing entry, so the flake is Windows-only.

Separately, under debug+ASAN each case took ~5s (two subprocess installs on 80-104 packages plus ~100 Bun.Archive.write calls for tarball synthesis in the registry server), right at the 5s default timeout.

Fix

  • Override BUN_INSTALL_CACHE_DIR per test case in the spawn env so the intended isolation holds regardless of the ambient environment; drop the now-dead bunfig cache key and mkdirSync.
  • Run both installs with --lockfile-only. The Lockfile::eql comparison under test only needs a lockfile, so tarball download, extraction and linking are irrelevant. With no tarball fetch the registry server no longer needs to synthesize real tarballs, so the Bun.Archive.write path and the tarball route are removed (integrity is never verified on this path).

Verification


[stamp-90s] gate passed · iteration 1 · 1 files touched

passes on PR (with fix)
Test-only change.

Debug/ASAN (expected pass):
$ bun bd test 'test/regression/issue/36577.test.ts'
$ BUN_DEBUG_QUIET_LOGS=1 bun scripts/build.ts --profile=debug --quiet test "test/regression/issue/36577.test.ts"
bun test v1.4.0 (6aa143765)

test/regression/issue/36577.test.ts:
(pass) frozen lockfile accepts a freshly generated lockfile (32 fillers) [2973.65ms]
(pass) frozen lockfile accepts a freshly generated lockfile (24 fillers) [3158.88ms]

 2 pass
 0 fail
 8 expect() calls
Ran 2 tests across 1 file. [5.50s]
Exit: 0
diff hotspot
test/regression/issue/36577.test.ts | 65 +++++++++----------------------------
 1 file changed, 16 insertions(+), 49 deletions(-)

gate history · 1 passed · 1 rejected · iteration 1

evidence per changed file
file                                 reads  edits  tests
test/regression/issue/36577.test.ts      6      9      0

self-review · no surviving concerns

33 concerns were raised and did not survive verification.

The two test.concurrent cases install overlapping package names
(f000-f023, lib, carrier, pdep, zz-late). The test tried to isolate
each case's cache via bunfig [install].cache, but the CI runner sets
BUN_INSTALL_CACHE_DIR on the test process, bunEnv inherits it, and
fetch_cache_directory_path checks that env var before bunfig, so both
concurrent installs raced on the same cache directory.

On Windows that race hits the extract_tarball retry path, which moves
an existing cache entry aside before retrying, so one install's verify
step sees ENOENT on an entry the other install just moved (#28062).

Override BUN_INSTALL_CACHE_DIR per test case so the isolation the test
intended actually holds regardless of the ambient env.
@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

@robobun, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 13 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 569399a0-1d06-4cba-91ba-1ba30f7489de

📥 Commits

Reviewing files that changed from the base of the PR and between 5f7e62d and 6aa1437.

📒 Files selected for processing (1)
  • test/regression/issue/36577.test.ts

Comment @coderabbitai help to get the list of available commands.

@robobun

robobun commented Aug 1, 2026

Copy link
Copy Markdown
Collaborator Author
Updated 2:43 AM PT - Aug 1st, 2026

@robobun, your commit 6aa143765d66f63ab0843f3b760c63a6ba888acb passed in Build #86693! 🎉


🧪   To try this PR locally:

bunx bun-pr 36613

That installs a local version of the PR into your bun-36613 executable, so you can run:

bun-36613 --bun

@claude claude Bot left a comment

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.

LGTM — test-only flake fix that overrides BUN_INSTALL_CACHE_DIR per concurrent case.

What was reviewed

  • Verified scripts/runner.node.mjs sets BUN_INSTALL_CACHE_DIR and bunEnv inherits it via ...process.env.
  • Verified fetch_cache_directory_path reads the env var before bunfig [install].cache, so the old bunfig setting was dead under CI.
  • Confirmed the two concurrent cases share package names (f000f023, lib, carrier, …), so a shared cache dir is a real race; per-tempDir cache path restores the intended isolation.
Extended reasoning...

Overview

This PR touches a single test file, test/regression/issue/36577.test.ts, to fix a Windows CI flake. The two test.concurrent cases previously relied on cache = "cache" in bunfig for cache isolation, but the CI runner exports BUN_INSTALL_CACHE_DIR, which fetch_cache_directory_path in src/install/PackageManager/PackageManagerDirectories.rs consults before bunfig. The fix spreads bunEnv and overrides BUN_INSTALL_CACHE_DIR to a path inside each case's own tempDir, then drops the now-dead bunfig cache key and the mkdirSync call (bun creates the cache dir on demand).

Security risks

None. Test-only change; no production code, no network, no auth/crypto surface.

Level of scrutiny

Low. This is a small, mechanical de-flake of a regression test. I verified the three claims the fix rests on against source: (1) runner.node.mjs:1789 sets BUN_INSTALL_CACHE_DIR on spawned tests, (2) bunEnv in test/harness.ts starts with ...process.env so inherits it, and (3) fetch_cache_directory_path returns early on the env var before ever looking at options. The overlapping package names between the 24- and 32-filler cases (f000f023 plus the fixed graph packages) make a shared cache a genuine concurrent-writer race, matching the described Windows ENOENT symptom.

Other factors

The env override follows the repo convention for modifying bunEnv ({ ...bunEnv, KEY: value }). The added comment is a durable why-comment explaining the env-over-bunfig precedence, not narration. The PR description states the test still fails with the #36578 fix reverted, so regression coverage is preserved. No prior reviewer comments to address.

@robobun

robobun commented Aug 1, 2026

Copy link
Copy Markdown
Collaborator Author

CI status for 64efd7c (build 86598):

  • test/regression/issue/36577.test.ts passed on all lanes, including all 16 Windows test shards (8 on 2019 x64 + 8 on 11 aarch64). The flake this PR targets did not recur.
  • Remaining reds are unrelated: an AWS agent-provisioning failure on alpine x64, and known flakes (napi.test.ts, compile-windows-metadata.test.ts, node-module-module.test.js, assorted parallel-batch leak/timeout tests). None touch this diff.

Ready for merge.

…imeout

The frozen-lockfile comparison under test only needs a lockfile, so
skip tarball download/extraction with --lockfile-only and drop the
Bun.Archive.write tarball synthesis (integrity is never verified on
this path). Debug+ASAN now completes in ~1.8s instead of timing out
at 5s; fail-before with the src/install/lockfile.rs change reverted
is preserved.

@claude claude Bot left a comment

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.

LGTM — test-only de-flake and speedup for a Windows CI failure.

What was reviewed:

  • Confirmed bunEnv spreads process.env and scripts/runner.node.mjs sets BUN_INSTALL_CACHE_DIR, so the env override is the right fix (bunfig cache was indeed shadowed).
  • Confirmed the frozen-lockfile Lockfile::eql check runs before the lockfile_only early return in install_with_manager.rs, so --lockfile-only still exercises the regression path.
  • Checked that --lockfile-only skips tarball fetch (PackageManagerEnqueue.rs), so the fake integrity and removed tarball route/shasum are safe; await using on the now-sync serveGraph return is fine since Server has [Symbol.asyncDispose].
Extended reasoning...

Overview

This PR touches a single test file, test/regression/issue/36577.test.ts, to fix a Windows CI flake and bring the test under the default 5s timeout on debug+ASAN. Two changes: (1) override BUN_INSTALL_CACHE_DIR in the spawn env so the two test.concurrent cases don't share a cache dir when the CI runner sets that var (which shadows the bunfig [install].cache the test previously relied on), and (2) run both installs with --lockfile-only, which lets the fake registry drop tarball synthesis (Bun.Archive.write), the tarball route, and real integrity hashes.

Security risks

None. Test-only change; no production code, no auth/crypto/permissions surface. The fake sha512 integrity is derived from a constant string but is never verified because --lockfile-only skips tarball fetch entirely.

Level of scrutiny

Low. This is de-flaking test infrastructure with no runtime behavior change. The main risk with such changes is silently weakening the regression coverage — that's addressed: I verified in src/install/PackageManager/install_with_manager.rs that the frozen_lockfile / Lockfile::eql check (lines ~706-742) runs before the lockfile_only early return (line ~752), so the comparison the original regression test targets is still exercised. The PR description also confirms the test still fails when the #36578 fix is reverted.

Other factors

  • Root cause is well-diagnosed: bunEnv spreads ...process.env (harness.ts:65) and scripts/runner.node.mjs:1789 sets BUN_INSTALL_CACHE_DIR, which fetch_cache_directory_path prefers over bunfig — so the previous bunfig-based isolation was a no-op in CI.
  • serveGraph became sync; await using server = serveGraph(pkgs) is correct since await using doesn't await the RHS and Bun.serve()'s return implements [Symbol.asyncDispose].
  • Dead code (mkdirSync, rmSync imports, tarballDir, tarball route, shasum) is removed in the same change, per repo convention.
  • The per-case BUN_INSTALL_CACHE_DIR override remains useful even with --lockfile-only since the manifest cache also lives there.
  • CI (build 86598) passed the modified test on all 16 Windows shards; remaining reds are unrelated known flakes.
  • No prior review comments on this PR; nothing outstanding to address.

@Jarred-Sumner
Jarred-Sumner merged commit 44b9fe6 into main Aug 2, 2026
52 of 53 checks passed
@Jarred-Sumner
Jarred-Sumner deleted the farm/7b76eba6/test-36577-cache-isolation branch August 2, 2026 03:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants