test: harden codex manager cli isolation - #321
Conversation
|
Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits. |
📝 WalkthroughWalkthroughtest setup and mocks updated: process.stdin state capture/restoration added, Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Suggested labels
notes for review
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
✨ Simplify code
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.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@test/codex-manager-cli.test.ts`:
- Around line 301-310: The test suite currently forces stdin to be "open" via
setOpenStdinState but lacks a focused regression that exercises the
short-circuit guard in lib/codex-manager.ts (the input.readableEnded ||
input.destroyed check); add a deterministic vitest regression test in
test/codex-manager-cli.test.ts that explicitly sets either
process.stdin.readableEnded = true or process.stdin.destroyed = true (after
calling setOpenStdinState or directly) and then runs the manual callback/login
flow used around the existing test call at lines ~769-771, asserting that manual
callback handling does not persist login state (i.e., the login state remains
unauthenticated or unchanged); keep the test deterministic (no real secrets, no
network flakiness) and assert the expected state to guard against future
concurrency/worker-reuse regressions.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 7b9fb00e-1209-43dd-a1c5-2f97d653b1c1
📒 Files selected for processing (1)
test/codex-manager-cli.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Greptile Review
🧰 Additional context used
📓 Path-based instructions (1)
test/**
⚙️ CodeRabbit configuration file
tests must stay deterministic and use vitest. demand regression cases that reproduce concurrency bugs, token refresh races, and windows filesystem behavior. reject changes that mock real secrets or skip assertions.
Files:
test/codex-manager-cli.test.ts
🔇 Additional comments (2)
test/codex-manager-cli.test.ts (2)
250-293: nice descriptor restore hardening for test isolationthe
stdin/stdoutdescriptor capture+restore flow is solid and deterministic intest/codex-manager-cli.test.ts:250-293. this reduces cross-test leakage risk in pooled workers and stabilizes windows-adjacent tty behavior.
593-799: good reset discipline in async beforeeachthe async
beforeEachreset/re-import flow intest/codex-manager-cli.test.ts:593-799is a strong isolation improvement. reapplying default stubs forauth/browser/serveraftervi.resetModules()removes one-shot mock bleed and makes concurrent/racy auth tests deterministic.as per coding guidelines
test/**: tests must stay deterministic and use vitest. demand regression cases that reproduce concurrency bugs, token refresh races, and windows filesystem behavior. reject changes that mock real secrets or skip assertions.
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
test/codex-manager-cli.test.ts (1)
593-626:⚠️ Potential issue | 🔴 Criticaladd
getPluginConfigExplainReportMock.mockReset()to the beforeEach hook.the mock is defined at
test/codex-manager-cli.test.ts:23as a top-levelvi.fn().vi.clearAllMocks()clears call history but leaves queued one-shots alive. the queued calls attest/codex-manager-cli.test.ts:888,925, and955will leak to the next test if the current test exits early. all other mocks in this block get explicit.mockReset()calls; this one is missing.suggested fix
loadPluginConfigMock.mockReset(); savePluginConfigMock.mockReset(); + getPluginConfigExplainReportMock.mockReset(); selectMock.mockReset();🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@test/codex-manager-cli.test.ts` around lines 593 - 626, Add a .mockReset() call for getPluginConfigExplainReportMock inside the beforeEach hook so its queued one-shot behaviors are cleared between tests; locate the beforeEach block that already calls mockReset() on many mocks (e.g., loadAccountsMock.mockReset(), confirmMock.mockReset()) and add getPluginConfigExplainReportMock.mockReset() alongside them to prevent leaked queued calls used later at the tests referencing that mock.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@test/codex-manager-cli.test.ts`:
- Around line 775-788: The test currently replaces parseAuthorizationInput with
a narrow regex that only handles query-style "code=..." inputs; instead either
stop mocking parseAuthorizationInput so the real implementation in
lib/auth/auth.ts (parseAuthorizationInput) is used, or extend the mocked
implementation to match the real parser’s accepted shapes (full URLs, `#code`=
fragments, code#state and bare codes); make sure the manual callback test cases
that exercise createAuthorizationFlow and exchangeAuthorizationCode also include
pasted-hash formats so regressions are caught, and add deterministic vitest
regression tests for pasted-hash inputs and relevant token-refresh/concurrency
edge cases rather than mocking real secrets.
---
Outside diff comments:
In `@test/codex-manager-cli.test.ts`:
- Around line 593-626: Add a .mockReset() call for
getPluginConfigExplainReportMock inside the beforeEach hook so its queued
one-shot behaviors are cleared between tests; locate the beforeEach block that
already calls mockReset() on many mocks (e.g., loadAccountsMock.mockReset(),
confirmMock.mockReset()) and add getPluginConfigExplainReportMock.mockReset()
alongside them to prevent leaked queued calls used later at the tests
referencing that mock.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: f2220300-77fe-40d2-8476-601074cf9ba8
📒 Files selected for processing (2)
test/codex-manager-cli.test.tstest/wait-utils.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Greptile Review
🧰 Additional context used
📓 Path-based instructions (1)
test/**
⚙️ CodeRabbit configuration file
tests must stay deterministic and use vitest. demand regression cases that reproduce concurrency bugs, token refresh races, and windows filesystem behavior. reject changes that mock real secrets or skip assertions.
Files:
test/wait-utils.test.tstest/codex-manager-cli.test.ts
| const authModule = await import("../lib/auth/auth.js"); | ||
| vi.mocked(authModule.createAuthorizationFlow).mockReset(); | ||
| vi.mocked(authModule.exchangeAuthorizationCode).mockReset(); | ||
| vi.mocked(authModule.parseAuthorizationInput).mockReset(); | ||
| vi.mocked(authModule.parseAuthorizationInput).mockImplementation( | ||
| (input: string) => { | ||
| const codeMatch = input.match(/code=([^&]+)/); | ||
| const stateMatch = input.match(/state=([^&#]+)/); | ||
| return { | ||
| code: codeMatch?.[1], | ||
| state: stateMatch?.[1], | ||
| }; | ||
| }, | ||
| ); |
There was a problem hiding this comment.
keep parseAuthorizationInput aligned with production.
test/codex-manager-cli.test.ts:779-788 still installs a query-only regex, but lib/auth/auth.ts:69-105 accepts full urls, #code=... fragments, code#state, and bare codes. the manual callback cases at test/codex-manager-cli.test.ts:4446-4448, 5236-5238, and 5339-5341 only cover that single shape, so a supported pasted-callback format can regress without this suite noticing. use the real parser here, or add one pasted-hash regression alongside these manual-login tests.
As per coding guidelines, test/**: tests must stay deterministic and use vitest. demand regression cases that reproduce concurrency bugs, token refresh races, and windows filesystem behavior. reject changes that mock real secrets or skip assertions.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@test/codex-manager-cli.test.ts` around lines 775 - 788, The test currently
replaces parseAuthorizationInput with a narrow regex that only handles
query-style "code=..." inputs; instead either stop mocking
parseAuthorizationInput so the real implementation in lib/auth/auth.ts
(parseAuthorizationInput) is used, or extend the mocked implementation to match
the real parser’s accepted shapes (full URLs, `#code`= fragments, code#state and
bare codes); make sure the manual callback test cases that exercise
createAuthorizationFlow and exchangeAuthorizationCode also include pasted-hash
formats so regressions are caught, and add deterministic vitest regression tests
for pasted-hash inputs and relevant token-refresh/concurrency edge cases rather
than mocking real secrets.
test: harden codex manager cli isolation
What Changed
test/codex-manager-cli.test.tsisolation by resetting shared mocks and reapplying auth/browser/server stubs aftervi.resetModules()test/wait-utils.test.tsfake-timer sleep mocking so virtual time advances instead of spinning into worker OOMRisk Level
Rollback Plan
#321Validation
node_modules\\.bin\\vitest.cmd run --pool=threads --maxWorkers=1 test/codex-manager-auth-commands.test.ts test/codex-manager-cli.test.tsnode_modules\\.bin\\vitest.cmd run --pool=threads --maxWorkers=1 test/wait-utils.test.tsnode_modules\\.bin\\vitest.cmd run --pool=threads --maxWorkers=1 test/codex-manager-cli.test.tsnpm run lintnpm run typechecknpm run build221/221files and3165/3165testsnpm test -- --pool=threads --maxWorkers=1still ends in a Vitest worker OOM near the end, but no functional test failures remained before the runner diednote: greptile review for oc-chatgpt-multi-auth. cite files like
lib/foo.ts:123. confirm regression tests + windows concurrency/token redaction coverage.Greptile Summary
this pr hardens test isolation in the codex manager cli suite and fixes an oom in the wait-utils test. all three problems it fixes are real and the solutions are sound.
codex-manager-cli.test.ts): six mocks (promptQuestionMock,planOcChatgptSyncMock,applyOcChatgptSyncMock,runNamedBackupExportMock,exportNamedBackupMock,detectOcChatgptMultiAuthTargetMock,normalizeAccountStorageMock) were not reset between tests; queuedmockResolvedValueOncevalues could bleed across cases. all are now reset inbeforeEach.codex-manager-cli.test.ts):readableEndedanddestroyedare now captured at module load, restored inafterEach, and pinned tofalseinbeforeEachviasetOpenStdinState(). this prevents a previous worker's closed-stdin state from short-circuiting manual-callback tests.wait-utils.test.ts): the oldsleepmock returned immediately without advancing fake time, sosleepWithCountdown'swhile (Date.now() < endTime)guard never moved forward. the fix injectsawait vi.advanceTimersByTimeAsync(ms)inside the mock, which advances fakeDate.now()and lets the loop terminate correctly.readableEnded: trueearly-exit path throughlib/codex-manager.ts:1252; the siblingdestroyed: truebranch (same||condition) has no coverage yet.Confidence Score: 5/5
destroyed: truebranch, which is a follow-up p2 — not a blockerImportant Files Changed
destroyed: truebranchvi.advanceTimersByTimeAsync(ms), correctly advancing fakeDate.now()inside sleepWithCountdown's while-loop guard, eliminating the infinite-spin OOMFlowchart
%%{init: {'theme': 'neutral'}}%% flowchart TD A[beforeEach] --> B[vi.resetModules + all mockReset] B --> C[restoreTTYDescriptors] C --> D[setOpenStdinState\nreadableEnded=false, destroyed=false] D --> E[import auth/browser/server modules\nreset + default implementations] E --> F[test body runs] F --> G{stdin state?} G -- readableEnded=true --> H[skip promptQuestion\nskip browser open\nskip server start\nexit 0] G -- open --> I[normal manual OAuth flow] F --> J[afterEach: restoreTTYDescriptors]Prompt To Fix All With AI
Reviews (2): Last reviewed commit: "test: cover closed stdin manual callback..." | Re-trigger Greptile