fix: stabilize full gate

This commit is contained in:
Peter Steinberger
2026-03-17 06:53:29 +00:00
parent 026d8ea534
commit 5fb7a1363f
92 changed files with 1381 additions and 838 deletions

View File

@@ -17,19 +17,19 @@ vi.mock("../logging/diagnostic.js", () => ({
diagnosticLogger: diagnosticMocks.diag,
}));
import {
clearCommandLane,
CommandLaneClearedError,
enqueueCommand,
enqueueCommandInLane,
GatewayDrainingError,
getActiveTaskCount,
getQueueSize,
markGatewayDraining,
resetAllLanes,
setCommandLaneConcurrency,
waitForActiveTasks,
} from "./command-queue.js";
type CommandQueueModule = typeof import("./command-queue.js");
let clearCommandLane: CommandQueueModule["clearCommandLane"];
let CommandLaneClearedError: CommandQueueModule["CommandLaneClearedError"];
let enqueueCommand: CommandQueueModule["enqueueCommand"];
let enqueueCommandInLane: CommandQueueModule["enqueueCommandInLane"];
let GatewayDrainingError: CommandQueueModule["GatewayDrainingError"];
let getActiveTaskCount: CommandQueueModule["getActiveTaskCount"];
let getQueueSize: CommandQueueModule["getQueueSize"];
let markGatewayDraining: CommandQueueModule["markGatewayDraining"];
let resetAllLanes: CommandQueueModule["resetAllLanes"];
let setCommandLaneConcurrency: CommandQueueModule["setCommandLaneConcurrency"];
let waitForActiveTasks: CommandQueueModule["waitForActiveTasks"];
function createDeferred(): { promise: Promise<void>; resolve: () => void } {
let resolve!: () => void;
@@ -54,7 +54,21 @@ function enqueueBlockedMainTask<T = void>(
}
describe("command queue", () => {
beforeEach(() => {
beforeEach(async () => {
vi.resetModules();
({
clearCommandLane,
CommandLaneClearedError,
enqueueCommand,
enqueueCommandInLane,
GatewayDrainingError,
getActiveTaskCount,
getQueueSize,
markGatewayDraining,
resetAllLanes,
setCommandLaneConcurrency,
waitForActiveTasks,
} = await import("./command-queue.js"));
resetAllLanes();
diagnosticMocks.logLaneEnqueue.mockClear();
diagnosticMocks.logLaneDequeue.mockClear();

View File

@@ -1,6 +1,6 @@
import type { ChildProcess } from "node:child_process";
import { EventEmitter } from "node:events";
import { afterEach, describe, expect, it, vi } from "vitest";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
const spawnMock = vi.hoisted(() => vi.fn());
@@ -12,7 +12,9 @@ vi.mock("node:child_process", async () => {
};
});
import { runCommandWithTimeout } from "./exec.js";
type ExecModule = typeof import("./exec.js");
let runCommandWithTimeout: ExecModule["runCommandWithTimeout"];
function createFakeSpawnedChild() {
const child = new EventEmitter() as EventEmitter & ChildProcess;
@@ -39,6 +41,11 @@ function createFakeSpawnedChild() {
}
describe("runCommandWithTimeout no-output timer", () => {
beforeEach(async () => {
vi.resetModules();
({ runCommandWithTimeout } = await import("./exec.js"));
});
afterEach(() => {
vi.useRealTimers();
vi.restoreAllMocks();

View File

@@ -1,5 +1,5 @@
import { EventEmitter } from "node:events";
import { afterEach, describe, expect, it, vi } from "vitest";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
const spawnMock = vi.hoisted(() => vi.fn());
const execFileMock = vi.hoisted(() => vi.fn());
@@ -13,7 +13,8 @@ vi.mock("node:child_process", async (importOriginal) => {
};
});
import { runCommandWithTimeout, runExec } from "./exec.js";
let runCommandWithTimeout: typeof import("./exec.js").runCommandWithTimeout;
let runExec: typeof import("./exec.js").runExec;
type MockChild = EventEmitter & {
stdout: EventEmitter;
@@ -64,6 +65,11 @@ function expectCmdWrappedInvocation(params: {
}
describe("windows command wrapper behavior", () => {
beforeEach(async () => {
vi.resetModules();
({ runCommandWithTimeout, runExec } = await import("./exec.js"));
});
afterEach(() => {
spawnMock.mockReset();
execFileMock.mockReset();

View File

@@ -1,5 +1,4 @@
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { killProcessTree } from "./kill-tree.js";
const { spawnMock } = vi.hoisted(() => ({
spawnMock: vi.fn(),
@@ -9,6 +8,8 @@ vi.mock("node:child_process", () => ({
spawn: (...args: unknown[]) => spawnMock(...args),
}));
let killProcessTree: typeof import("./kill-tree.js").killProcessTree;
async function withPlatform<T>(platform: NodeJS.Platform, run: () => Promise<T> | T): Promise<T> {
const originalPlatform = Object.getOwnPropertyDescriptor(process, "platform");
Object.defineProperty(process, "platform", { value: platform, configurable: true });
@@ -24,7 +25,9 @@ async function withPlatform<T>(platform: NodeJS.Platform, run: () => Promise<T>
describe("killProcessTree", () => {
let killSpy: ReturnType<typeof vi.spyOn>;
beforeEach(() => {
beforeEach(async () => {
vi.resetModules();
({ killProcessTree } = await import("./kill-tree.js"));
spawnMock.mockClear();
killSpy = vi.spyOn(process, "kill");
vi.useFakeTimers();

View File

@@ -1,7 +1,7 @@
import type { ChildProcess } from "node:child_process";
import { EventEmitter } from "node:events";
import { PassThrough } from "node:stream";
import { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import { afterAll, beforeEach, describe, expect, it, vi } from "vitest";
const { spawnWithFallbackMock, killProcessTreeMock } = vi.hoisted(() => ({
spawnWithFallbackMock: vi.fn(),
@@ -51,11 +51,9 @@ async function createAdapterHarness(params?: {
describe("createChildAdapter", () => {
const originalServiceMarker = process.env.OPENCLAW_SERVICE_MARKER;
beforeAll(async () => {
beforeEach(async () => {
vi.resetModules();
({ createChildAdapter } = await import("./child.js"));
});
beforeEach(() => {
spawnWithFallbackMock.mockClear();
killProcessTreeMock.mockClear();
delete process.env.OPENCLAW_SERVICE_MARKER;

View File

@@ -1,4 +1,4 @@
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
const { spawnMock, ptyKillMock, killProcessTreeMock } = vi.hoisted(() => ({
spawnMock: vi.fn(),
@@ -39,11 +39,9 @@ function expectSpawnEnv() {
describe("createPtyAdapter", () => {
let createPtyAdapter: typeof import("./pty.js").createPtyAdapter;
beforeAll(async () => {
beforeEach(async () => {
vi.resetModules();
({ createPtyAdapter } = await import("./pty.js"));
});
beforeEach(() => {
spawnMock.mockClear();
ptyKillMock.mockClear();
killProcessTreeMock.mockClear();

View File

@@ -1,4 +1,4 @@
import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import { beforeEach, describe, expect, it, vi } from "vitest";
const { createPtyAdapterMock } = vi.hoisted(() => ({
createPtyAdapterMock: vi.fn(),
@@ -35,11 +35,9 @@ function createStubPtyAdapter() {
describe("process supervisor PTY command contract", () => {
let createProcessSupervisor: typeof import("./supervisor.js").createProcessSupervisor;
beforeAll(async () => {
beforeEach(async () => {
vi.resetModules();
({ createProcessSupervisor } = await import("./supervisor.js"));
});
beforeEach(() => {
createPtyAdapterMock.mockClear();
});