Skip to content

fix(tests): capture the real resolver before mocking adapter-resolve - #5482

Closed
FredAmartey wants to merge 1 commit into
lidge-jun:devfrom
FredAmartey:fix/abort-race-resolver-capture
Closed

FredAmartey wants to merge 1 commit into
lidge-jun:devfrom
FredAmartey:fix/abort-race-resolver-capture

Conversation

@FredAmartey

@FredAmartey FredAmartey commented Sep 22, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • tests/adapters/abort-race.test.ts, tests/claude-integration/claude-code-thought-signature-scope.test.ts and tests/routing/routing-policy-surface-parity.test.ts override resolveAdapter with mock.module and fall back to the real function by reading actualResolver.resolveAdapter when the call is made. Bun rewrites that live binding in place, so as soon as another file in the same process installs its own override, the fallback resolves to the newest wrapper. The two wrappers then call each other until the stack overflows.
  • abort-race.test.ts sits in shard 1 batch 1 next to anthropic-quota-dispatch.test.ts, which also overrides the module. Run those two files in one process without --isolate and 11 of the quota-dispatch cases fail with RangeError: Maximum call stack size exceeded, on macOS and Linux alike. Each file passes alone, because abort-race sets its factory in every case and never reaches the fallback.
  • CI does not see this because every lane, and bun run test, passes --isolate, so each file gets its own module registry. The plain bun test <files> a contributor types by hand does not, which is one of the ways the failure count in Batched test runner cannot run on macOS, and one-process runs give batch-size-dependent failure counts #5439 comes to depend on how the files are sliced.
  • Each of the three files now captures actualResolver.resolveAdapter once, before the override, which is what the other seven resolver wrappers in the tree already do. No runtime code changes.

Verification

Head 0aed30205 on dev 39143fddf, Bun 1.4.0 (the bun dependency in package.json). The pair, the six-file run, typecheck, structure, privacy, layout and git diff --check were rerun on this head after the rebase; the shard runs below were made on the previous base e4ceeb38d, and the change carries no conflicts across:

  • Driven red first: on untouched dev, bun test tests/adapters/abort-race.test.ts tests/adapters/anthropic/anthropic-quota-dispatch.test.ts gives 5 pass, 11 fail, all Maximum call stack size exceeded. Same result in an oven/bun:1.4.0 Linux container. With --isolate the same pair passes, which is why dev is green.
  • With this change the pair gives 16 pass, 0 fail, and the three edited files together with anthropic-quota-dispatch, terminal-continuation-owner-rotation and anthropic-sidecar-account-failover give 30 pass, 0 fail, all without --isolate.
  • bash scripts/ci/run-bun-test-batches.sh 1/4 on macOS: batches 1 to 6 pass; batch 7 stops on remote-workspace-command-runner.test.ts, which fails alone on this machine too (bubblewrap must be a private executable file) and is unrelated. Batches 8 to 32 rerun by hand with the same slicing: 20 batches clean; the failures in batches 11, 14, 21, 29 and 31 (codex-shim, winsw, service-tier-capability, vision-reasoning-contract) reproduce on untouched dev.
  • bun run typecheck, bun run structure:check, bun run privacy:scan, bun test tests/test-layout.test.ts tests/test-layout-tooling.test.ts (18 pass) and git diff --check: passed.

Checklist

  • Scope stays focused and avoids unrelated cleanup.
  • Docs or release notes were updated when needed.
  • Security-sensitive changes were reviewed for secrets, auth, and unsafe defaults.

Review readiness checklist

This PR stays in draft until every box below is ticked. Tick all four boxes once the requirements are met:

  • All CI tests are green on my local testing.

  • I pushed my PR to the latest dev commit.

  • I resolved all correct Codex and CodeRabbit findings.

  • My PR is ready for review.

Summary by CodeRabbit

  • Tests
    • Improved test isolation and reliability for adapter resolution scenarios.
    • Prevented interactions between independently mocked test cases from causing incorrect fallback behavior or recursive failures.
    • Added safeguards for integration and routing tests running together in the same process.

@coderabbitai

coderabbitai Bot commented Sep 22, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository: lidge-jun/opencodex/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Advanced

Run ID: e2c0d66c-7d60-4179-af44-d87dddb55986

📥 Commits

Reviewing files that changed from the base of the PR and between 39143fd and 0aed302.

📒 Files selected for processing (3)
  • tests/adapters/abort-race.test.ts
  • tests/claude-integration/claude-code-thought-signature-scope.test.ts
  • tests/routing/routing-policy-surface-parity.test.ts

Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review.


📝 Walkthrough

Walkthrough

The test mocks capture the original resolveAdapter function before installing module overrides. Fallback delegation now uses that captured function instead of the live module binding.

Changes

Adapter resolver mock isolation

Layer / File(s) Summary
Capture the original resolver before mocking
tests/adapters/abort-race.test.ts, tests/claude-integration/claude-code-thought-signature-scope.test.ts, tests/routing/routing-policy-surface-parity.test.ts
The mocks store actualResolver.resolveAdapter before mock.module installs an override. Fallback paths call actualResolveAdapter, preventing delegation through another active override.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Merge Risk: ⚪ Minimal · up to 0aed3

This test-only change captures the original resolver before module overrides, preventing recursive mocks without changing production behavior. No actionable merge-blocking risk remains.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: test overrides now capture the real resolver before mocking adapter-resolve. It matches the changes in all three affected test files.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 3…
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR

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.

❤️ Share

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

Three test files wrap `resolveAdapter` through `mock.module` and fall back to
the real function by reading `actualResolver.resolveAdapter` at call time.
Bun rewrites that namespace binding in place, so once a second file in the
same process installs its own override, the fallback resolves to the newest
wrapper and the two call each other until the stack overflows.

CI never meets this because every lane passes `--isolate`, which gives each
file its own module registry. A plain `bun test <files>` does not, and
`tests/adapters/abort-race.test.ts` shares shard 1 batch 1 with
`anthropic-quota-dispatch.test.ts`, so that invocation fails 11 of its cases
with `RangeError: Maximum call stack size exceeded`. Capture the real
function once, before the override, the way the other resolver wrappers
already do.
@FredAmartey
FredAmartey force-pushed the fix/abort-race-resolver-capture branch from 4cc38f6 to 0aed302 Compare September 22, 2026 01:06
@github-actions

Copy link
Copy Markdown
Contributor

✅ Deterministic PR hygiene checks passed.

@github-actions github-actions Bot added the bug Something isn't working label Sep 22, 2026
@github-actions

github-actions Bot commented Sep 22, 2026 •

Copy link
Copy Markdown
Contributor

✅ READY

  • all PR quality gates passed; the review readiness checklist is complete.

Review readiness checklist

  • ✅ All CI tests are green on my local testing.
  • ✅ I pushed my PR to the latest dev commit.
  • ✅ I resolved all correct Codex and CodeRabbit findings.
  • ✅ My PR is ready for review.

✅ 4/4 boxes ticked.

This pull request is already Ready for Review.
The review-ready label marks this PR as ready; review automation runs independently.
Maintainers: @lidge-jun @Ingwannu

@github-actions
github-actions Bot marked this pull request as ready for review September 22, 2026 01:13
@lidge-jun

Copy link
Copy Markdown
Owner

리뷰 · 우선순위 71 / 80

이 PR은 실제 서버 코드는 건드리지 않고, Bun 테스트 세 개만 고칩니다. 세 파일 모두 adapter-resolve 모듈을 mock.module로 감싼 뒤, 가짜 어댑터가 없을 때 진짜 resolveAdapter를 부르도록 되어 있었는데, 그때마다 actualResolver.resolveAdapter를 다시 읽고 있었습니다. Bun은 같은 프로세스 안에서 그 이름을 한 번에 바꿔 버리기 때문에, 다른 테스트 파일도 같은 모듈을 mock하면 “진짜 함수” 자리에 방금 만든 mock이 들어가고, 두 mock이 서로를 부르다가 스택이 터집니다. CI는 --isolate로 파일마다 모듈을 나눠서 이걸 못 봤고, 로컬에서 bun test로 여러 파일을 한꺼번에 돌리면 abort-race와 anthropic-quota-dispatch 같이 shard 1에 붙어 있는 조합에서 깨졌습니다. 수정은 mock 하기 전에 actualResolveAdapter를 한 번만 잡아 두고, fallback에 그걸 쓰는 방식이고, 이미 그렇게 쓰고 있던 다른 resolver mock 테스트들과 같은 패턴입니다.

라인 - PR 본문의 “ready for review” 체크리스트가 아직 비어 있고 상태가 draft라, 머지 타이밍은 작성자가 준비 완료로 표시할 때까지 메인테이너 쪽에서 한 번 더 보면 좋겠습니다.
라인 - 같은 설명 주석이 세 파일에 거의 똑같이 들어가서, 나중에 Bun mock 동작을 바꿀 때 세 군데를 같이 고쳐야 할 수 있습니다. (지금 PR 범위 밖이면 참고만.)

메인테이너의 판단이 필요한 지점

  • draft·체크리스트를 풀고 리뷰 요청으로 올릴지, 아니면 테스트-only 수정이라 draft인 채로도 머지할지.
  • 같은 mock 패턴을 공용 헬퍼로 빼는 리팩터를 지금 할지, 이번에는 세 파일만 맞출지.

너의 추천

  • 원인 설명과 수정 방향이 맞고, 런타임 영향 없이 로컬·비-isolate 실행과 shard 이웃 파일 간 간섭만 줄이므로 머지해도 됩니다. 작성자가 draft를 풀고 체크리스트를 채운 뒤 green이면 승인 쪽이 좋습니다. 주석 중복은 optional follow-up으로 두어도 됩니다.

이 댓글은 grok-bot이 작성했습니다

lidge-jun added a commit that referenced this pull request Sep 23, 2026
…EADME inventory counts (#5672)

* docs(devlog): triage the lane A tests-hygiene bundle

* fix(tests): capture the real resolver before mocking adapter-resolve

Carries #5482.

Co-authored-by: Fred Amartey <43480311+FredAmartey@users.noreply.github.com>

* fix(tests): dispose test translator budgets in every file that creates them

Carries #5607.

Co-authored-by: Fred Amartey <43480311+FredAmartey@users.noreply.github.com>

* fix(tests): restore the sandbox home after every test file

Carries #5570 (both PR commits, including the CodeRabbit ordering fix).

Co-authored-by: Fred Amartey <43480311+FredAmartey@users.noreply.github.com>

* fix(tests): put the real modules back after the image tests mock them

Carries #5605. Folded review fix: each file restores only the module
snapshots it actually captured, so a beforeAll that failed partway
cannot install an empty module, and z-handler-activation restores its
overrides in a finally block so a failed directory removal cannot leave
them installed for later files in the process.

Co-authored-by: Fred Amartey <43480311+FredAmartey@users.noreply.github.com>

* fix(desktop): never restart the real desktop app from the test runner

Carries #5630. restartCodexDesktopApp returns the skipped reason
test_environment when the test preload armed OCX_TEST_HOME_GUARD and no
execFile was injected, and the CLI reports that skip. Folded review fix:
structure/runtime.md documents the guarded outcome next to the CLI
restart scope it owns.

Co-authored-by: terin <100397903+sh940701@users.noreply.github.com>

* docs(readme): derive the memory inventory counts instead of restating them

Carries #5340, rebuilt on dev after #5615 and #5638 so their README and
locale prose stays intact. Folded review fixes: dev now registers 14
retained stores, and native_control_replay is pinned (evictOldest
returns 0), so every page says 14 and names the one store the budget
never evicts; the guard's header drops the numbers that had gone stale;
readme/i18n-manifest.json carries the hash of the final README.md.

Co-authored-by: codingbo <9621077+codingbooo@users.noreply.github.com>

* docs(devlog): record the lane A delivery

---------

Co-authored-by: Fred Amartey <43480311+FredAmartey@users.noreply.github.com>
Co-authored-by: terin <100397903+sh940701@users.noreply.github.com>
Co-authored-by: codingbo <9621077+codingbooo@users.noreply.github.com>
@lidge-jun

Copy link
Copy Markdown
Owner

Carried onto dev in bundle PR #5672 (squash-merged as 7dd1db2), rebuilt on current dev as commit 0913538 on the lane branch with a Co-authored-by trailer for you, so the credit stays on the merged commit. Closing this one as superseded. Thank you for the fix.

@lidge-jun lidge-jun closed this Sep 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working review-ready

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants