mirror of
https://github.com/openclaw/openclaw.git
synced 2026-10-03 01:29:56 +00:00
fix(test): keep subprocess fixtures consistent across Node and Bun (#163805)
Couple test-worker arguments to the executable selected by the shared subprocess helper and migrate its runtime-dependent callers. Repair command parsing, runtime pinning, worker observation, storage settlement, and cleanup-clock fixtures while preserving their contracts. Fourteen scoped suites pass on Node 24 and Bun; the Bun readSync gap remains an unchanged stop. Refreshed proof covers 638 passed/1 existing skip on Node and 636 passed/3 existing skips on Bun. P2 review and exact-head ClawSweeper found no actionable defects. Production LOC delta is zero. The first CI head exposed an inherited UI-validator fixture omission. After incorporating its existing main fix, exact-head CI passed, including the published-driver update job. No same-head retry or admin exception was used.
This commit is contained in:
parent
db30aa2108
commit
ee51203de7
32 changed files with 209 additions and 160 deletions
|
|
@ -3,10 +3,7 @@ import path from "node:path";
|
|||
import { fileURLToPath } from "node:url";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { runNodeScript } from "../../../test/helpers/run-node-script.js";
|
||||
import {
|
||||
resolveRuntimeWorkerArgv,
|
||||
resolveRuntimeWorkerUrl,
|
||||
} from "../../infra/runtime-worker-url.js";
|
||||
import { resolveRuntimeWorkerUrl } from "../../infra/runtime-worker-url.js";
|
||||
import { prepareSecretsRuntimeFastPathSnapshot } from "../../secrets/runtime-fast-path.js";
|
||||
import { activateSecretsRuntimeSnapshotState } from "../../secrets/runtime-state.js";
|
||||
import { openOpenClawStateDatabase } from "../../state/openclaw-state-db.js";
|
||||
|
|
@ -661,8 +658,8 @@ describe("auth publication owner receipts", () => {
|
|||
const laterCwd = path.join(tempDirs.make("openclaw-auth-scope-later-cwd-"), "nested");
|
||||
fs.mkdirSync(laterCwd);
|
||||
const result = await runNodeScript(
|
||||
[
|
||||
...resolveRuntimeWorkerArgv(resolveRuntimeWorkerUrl(authProfileScopeCwdEntrypoint)),
|
||||
(workerArgv) => [
|
||||
...workerArgv(resolveRuntimeWorkerUrl(authProfileScopeCwdEntrypoint)),
|
||||
stateDir,
|
||||
agentDir,
|
||||
laterCwd,
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
import { fileURLToPath } from "node:url";
|
||||
import { expect, it } from "vitest";
|
||||
import { runNodeScript } from "../../test/helpers/run-node-script.js";
|
||||
import { resolveRuntimeWorkerArgv, resolveRuntimeWorkerUrl } from "../infra/runtime-worker-url.js";
|
||||
import { resolveTestNodeExecPath } from "../test-utils/node-process.js";
|
||||
import { resolveRuntimeWorkerUrl } from "../infra/runtime-worker-url.js";
|
||||
import {
|
||||
codeModeDescriptionRetentionEntrypoint,
|
||||
codeModeRetentionEntrypoint,
|
||||
|
|
@ -21,10 +20,7 @@ it.for([
|
|||
},
|
||||
])("$name", { timeout: 30_000 }, async ({ entrypoint, expected }, { signal }) => {
|
||||
const result = await runNodeScript(
|
||||
[
|
||||
"--expose-gc",
|
||||
...resolveRuntimeWorkerArgv(resolveRuntimeWorkerUrl(entrypoint), resolveTestNodeExecPath()),
|
||||
],
|
||||
(workerArgv) => ["--expose-gc", ...workerArgv(resolveRuntimeWorkerUrl(entrypoint))],
|
||||
{ ...process.env, NODE_OPTIONS: "", TSX_DISABLE_CACHE: "1" },
|
||||
15_000,
|
||||
{
|
||||
|
|
|
|||
|
|
@ -3,8 +3,7 @@ import { describe, expect, it, vi } from "vitest";
|
|||
import * as fences from "../../packages/markdown-core/src/fences.js";
|
||||
import { markdownToIR } from "../../packages/markdown-core/src/ir.js";
|
||||
import { runNodeScript } from "../../test/helpers/run-node-script.js";
|
||||
import { resolveRuntimeWorkerArgv, resolveRuntimeWorkerUrl } from "../infra/runtime-worker-url.js";
|
||||
import { resolveTestNodeExecPath } from "../test-utils/node-process.js";
|
||||
import { resolveRuntimeWorkerUrl } from "../infra/runtime-worker-url.js";
|
||||
import { EmbeddedBlockChunker } from "./embedded-agent-block-chunker.js";
|
||||
import { agentProcessTestEntrypoints } from "./process-runtime.test-support.js";
|
||||
|
||||
|
|
@ -223,8 +222,8 @@ describe("EmbeddedBlockChunker", () => {
|
|||
// A synchronous stalled drain needs an external deadline, not Vitest's in-process timer.
|
||||
const chunkerUrl = resolveRuntimeWorkerUrl(agentProcessTestEntrypoints.blockChunker);
|
||||
const result = await runNodeScript(
|
||||
[
|
||||
...resolveRuntimeWorkerArgv(chunkerUrl, resolveTestNodeExecPath()).slice(0, -1),
|
||||
(workerArgv) => [
|
||||
...workerArgv(chunkerUrl).slice(0, -1),
|
||||
"--input-type=module",
|
||||
"--eval",
|
||||
`
|
||||
|
|
|
|||
|
|
@ -55,10 +55,20 @@ it("prepares known provider owners once while keeping catalog execution and auth
|
|||
`provider: ${JSON.stringify(provider)}, filename: __filename`,
|
||||
);
|
||||
const execution = (provider: string) =>
|
||||
`require("node:v8").queryObjects(WeakRef);` +
|
||||
`require("node:v8").queryObjects(WeakRef);
|
||||
const retainedPayloads = globalThis[Symbol.for("catalog.reuse.payloads")];
|
||||
const activePayload = retainedPayloads.at(-1);
|
||||
const currentPayload = activePayload.ref.deref();
|
||||
` +
|
||||
record(
|
||||
"heap.jsonl",
|
||||
`memory: process.memoryUsage(), payloads: globalThis[Symbol.for("catalog.reuse.payloads")].filter(ref => ref.deref()).length`,
|
||||
`memory: process.memoryUsage(),
|
||||
payloads: retainedPayloads.filter(({ ref }) => ref.deref()).length,
|
||||
currentPayload: currentPayload && {
|
||||
filename: activePayload.filename,
|
||||
row: currentPayload.rows[99_999].index,
|
||||
bufferBytes: currentPayload.buffer.byteLength,
|
||||
}`,
|
||||
) +
|
||||
record(
|
||||
"executions.jsonl",
|
||||
|
|
@ -77,7 +87,7 @@ it("prepares known provider owners once while keeping catalog execution and auth
|
|||
fs.writeFileSync(
|
||||
baseEntry,
|
||||
`const { payload } = require("./payload.mjs");
|
||||
(globalThis[Symbol.for("catalog.reuse.payloads")] ??= []).push(new WeakRef(payload));
|
||||
(globalThis[Symbol.for("catalog.reuse.payloads")] ??= []).push({ ref: new WeakRef(payload), filename: __filename });
|
||||
` +
|
||||
fs
|
||||
.readFileSync(baseEntry, "utf8")
|
||||
|
|
@ -242,7 +252,7 @@ module.exports = { id: ${JSON.stringify(provider)}, register(api) {
|
|||
).toEqual(index === 0 ? [PROVIDER_ID, ...providerIds].toSorted() : []);
|
||||
const expanded = registrations();
|
||||
const footprint = readCatalogCaptureFootprint(captureRoot);
|
||||
// Retired capture files disappear even though Node retains their native ESM payloads.
|
||||
// Retired capture files disappear even if native ESM payloads remain cached.
|
||||
expect(footprint.captures).toHaveLength(1);
|
||||
await refreshScope((index + 1) % 2, provider);
|
||||
expect(registrations()).toEqual(expanded);
|
||||
|
|
@ -285,9 +295,28 @@ module.exports = { id: ${JSON.stringify(provider)}, register(api) {
|
|||
.readFileSync(path.join(fixture.root, "heap.jsonl"), "utf8")
|
||||
.trim()
|
||||
.split("\n")
|
||||
.map((line) => JSON.parse(line) as { memory: NodeJS.MemoryUsage; payloads: number });
|
||||
.map(
|
||||
(line) =>
|
||||
JSON.parse(line) as {
|
||||
memory: NodeJS.MemoryUsage;
|
||||
payloads: number;
|
||||
currentPayload?: { filename: string; row: number; bufferBytes: number };
|
||||
},
|
||||
);
|
||||
expect(heap).toHaveLength(providerIds.length * agentIds.length * 2);
|
||||
expect(heap.map(({ payloads }) => payloads)).toEqual(heap.map(() => 2));
|
||||
const currentFilename = warmedRegistrations.findLast(
|
||||
({ provider }) => provider === PROVIDER_ID,
|
||||
)!.filename;
|
||||
for (const sample of heap) {
|
||||
// Engines may collect the retired ESM payload; the current capture must remain usable.
|
||||
expect(sample.payloads).toBeGreaterThanOrEqual(1);
|
||||
expect(sample.payloads).toBeLessThanOrEqual(2);
|
||||
expect(sample.currentPayload).toEqual({
|
||||
filename: currentFilename,
|
||||
row: 99_999,
|
||||
bufferBytes: 1024 * 1024,
|
||||
});
|
||||
}
|
||||
expect(heap.at(-1)!.memory.heapUsed - heap[0]!.memory.heapUsed).toBeLessThan(16 * 1024 * 1024);
|
||||
expect(heap.at(-1)!.memory.arrayBuffers - heap[0]!.memory.arrayBuffers).toBeLessThan(1024 * 1024);
|
||||
console.log("Provider-scope heap", JSON.stringify({ first: heap[0], last: heap.at(-1) }));
|
||||
|
|
|
|||
|
|
@ -193,8 +193,8 @@ describe("FileSettingsStorage", () => {
|
|||
const root = fixtures.createTempDir("openclaw-settings-umask-");
|
||||
const agentDir = join(root, "agent");
|
||||
const result = await runNodeScript(
|
||||
[
|
||||
...resolveRuntimeWorkerArgv(storageUrl, resolveTestNodeExecPath()).slice(0, -1),
|
||||
(workerArgv) => [
|
||||
...workerArgv(storageUrl).slice(0, -1),
|
||||
"--input-type=module",
|
||||
"--eval",
|
||||
String.raw`
|
||||
|
|
|
|||
|
|
@ -1,11 +1,7 @@
|
|||
import { fileURLToPath } from "node:url";
|
||||
import { beforeAll, expect, it } from "vitest";
|
||||
import { runNodeScript } from "../../../../test/helpers/run-node-script.js";
|
||||
import {
|
||||
resolveRuntimeWorkerArgv,
|
||||
resolveRuntimeWorkerUrl,
|
||||
} from "../../../infra/runtime-worker-url.js";
|
||||
import { resolveTestNodeExecPath } from "../../../test-utils/node-process.js";
|
||||
import { resolveRuntimeWorkerUrl } from "../../../infra/runtime-worker-url.js";
|
||||
import { agentProcessTestEntrypoints } from "../../process-runtime.test-support.js";
|
||||
|
||||
type Observation = {
|
||||
|
|
@ -19,12 +15,9 @@ let observations: Observation[] = [];
|
|||
|
||||
beforeAll(async () => {
|
||||
const result = await runNodeScript(
|
||||
[
|
||||
(workerArgv) => [
|
||||
"--expose-gc",
|
||||
...resolveRuntimeWorkerArgv(
|
||||
resolveRuntimeWorkerUrl(agentProcessTestEntrypoints.readRetention),
|
||||
resolveTestNodeExecPath(),
|
||||
),
|
||||
...workerArgv(resolveRuntimeWorkerUrl(agentProcessTestEntrypoints.readRetention)),
|
||||
"all",
|
||||
],
|
||||
{ ...process.env, NODE_OPTIONS: "", TSX_DISABLE_CACHE: "1" },
|
||||
|
|
|
|||
|
|
@ -8,17 +8,13 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|||
import { createDeferred } from "../../../test/helpers/promise.js";
|
||||
import { runNodeScript } from "../../../test/helpers/run-node-script.js";
|
||||
import * as backoff from "../../infra/backoff.js";
|
||||
import {
|
||||
resolveRuntimeWorkerArgv,
|
||||
resolveRuntimeWorkerUrl,
|
||||
} from "../../infra/runtime-worker-url.js";
|
||||
import { resolveRuntimeWorkerUrl } from "../../infra/runtime-worker-url.js";
|
||||
import { createWarnLogCapture } from "../../logging/test-helpers/warn-log-capture.js";
|
||||
import * as pidAlive from "../../shared/pid-alive.js";
|
||||
import {
|
||||
closeOpenClawStateDatabaseAsync,
|
||||
closeOpenClawStateDatabaseForTest,
|
||||
} from "../../state/openclaw-state-db.js";
|
||||
import { resolveTestNodeExecPath } from "../../test-utils/node-process.js";
|
||||
import * as worktreeCapacity from "./capacity.js";
|
||||
import * as worktreeGit from "./git.js";
|
||||
import { requireGit } from "./git.js";
|
||||
|
|
@ -338,11 +334,8 @@ describe("ManagedWorktreeService garbage collection", () => {
|
|||
|
||||
// Gateway cleanup runs on Node's main thread, whose stack limit differs from Vitest workers.
|
||||
const collected = await runNodeScript(
|
||||
[
|
||||
...resolveRuntimeWorkerArgv(
|
||||
resolveRuntimeWorkerUrl(managedWorktreeGcEntrypoint),
|
||||
resolveTestNodeExecPath(),
|
||||
),
|
||||
(workerArgv) => [
|
||||
...workerArgv(resolveRuntimeWorkerUrl(managedWorktreeGcEntrypoint)),
|
||||
String(now),
|
||||
],
|
||||
env,
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import { resolveVitestNodeArgs } from "../../scripts/lib/vitest-process-env.mts"
|
|||
import { createFixtureLifetime } from "../../test/helpers/fixture-lifetime.js";
|
||||
import { runNodeScript } from "../../test/helpers/run-node-script.js";
|
||||
import { useAutoCleanupTempDirTracker } from "../../test/helpers/temp-dir.js";
|
||||
import { resolveRuntimeWorkerArgv, resolveRuntimeWorkerUrl } from "../infra/runtime-worker-url.js";
|
||||
import { resolveRuntimeWorkerUrl } from "../infra/runtime-worker-url.js";
|
||||
import { resolveTestNodeExecPath } from "../test-utils/node-process.js";
|
||||
import {
|
||||
cliMessageExitEntrypoints,
|
||||
|
|
@ -486,9 +486,9 @@ await runCliWithExitFinalization({
|
|||
const spawned: { child?: ChildProcess } = {};
|
||||
const child = await lifetime.track(
|
||||
runNodeScript(
|
||||
[
|
||||
(workerArgv) => [
|
||||
...resolveVitestNodeArgs(),
|
||||
...resolveRuntimeWorkerArgv(helpersUrl, nodeExecutable).slice(0, -1),
|
||||
...workerArgv(helpersUrl).slice(0, -1),
|
||||
entryPath,
|
||||
],
|
||||
{
|
||||
|
|
|
|||
|
|
@ -140,13 +140,10 @@ export function createCandidateAdmissionFixtures(f: CandidateAdmissionFixture) {
|
|||
);
|
||||
const originalSpawn = expectDefined(spawn.getMockImplementation(), "default child transport");
|
||||
spawn.mockImplementation((command: string, args: string[], options: SpawnOptions) => {
|
||||
if (args[1] !== "update" || args[2] !== "admit") {
|
||||
if (args.at(-4) !== "update" || args.at(-3) !== "admit" || args.at(-2) !== "--context") {
|
||||
return originalSpawn(command, args, options);
|
||||
}
|
||||
const contextPath = expectDefined(
|
||||
args[args.indexOf("--context") + 1],
|
||||
"candidate admission context",
|
||||
);
|
||||
const contextPath = expectDefined(args.at(-1), "candidate admission context");
|
||||
contexts.push(JSON.parse(fsSync.readFileSync(contextPath, "utf8")) as UpdateAdmissionContext);
|
||||
events.push("admission");
|
||||
databaseExistsAtAdmission.push(
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import fs from "node:fs";
|
|||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { resolveTestNodeExecPath } from "../test-utils/node-process.js";
|
||||
import {
|
||||
resolveDaemonInstallRuntimeInputs,
|
||||
resolveDaemonServicePathDirs,
|
||||
|
|
@ -15,7 +16,7 @@ describe("resolveDaemonInstallRuntimeInputs", () => {
|
|||
const root = fs.realpathSync(fs.mkdtempSync(path.join(os.tmpdir(), "daemon-pin-")));
|
||||
const pinned = path.join(root, "node");
|
||||
try {
|
||||
fs.symlinkSync(process.execPath, pinned);
|
||||
fs.symlinkSync(resolveTestNodeExecPath(), pinned);
|
||||
await expect(
|
||||
resolveDaemonInstallRuntimeInputs({
|
||||
env: {},
|
||||
|
|
|
|||
|
|
@ -32,13 +32,22 @@ const postGrantPreload = `
|
|||
const fixture = workerData.cronMutationProbe;
|
||||
let gate;
|
||||
let held = false;
|
||||
parentPort.on("message", (request) => {
|
||||
const observeRequest = (request) => {
|
||||
if (request.type === "reclaim" &&
|
||||
["entry", "lifecycle-projection-commit"].includes(request.plan.kind) &&
|
||||
request.plan.descendantRunBasis?.sessionKeys.includes(fixture.sessionKey)) {
|
||||
gate = request.commitGate;
|
||||
}
|
||||
});
|
||||
};
|
||||
const on = parentPort.on;
|
||||
parentPort.on = function(event, listener) {
|
||||
if (event === "message") {
|
||||
// An eager preload listener consumes queued requests before the real worker imports finish.
|
||||
parentPort.on = on;
|
||||
on.call(this, event, observeRequest);
|
||||
}
|
||||
return on.call(this, event, listener);
|
||||
};
|
||||
const load = Atomics.load;
|
||||
Atomics.load = function(view, index) {
|
||||
const observed = load(view, index);
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
import { fileURLToPath } from "node:url";
|
||||
import { expect, it } from "vitest";
|
||||
import { runNodeScript } from "../../test/helpers/run-node-script.js";
|
||||
import { resolveRuntimeWorkerArgv, resolveRuntimeWorkerUrl } from "../infra/runtime-worker-url.js";
|
||||
import { resolveRuntimeWorkerUrl } from "../infra/runtime-worker-url.js";
|
||||
import { sessionChildCacheRetentionEntrypoint } from "./session-child-cache-retention-entrypoint.test-support.js";
|
||||
|
||||
it("keeps child links without retaining released session metadata", async ({ signal }) => {
|
||||
const result = await runNodeScript(
|
||||
[
|
||||
(workerArgv) => [
|
||||
"--expose-gc",
|
||||
...resolveRuntimeWorkerArgv(resolveRuntimeWorkerUrl(sessionChildCacheRetentionEntrypoint)),
|
||||
...workerArgv(resolveRuntimeWorkerUrl(sessionChildCacheRetentionEntrypoint)),
|
||||
],
|
||||
{ ...process.env, NODE_OPTIONS: "", TSX_DISABLE_CACHE: "1" },
|
||||
15_000,
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ import {
|
|||
withStateDatabaseColdAdmission,
|
||||
} from "./gateway-state-owner.js";
|
||||
import * as nodeSqlite from "./node-sqlite.js";
|
||||
import { resolveRuntimeWorkerArgv, resolveRuntimeWorkerUrl } from "./runtime-worker-url.js";
|
||||
import { resolveRuntimeWorkerUrl } from "./runtime-worker-url.js";
|
||||
|
||||
describe("Gateway state ownership", () => {
|
||||
it.skipIf(process.platform === "win32").each(["state", "explicit"] as const)(
|
||||
|
|
@ -492,8 +492,8 @@ describe("Gateway state ownership", () => {
|
|||
);
|
||||
const stateUrl = resolveRuntimeWorkerUrl(stateNativeProcessEntrypoints.stateDatabase);
|
||||
const child = await runNodeScript(
|
||||
[
|
||||
...resolveRuntimeWorkerArgv(stateUrl).slice(0, -1),
|
||||
(workerArgv) => [
|
||||
...workerArgv(stateUrl).slice(0, -1),
|
||||
"--input-type=module",
|
||||
"--eval",
|
||||
`import { runOpenClawStateWriteTransaction, closeOpenClawStateDatabaseForTest } from ${JSON.stringify(stateUrl.href)};
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
import { afterEach, expect, it } from "vitest";
|
||||
import { createFixtureLifetime } from "../../test/helpers/fixture-lifetime.js";
|
||||
import { runNodeScript } from "../../test/helpers/run-node-script.js";
|
||||
import { resolveTestNodeExecPath } from "../test-utils/node-process.js";
|
||||
import { resolveRuntimeWorkerArgv, resolveRuntimeWorkerUrl } from "./runtime-worker-url.js";
|
||||
import { resolveRuntimeWorkerUrl } from "./runtime-worker-url.js";
|
||||
import { sqliteReadOnlyCompileCacheParentEntrypoint } from "./sqlite-readonly-worker.compile-cache-runtime.test-support.js";
|
||||
|
||||
const fixture = createFixtureLifetime();
|
||||
|
|
@ -22,11 +21,8 @@ it.for(["sync", "async", "scoped"] as const)(
|
|||
delete env.NODE_OPTIONS;
|
||||
const result = await fixture.track(
|
||||
runNodeScript(
|
||||
[
|
||||
...resolveRuntimeWorkerArgv(
|
||||
resolveRuntimeWorkerUrl(sqliteReadOnlyCompileCacheParentEntrypoint),
|
||||
resolveTestNodeExecPath(),
|
||||
),
|
||||
(workerArgv) => [
|
||||
...workerArgv(resolveRuntimeWorkerUrl(sqliteReadOnlyCompileCacheParentEntrypoint)),
|
||||
root,
|
||||
mode,
|
||||
],
|
||||
|
|
|
|||
|
|
@ -3,8 +3,7 @@ import path from "node:path";
|
|||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import { runNodeScript } from "../../test/helpers/run-node-script.js";
|
||||
import { useAutoCleanupTempDirTracker } from "../../test/helpers/temp-dir.js";
|
||||
import { resolveTestNodeExecPath } from "../test-utils/node-process.js";
|
||||
import { resolveRuntimeWorkerArgv, resolveRuntimeWorkerUrl } from "./runtime-worker-url.js";
|
||||
import { resolveRuntimeWorkerUrl } from "./runtime-worker-url.js";
|
||||
import { sqliteWorkerStoreCompileCacheParentEntrypoint } from "./sqlite-worker-store.compile-cache-runtime.test-support.js";
|
||||
|
||||
const tempDirs = useAutoCleanupTempDirTracker(afterEach);
|
||||
|
|
@ -58,11 +57,8 @@ describe("SQLite store worker compile cache", () => {
|
|||
delete env.NODE_DISABLE_COMPILE_CACHE;
|
||||
delete env.NODE_OPTIONS;
|
||||
const result = await runNodeScript(
|
||||
[
|
||||
...resolveRuntimeWorkerArgv(
|
||||
resolveRuntimeWorkerUrl(sqliteWorkerStoreCompileCacheParentEntrypoint),
|
||||
resolveTestNodeExecPath(),
|
||||
),
|
||||
(workerArgv) => [
|
||||
...workerArgv(resolveRuntimeWorkerUrl(sqliteWorkerStoreCompileCacheParentEntrypoint)),
|
||||
root,
|
||||
testCase.owner,
|
||||
testCase.cache ?? "unset",
|
||||
|
|
|
|||
|
|
@ -57,8 +57,9 @@ export function scopeWrapperSource(helperExitPath: string): string {
|
|||
return `#!${process.execPath}
|
||||
const fs = require("node:fs");
|
||||
const { spawn } = require("node:child_process");
|
||||
const [command, scriptPath, paramsPath] = process.argv.slice(-3);
|
||||
const helper = spawn(command, [scriptPath, paramsPath], { stdio: ["pipe", "pipe", "ignore"] });
|
||||
const args = process.argv.slice(2);
|
||||
const [command, ...helperArgs] = args.slice(args.findIndex((arg) => !arg.startsWith("-")));
|
||||
const helper = spawn(command, helperArgs, { stdio: ["pipe", "pipe", "ignore"] });
|
||||
let helperAlive = true;
|
||||
helper.stdin.on("error", () => {});
|
||||
helper.stdout.pipe(process.stdout, { end: false });
|
||||
|
|
|
|||
|
|
@ -2,8 +2,7 @@ import type { Profiler } from "node:inspector";
|
|||
import { fileURLToPath } from "node:url";
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { runNodeScript } from "../../test/helpers/run-node-script.js";
|
||||
import { resolveRuntimeWorkerArgv, resolveRuntimeWorkerUrl } from "../infra/runtime-worker-url.js";
|
||||
import { resolveTestNodeExecPath } from "../test-utils/node-process.js";
|
||||
import { resolveRuntimeWorkerUrl } from "../infra/runtime-worker-url.js";
|
||||
import { diagnosticProfileEntrypoints } from "./diagnostic-profile-runtime.test-support.js";
|
||||
|
||||
const native = vi.hoisted(() => ({
|
||||
|
|
@ -518,8 +517,8 @@ assert.equal(process.pid, pid);
|
|||
console.log(JSON.stringify({ node: process.version, platform: process.platform, arch: process.arch, actualDurationMs: result.actualDurationMs, samples: result.profile.samples.length, nodes: result.profile.nodes.length, listener: false }));
|
||||
`;
|
||||
const result = await runNodeScript(
|
||||
[
|
||||
...resolveRuntimeWorkerArgv(ownerUrl, resolveTestNodeExecPath()).slice(0, -1),
|
||||
(workerArgv) => [
|
||||
...workerArgv(ownerUrl).slice(0, -1),
|
||||
"--input-type=module",
|
||||
"--eval",
|
||||
source,
|
||||
|
|
|
|||
|
|
@ -3,8 +3,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|||
import type { DiagnosticsHeapProfileParams } from "../../packages/gateway-protocol/src/schema/diagnostics.js";
|
||||
import { createDeferred } from "../../test/helpers/promise.js";
|
||||
import { runNodeScript } from "../../test/helpers/run-node-script.js";
|
||||
import { resolveRuntimeWorkerArgv, resolveRuntimeWorkerUrl } from "../infra/runtime-worker-url.js";
|
||||
import { resolveTestNodeExecPath } from "../test-utils/node-process.js";
|
||||
import { resolveRuntimeWorkerUrl } from "../infra/runtime-worker-url.js";
|
||||
import { diagnosticProfileEntrypoints } from "./diagnostic-profile-runtime.test-support.js";
|
||||
|
||||
const hostBunVersion = Object.getOwnPropertyDescriptor(process.versions, "bun");
|
||||
|
|
@ -378,8 +377,8 @@ for (const includeCollected of [false, true]) {
|
|||
assert.equal(url(), undefined);
|
||||
`;
|
||||
const result = await runNodeScript(
|
||||
[
|
||||
...resolveRuntimeWorkerArgv(ownerUrl, resolveTestNodeExecPath()).slice(0, -1),
|
||||
(workerArgv) => [
|
||||
...workerArgv(ownerUrl).slice(0, -1),
|
||||
"--expose-gc",
|
||||
"--input-type=module",
|
||||
"--eval",
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ import {
|
|||
completeAgentDeletionJournalInDatabase,
|
||||
} from "../state/agent-deletion-journal.js";
|
||||
import {
|
||||
closeOpenClawAgentDatabasesForTest,
|
||||
closeOpenClawAgentDatabasesAsync,
|
||||
openOpenClawAgentDatabase,
|
||||
} from "../state/openclaw-agent-db.js";
|
||||
import { SQLITE_SESSION_WRITER_QUEUES } from "../state/openclaw-agent-write-admission.js";
|
||||
|
|
@ -62,7 +62,7 @@ describe("plugin host cleanup session stores", () => {
|
|||
},
|
||||
);
|
||||
}
|
||||
closeOpenClawAgentDatabasesForTest();
|
||||
await closeOpenClawAgentDatabasesAsync();
|
||||
const retainedDatabase = path.join(
|
||||
fixtureStateDir,
|
||||
"agents",
|
||||
|
|
@ -224,7 +224,7 @@ describe("plugin host cleanup session stores", () => {
|
|||
},
|
||||
);
|
||||
}
|
||||
closeOpenClawAgentDatabasesForTest();
|
||||
await closeOpenClawAgentDatabasesAsync();
|
||||
const retiredBefore = loadSessionEntry({
|
||||
agentId: "retired",
|
||||
storePath: sharedStore,
|
||||
|
|
@ -288,7 +288,7 @@ describe("plugin host cleanup session stores", () => {
|
|||
pluginExtensions: { fixture: { active: true } },
|
||||
},
|
||||
);
|
||||
closeOpenClawAgentDatabasesForTest();
|
||||
await closeOpenClawAgentDatabasesAsync();
|
||||
const databasePath = path.join(
|
||||
fixtureStateDir,
|
||||
"agents",
|
||||
|
|
@ -532,7 +532,7 @@ describe("plugin host cleanup session stores", () => {
|
|||
});
|
||||
|
||||
expect(result).toEqual({ cleanupCount: 1, failures: [] });
|
||||
closeOpenClawAgentDatabasesForTest();
|
||||
await closeOpenClawAgentDatabasesAsync();
|
||||
const target = loadSessionEntry({ sessionKey: targetKey, storePath });
|
||||
expect(target?.pluginExtensions).toEqual({ other: { state: { preserved: true } } });
|
||||
expect(target?.pluginNextTurnInjections).toBeUndefined();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import assert from "node:assert/strict";
|
||||
import { expect, it, vi } from "vitest";
|
||||
import { afterEach, beforeEach, expect, it, vi } from "vitest";
|
||||
import type { OpenClawConfig } from "../config/types.openclaw.js";
|
||||
import { createDeferredCore } from "../shared/deferred.js";
|
||||
import { createOpenClawTestState } from "../test-utils/openclaw-test-state.js";
|
||||
|
|
@ -15,12 +15,30 @@ import { createTestPluginRegistry } from "./registry-runtime.test-helpers.js";
|
|||
import { disposePluginRegistryInstances } from "./runtime.js";
|
||||
import { getPluginRuntimeGatewayRequestScope } from "./runtime/gateway-request-scope.js";
|
||||
|
||||
const cleanupClock = vi.hoisted(() => ({ setTimeout: globalThis.setTimeout }));
|
||||
|
||||
beforeEach(() => {
|
||||
const nativeSetTimeout = globalThis.setTimeout;
|
||||
vi.useFakeTimers({ toFake: ["setTimeout", "clearTimeout"], shouldClearNativeTimers: true });
|
||||
cleanupClock.setTimeout = globalThis.setTimeout;
|
||||
globalThis.setTimeout = nativeSetTimeout;
|
||||
});
|
||||
afterEach(() => vi.useRealTimers());
|
||||
|
||||
vi.mock("./host-hook-cleanup-timeout.js", async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof import("./host-hook-cleanup-timeout.js")>();
|
||||
return {
|
||||
...actual,
|
||||
withPluginHostCleanupTimeout: <T>(hookId: string, cleanup: () => T | Promise<T>) =>
|
||||
actual.withPluginHostCleanupTimeout(hookId, cleanup, 500),
|
||||
withPluginHostCleanupTimeout: <T>(hookId: string, cleanup: () => T | Promise<T>) => {
|
||||
const nativeSetTimeout = globalThis.setTimeout;
|
||||
// Only the cleanup deadline is virtual; asynchronous workers and watchers keep real timers.
|
||||
globalThis.setTimeout = cleanupClock.setTimeout;
|
||||
try {
|
||||
return actual.withPluginHostCleanupTimeout(hookId, cleanup, 500);
|
||||
} finally {
|
||||
globalThis.setTimeout = nativeSetTimeout;
|
||||
}
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
|
|
@ -144,6 +162,7 @@ it.each([
|
|||
const entered = createDeferredCore();
|
||||
const releaseCreate = createDeferredCore();
|
||||
const releaseClose = createDeferredCore();
|
||||
const closeEntered = createDeferredCore();
|
||||
const probeEntered = createDeferredCore();
|
||||
const releaseProbe = createDeferredCore();
|
||||
let rejectClose = mode === "failed-close";
|
||||
|
|
@ -173,6 +192,7 @@ it.each([
|
|||
};
|
||||
});
|
||||
const close = vi.fn(async () => {
|
||||
closeEntered.resolve();
|
||||
expect(getPluginRuntimeGatewayRequestScope()?.pluginId).toBe(targetId);
|
||||
if (rejectClose) {
|
||||
throw new Error("synthetic provider cleanup refused");
|
||||
|
|
@ -366,7 +386,10 @@ it.each([
|
|||
activatePluginRegistry(next, null, "gateway-bindable", undefined, owner.registry);
|
||||
reload.commit();
|
||||
} else if (mode === "timeout") {
|
||||
await expect(drain).rejects.toThrow("plugin host cleanup timed out");
|
||||
const expired = expect(drain).rejects.toThrow("plugin host cleanup timed out");
|
||||
await closeEntered.promise;
|
||||
await vi.advanceTimersByTimeAsync(500);
|
||||
await expired;
|
||||
activatePluginRegistry(next, null, "gateway-bindable", undefined, owner.registry);
|
||||
reload.commit();
|
||||
const fresh = await owner.runtime.getMemorySearchManager({ cfg: config, agentId: "main" });
|
||||
|
|
@ -383,7 +406,9 @@ it.each([
|
|||
await finalClose;
|
||||
expect(close).toHaveBeenCalledOnce();
|
||||
} else if (mode === "late-probe") {
|
||||
await expect(drain).rejects.toThrow("plugin host cleanup timed out");
|
||||
const expired = expect(drain).rejects.toThrow("plugin host cleanup timed out");
|
||||
await vi.advanceTimersByTimeAsync(500);
|
||||
await expired;
|
||||
activatePluginRegistry(next, null, "gateway-bindable", undefined, owner.registry);
|
||||
reload.commit();
|
||||
const fresh = await owner.runtime.getMemorySearchManager({ cfg: config, agentId: "main" });
|
||||
|
|
|
|||
|
|
@ -1,20 +1,16 @@
|
|||
import { fileURLToPath } from "node:url";
|
||||
import { expect, it } from "vitest";
|
||||
import { runNodeScript } from "../../test/helpers/run-node-script.js";
|
||||
import { resolveRuntimeWorkerArgv, resolveRuntimeWorkerUrl } from "../infra/runtime-worker-url.js";
|
||||
import { resolveTestNodeExecPath } from "../test-utils/node-process.js";
|
||||
import { resolveRuntimeWorkerUrl } from "../infra/runtime-worker-url.js";
|
||||
import { execOutputRetentionEntrypoint } from "./retention-runtime.test-support.js";
|
||||
|
||||
it("releases discarded backing buffers while capped commands are still running", async ({
|
||||
signal,
|
||||
}) => {
|
||||
const result = await runNodeScript(
|
||||
[
|
||||
(workerArgv) => [
|
||||
"--expose-gc",
|
||||
...resolveRuntimeWorkerArgv(
|
||||
resolveRuntimeWorkerUrl(execOutputRetentionEntrypoint),
|
||||
resolveTestNodeExecPath(),
|
||||
),
|
||||
...workerArgv(resolveRuntimeWorkerUrl(execOutputRetentionEntrypoint)),
|
||||
],
|
||||
{ ...process.env, NODE_OPTIONS: "", TSX_DISABLE_CACHE: "1" },
|
||||
15_000,
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@ import {
|
|||
readClawPackageRefs,
|
||||
} from "../claws/provenance.js";
|
||||
import type { ClawAddPlan } from "../claws/types.js";
|
||||
import { resolveRuntimeWorkerArgv, resolveRuntimeWorkerUrl } from "../infra/runtime-worker-url.js";
|
||||
import { createNodeEvalArgs, resolveTestNodeExecPath } from "../test-utils/node-process.js";
|
||||
import { resolveRuntimeWorkerUrl } from "../infra/runtime-worker-url.js";
|
||||
import { createNodeEvalArgs } from "../test-utils/node-process.js";
|
||||
import { markClawPackageIndependentlyOwned } from "./claw-package-adoption.js";
|
||||
import { acquireClawPackageLifecycleLease } from "./claw-package-lifecycle-lease.js";
|
||||
import { stateNativeProcessEntrypoints } from "./native-process-runtime.test-support.js";
|
||||
|
|
@ -286,8 +286,8 @@ describe("Claw package independent adoption", () => {
|
|||
stateNativeProcessEntrypoints.clawPackageLifecycleLease,
|
||||
);
|
||||
const result = await runNodeScript(
|
||||
[
|
||||
...resolveRuntimeWorkerArgv(moduleUrl, resolveTestNodeExecPath()).slice(0, -1),
|
||||
(workerArgv) => [
|
||||
...workerArgv(moduleUrl).slice(0, -1),
|
||||
...createNodeEvalArgs(
|
||||
`
|
||||
import { withClawPackageLifecycleLease } from ${JSON.stringify(moduleUrl.href)};
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { afterEach, describe, expect, it, vi } from "vitest";
|
|||
import { runNodeScript } from "../../test/helpers/run-node-script.js";
|
||||
import { useAutoCleanupTempDirTracker } from "../../test/helpers/temp-dir.js";
|
||||
import { requireNodeSqlite } from "../infra/node-sqlite.js";
|
||||
import { resolveRuntimeWorkerArgv, resolveRuntimeWorkerUrl } from "../infra/runtime-worker-url.js";
|
||||
import { resolveRuntimeWorkerUrl } from "../infra/runtime-worker-url.js";
|
||||
import { readStableSqliteFileGeneration } from "../infra/sqlite-file-generation.js";
|
||||
import { readMainDatabasePosixLocks } from "../infra/sqlite-posix-locks.test-support.js";
|
||||
import { readSqliteNumberPragma } from "../infra/sqlite-pragma.test-support.js";
|
||||
|
|
@ -234,7 +234,7 @@ describe("OpenClaw database integrity verifier", () => {
|
|||
|
||||
it("relays a late restart-receipt Worker open to the parent verifier after native opening settles", async () => {
|
||||
const result = await runNodeScript(
|
||||
resolveRuntimeWorkerArgv(resolveRuntimeWorkerUrl(databaseVerifyHostRuntimeEntrypoint)),
|
||||
(workerArgv) => workerArgv(resolveRuntimeWorkerUrl(databaseVerifyHostRuntimeEntrypoint)),
|
||||
process.env,
|
||||
30_000,
|
||||
{ requireProcessTreeExit: true },
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import { spawnSync } from "node:child_process";
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
|
|
@ -7,14 +6,14 @@ import {
|
|||
TRANSCRIPTS_LEGACY_RESULT_MAX_BYTES,
|
||||
TRANSCRIPTS_RESULT_MAX_BYTES,
|
||||
} from "../../packages/gateway-protocol/src/schema/transcripts.js";
|
||||
import { runNodeScript } from "../../test/helpers/run-node-script.js";
|
||||
import { useAutoCleanupTempDirTracker } from "../../test/helpers/temp-dir.js";
|
||||
import { executeSqliteQuerySync } from "../infra/kysely-sync.js";
|
||||
import { resolveRuntimeWorkerArgv, resolveRuntimeWorkerUrl } from "../infra/runtime-worker-url.js";
|
||||
import { resolveRuntimeWorkerUrl } from "../infra/runtime-worker-url.js";
|
||||
import {
|
||||
closeOpenClawStateDatabaseAsync,
|
||||
closeOpenClawStateDatabaseForTest,
|
||||
} from "../state/openclaw-state-db.js";
|
||||
import { resolveTestNodeExecPath } from "../test-utils/node-process.js";
|
||||
import { activeSessions } from "./capture-startup.js";
|
||||
import { transcriptLibraryTimezoneEntrypoint } from "./library-timezone-runtime.test-support.js";
|
||||
import { exportTranscriptLibrary, getTranscriptLibrary, listTranscriptLibrary } from "./library.js";
|
||||
|
|
@ -146,24 +145,21 @@ describe("transcript library SQLite reads", () => {
|
|||
it(
|
||||
"uses the process timezone for unzoned stored dates and range bounds",
|
||||
{ timeout: 45_000 },
|
||||
() => {
|
||||
async ({ signal }) => {
|
||||
const stateDir = tempDirs.make("transcript-library-timezone-");
|
||||
const child = spawnSync(
|
||||
resolveTestNodeExecPath(),
|
||||
[
|
||||
...resolveRuntimeWorkerArgv(resolveRuntimeWorkerUrl(transcriptLibraryTimezoneEntrypoint)),
|
||||
const child = await runNodeScript(
|
||||
(workerArgv) => [
|
||||
...workerArgv(resolveRuntimeWorkerUrl(transcriptLibraryTimezoneEntrypoint)),
|
||||
stateDir,
|
||||
],
|
||||
{
|
||||
encoding: "utf8",
|
||||
timeout: 30_000,
|
||||
env: {
|
||||
...process.env,
|
||||
TZ: "America/Los_Angeles",
|
||||
OPENCLAW_STATE_DIR: stateDir,
|
||||
OPENCLAW_CONFIG_PATH: path.join(stateDir, "openclaw.json"),
|
||||
},
|
||||
...process.env,
|
||||
TZ: "America/Los_Angeles",
|
||||
OPENCLAW_STATE_DIR: stateDir,
|
||||
OPENCLAW_CONFIG_PATH: path.join(stateDir, "openclaw.json"),
|
||||
},
|
||||
30_000,
|
||||
{ signal, maxBuffer: 1024 * 1024, requireProcessTreeExit: process.platform !== "win32" },
|
||||
);
|
||||
expect(child.error, child.stderr).toBeUndefined();
|
||||
expect(child.status, child.stderr).toBe(0);
|
||||
|
|
|
|||
|
|
@ -4,8 +4,7 @@ import { fileURLToPath } from "node:url";
|
|||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import { runNodeScript } from "../../test/helpers/run-node-script.js";
|
||||
import { useAutoCleanupTempDirTracker } from "../../test/helpers/temp-dir.js";
|
||||
import { resolveRuntimeWorkerArgv, resolveRuntimeWorkerUrl } from "../infra/runtime-worker-url.js";
|
||||
import { resolveTestNodeExecPath } from "../test-utils/node-process.js";
|
||||
import { resolveRuntimeWorkerUrl } from "../infra/runtime-worker-url.js";
|
||||
import { workerImportRuntimeEntrypoints } from "./worker-import-runtime.test-support.js";
|
||||
|
||||
const tempDirs = useAutoCleanupTempDirTracker(afterEach);
|
||||
|
|
@ -23,9 +22,9 @@ describe("worker runtime imports during admission", () => {
|
|||
const workspace = path.join(root, "workspace");
|
||||
await mkdir(workspace);
|
||||
const result = await runNodeScript(
|
||||
[
|
||||
(workerArgv) => [
|
||||
"--unhandled-rejections=strict",
|
||||
...resolveRuntimeWorkerArgv(runtimeUrl, resolveTestNodeExecPath()).slice(0, -1),
|
||||
...workerArgv(runtimeUrl).slice(0, -1),
|
||||
fileURLToPath(new URL("./worker.runtime-imports.test-support.mjs", import.meta.url)),
|
||||
mode,
|
||||
workspace,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import { existsSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
||||
import { join } from "node:path";
|
||||
import { setTimeout as delay } from "node:timers/promises";
|
||||
import { pathToFileURL } from "node:url";
|
||||
import { afterEach, expect, it, vi } from "vitest";
|
||||
import { createVitestResourceOwner } from "../../scripts/lib/vitest-resource-ownership.mts";
|
||||
import { createFixtureLifetime } from "./fixture-lifetime.js";
|
||||
|
|
@ -64,6 +65,32 @@ child.once("message", () => process.exit(17));
|
|||
});
|
||||
});
|
||||
|
||||
it.for(["node", "current"] as const)(
|
||||
"builds source worker arguments for the selected %s runtime",
|
||||
async (runtime) => {
|
||||
const script = join(tempDirs.make("openclaw-node-script-runtime-"), "worker.ts");
|
||||
writeFileSync(
|
||||
script,
|
||||
`enum Answer { value = 42 }
|
||||
console.log(JSON.stringify({ answer: Answer.value, bun: Boolean(process.versions.bun), args: process.argv.slice(2) }));
|
||||
`,
|
||||
);
|
||||
const result = await runNodeScript(
|
||||
(workerArgv) => [...workerArgv(pathToFileURL(script)), "worker-argument"],
|
||||
process.env,
|
||||
5_000,
|
||||
{ executable: runtime === "current" ? process.execPath : undefined },
|
||||
);
|
||||
expect(result.error, result.stderr).toBeUndefined();
|
||||
expect(result.status, result.stderr).toBe(0);
|
||||
expect(JSON.parse(result.stdout)).toEqual({
|
||||
answer: 42,
|
||||
bun: runtime === "current" && Boolean(process.versions.bun),
|
||||
args: ["worker-argument"],
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
it.for(["at limit", "stdout overflow", "stderr overflow"])(
|
||||
"preserves independent 2 MiB output failure boundaries: %s",
|
||||
async (mode) => {
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
import type { ChildProcess } from "node:child_process";
|
||||
import { runManagedCommand } from "../../scripts/lib/managed-child-process.mts";
|
||||
import { resolveRuntimeWorkerArgv } from "../../src/infra/runtime-worker-url.js";
|
||||
import { resolveTestNodeExecPath } from "../../src/test-utils/node-process.js";
|
||||
import { createBoundedChildOutput } from "./bounded-child-output.js";
|
||||
|
||||
/** Worker argv is resolved against the executable selected for this child. */
|
||||
export async function runNodeScript(
|
||||
scriptPathOrArgs: string | string[],
|
||||
scriptPathOrArgs: string | string[] | ((workerArgv: (url: URL) => string[]) => string[]),
|
||||
env: NodeJS.ProcessEnv,
|
||||
timeoutMs: number | undefined,
|
||||
{
|
||||
|
|
@ -31,9 +33,16 @@ export async function runNodeScript(
|
|||
let status: number | null = null;
|
||||
let error: unknown;
|
||||
try {
|
||||
const execPath = executable ?? resolveTestNodeExecPath();
|
||||
const args =
|
||||
typeof scriptPathOrArgs === "function"
|
||||
? scriptPathOrArgs((url) => resolveRuntimeWorkerArgv(url, execPath))
|
||||
: typeof scriptPathOrArgs === "string"
|
||||
? [scriptPathOrArgs]
|
||||
: scriptPathOrArgs;
|
||||
status = await runManagedCommand({
|
||||
bin: executable ?? resolveTestNodeExecPath(),
|
||||
args: typeof scriptPathOrArgs === "string" ? [scriptPathOrArgs] : scriptPathOrArgs,
|
||||
bin: execPath,
|
||||
args,
|
||||
cwd,
|
||||
env,
|
||||
timeoutMs,
|
||||
|
|
|
|||
|
|
@ -3,11 +3,7 @@ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|||
import path from "node:path";
|
||||
import { afterEach, expect, it } from "vitest";
|
||||
import { scriptProcessEntrypoints } from "../../scripts/script-process-runtime.test-support.js";
|
||||
import {
|
||||
resolveRuntimeWorkerArgv,
|
||||
resolveRuntimeWorkerUrl,
|
||||
} from "../../src/infra/runtime-worker-url.js";
|
||||
import { resolveTestNodeExecPath } from "../../src/test-utils/node-process.js";
|
||||
import { resolveRuntimeWorkerUrl } from "../../src/infra/runtime-worker-url.js";
|
||||
import { createFixtureLifetime } from "../helpers/fixture-lifetime.js";
|
||||
import { createDeferred } from "../helpers/promise.js";
|
||||
import { runNodeScript } from "../helpers/run-node-script.js";
|
||||
|
|
@ -40,15 +36,17 @@ it.skipIf(process.platform === "win32").for(cases)(
|
|||
const ready = createDeferred();
|
||||
const receivedSignal = createDeferred();
|
||||
let child: ChildProcess | undefined;
|
||||
const scriptArgs = resolveRuntimeWorkerArgv(scriptUrl, resolveTestNodeExecPath());
|
||||
const command = fixtures.track(
|
||||
runNodeScript(
|
||||
[
|
||||
...scriptArgs.slice(0, -1),
|
||||
"--import",
|
||||
new URL("./fixtures/agent-plugin-gateway-cancellation.mjs", import.meta.url).href,
|
||||
...scriptArgs.slice(-1),
|
||||
],
|
||||
(workerArgv) => {
|
||||
const scriptArgs = workerArgv(scriptUrl);
|
||||
return [
|
||||
...scriptArgs.slice(0, -1),
|
||||
"--import",
|
||||
new URL("./fixtures/agent-plugin-gateway-cancellation.mjs", import.meta.url).href,
|
||||
...scriptArgs.slice(-1),
|
||||
];
|
||||
},
|
||||
{
|
||||
PATH: process.env.PATH,
|
||||
HOME: home,
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import {
|
|||
PACKAGE_LIFECYCLE_PENDING_RELATIVE_PATH,
|
||||
} from "../../scripts/lib/package-lifecycle-marker.mjs";
|
||||
import { WORKSPACE_TEMPLATE_PACK_PATHS } from "../../scripts/lib/workspace-bootstrap-smoke.mts";
|
||||
import { resolveTestNodeExecPath } from "../../src/test-utils/node-process.js";
|
||||
import { useAutoCleanupTempDirTracker } from "../helpers/temp-dir.js";
|
||||
import {
|
||||
CODE_MODE_WORKER_PATH,
|
||||
|
|
@ -220,7 +221,7 @@ childProcess.spawnSync = function (...callArgs) {
|
|||
syncBuiltinESMExports();
|
||||
`,
|
||||
);
|
||||
const result = spawnSync(process.execPath, [resolve(CHECK_SCRIPT), tarball], {
|
||||
const result = spawnSync(resolveTestNodeExecPath(), [resolve(CHECK_SCRIPT), tarball], {
|
||||
encoding: "utf8",
|
||||
env: {
|
||||
...process.env,
|
||||
|
|
|
|||
|
|
@ -1,10 +1,6 @@
|
|||
import { afterEach, expect, it } from "vitest";
|
||||
import { scriptModuleEntrypoints } from "../../scripts/script-module-runtime.test-support.mjs";
|
||||
import {
|
||||
resolveRuntimeWorkerArgv,
|
||||
resolveRuntimeWorkerUrl,
|
||||
} from "../../src/infra/runtime-worker-url.js";
|
||||
import { resolveTestNodeExecPath } from "../../src/test-utils/node-process.js";
|
||||
import { resolveRuntimeWorkerUrl } from "../../src/infra/runtime-worker-url.js";
|
||||
import { runNodeScript } from "../helpers/run-node-script.js";
|
||||
import { useAutoCleanupTempDirTracker } from "../helpers/temp-dir.js";
|
||||
|
||||
|
|
@ -15,11 +11,8 @@ it("loads installed tooling when the prepared CLI validates native Vitest option
|
|||
}) => {
|
||||
const directory = tempDirs.make("openclaw-compiled-tooling-");
|
||||
const result = await runNodeScript(
|
||||
[
|
||||
...resolveRuntimeWorkerArgv(
|
||||
resolveRuntimeWorkerUrl(scriptModuleEntrypoints.testProjects),
|
||||
resolveTestNodeExecPath(),
|
||||
),
|
||||
(workerArgv) => [
|
||||
...workerArgv(resolveRuntimeWorkerUrl(scriptModuleEntrypoints.testProjects)),
|
||||
"test/scripts/test-projects.test.ts",
|
||||
"--",
|
||||
"--invalid-native-vitest-option",
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ function createWorkerArtifactFixtures(
|
|||
return joined;
|
||||
}
|
||||
|
||||
function node(args: string[], cwd = root, env = process.env) {
|
||||
function node(args: Parameters<typeof runNodeScript>[0], cwd = root, env = process.env) {
|
||||
const completion = fixtureLifetime.track(
|
||||
runNodeScript(args, compilerEnv(env, "node"), undefined, {
|
||||
cwd,
|
||||
|
|
@ -401,7 +401,9 @@ export function workerProbe(
|
|||
const sourceLoader = sourceMode && !process.versions.bun;
|
||||
expect(args.includes('--import')).toBe(sourceLoader);
|
||||
if (sourceLoader) expect(args[1].startsWith('file:')).toBe(true);
|
||||
expect(args[sourceLoader ? 2 : 0]).toMatch(sourceMode ? /\\.ts$/ : /\\.js$/);
|
||||
const runtimeArgs = sourceLoader ? ['--import', expect.stringMatching(/^file:/)] : process.versions.bun ? ['--no-install'] : [];
|
||||
expect(args.slice(0, runtimeArgs.length + 1)).toEqual([...runtimeArgs, fileURLToPath(generation)]);
|
||||
expect(args[runtimeArgs.length]).toMatch(sourceMode ? /\\.ts$/ : /\\.js$/);
|
||||
fs.appendFileSync(${JSON.stringify(path.join(directory, "observations.jsonl"))}, JSON.stringify({args, tuiUrls, setupUrls, retentionUrl, value, configValue:inject('configValue'), knn:resolveRuntimeWorkerUrl(vectorKnnProcessEntrypoint).href})+'\\n');
|
||||
fs.appendFileSync(${JSON.stringify(path.join(directory, "generations.jsonl"))}, JSON.stringify(generation)+'\\n');
|
||||
${receiptEndpoint ? `sendReceipt(${JSON.stringify(path.join(directory, "generations.jsonl"))}, 'written');` : ""}
|
||||
|
|
|
|||
|
|
@ -15,8 +15,6 @@ import {
|
|||
} from "../../scripts/lib/vitest-worker-artifacts.mts";
|
||||
import { resolveVitestSpawnParams, spawnWatchedVitestProcess } from "../../scripts/run-vitest.mts";
|
||||
import { createVitestProcessCompletion } from "../../scripts/vitest-process-group.mts";
|
||||
import { resolveRuntimeWorkerArgv } from "../../src/infra/runtime-worker-url.js";
|
||||
import { resolveTestNodeExecPath } from "../../src/test-utils/node-process.js";
|
||||
import {
|
||||
fixtureReceiptClientSource,
|
||||
openFixtureReceiptChannel,
|
||||
|
|
@ -751,8 +749,8 @@ describe.concurrent("fresh compiled subprocess invocation", () => {
|
|||
: path.join(root, "src/agents/embedded-agent-runner/run/payloads.ts"),
|
||||
);
|
||||
const result = await node(
|
||||
[
|
||||
...resolveRuntimeWorkerArgv(pathToFileURL(probe), resolveTestNodeExecPath()),
|
||||
(workerArgv) => [
|
||||
...workerArgv(pathToFileURL(probe)),
|
||||
url.href,
|
||||
pathToFileURL(
|
||||
owner
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue