mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-06 19:12:52 +00:00
fix(ci): isolate timer-sensitive tests
This commit is contained in:
@@ -9,10 +9,13 @@ describe("isCliBindingFlushed", () => {
|
||||
const workspaceDir = "/tmp/openclaw-workspace";
|
||||
|
||||
beforeEach(() => {
|
||||
vi.useRealTimers();
|
||||
restoreCliRunnerTestDeps();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.clearAllTimers();
|
||||
vi.useRealTimers();
|
||||
restoreCliRunnerTestDeps();
|
||||
});
|
||||
|
||||
@@ -34,14 +37,21 @@ describe("isCliBindingFlushed", () => {
|
||||
});
|
||||
|
||||
it("retries up to three times before giving up", async () => {
|
||||
vi.useFakeTimers();
|
||||
const probe = vi.fn(async () => false);
|
||||
setCliRunnerTestDeps({ claudeCliSessionTranscriptHasContent: probe });
|
||||
|
||||
expect(await isCliBindingFlushed("sid-cold", "claude-cli", workspaceDir)).toBe(false);
|
||||
const resultPromise = isCliBindingFlushed("sid-cold", "claude-cli", workspaceDir);
|
||||
await vi.advanceTimersByTimeAsync(0);
|
||||
await vi.advanceTimersByTimeAsync(50);
|
||||
await vi.advanceTimersByTimeAsync(150);
|
||||
|
||||
await expect(resultPromise).resolves.toBe(false);
|
||||
expect(probe).toHaveBeenCalledTimes(3);
|
||||
});
|
||||
|
||||
it("succeeds when the transcript becomes visible on a later retry", async () => {
|
||||
vi.useFakeTimers();
|
||||
let calls = 0;
|
||||
const probe = vi.fn(async () => {
|
||||
calls += 1;
|
||||
@@ -49,7 +59,11 @@ describe("isCliBindingFlushed", () => {
|
||||
});
|
||||
setCliRunnerTestDeps({ claudeCliSessionTranscriptHasContent: probe });
|
||||
|
||||
expect(await isCliBindingFlushed("sid-late", "claude-cli", workspaceDir)).toBe(true);
|
||||
const resultPromise = isCliBindingFlushed("sid-late", "claude-cli", workspaceDir);
|
||||
await vi.advanceTimersByTimeAsync(0);
|
||||
await vi.advanceTimersByTimeAsync(50);
|
||||
|
||||
await expect(resultPromise).resolves.toBe(true);
|
||||
expect(probe).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
|
||||
@@ -72,6 +86,7 @@ describe("isCliBindingFlushed", () => {
|
||||
expect(errored).not.toHaveBeenCalled();
|
||||
expect(probe).toHaveBeenCalledTimes(3);
|
||||
} finally {
|
||||
vi.clearAllTimers();
|
||||
vi.useRealTimers();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import type { OpenClawConfig } from "../config/types.openclaw.js";
|
||||
import { MAX_TIMER_TIMEOUT_MS } from "../shared/number-coercion.js";
|
||||
import { loadModelCatalogForBrowse } from "./model-catalog-browse.js";
|
||||
@@ -24,7 +24,12 @@ function config(params: { providerWildcard?: boolean } = {}): OpenClawConfig {
|
||||
}
|
||||
|
||||
describe("loadModelCatalogForBrowse", () => {
|
||||
beforeEach(() => {
|
||||
vi.useRealTimers();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.clearAllTimers();
|
||||
vi.useRealTimers();
|
||||
});
|
||||
|
||||
@@ -65,6 +70,7 @@ describe("loadModelCatalogForBrowse", () => {
|
||||
});
|
||||
|
||||
it("returns an empty catalog when read-only catalog loading times out", async () => {
|
||||
vi.useFakeTimers();
|
||||
const onTimeout = vi.fn();
|
||||
const loadCatalog = vi.fn(
|
||||
() =>
|
||||
@@ -80,9 +86,10 @@ describe("loadModelCatalogForBrowse", () => {
|
||||
onTimeout,
|
||||
});
|
||||
|
||||
await vi.advanceTimersByTimeAsync(5);
|
||||
await expect(resultPromise).resolves.toEqual([]);
|
||||
expect(onTimeout).toHaveBeenCalledExactlyOnceWith(5);
|
||||
await new Promise((resolve) => setTimeout(resolve, 15));
|
||||
await vi.advanceTimersByTimeAsync(10);
|
||||
});
|
||||
|
||||
it("uses the default timeout when timeoutMs is non-finite", async () => {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { MAX_TIMER_TIMEOUT_MS } from "../shared/number-coercion.js";
|
||||
import { createTypingCallbacks } from "./typing.js";
|
||||
|
||||
@@ -16,6 +16,7 @@ async function withFakeTimers(run: () => Promise<void>) {
|
||||
try {
|
||||
await run();
|
||||
} finally {
|
||||
vi.clearAllTimers();
|
||||
vi.useRealTimers();
|
||||
}
|
||||
}
|
||||
@@ -56,6 +57,15 @@ function createTypingHarness(overrides: TypingCallbackOverrides = {}) {
|
||||
}
|
||||
|
||||
describe("createTypingCallbacks", () => {
|
||||
beforeEach(() => {
|
||||
vi.useRealTimers();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.clearAllTimers();
|
||||
vi.useRealTimers();
|
||||
});
|
||||
|
||||
it("invokes start on reply start", async () => {
|
||||
const { start, onStartError, callbacks } = createTypingHarness();
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import type { MsgContext } from "../auto-reply/templating.js";
|
||||
import type { OpenClawConfig } from "../config/types.js";
|
||||
import { MIN_AUDIO_FILE_BYTES } from "./defaults.js";
|
||||
@@ -78,6 +78,10 @@ async function runAudioCapabilityWithTranscriber(params: {
|
||||
}
|
||||
|
||||
describe("runCapability skips tiny audio files", () => {
|
||||
beforeEach(() => {
|
||||
vi.useRealTimers();
|
||||
});
|
||||
|
||||
it("skips audio transcription when file is smaller than MIN_AUDIO_FILE_BYTES", async () => {
|
||||
await withAudioFixture({
|
||||
filePrefix: "openclaw-tiny-audio",
|
||||
@@ -172,7 +176,7 @@ describe("runCapability skips tiny audio files", () => {
|
||||
media,
|
||||
cache,
|
||||
transcribeAudio: async () => {
|
||||
throw new Error("upstream 500");
|
||||
throw Object.assign(new Error("HTTP 400 validation failed"), { status: 400 });
|
||||
},
|
||||
});
|
||||
|
||||
@@ -189,7 +193,7 @@ describe("runCapability skips tiny audio files", () => {
|
||||
throw new Error("expected failed audio decision attempt");
|
||||
}
|
||||
expect(attempt.outcome).toBe("failed");
|
||||
expect(attempt.reason).toContain("upstream 500");
|
||||
expect(attempt.reason).toContain("HTTP 400 validation failed");
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user