mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-06 05:51:15 +08:00
fix(e2e): stream docker stats resource scans
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import fs from "node:fs";
|
||||
import { createInterface } from "node:readline";
|
||||
|
||||
const [statsFile, maxMemoryRaw, maxCpuRaw, label = "docker"] = process.argv.slice(2);
|
||||
const maxMemoryMiB = Number(maxMemoryRaw);
|
||||
@@ -55,9 +56,19 @@ function assertSampleValue(value, raw, name, labelLocal) {
|
||||
}
|
||||
}
|
||||
|
||||
const lines = fs.existsSync(statsFile)
|
||||
? fs.readFileSync(statsFile, "utf8").split(/\r?\n/u).filter(Boolean)
|
||||
: [];
|
||||
async function scanStatsFileLines(file, onLine) {
|
||||
if (!fs.existsSync(file)) {
|
||||
return;
|
||||
}
|
||||
const input = fs.createReadStream(file, { encoding: "utf8" });
|
||||
const lines = createInterface({ crlfDelay: Infinity, input });
|
||||
for await (const line of lines) {
|
||||
if (line) {
|
||||
onLine(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let maxObservedMemoryMiB = 0;
|
||||
let maxObservedCpuPercent = 0;
|
||||
let parsedSamples = 0;
|
||||
@@ -65,7 +76,7 @@ let parsedSamples = 0;
|
||||
assertFiniteLimit(maxMemoryMiB, maxMemoryRaw, "max memory MiB");
|
||||
assertFiniteLimit(maxCpuPercent, maxCpuRaw, "max CPU percent");
|
||||
|
||||
for (const line of lines) {
|
||||
await scanStatsFileLines(statsFile, (line) => {
|
||||
let parsed;
|
||||
try {
|
||||
parsed = JSON.parse(line);
|
||||
@@ -79,7 +90,7 @@ for (const line of lines) {
|
||||
parsedSamples += 1;
|
||||
maxObservedMemoryMiB = Math.max(maxObservedMemoryMiB, observedMemoryMiB);
|
||||
maxObservedCpuPercent = Math.max(maxObservedCpuPercent, observedCpuPercent);
|
||||
}
|
||||
});
|
||||
|
||||
console.log(
|
||||
`${label} resource peak: memory=${maxObservedMemoryMiB.toFixed(1)}MiB cpu=${maxObservedCpuPercent.toFixed(1)}% samples=${parsedSamples}`,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { spawnSync } from "node:child_process";
|
||||
import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
||||
import { mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
||||
import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
@@ -16,9 +16,13 @@ function writeStats(contents: string): string {
|
||||
}
|
||||
|
||||
function runAssert(statsFile: string, maxMemoryMiB = "512", maxCpuPercent = "100") {
|
||||
return spawnSync(process.execPath, [SCRIPT_PATH, statsFile, maxMemoryMiB, maxCpuPercent, "test"], {
|
||||
encoding: "utf8",
|
||||
});
|
||||
return spawnSync(
|
||||
process.execPath,
|
||||
[SCRIPT_PATH, statsFile, maxMemoryMiB, maxCpuPercent, "test"],
|
||||
{
|
||||
encoding: "utf8",
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
afterEach(() => {
|
||||
@@ -36,7 +40,10 @@ describe("scripts/e2e/lib/docker-stats/assert-resource-ceiling.mjs", () => {
|
||||
});
|
||||
|
||||
it("rejects invalid resource limits instead of disabling the ceiling", () => {
|
||||
const result = runAssert(writeStats('{"MemUsage":"128MiB / 2GiB","CPUPerc":"25.0%"}\n'), "nope");
|
||||
const result = runAssert(
|
||||
writeStats('{"MemUsage":"128MiB / 2GiB","CPUPerc":"25.0%"}\n'),
|
||||
"nope",
|
||||
);
|
||||
|
||||
expect(result.status).not.toBe(0);
|
||||
expect(result.stderr).toContain("max memory MiB must be a finite non-negative number");
|
||||
@@ -67,6 +74,14 @@ describe("scripts/e2e/lib/docker-stats/assert-resource-ceiling.mjs", () => {
|
||||
expect(result.stdout).toContain("samples=1");
|
||||
});
|
||||
|
||||
it("streams stats logs instead of slurping them into memory", () => {
|
||||
const source = readFileSync(SCRIPT_PATH, "utf8");
|
||||
|
||||
expect(source).toContain("createReadStream");
|
||||
expect(source).not.toContain("readFileSync(statsFile");
|
||||
expect(source).not.toContain("split(/\\r?\\n/u)");
|
||||
});
|
||||
|
||||
it("accepts byte-unit Docker memory samples", () => {
|
||||
const result = runAssert(writeStats('{"MemUsage":"512B / 2GiB","CPUPerc":"0.5%"}\n'));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user