Repository navigation
fix(test): restore abort-and-lifecycle stdin-close test to pre-#3723 version #3777
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
88b3e1b
b4e4dd6
432bbf7
bf82093
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -314,23 +314,38 @@ describe('AbortController and Process Lifecycle (E2E)', () => { | |
| }); | ||
|
|
||
| it('should handle control responses when stdin closes before replies', async () => { | ||
| const testFilePath = await helper.getPath('test.txt'); | ||
| await helper.createFile('test.txt', 'original content'); | ||
|
|
||
| let canUseToolCalled = false; | ||
| let canUseToolCalledResolve: () => void = () => {}; | ||
| const canUseToolCalledPromise = new Promise<void>((resolve) => { | ||
| const canUseToolCalledPromise = new Promise<void>((resolve, reject) => { | ||
| canUseToolCalledResolve = resolve; | ||
| setTimeout(() => { | ||
| reject(new Error('canUseTool callback not called')); | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Critical] The targeted E2E test failed in verification because — gpt-5.5 via Qwen Code /review |
||
| }, 15000); | ||
| }); | ||
|
|
||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Suggestion] Consider matching the 15 s budgets to 30 s, or deferring promise creation until just before the relevant phase starts. — glm-5.1 via Qwen Code /review |
||
| let inputStreamDoneResolve: () => void = () => {}; | ||
| const inputStreamDonePromise = new Promise<void>((resolve, reject) => { | ||
| inputStreamDoneResolve = resolve; | ||
| setTimeout(() => { | ||
| reject(new Error('inputStreamDonePromise timeout')); | ||
| }, 15000); | ||
| }); | ||
|
|
||
| let firstResultResolve: () => void = () => {}; | ||
| const firstResultPromise = new Promise<void>((resolve) => { | ||
| const firstResultPromise = new Promise<void>((resolve, reject) => { | ||
| firstResultResolve = resolve; | ||
| setTimeout(() => { | ||
| reject(new Error('firstResult not received within 30s')); | ||
| }, 30000); | ||
| }); | ||
|
|
||
| let secondResultResolve: () => void = () => {}; | ||
| const secondResultPromise = new Promise<void>((resolve, reject) => { | ||
| secondResultResolve = resolve; | ||
| setTimeout(() => { | ||
| reject(new Error('secondResult not received within 30s')); | ||
| }, 30000); | ||
| }); | ||
|
|
||
| async function* createPrompt(): AsyncIterable<SDKUserMessage> { | ||
|
|
@@ -353,10 +368,12 @@ describe('AbortController and Process Lifecycle (E2E)', () => { | |
| session_id: sessionId, | ||
| message: { | ||
| role: 'user', | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Suggestion] The prompt now uses relative — gpt-5.5 via Qwen Code /review |
||
| content: `Use the write_file tool to write "updated" to the file at ${testFilePath}. Then reply with "done".`, | ||
| content: | ||
| 'Write "updated" to test.txt. Stop if any exception occurs.', | ||
| }, | ||
| parent_tool_use_id: null, | ||
| }; | ||
| await inputStreamDonePromise; | ||
| } | ||
|
|
||
| const q = query({ | ||
|
|
@@ -367,8 +384,10 @@ describe('AbortController and Process Lifecycle (E2E)', () => { | |
| permissionMode: 'default', | ||
| coreTools: ['read_file', 'write_file'], | ||
| canUseTool: async (toolName, input) => { | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Critical] This callback resolves the synchronization promises for any tool call, but — gpt-5.5 via Qwen Code /review |
||
| canUseToolCalled = true; | ||
| inputStreamDoneResolve(); | ||
| await new Promise((resolve) => setTimeout(resolve, 1000)); | ||
| canUseToolCalledResolve(); | ||
|
|
||
| return { | ||
| behavior: 'allow', | ||
| updatedInput: input, | ||
|
|
@@ -381,8 +400,10 @@ describe('AbortController and Process Lifecycle (E2E)', () => { | |
| try { | ||
| const loop = async () => { | ||
| let resultCount = 0; | ||
| for await (const message of q) { | ||
| if (isSDKResultMessage(message)) { | ||
| for await (const _message of q) { | ||
| console.log(JSON.stringify(_message, null, 2)); | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Suggestion] This unconditional Please remove the unconditional log, or gate compact diagnostics behind an explicit debug flag. — gpt-5.5 via Qwen Code /review |
||
| // Consume messages until completion. | ||
| if (isSDKResultMessage(_message)) { | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Critical] The loop treats any second Please capture the second result and assert the intended outcome explicitly, for example — gpt-5.5 via Qwen Code /review |
||
| resultCount += 1; | ||
| if (resultCount === 1) { | ||
| firstResultResolve(); | ||
|
|
@@ -395,18 +416,19 @@ describe('AbortController and Process Lifecycle (E2E)', () => { | |
| } | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Critical] Please do not treat normal — gpt-5.5 via Qwen Code /review |
||
| }; | ||
|
|
||
| loop(); | ||
| const loopPromise = loop(); | ||
|
|
||
| await firstResultPromise; | ||
| await canUseToolCalledPromise; | ||
| await secondResultPromise; | ||
|
|
||
| // Signal stdin is done so CLI stops waiting | ||
| q.endInput(); | ||
| await Promise.race([ | ||
| (async () => { | ||
| await firstResultPromise; | ||
| await canUseToolCalledPromise; | ||
| await secondResultPromise; | ||
| })(), | ||
| loopPromise, | ||
| ]); | ||
|
|
||
| const content = await helper.readFile('test.txt'); | ||
| expect(canUseToolCalled).toBe(true); | ||
| expect(content).toBe('updated'); | ||
| expect(content).toBe('original content'); | ||
| } finally { | ||
| await q.close(); | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[Suggestion] These new timeout handles are not cleared after the promises resolve. On successful runs the real timers can remain live until they fire, adding latency or open-handle noise to the integration test worker. Please store each timeout handle and clear it in the corresponding resolve path, or use a helper that clears on settle.
— gpt-5.5 via Qwen Code /review