fix(qa): avoid extension memory report collisions

This commit is contained in:
Vincent Koc
2026-06-23 12:48:12 +02:00
parent 306f0ec37f
commit a972855150
2 changed files with 56 additions and 1 deletions

View File

@@ -3,6 +3,7 @@
// Profiles peak RSS for built bundled plugin entrypoints and emits a JSON
// report suitable for extension memory budget review.
import { spawn } from "node:child_process";
import { randomUUID } from "node:crypto";
import { existsSync, mkdirSync, mkdtempSync, readdirSync, rmSync, writeFileSync } from "node:fs";
import os from "node:os";
import path from "node:path";
@@ -28,6 +29,13 @@ const parentSignalHandlers = new Map();
let parentSignalHandlersInstalled = false;
let parentSignalShutdownStarted = false;
function defaultJsonReportPath() {
return path.join(
os.tmpdir(),
`openclaw-extension-memory-${process.pid}-${Date.now()}-${randomUUID()}.json`,
);
}
function printHelp() {
console.log(`Usage: node scripts/profile-extension-memory.mjs [options]
@@ -429,7 +437,7 @@ async function main() {
const tmpHome = mkdtempSync(path.join(os.tmpdir(), "openclaw-extension-memory-"));
const hookPath = path.join(tmpHome, "measure-rss.mjs");
const jsonPath = options.jsonPath ?? path.join(os.tmpdir(), "openclaw-extension-memory.json");
const jsonPath = options.jsonPath ?? defaultJsonReportPath();
writeFileSync(
hookPath,

View File

@@ -39,6 +39,15 @@ function runProfileExtensionMemory(args: string[], cwd = process.cwd()) {
});
}
function extractReportPath(stdout: string) {
const match = stdout.match(/^\[extension-memory\] report: (.+)$/mu);
const reportPath = match?.[1];
if (!reportPath) {
throw new Error(`missing report path in stdout:\n${stdout}`);
}
return reportPath;
}
async function waitForChildExit(
child: ReturnType<typeof spawn>,
timeoutMs = 8_000,
@@ -176,6 +185,44 @@ describe("scripts/profile-extension-memory", () => {
}
});
it("uses distinct default JSON report paths for separate runs", () => {
const root = mkdtempSync(path.join(tmpdir(), "openclaw-extension-memory-test-"));
const reportPaths: string[] = [];
try {
const extensionDir = path.join(root, "dist", "extensions", "simple");
mkdirSync(extensionDir, { recursive: true });
writeFileSync(path.join(extensionDir, "index.js"), `export default {};\n`, "utf8");
for (let index = 0; index < 2; index += 1) {
const result = runProfileExtensionMemory(
["--extension", "simple", "--skip-combined", "--concurrency", "1"],
root,
);
expect(result.status, result.stderr).toBe(0);
const reportPath = extractReportPath(result.stdout);
reportPaths.push(reportPath);
expect(path.dirname(reportPath)).toBe(tmpdir());
expect(path.basename(reportPath)).toMatch(
/^openclaw-extension-memory-\d+-\d+-[0-9a-f-]+\.json$/u,
);
expect(JSON.parse(readFileSync(reportPath, "utf8")).counts).toMatchObject({
totalEntries: 1,
ok: 1,
fail: 0,
timeout: 0,
});
}
expect(reportPaths[0]).not.toBe(reportPaths[1]);
} finally {
for (const reportPath of reportPaths) {
rmSync(reportPath, { force: true });
}
rmSync(root, { recursive: true, force: true });
}
});
it("fails when a profiled plugin import fails", () => {
const root = mkdtempSync(path.join(tmpdir(), "openclaw-extension-memory-test-"));
try {