Skip to content

Commit ce076d2

Browse files
committed
test(api): close changed-line coverage gaps in bedrock
1 parent 65e2a33 commit ce076d2

1 file changed

Lines changed: 64 additions & 0 deletions

File tree

‎src/api/providers/__tests__/bedrock.spec.ts‎

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2310,6 +2310,70 @@ describe("AwsBedrockHandler", () => {
23102310
clearTimeoutSpy.mockRestore()
23112311
clearTimeout(timeoutHandle)
23122312
})
2313+
2314+
it("createMessage should abort the in-flight request when the 10 minute request timeout fires", async () => {
2315+
const handler = new AwsBedrockHandler({
2316+
apiModelId: "anthropic.claude-3-5-sonnet-20241022-v2:0",
2317+
awsAccessKey: "test-access-key",
2318+
awsSecretKey: "test-secret-key",
2319+
awsRegion: "us-east-1",
2320+
})
2321+
2322+
let internalSignal: AbortSignal | undefined
2323+
const mockSend = vi
2324+
.fn()
2325+
.mockImplementation((_command: unknown, options?: { abortSignal?: AbortSignal }) => {
2326+
internalSignal = options?.abortSignal
2327+
return new Promise<unknown>((_resolve, reject) => {
2328+
internalSignal?.addEventListener(
2329+
"abort",
2330+
() => {
2331+
const abortError = new Error("The operation was aborted")
2332+
abortError.name = "AbortError"
2333+
reject(abortError)
2334+
},
2335+
{ once: true },
2336+
)
2337+
})
2338+
})
2339+
handler["client"].send = mockSend
2340+
2341+
// Capture the 10-minute request timer scheduled by createMessage
2342+
const setTimeoutSpy = vi.spyOn(globalThis, "setTimeout")
2343+
2344+
const generator = handler.createMessage(
2345+
"You are a helpful assistant",
2346+
[{ role: "user", content: "Hello" }],
2347+
makeCreateMessageMetadata(),
2348+
)
2349+
const consumed = (async () => {
2350+
for await (const _chunk of generator) {
2351+
// ignore chunks
2352+
}
2353+
})()
2354+
2355+
// Wait until the request is in flight and the 10-minute timer is scheduled
2356+
let timeoutHandle: NodeJS.Timeout | undefined
2357+
let timeoutCallback: (() => void) | undefined
2358+
await vi.waitFor(() => {
2359+
const timerIndex = setTimeoutSpy.mock.calls.findIndex(([, delay]) => delay === 10 * 60 * 1000)
2360+
expect(timerIndex).toBeGreaterThanOrEqual(0)
2361+
expect(internalSignal).toBeDefined()
2362+
timeoutHandle = setTimeoutSpy.mock.results[timerIndex]?.value as NodeJS.Timeout
2363+
timeoutCallback = setTimeoutSpy.mock.calls[timerIndex]?.[0] as () => void
2364+
})
2365+
expect(internalSignal?.aborted).toBe(false)
2366+
2367+
// Fire the 10-minute request timeout: it must abort the request-local
2368+
// controller, which cancels the in-flight request with an AbortError.
2369+
timeoutCallback?.()
2370+
2371+
await expect(consumed).rejects.toMatchObject({ name: "AbortError" })
2372+
2373+
// Belt and braces: make sure no real 10-minute timer survives the test
2374+
setTimeoutSpy.mockRestore()
2375+
clearTimeout(timeoutHandle)
2376+
})
23132377
})
23142378
})
23152379
})

0 commit comments

Comments
 (0)