mirror of
https://github.com/stablyai/orca.git
synced 2026-10-30 08:37:49 +00:00
test(native-chat): name the stalled step in the live-history watcher test (#34663)
* test(native-chat): name the stalled step in the live-history watcher test A CI run hit the 30 s test timeout with no step named. Each wait now has its own 8 s deadline that reports the stalled step with what the watcher had delivered, and the file sets IS_REACT_ACT_ENVIRONMENT so act() flushes. * test(native-chat): share one 27 s budget across the live-history waits Per-step 8 s deadlines were stricter than the old 30 s test timeout; a shared deadline keeps the total unchanged and only improves the failure message. * test(native-chat): use an AbortSignal budget instead of the wall clock Date.now trips the flaky-test wall-clock rule; AbortSignal.timeout gives the same shared 27 s budget without reading the clock.
This commit is contained in:
@@ -67,6 +67,8 @@ describe('useNativeChatLiveSession — file watcher pagination composition', ()
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
// Without it React warns on every act() and may not flush updates inside it.
|
||||
vi.stubGlobal('IS_REACT_ACT_ENVIRONMENT', true)
|
||||
useAppStore.setState({ agentStatusByPaneKey: {} })
|
||||
})
|
||||
|
||||
@@ -76,10 +78,13 @@ describe('useNativeChatLiveSession — file watcher pagination composition', ()
|
||||
}
|
||||
latest = null
|
||||
vi.clearAllMocks()
|
||||
vi.unstubAllGlobals()
|
||||
resetTransport()
|
||||
})
|
||||
|
||||
it('keeps the original watcher append after a real 300-to-500 loadEarlier', async () => {
|
||||
// One budget shared by every step, just under the 30 s test timeout, so only the message changes.
|
||||
const budget = AbortSignal.timeout(27_000)
|
||||
const { mkdtemp, writeFile, appendFile, rm } = await import('node:fs/promises')
|
||||
const { tmpdir } = await import('node:os')
|
||||
const { join } = await import('node:path')
|
||||
@@ -120,6 +125,28 @@ describe('useNativeChatLiveSession — file watcher pagination composition', ()
|
||||
sessionId: SESSION,
|
||||
runtimeEnvironmentId: 'env-history'
|
||||
})
|
||||
// A CI run hit the 30 s test timeout with no step named; each wait names its own stall.
|
||||
const delivered: string[] = []
|
||||
const within = <T>(step: string, promise: Promise<T>): Promise<T> =>
|
||||
Promise.race([
|
||||
promise,
|
||||
new Promise<never>((_, reject) => {
|
||||
const stalled = (): void => {
|
||||
const rows = latest ? ids().length : null
|
||||
const limits = transport.readSession.mock.calls.map((call) => call[2])
|
||||
reject(
|
||||
new Error(
|
||||
`Stalled at ${step}: ${JSON.stringify({ delivered, rows, readSessionLimits: limits })}`
|
||||
)
|
||||
)
|
||||
}
|
||||
if (budget.aborted) {
|
||||
stalled()
|
||||
} else {
|
||||
budget.addEventListener('abort', stalled, { once: true })
|
||||
}
|
||||
})
|
||||
])
|
||||
const initialSnapshotCommitted = Promise.withResolvers<void>()
|
||||
const appendCommitted = Promise.withResolvers<void>()
|
||||
const subscription = await subscribeNativeChatTranscript({
|
||||
@@ -131,28 +158,34 @@ describe('useNativeChatLiveSession — file watcher pagination composition', ()
|
||||
debounceMs: 5,
|
||||
reconciliationIntervalMs: 20,
|
||||
onInitialSnapshot: (messages, hasMore) => {
|
||||
delivered.push(`snapshot:${messages.length}`)
|
||||
void act(async () => {
|
||||
transport.emit({ type: 'snapshot', messages, hasMore })
|
||||
}).then(initialSnapshotCommitted.resolve, initialSnapshotCommitted.reject)
|
||||
},
|
||||
onAppend: (messages) => {
|
||||
delivered.push(`append:${messages.length}`)
|
||||
void act(async () => {
|
||||
transport.emit({ type: 'appended', messages })
|
||||
}).then(appendCommitted.resolve, appendCommitted.reject)
|
||||
},
|
||||
onReplace: (messages, hasMore) =>
|
||||
act(() => transport.emit({ type: 'replacement', messages, hasMore }))
|
||||
onReplace: (messages, hasMore) => {
|
||||
delivered.push(`replace:${messages.length}`)
|
||||
return act(() => transport.emit({ type: 'replacement', messages, hasMore }))
|
||||
}
|
||||
})
|
||||
try {
|
||||
await initialSnapshotCommitted.promise
|
||||
await within('initial snapshot', initialSnapshotCommitted.promise)
|
||||
expect(ids()).toEqual(Array.from({ length: 300 }, (_, i) => String(i + 201).padStart(4, '0')))
|
||||
await act(async () => {
|
||||
await expect(session().loadEarlier()).resolves.toBe('applied')
|
||||
await expect(within('loadEarlier 300 to 500', session().loadEarlier())).resolves.toBe(
|
||||
'applied'
|
||||
)
|
||||
})
|
||||
expect(transport.readSession).toHaveBeenLastCalledWith(AGENT, SESSION, 500, undefined)
|
||||
expect(ids()).toEqual(Array.from({ length: 500 }, (_, i) => String(i + 1).padStart(4, '0')))
|
||||
await appendFile(filePath, line(501))
|
||||
await appendCommitted.promise
|
||||
await within('watcher append of line 501', appendCommitted.promise)
|
||||
expect(ids()).toEqual(Array.from({ length: 501 }, (_, i) => String(i + 1).padStart(4, '0')))
|
||||
expect(ids().at(-1)).toBe('0501')
|
||||
expect(transport.subscribe).toHaveBeenCalledOnce()
|
||||
|
||||
Reference in New Issue
Block a user