Skip to content

test(Bun.write): build scratch paths inside the per-test temp dir - #38496

Open
robobun wants to merge 1 commit into
mainfrom
farm/bc0aab79/bun-write-test-tempdir-paths
Open

robobun wants to merge 1 commit into
mainfrom
farm/bc0aab79/bun-write-test-tempdir-paths

Conversation

@robobun

@robobun robobun commented Aug 14, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

  • Every direct run of test/js/bun/io/bun-write.test.js (bun test or bun bd test on a dev machine) leaves 10 scratch files (about 1.9 MB) behind in os.tmpdir(), for example /tmp/bun-write-output-html_mfwTfcoutput.html and three 630 KB large-file-*_XXXXXXbun-test-large-file-<ts>.txt* files. CI does not accumulate them only because scripts/runner.node.mjs hands each test process a private TMPDIR and removes it afterwards.
  • Seven tests build their paths as tmpbase + "name". tmpbase is a using tmpbase = tempDir(...) directory with no trailing separator, so the concatenation names a sibling of the temp dir, not a file inside it, and disposing the dir does not remove it.
  • The concatenation dates from when the file had a module level const tmpbase = tmpdir() + path.sep; abb82a6 moved the tests to per-test tempDir(...) and converted some call sites to join() but not these.
  • The three "large file" tests look like they clean up after themselves, but their try { unlinkSync(...) } catch {} blocks call a bare unlinkSync that is never imported in this file, so each block swallows a ReferenceError and nothing is unlinked.

Fix

  • Build every scratch path with join(tmpbase, name), which the other tests in this file already do (including untouched lines in the same test bodies), so the files are created inside the directory that using disposes.
  • Remove the dead unlinkSync blocks in the "large file" tests; the per-test directory is fresh, and disposal now covers the cleanup. The Date.now() suffixes are also dropped since the directory already makes the names unique.
  • No runtime change; the assertions in each test are unchanged.
  • Verified: ls /tmp before and after USE_SYSTEM_BUN=1 bun test test/js/bun/io/bun-write.test.js on main shows the 10 stray files listed below; the same before/after with this branch under bun bd test shows none.
  • bun bd test test/js/bun/io/bun-write.test.js: 49 pass. The one failure, should work when copyFileRange is not available > on large files timing out at 5 s under the debug build, is unchanged from main (reproduced with the unmodified file) and is being addressed separately in test: stop the Bun.write copy_file_range fallback test from starving its concurrent siblings #37792.
Stray files left by one run on main
$ comm -13 /tmp/before.txt /tmp/after.txt
bun-file-to-file_MeOpvWfetch.js.in                                     1326 bytes
bun-file-to-file_MeOpvWfetch.js.out                                    1326 bytes
bun-file-to-response_8s99cIfetch.js.out                                1326 bytes
bun-write-blob_RTgrFXresponse-file.test.txt                            4096 bytes
bun-write-output-html_mfwTfcoutput.html                                   8 bytes
html-rewriter_Ak3Mthhtml-rewriter.1786710027359.html                     36 bytes
html-rewriter_Ak3Mthhtml-rewriter.txt.js                                 16 bytes
large-file-blob_yb1jo7bun-test-large-file-1786710027272.txt.blob     630000 bytes
large-file-bytes_YJQJLKbun-test-large-file-1786710027271.txt.bytes   630000 bytes
large-file-text_ipIeApbun-test-large-file-1786710027270.txt          630000 bytes

Several tests in bun-write.test.js built their paths as tmpbase + "name".
That was correct when tmpbase was tmpdir() + path.sep, but since the tests
moved to per-test `using tmpbase = tempDir(...)` (which has no trailing
separator) the concatenation names a sibling of the temp dir, so every run
left the scratch files behind in os.tmpdir() after the dir was disposed.

Use join(tmpbase, name) everywhere so the files land inside the disposed
directory, and drop the try/unlinkSync blocks in the "large file" tests:
unlinkSync was never imported there, so they only ever swallowed a
ReferenceError, and disposal now covers the cleanup.
@coderabbitai

coderabbitai Bot commented Aug 14, 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: 26 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: 82970037-bd8e-4776-81e9-f1cba4a8d4f4

📥 Commits

Reviewing files that changed from the base of the PR and between 032b8db and aa2955d.

📒 Files selected for processing (1)
  • test/js/bun/io/bun-write.test.js

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

@robobun

robobun commented Aug 14, 2026 •

Copy link
Copy Markdown
Collaborator Author

Status: test-only change, ready for review.

Reproduced on main with the release binary: ls /tmp before and after USE_SYSTEM_BUN=1 bun test test/js/bun/io/bun-write.test.js shows 10 new files left outside the disposed temp dirs (listed in the PR body). With this branch, bun bd test test/js/bun/io/bun-write.test.js leaves none; 49 tests pass, and the one failure (copyFileRange ... on large files timing out under the debug build) reproduces with the unmodified file and is being handled in #37792.

CI (build 95995): 177 of 179 jobs passed, including every Linux and Windows test lane. The remaining two are the darwin 14 aarch64 - test-bun shards, which expired waiting for an agent and never ran (that queue is backlogged across the pipeline right now); they only need a job retry once agents are available. Nothing in the diff is platform specific.

@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 — mechanical test-hermeticity cleanup, no runtime changes.

What was reviewed:

  • Each converted call site: tmpbase + "name" → join(tmpbase, name) matches the pattern already used elsewhere in this file, and tempDir returns a DisposableString (extends String) that join() already accepts at the untouched sites.
  • Confirmed unlinkSync is not imported in this file (import fs, { mkdirSync } from "fs"), so the removed try { unlinkSync(...) } catch {} blocks were indeed swallowing ReferenceError and doing nothing.
  • Removed fs.unlinkSync pre-cleanup and Date.now() suffixes are redundant now that each test has a fresh per-test temp dir; the two dropped gcTick() calls in "Bun.file -> Bun.file" were tied to the deleted unlinks.
  • All assertions in every touched test are byte-identical to before.
Extended reasoning...

Overview

This PR touches a single test file, test/js/bun/io/bun-write.test.js, fixing seven tests that were leaking ~1.9 MB of scratch files into os.tmpdir() on every CI run. The root cause was tmpbase + "name" concatenation where tmpbase is a using tempDir(...) handle with no trailing separator, producing sibling paths that survive the directory's disposal. The fix replaces every such concatenation with join(tmpbase, name), removes dead try { unlinkSync } catch {} blocks (where unlinkSync was never imported and the catch swallowed the ReferenceError), removes now-redundant pre-cleanup fs.unlinkSync calls on fresh temp dirs, and drops Date.now() filename suffixes made unnecessary by per-test isolation.

Security risks

None. Test-only change; no runtime code, no new inputs, no external I/O beyond what the tests already did.

Level of scrutiny

Low. This is a mechanical refactor of test scratch-path construction with no assertion changes. I verified against test/harness.ts that tempDir returns a DisposableString extends String, which path.join already handles at the untouched join(tmpbase, ...) sites in the same file (e.g. the first four lines of the "Bun.write blob" test), so the new sites follow an established, working local convention. I confirmed from the file's import list that bare unlinkSync is genuinely undefined, validating the PR description's claim that those blocks were dead. Every assertion in the diff is unchanged; only the path variable feeding it moved from a leaking sibling path to a path inside the disposed directory.

Other factors

The PR description documents both a before/after ls /tmp verification and a full bun bd test run (49 pass, one pre-existing timeout unchanged from main and tracked separately). The change aligns directly with the repo's review guidance that tests must be hermetic and leave nothing behind on persistent CI runners. The two removed await gcTick() calls in "Bun.file -> Bun.file" were interleaved with the deleted no-op unlinks and had no bearing on the assertions that follow. No CODEOWNERS or security-sensitive paths are involved.

@robobun

robobun commented Aug 14, 2026

Copy link
Copy Markdown
Collaborator Author
Updated 7:05 AM PT - Aug 14th, 2026

@robobun, your commit aa2955d is building: #95995

This branch has not been deployed

No deployments
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.

1 participant