mirror of
https://github.com/openclaw/openclaw.git
synced 2026-10-03 01:29:56 +00:00
* fix(test): load compiled-subprocess declarations at collection The first load of a compiled-subprocess declaration in a Vitest invocation prepares the whole compiled worker generation (tens of seconds warm, minutes cold). 387 test files first reached a declaration through an await import() inside a test body or hook, so their first test or hook absorbed that preparation and could time out. Move those loads to collection at their owner: static subject imports, static imports in the shared helpers that owned the lazy load, and a named side-effect preload (src/test-utils/prepare-compiled-subprocesses.ts) for suites that re-import their subject per test or whose first load happens in production code they call. plugin-test-runtime keeps the host-capability fixture lazy so its other consumers do not start loading that graph. Document the rule in docs/help/testing/writing-tests.md. 335 of the 387 files now load their first declaration before collection ends; 52 remain (48 extension tests needing an SDK preload, one package test, three files over the line cap). * fix(test): retain npm install fixture reuse Preserve the existing failedSpawn reuse after merging main so the collection-time preload stays within the line-cap ratchet. Assertions and import ordering are unchanged. * fix(test): keep memory-core facade cold-import assertion meaningful The static subject import ran before beforeEach reset the loader mock, so the cold-import assertion passed vacuously. Restore the in-test subject imports after mock setup and preload the compiled-subprocess declaration during collection instead.
75 lines
2.5 KiB
TypeScript
75 lines
2.5 KiB
TypeScript
import { expect, it, vi } from "vitest";
|
|
import "../src/test-utils/prepare-compiled-subprocesses.js";
|
|
import { createDeferredCore } from "../src/shared/deferred.js";
|
|
|
|
const hooks = vi.hoisted(() => ({ afterEach: [] as Array<() => Promise<void>> }));
|
|
vi.mock("vitest", async (importOriginal) => ({
|
|
...(await importOriginal<typeof import("vitest")>()),
|
|
beforeAll: () => {},
|
|
afterAll: () => {},
|
|
afterEach: (cleanup: () => Promise<void>) => hooks.afterEach.push(cleanup),
|
|
}));
|
|
|
|
it.each([false, true])(
|
|
"joins retired plugin caches in the registered runtime reset (cleanup fails: %s)",
|
|
async (fails) => {
|
|
vi.resetModules();
|
|
hooks.afterEach.length = 0;
|
|
await import("./setup-openclaw-runtime.js");
|
|
const cleanup = hooks.afterEach.at(-1);
|
|
if (!cleanup) {
|
|
throw new Error("Runtime setup did not register its cleanup hook");
|
|
}
|
|
const { getProcessPluginCache, retainPluginCacheInstance, waitForPluginCacheRetirement } =
|
|
await import("../src/plugins/plugin-cache.js");
|
|
const { PluginInstance } = await import("../src/plugins/plugin-instance.js");
|
|
const entered = createDeferredCore();
|
|
const finish = createDeferredCore();
|
|
const failure = new Error("synthetic plugin retirement failure");
|
|
const instance = new PluginInstance("runtime-reset-fixture");
|
|
instance.lifecycle.onDispose(async () => {
|
|
entered.resolve();
|
|
await finish.promise;
|
|
if (fails) {
|
|
throw failure;
|
|
}
|
|
});
|
|
retainPluginCacheInstance(instance, getProcessPluginCache());
|
|
let settled = false;
|
|
const result = cleanup().then(
|
|
() => {
|
|
settled = true;
|
|
return undefined;
|
|
},
|
|
(error: unknown) => {
|
|
settled = true;
|
|
return error;
|
|
},
|
|
);
|
|
try {
|
|
await entered.promise;
|
|
expect(settled).toBe(false);
|
|
finish.resolve();
|
|
if (fails) {
|
|
const error = await result;
|
|
expect(error).toBeInstanceOf(AggregateError);
|
|
if (!(error instanceof AggregateError)) {
|
|
throw new Error("Runtime cleanup did not report the plugin retirement failure");
|
|
}
|
|
expect(error.errors).toEqual([
|
|
{ pluginId: "runtime-reset-fixture", hookId: "instance", error: failure },
|
|
]);
|
|
} else {
|
|
await expect(result).resolves.toBeUndefined();
|
|
}
|
|
await expect(waitForPluginCacheRetirement()).resolves.toEqual({
|
|
cleanupCount: 0,
|
|
failures: [],
|
|
});
|
|
} finally {
|
|
finish.resolve();
|
|
await result;
|
|
await waitForPluginCacheRetirement();
|
|
}
|
|
},
|
|
);
|