Files
lume-ctrl/test/m0-spike.test.mjs
T

89 lines
4.2 KiB
JavaScript

import assert from "node:assert/strict";
import { randomUUID } from "node:crypto";
import test from "node:test";
import {
boundedBody,
eventCollector,
exportSession,
queryRecords,
redactHeaders,
safeUrl,
shouldRetryStartup,
summarizeProcessSamples,
} from "../scripts/m0-spike.mjs";
test("export policy redacts credentials and bounds bodies", () => {
const sensitive = randomUUID();
assert.deepEqual(redactHeaders({ Cookie: sensitive, Authorization: sensitive, Referer: "https://example.test/private", "Set-Cookie": sensitive, Accept: "*/*" }), {
accept: "*/*",
authorization: "[REDACTED]",
cookie: "[REDACTED]",
referer: "[REDACTED]",
"set-cookie": "[REDACTED]",
});
assert.equal(safeUrl("https://example.test/path?token=secret"), "https://example.test/path?<redacted>");
assert.deepEqual(boundedBody(sensitive, false, 100), { state: "fetched", source: "network", encoding: "utf8", storage: "omitted", reason: "default_body_policy", bytes: Buffer.byteLength(sensitive) });
assert(!JSON.stringify(boundedBody(sensitive, false, 100)).includes(sensitive));
assert.deepEqual(boundedBody("AP8=", true, 10, "memory_cache"), { state: "fetched", source: "memory_cache", encoding: "base64", storage: "omitted", reason: "default_body_policy", bytes: 2 });
assert.deepEqual(boundedBody("hello!", false, 5), { state: "size_limit", source: "network", encoding: "utf8", storage: "omitted", reason: "size_limit", bytes: 6 });
assert(shouldRetryStartup("Render process gone."));
assert(!shouldRetryStartup("Target closed."));
assert(!shouldRetryStartup(undefined));
});
test("cache state stays unknown without a preceding request event", () => {
const collector = eventCollector("session-a", "target-a");
collector.listener("Network.responseReceived", {
requestId: "orphan-response",
response: { url: "https://example.test/favicon.ico", status: 200, protocol: "h2", mimeType: "image/x-icon", headers: {} },
});
assert.deepEqual(collector.records[0].response.cache, { state: "unknown" });
});
test("WebSocket limits aggregate drops without payloads", () => {
const collector = eventCollector("session-a", "target-a", {
maxWebSocketFrameBytes: 4,
maxWebSocketEventsPerSecond: 1,
maxWebSocketEventsPerConnection: 2,
});
const frame = (method, payloadData, timestamp, opcode = 1) => collector.listener(method, { requestId: "ws-1", timestamp, response: { opcode, payloadData } });
frame("Network.webSocketFrameSent", "okay", 1.1);
frame("Network.webSocketFrameReceived", "x", 1.2);
frame("Network.webSocketFrameReceived", "YWJjZGVm", 2.1, 2);
frame("Network.webSocketFrameSent", "ok", 2.2);
frame("Network.webSocketFrameSent", "ok", 3.1);
frame("Network.webSocketFrameSent", "ok", 4.1);
assert.equal(collector.records.filter((record) => record.kind === "websocket_frame").length, 2);
const dropped = collector.records.find((record) => record.kind === "websocket_frames_dropped");
assert.deepEqual(dropped.dropped.reasons, { rate_limit: 2, frame_size_limit: 1, event_limit: 1 });
assert.equal(dropped.dropped.count, 4);
assert(!JSON.stringify(dropped).includes("YWJjZGVm"));
});
test("query and export isolate sessions before pagination", () => {
const records = [
{ session_id: "a", target_id: "a1", value: 1 },
{ session_id: "b", target_id: "b1", value: 2 },
{ session_id: "a", target_id: "a1", value: 3 },
];
assert.deepEqual(queryRecords(records, "a", { limit: 1 }), { items: [records[0]], next_cursor: 1 });
assert.deepEqual(queryRecords(records, "a", { cursor: 1, limit: 1 }), { items: [records[2]], next_cursor: null });
assert(!exportSession(records, "a").includes('"session_id":"b"'));
});
test("resource baseline summarizes repeated samples", () => {
assert.deepEqual(summarizeProcessSamples([
{ process_count: 8, rss_kib: 700_000, cpu_percent_snapshot: 10 },
{ process_count: 9, rss_kib: 800_000, cpu_percent_snapshot: 20 },
{ process_count: 9, rss_kib: 900_000, cpu_percent_snapshot: 30 },
], 200), {
sample_count: 3,
interval_ms: 200,
process_count: { min: 8, max: 9 },
rss_kib: { min: 700_000, max: 900_000, mean: 800_000, p95: 900_000 },
cpu_percent: { min: 10, max: 30, mean: 20, p95: 30 },
});
});