mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-28 00:52:57 +00:00
fix(test): avoid source gateway import in rpc walk
This commit is contained in:
@@ -227,36 +227,33 @@ function unwrapRpcPayload(raw) {
|
||||
}
|
||||
|
||||
async function rpcCall(method, params, options) {
|
||||
const { callGateway } = await loadCallGatewayModule(options.runner);
|
||||
const payload = await callGateway({
|
||||
config: readJson(options.env.OPENCLAW_CONFIG_PATH),
|
||||
configPath: options.env.OPENCLAW_CONFIG_PATH,
|
||||
url: `ws://127.0.0.1:${options.port}`,
|
||||
token: TOKEN,
|
||||
method,
|
||||
params: params ?? {},
|
||||
timeoutMs: RPC_TIMEOUT_MS,
|
||||
requiredMethods: [method],
|
||||
});
|
||||
const module = await loadCallGatewayModule(options.runner);
|
||||
const payload = module
|
||||
? await module.callGateway({
|
||||
config: readJson(options.env.OPENCLAW_CONFIG_PATH),
|
||||
configPath: options.env.OPENCLAW_CONFIG_PATH,
|
||||
url: `ws://127.0.0.1:${options.port}`,
|
||||
token: TOKEN,
|
||||
method,
|
||||
params: params ?? {},
|
||||
timeoutMs: RPC_TIMEOUT_MS,
|
||||
requiredMethods: [method],
|
||||
})
|
||||
: await rpcCallViaCli(method, params, options);
|
||||
return unwrapRpcPayload(payload);
|
||||
}
|
||||
|
||||
async function loadCallGatewayModule(runner) {
|
||||
callGatewayModulePromise ??= importCallGatewayModule(runner);
|
||||
if (!usesBuiltOpenClawEntry(runner)) {
|
||||
return null;
|
||||
}
|
||||
callGatewayModulePromise ??= importCallGatewayModule();
|
||||
return callGatewayModulePromise;
|
||||
}
|
||||
|
||||
async function importCallGatewayModule(runner) {
|
||||
if (!usesPackagedOpenClawEntry(runner)) {
|
||||
return import(pathToFileURL(path.join(process.cwd(), "src/gateway/call.ts")).href);
|
||||
}
|
||||
async function importCallGatewayModule() {
|
||||
const distDir = path.join(process.cwd(), "dist");
|
||||
const candidates = fs.existsSync(distDir)
|
||||
? fs
|
||||
.readdirSync(distDir)
|
||||
.filter((name) => /^call(?:\.runtime)?-[A-Za-z0-9_-]+\.js$/u.test(name))
|
||||
.toSorted((left, right) => left.localeCompare(right))
|
||||
: [];
|
||||
const candidates = findDistCallGatewayModuleFiles();
|
||||
for (const name of candidates) {
|
||||
const module = await import(pathToFileURL(path.join(distDir, name)).href);
|
||||
if (typeof module.callGateway === "function") {
|
||||
@@ -266,10 +263,49 @@ async function importCallGatewayModule(runner) {
|
||||
throw new Error(`unable to find callGateway export in dist (${candidates.join(", ")})`);
|
||||
}
|
||||
|
||||
function usesPackagedOpenClawEntry(runner) {
|
||||
return Boolean(
|
||||
process.env.OPENCLAW_ENTRY && runner?.baseArgs?.[0] === process.env.OPENCLAW_ENTRY,
|
||||
async function rpcCallViaCli(method, params, options) {
|
||||
const { stdout } = await runOpenClaw(
|
||||
options.runner,
|
||||
[
|
||||
"gateway",
|
||||
"call",
|
||||
method,
|
||||
"--url",
|
||||
`ws://127.0.0.1:${options.port}`,
|
||||
"--token",
|
||||
TOKEN,
|
||||
"--timeout",
|
||||
String(RPC_TIMEOUT_MS),
|
||||
"--json",
|
||||
"--params",
|
||||
JSON.stringify(params ?? {}),
|
||||
],
|
||||
options.env,
|
||||
{ timeoutMs: RPC_TIMEOUT_MS + 30000 },
|
||||
);
|
||||
return parseJsonOutput(stdout);
|
||||
}
|
||||
|
||||
export function findDistCallGatewayModuleFiles(cwd = process.cwd()) {
|
||||
const distDir = path.join(cwd, "dist");
|
||||
return fs.existsSync(distDir)
|
||||
? fs
|
||||
.readdirSync(distDir)
|
||||
.filter((name) => /^call(?:\.runtime)?-[A-Za-z0-9_-]+\.js$/u.test(name))
|
||||
.toSorted((left, right) => left.localeCompare(right))
|
||||
: [];
|
||||
}
|
||||
|
||||
export function usesBuiltOpenClawEntry(runner, cwd = process.cwd(), env = process.env) {
|
||||
if (runner?.pnpm || !runner?.baseArgs?.[0]) {
|
||||
return false;
|
||||
}
|
||||
const entry = runner.baseArgs[0];
|
||||
if (env.OPENCLAW_ENTRY && entry === env.OPENCLAW_ENTRY) {
|
||||
return true;
|
||||
}
|
||||
const relative = path.relative(path.resolve(cwd, "dist"), path.resolve(cwd, entry));
|
||||
return relative.length > 0 && !relative.startsWith("..") && !path.isAbsolute(relative);
|
||||
}
|
||||
|
||||
async function retryRpcCall(method, params, options) {
|
||||
|
||||
@@ -1,12 +1,52 @@
|
||||
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
||||
import { tmpdir } from "node:os";
|
||||
import path from "node:path";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import {
|
||||
assertResourceCeiling,
|
||||
fetchJson,
|
||||
findDistCallGatewayModuleFiles,
|
||||
sampleProcess,
|
||||
sampleWindowsProcessByPort,
|
||||
summarizeProcessSamples,
|
||||
usesBuiltOpenClawEntry,
|
||||
} from "../../scripts/e2e/kitchen-sink-rpc-walk.mjs";
|
||||
|
||||
describe("kitchen-sink RPC caller loading", () => {
|
||||
it("uses built callGateway chunks for dist and packaged entries", () => {
|
||||
expect(usesBuiltOpenClawEntry({ command: "node", baseArgs: ["dist/index.js"] })).toBe(true);
|
||||
expect(
|
||||
usesBuiltOpenClawEntry(
|
||||
{ command: "node", baseArgs: ["/app/openclaw.mjs"] },
|
||||
"/repo",
|
||||
{ OPENCLAW_ENTRY: "/app/openclaw.mjs" },
|
||||
),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it("does not deep-import gateway TypeScript for source pnpm runners", () => {
|
||||
expect(usesBuiltOpenClawEntry({ pnpm: true, baseArgs: ["openclaw"] })).toBe(false);
|
||||
expect(usesBuiltOpenClawEntry({ command: "node", baseArgs: ["scripts/dev.mjs"] })).toBe(false);
|
||||
});
|
||||
|
||||
it("finds only built callGateway chunks", () => {
|
||||
const root = mkdtempSync(path.join(tmpdir(), "openclaw-rpc-call-chunks-"));
|
||||
try {
|
||||
mkdirSync(path.join(root, "dist"));
|
||||
writeFileSync(path.join(root, "dist", "call-Abc123.js"), "");
|
||||
writeFileSync(path.join(root, "dist", "call.runtime-Def456.js"), "");
|
||||
writeFileSync(path.join(root, "dist", "index.js"), "");
|
||||
|
||||
expect(findDistCallGatewayModuleFiles(root)).toEqual([
|
||||
"call-Abc123.js",
|
||||
"call.runtime-Def456.js",
|
||||
]);
|
||||
} finally {
|
||||
rmSync(root, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("kitchen-sink RPC process sampling", () => {
|
||||
it("samples RSS on Windows instead of silently disabling the resource guard", async () => {
|
||||
const calls: Array<{ command: string; args: string[] }> = [];
|
||||
|
||||
@@ -189,8 +189,10 @@ describe("scripts/lib/plugin-prerelease-test-plan.mjs", () => {
|
||||
expect(walkScript).toContain("tts.providers");
|
||||
expect(walkScript).toContain("plugins.uiDescriptors");
|
||||
expect(walkScript).toContain("loadCallGatewayModule(options.runner)");
|
||||
expect(walkScript).toContain("usesPackagedOpenClawEntry(runner)");
|
||||
expect(walkScript).toContain("src/gateway/call.ts");
|
||||
expect(walkScript).toContain("usesBuiltOpenClawEntry(runner)");
|
||||
expect(walkScript).toContain('"gateway"');
|
||||
expect(walkScript).toContain('"call"');
|
||||
expect(walkScript).not.toContain("src/gateway/call.ts");
|
||||
expect(walkScript).toContain("^call(?:\\.runtime)?");
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user