test(opencode): avoid Windows Node exit teardown in built harnesses#499
test(opencode): avoid Windows Node exit teardown in built harnesses#499
Conversation
|
Warning Rate limit exceeded
To continue reviewing without waiting, purchase usage credits in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughTwo test files are refactored to replace fetch-based HTTP clients with native Node ChangesNode Server Teardown Stability
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Code Review
This pull request replaces the fetch API with node:http's request in a test script to prevent issues on Windows Node 24 where fetch can abort during process termination. The reviewer recommended removing the redundant readEndpoint wrapper and calling the request function directly to streamline the code.
There was a problem hiding this comment.
🧹 Nitpick comments (1)
packages/opencode/test/server/built-node-webfetch.test.ts (1)
89-128: 💤 Low value
init.headersas aHeadersinstance would be silently dropped.On Line 92,
{ ...(init.headers ?? {}) }uses object spread, which only copies own enumerable properties. AHeadersobject exposes its entries via the iterator protocol, not own properties, so any caller passinginit.headersas aHeadersinstance (allowed by the standardfetchRequestInitshape) would have those headers silently dropped. Theinput instanceof Requestbranch already handles this viaObject.fromEntries(input.headers); consider the same treatment forinit.headers.The Effect
FetchHttpClientpath may not exercise this today, but the harness is presented as afetchpolyfill, so making it tolerant of all standard inputs avoids a future-test foot-gun.♻️ Proposed fix
- const headers = { ...(input instanceof Request ? Object.fromEntries(input.headers) : {}), ...(init.headers ?? {}) } + const toRecord = (h) => + h instanceof Headers + ? Object.fromEntries(h) + : Array.isArray(h) + ? Object.fromEntries(h) + : (h ?? {}) + const headers = { + ...(input instanceof Request ? Object.fromEntries(input.headers) : {}), + ...toRecord(init.headers), + }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/opencode/test/server/built-node-webfetch.test.ts` around lines 89 - 128, The nodeFetch polyfill currently drops Headers instances because headers are built with { ...(init.headers ?? {}) }; update the headers merge in the nodeFetch function so init.headers is normalized like the Request branch (e.g., convert Headers or iterable headers into a plain object via Object.fromEntries when init.headers is a Headers or iterable, otherwise use init.headers as-is), then merge with the input headers and set connection: "close"; modify the header construction around the headers = { ...(input instanceof Request ? Object.fromEntries(input.headers) : {}), ...(init.headers ?? {}) } expression to first detect and convert Headers/iterable init.headers (or arrays of pairs) into an object before spreading.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@packages/opencode/test/server/built-node-webfetch.test.ts`:
- Around line 89-128: The nodeFetch polyfill currently drops Headers instances
because headers are built with { ...(init.headers ?? {}) }; update the headers
merge in the nodeFetch function so init.headers is normalized like the Request
branch (e.g., convert Headers or iterable headers into a plain object via
Object.fromEntries when init.headers is a Headers or iterable, otherwise use
init.headers as-is), then merge with the input headers and set connection:
"close"; modify the header construction around the headers = { ...(input
instanceof Request ? Object.fromEntries(input.headers) : {}), ...(init.headers
?? {}) } expression to first detect and convert Headers/iterable init.headers
(or arrays of pairs) into an object before spreading.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: d7e21fd2-a5d9-45f0-be04-e2edb8900ac4
📒 Files selected for processing (2)
packages/opencode/test/server/built-node-skill-bootstrap.test.tspackages/opencode/test/server/built-node-webfetch.test.ts
Summary
Updates the built Node test harnesses that were still tripping Windows Node 24 teardown assertions after #494:
built-node-skill-bootstraprequests/agentand/commandwithnode:httpinstead of Node globalfetch, while preserving the same built artifact bootstrap and endpoint assertions.built-node-webfetchstill exercises the built WebFetch tool and parser path, but closes the test-local HTTP server connections explicitly before child shutdown.built-node-webfetchinjects a test-localnode:http/node:httpsimplementation for Effect'sFetchHttpClient.Fetchreference, so the test does not trip the Windows Node 24 global fetch teardown abort after the WebFetch assertions have already succeeded.Why
Follow-up to #494 and #492.
After #494 merged,
devstill failed the advisory Windows run:windows-advisory, run25496202877unit-windows-opencode-server-tools, job74816526956test/server/built-node-skill-bootstrap.test.tsprocess.exit(exitCode)Assertion failed: !(handle->flags & UV_HANDLE_CLOSING), file src\\win\\async.c, line 76The first PR version fixed that bootstrap harness. A manual Windows advisory run on PR head
580534bthen proved the bootstrap test passed, but exposed the same teardown class inbuilt-node-webfetch:windows-advisory, run25498482049unit-windows-opencode-server-tools, job74824553484built-node-skill-bootstrap: passedbuilt-node-webfetch: produced the expected JSON output, then failed atprocess.exit(0)with the samesrc\\win\\async.cassertionClosing the test-local HTTP server sockets was necessary but not sufficient. A second manual Windows advisory run on
bdac89astill failedbuilt-node-webfetchwith correct stdout and the same Node 24 global fetch teardown assertion. The final fix keeps the built WebFetch tool coverage but removes Node globalfetchfrom this harness.I also tested replacing
process.exit()withprocess.exitCode. It avoids the explicit exit, but locally leaves the built Node child alive until the test times out, so it is not a usable fix for either harness.Related Issue
Fixes #492
Human Review Status
Pending. A human should make the final merge decision after reviewing the final diff and verification evidence.
Review Focus
Please focus on the harness boundary. This PR intentionally avoids changing product server shutdown behavior again. It keeps the built artifact coverage intact and only makes the test child processes stop tripping the Windows Node 24 exit bug after their assertions have already succeeded.
Risk Notes
Low product risk because this changes only tests. The main risk is test fidelity:
built-node-skill-bootstrapno longer uses Node globalfetch; that is intentional because this test is about built server bootstrap and endpoint availability, not WebFetch.built-node-webfetchstill uses the built WebFetch tool and parser path; the only transport substitution is the test-localFetchHttpClient.Fetchimplementation to avoid the Windows Node 24 global fetch teardown bug.built-node-webfetchstill verifies the hostile HTML, raw<, whitespace, and extracted text assertions against the built artifact.How To Verify
Screenshots or Recordings
Not applicable. No visible UI changes.
Checklist
dev, and my PR title and commit messages use Conventional Commits in English