Skip to content

test(serve-body-leak): give release-asan the same 60s per-test timeout as debug - #34297

Merged
dylan-conway merged 1 commit into
mainfrom
farm/a9391ab3/serve-body-leak-asan-timeout
Jul 16, 2026
Merged

test(serve-body-leak): give release-asan the same 60s per-test timeout as debug#34297
dylan-conway merged 1 commit into
mainfrom
farm/a9391ab3/serve-body-leak-asan-timeout

Conversation

@robobun

@robobun robobun commented Jul 16, 2026

Copy link
Copy Markdown
Collaborator

test/js/bun/http/serve-body-leak.test.ts went red on the debian 13 x64-asan lane in build 73611: the "should not leak memory when streaming the body and echoing it back" case timed out at 40s on all four retries. The PR under test (#33580, tty setRawMode) does not touch anything related, so this is the test's own budget.

Cause

This is not a hang and not a code regression. Scraping the timestamped logs from 35 recent x64-asan runs (builds 73562-73623) plus 4 pre-#33193 runs:

case release (debian 13 x64) release-asan (debian 13 x64-asan)
callIgnore ~5s 15-24s
callStreamingEcho ~8s 27-39s (median ~31s)
total file ~40-47s ~125-195s

The streaming-echo case has been running at ~31s median on ASAN since well before the webstreams rewrite (pre-#33193 samples: 28.2 / 30.9 / 28.2 / 31.6s), so the 40s budget has always been tight there. On build 73611 every case in the file ran ~35% slower than typical (the shard landed on a slower EC2 instance; callIgnore 23.6s vs a typical ~17s), which is enough to push echo past 40s. A local 15000-request /streaming-echo probe against a debug build runs at a flat ~395 req/s with no stalls, confirming throughput, not a hang.

The file already scales its end_memory threshold for ASAN (#32520), and scripts/runner.node.mjs already applies a 3x ASAN multiplier to the default --timeout for the same reason, but that multiplier does not reach tests that pass their own explicit third-argument timeout. Skipping on ASAN was tried in #28301 and reverted in #28337; this change keeps the test running there with a budget that matches the measured cost.

Fix

-    isDebug ? 60_000 : 40_000,
+    isDebug || isASAN ? 60_000 : 40_000,

Matches the isDebug || isASAN convention already used by 16 other test files for timeouts/iteration counts. 60s is ~2x the ASAN median and ~1.4x the extrapolated worst case (73611). Release lanes stay at 40s.

Verification

  • USE_SYSTEM_BUN=1 bun test test/js/bun/http/serve-body-leak.test.ts: 8 pass, echo 11.4s (release, budget unchanged at 40s).
  • bun bd test test/js/bun/http/serve-body-leak.test.ts -t 'ignoring the body': passes; file parses and the unchanged isDebug=60s branch applies under the debug build.
  • /tmp/echo-probe.ts against debug build: 15000 /streaming-echo requests at a steady ~395 req/s, no stalls.

no test proof · iteration 0 · Platform-specific test-only change; deferring to CI.

…t as debug

The streaming-echo case runs at ~31s median (27-39s across 35 CI runs) on
the debian 13 x64-asan lane, so the 40s per-test timeout leaves next to
no margin. On a slower-than-typical EC2 instance (build 73611) every case
in the file ran ~35% slower and streaming-echo timed out on all four
retries. The test file already scales the end_memory threshold for ASAN
(PR #32520), and scripts/runner.node.mjs scales the default per-test
timeout 3x on ASAN for the same reason; this explicit per-test timeout
simply was not given the same treatment.
@coderabbitai

coderabbitai Bot commented Jul 16, 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: 1 minute

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: f7903779-f229-4f13-9671-f7dfa24842f9

📥 Commits

Reviewing files that changed from the base of the PR and between c4fad46 and b44cd96.

📒 Files selected for processing (1)
  • test/js/bun/http/serve-body-leak.test.ts

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

@robobun

robobun commented Jul 16, 2026

Copy link
Copy Markdown
Collaborator Author
Updated 11:05 PM PT - Jul 15th, 2026

@robobun, your commit b44cd96 is still building in Build #73652, but has 1 failures so far (All Failures):

@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 timeout bump for the ASAN lane, matching the existing isDebug || isASAN convention.

What was reviewed:

  • isASAN is already imported from harness and used in this file for the end_memory threshold, so no new import needed.
  • Release (non-ASAN, non-debug) lanes keep the 40s budget unchanged.
  • Operator precedence: isDebug || isASAN ? 60_000 : 40_000 parses as (isDebug || isASAN) ? ..., which is the intended grouping.
Extended reasoning...

Overview

Single-line change in test/js/bun/http/serve-body-leak.test.ts: the per-test timeout expression isDebug ? 60_000 : 40_000 becomes isDebug || isASAN ? 60_000 : 40_000, plus a two-line explanatory comment. No production code, no assertion changes, no test logic changes.

Security risks

None. Test-only timeout constant; no auth, crypto, network surface, or user-facing code touched.

Level of scrutiny

Low. This is a mechanical CI-budget adjustment following an existing pattern (the same file already branches on isASAN for the end_memory threshold, and the PR description cites 16 other files using isDebug || isASAN for the same purpose). The change only loosens a timeout on an instrumented build lane; the plain release lane keeps its 40s budget, so this cannot mask a regression there. Verified that isASAN is already in the import list at the top of the file.

Other factors

  • Operator precedence checked: || binds tighter than ?:, so no parentheses are needed.
  • The added comment is concise and records the measured CI data justifying the number, which is exactly what CLAUDE.md asks for (durable non-obvious content).
  • No prior reviewer comments to address; no bugs found by the bug-hunting pass.

@github-actions

Copy link
Copy Markdown
Contributor

Found 1 issue this PR may fix:

  1. #32179 — serve-body-leak.test.ts absolute 512MB end-memory cap has no headroom under ASAN, flakes on the x64-asan lane — the same test file, same CI lane; the 40s timeout was causing the streaming echo test to time out under ASAN's slowdown, which is part of the broader flakiness described in this issue.

To close it via merge, add to the PR description:

Fixes #32179

🤖 Generated with Claude Code

@robobun

robobun commented Jul 16, 2026

Copy link
Copy Markdown
Collaborator Author

Self-review clean. Build 73652: all 20 x64-asan test shards passed (serve-body-leak included), so the target lane is green. Remaining reds are unrelated to this one-line test-file change: test-net-connect-memleak.js on alpine x64 is a pre-existing main break (already being addressed separately), and the http3/webview/cron failures are flaky (each passed on retry). Ready for review.

@dylan-conway
dylan-conway merged commit fbe467c into main Jul 16, 2026
77 of 78 checks passed
@dylan-conway
dylan-conway deleted the farm/a9391ab3/serve-body-leak-asan-timeout branch July 16, 2026 06:33
hughescr added a commit to hughescr/bun that referenced this pull request Jul 16, 2026
* upstream/main: (57 commits)
  node:http/https/http2: raise Node v26.3.0 compat to ~94%, sync the upstream suites, and fix the Windows/macOS transport-layer teardown bugs they exposed (oven-sh#32488)
  expect: fix panic in toBeArrayOfSize/toHaveBeenCalledTimes with length > i32 max (oven-sh#32266)
  lexer: fix TOKEN_TO_STRING[TColon] showing " =" instead of ":" (oven-sh#34253)
  Bun.Terminal: write() returns bytes accepted, fire drain on POSIX (oven-sh#34289)
  test(serve-body-leak): give release-asan the same 60s per-test timeout as debug (oven-sh#34297)
  worker: mark the context terminating before the final concurrent-queue drain (oven-sh#34278)
  buffer: wrap negative ucs2 indexOf offset against raw byte length for Buffer needles (oven-sh#34273)
  fs.promises.watch: yield events with a null prototype (oven-sh#34279)
  child_process: latch stdin write EPIPE as 'error' + destroy, fail later writes with ERR_STREAM_DESTROYED (oven-sh#34268)
  Fix asString assertion when passing String objects as signals (oven-sh#34265)
  Buffer: carry size_t through toString/write so length 2^32 doesn't wrap to 0 (oven-sh#34274)
  test: use tempDir in log-test.test.ts instead of hardcoded /tmp path (oven-sh#34294)
  tty: track raw mode per handle instead of per process (oven-sh#33527)
  test: expect the bumped mimalloc SHA in process.versions
  Return freed memory to the OS on a background thread instead of the JS thread (oven-sh#34181)
  Move WTFTimer out of the shared timer heap to fix a cross-thread race (oven-sh#33131)
  test: update block-scoped enum lowering expectations to let (oven-sh#34287)
  Error.captureStackTrace: install .stack as non-enumerable (oven-sh#34259)
  js_parser: treat "async as T" / "async satisfies T" as a cast, not an arrow (oven-sh#34246)
  js_parser: accept `!`, `#name`, and `export @dec` in standard decorator grammar (oven-sh#34245)
  ...
hughescr added a commit to hughescr/bun that referenced this pull request Jul 16, 2026
* upstream/main: (70 commits)
  node:http/https/http2: raise Node v26.3.0 compat to ~94%, sync the upstream suites, and fix the Windows/macOS transport-layer teardown bugs they exposed (oven-sh#32488)
  expect: fix panic in toBeArrayOfSize/toHaveBeenCalledTimes with length > i32 max (oven-sh#32266)
  lexer: fix TOKEN_TO_STRING[TColon] showing " =" instead of ":" (oven-sh#34253)
  Bun.Terminal: write() returns bytes accepted, fire drain on POSIX (oven-sh#34289)
  test(serve-body-leak): give release-asan the same 60s per-test timeout as debug (oven-sh#34297)
  worker: mark the context terminating before the final concurrent-queue drain (oven-sh#34278)
  buffer: wrap negative ucs2 indexOf offset against raw byte length for Buffer needles (oven-sh#34273)
  fs.promises.watch: yield events with a null prototype (oven-sh#34279)
  child_process: latch stdin write EPIPE as 'error' + destroy, fail later writes with ERR_STREAM_DESTROYED (oven-sh#34268)
  Fix asString assertion when passing String objects as signals (oven-sh#34265)
  Buffer: carry size_t through toString/write so length 2^32 doesn't wrap to 0 (oven-sh#34274)
  test: use tempDir in log-test.test.ts instead of hardcoded /tmp path (oven-sh#34294)
  tty: track raw mode per handle instead of per process (oven-sh#33527)
  test: expect the bumped mimalloc SHA in process.versions
  Return freed memory to the OS on a background thread instead of the JS thread (oven-sh#34181)
  Move WTFTimer out of the shared timer heap to fix a cross-thread race (oven-sh#33131)
  test: update block-scoped enum lowering expectations to let (oven-sh#34287)
  Error.captureStackTrace: install .stack as non-enumerable (oven-sh#34259)
  js_parser: treat "async as T" / "async satisfies T" as a cast, not an arrow (oven-sh#34246)
  js_parser: accept `!`, `#name`, and `export @dec` in standard decorator grammar (oven-sh#34245)
  ...
hughescr added a commit to hughescr/bun that referenced this pull request Jul 16, 2026
* upstream/main: (52 commits)
  node:http/https/http2: raise Node v26.3.0 compat to ~94%, sync the upstream suites, and fix the Windows/macOS transport-layer teardown bugs they exposed (oven-sh#32488)
  expect: fix panic in toBeArrayOfSize/toHaveBeenCalledTimes with length > i32 max (oven-sh#32266)
  lexer: fix TOKEN_TO_STRING[TColon] showing " =" instead of ":" (oven-sh#34253)
  Bun.Terminal: write() returns bytes accepted, fire drain on POSIX (oven-sh#34289)
  test(serve-body-leak): give release-asan the same 60s per-test timeout as debug (oven-sh#34297)
  worker: mark the context terminating before the final concurrent-queue drain (oven-sh#34278)
  buffer: wrap negative ucs2 indexOf offset against raw byte length for Buffer needles (oven-sh#34273)
  fs.promises.watch: yield events with a null prototype (oven-sh#34279)
  child_process: latch stdin write EPIPE as 'error' + destroy, fail later writes with ERR_STREAM_DESTROYED (oven-sh#34268)
  Fix asString assertion when passing String objects as signals (oven-sh#34265)
  Buffer: carry size_t through toString/write so length 2^32 doesn't wrap to 0 (oven-sh#34274)
  test: use tempDir in log-test.test.ts instead of hardcoded /tmp path (oven-sh#34294)
  tty: track raw mode per handle instead of per process (oven-sh#33527)
  test: expect the bumped mimalloc SHA in process.versions
  Return freed memory to the OS on a background thread instead of the JS thread (oven-sh#34181)
  Move WTFTimer out of the shared timer heap to fix a cross-thread race (oven-sh#33131)
  test: update block-scoped enum lowering expectations to let (oven-sh#34287)
  Error.captureStackTrace: install .stack as non-enumerable (oven-sh#34259)
  js_parser: treat "async as T" / "async satisfies T" as a cast, not an arrow (oven-sh#34246)
  js_parser: accept `!`, `#name`, and `export @dec` in standard decorator grammar (oven-sh#34245)
  ...
hughescr added a commit to hughescr/bun that referenced this pull request Jul 16, 2026
* upstream/main: (52 commits)
  node:http/https/http2: raise Node v26.3.0 compat to ~94%, sync the upstream suites, and fix the Windows/macOS transport-layer teardown bugs they exposed (oven-sh#32488)
  expect: fix panic in toBeArrayOfSize/toHaveBeenCalledTimes with length > i32 max (oven-sh#32266)
  lexer: fix TOKEN_TO_STRING[TColon] showing " =" instead of ":" (oven-sh#34253)
  Bun.Terminal: write() returns bytes accepted, fire drain on POSIX (oven-sh#34289)
  test(serve-body-leak): give release-asan the same 60s per-test timeout as debug (oven-sh#34297)
  worker: mark the context terminating before the final concurrent-queue drain (oven-sh#34278)
  buffer: wrap negative ucs2 indexOf offset against raw byte length for Buffer needles (oven-sh#34273)
  fs.promises.watch: yield events with a null prototype (oven-sh#34279)
  child_process: latch stdin write EPIPE as 'error' + destroy, fail later writes with ERR_STREAM_DESTROYED (oven-sh#34268)
  Fix asString assertion when passing String objects as signals (oven-sh#34265)
  Buffer: carry size_t through toString/write so length 2^32 doesn't wrap to 0 (oven-sh#34274)
  test: use tempDir in log-test.test.ts instead of hardcoded /tmp path (oven-sh#34294)
  tty: track raw mode per handle instead of per process (oven-sh#33527)
  test: expect the bumped mimalloc SHA in process.versions
  Return freed memory to the OS on a background thread instead of the JS thread (oven-sh#34181)
  Move WTFTimer out of the shared timer heap to fix a cross-thread race (oven-sh#33131)
  test: update block-scoped enum lowering expectations to let (oven-sh#34287)
  Error.captureStackTrace: install .stack as non-enumerable (oven-sh#34259)
  js_parser: treat "async as T" / "async satisfies T" as a cast, not an arrow (oven-sh#34246)
  js_parser: accept `!`, `#name`, and `export @dec` in standard decorator grammar (oven-sh#34245)
  ...

# Conflicts:
#	test/js/bun/websocket/websocket-server.test.ts
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