test(azure-speech): make voices timeout proof deterministic (#124694)

This commit is contained in:
Peter Steinberger
2026-08-16 09:55:23 -07:00
committed by GitHub
parent 551c65e490
commit 3ca7b038f0
2 changed files with 63 additions and 24 deletions
+28 -16
View File
@@ -3,6 +3,7 @@
// the real fetch abort path without depending on Azure latency.
import { createServer, type Server } from "node:http";
import type { AddressInfo } from "node:net";
import { clearTimeout as clearRealTimeout, setTimeout as setRealTimeout } from "node:timers";
import { afterEach, describe, expect, it, vi } from "vitest";
import { listAzureSpeechVoices } from "./tts.js";
@@ -39,8 +40,13 @@ describe("listAzureSpeechVoices timeout", () => {
{ timeout: 2_000 },
async () => {
let requestCount = 0;
const server = createServer((_req, _res) => {
let notifyRequest = () => {};
const requestReceived = new Promise<void>((resolve) => {
notifyRequest = resolve;
});
const server = createServer((_request, _response) => {
requestCount += 1;
notifyRequest();
});
const port = await listenLocal(server);
@@ -56,26 +62,32 @@ describe("listAzureSpeechVoices timeout", () => {
);
const startedAt = Date.now();
let watchdog: ReturnType<typeof setTimeout> | undefined;
let watchdog: ReturnType<typeof setRealTimeout> | undefined;
try {
await expect(
Promise.race([
listAzureSpeechVoices({
apiKey: "not-a-real",
baseUrl: "https://custom.example.com",
timeoutMs: 100,
}),
new Promise<never>((_, reject) => {
watchdog = setTimeout(() => reject(new Error("voices list did not time out")), 1_000);
}),
]),
).rejects.toThrow(/aborted|timeout|timed out/i);
expect(Date.now() - startedAt).toBeLessThan(1_000);
vi.useFakeTimers({ toFake: ["setTimeout", "clearTimeout"] });
const watchdogPromise = new Promise<never>((_, reject) => {
watchdog = setRealTimeout(() => reject(new Error("voices list did not time out")), 1_000);
});
const request = Promise.race([
listAzureSpeechVoices({
apiKey: "not-a-real",
baseUrl: "https://custom.example.com",
timeoutMs: 100,
}),
watchdogPromise,
]);
const rejection = expect(request).rejects.toThrow(/aborted|timeout|timed out/i);
await Promise.race([requestReceived, watchdogPromise]);
expect(requestCount).toBe(1);
await vi.advanceTimersByTimeAsync(100);
await rejection;
expect(Date.now() - startedAt).toBeLessThan(1_000);
} finally {
vi.useRealTimers();
if (watchdog) {
clearTimeout(watchdog);
clearRealTimeout(watchdog);
}
await closeServer(server);
}
+35 -8
View File
@@ -1,3 +1,4 @@
import { clearTimeout as clearRealTimeout, setTimeout as setRealTimeout } from "node:timers";
import { withServer } from "openclaw/plugin-sdk/test-env";
import { afterEach, describe, expect, it, vi } from "vitest";
import { listInworldVoices } from "./tts.js";
@@ -14,9 +15,14 @@ describe("listInworldVoices live timeout", () => {
{ timeout: 2_000 },
async () => {
let requestCount = 0;
let notifyRequest = () => {};
const requestReceived = new Promise<void>((resolve) => {
notifyRequest = resolve;
});
await withServer(
(request) => {
requestCount += 1;
notifyRequest();
request.resume();
},
async (baseUrl) => {
@@ -27,14 +33,35 @@ describe("listInworldVoices live timeout", () => {
}) as unknown as typeof globalThis.fetch,
);
await expect(
listInworldVoices({
apiKey: "test-key",
baseUrl: "https://custom.inworld.example.com",
timeoutMs: 250,
}),
).rejects.toThrow(/aborted|timeout|timed out/i);
expect(requestCount).toBe(1);
let watchdog: ReturnType<typeof setRealTimeout> | undefined;
try {
vi.useFakeTimers({ toFake: ["setTimeout", "clearTimeout"] });
const watchdogPromise = new Promise<never>((_, reject) => {
watchdog = setRealTimeout(
() => reject(new Error("voices list did not time out")),
1_000,
);
});
const request = Promise.race([
listInworldVoices({
apiKey: "test-key",
baseUrl: "https://custom.inworld.example.com",
timeoutMs: 250,
}),
watchdogPromise,
]);
const rejection = expect(request).rejects.toThrow(/aborted|timeout|timed out/i);
await Promise.race([requestReceived, watchdogPromise]);
expect(requestCount).toBe(1);
await vi.advanceTimersByTimeAsync(250);
await rejection;
} finally {
vi.useRealTimers();
if (watchdog) {
clearRealTimeout(watchdog);
}
}
},
);
},