Files
openclaw/test/e2e/qa-lab/runtime/logging-file-boundary-runtime.ts
Peter Steinberger dceb2c343c refactor: retire due compat-ledger surfaces (context-engine host params, deactivate alias, logging internals) (#121845)
* refactor(plugins): retire deactivate hook alias

* refactor(plugin-sdk): prune retired facade exports

* test(logging): isolate logger test controls

* refactor(logging): internalize file transport controls

* test(plugin-sdk): preserve retired facade coverage

* test(auto-reply): remove stale diagnostic imports

* refactor(logging): delete dead config-read guard

shouldSkipMutatingLoggingConfigRead had no production caller even on main;
it survived the dead-export scan only via logger's testApi re-export. The
test-isolation commit removed that mask, exposing the fossil. Delete the
guard, its test-only re-export, its mock entry, and its dedicated test file.

* refactor(plugin-sdk): retire due compatibility subpaths

* test(plugin-sdk): type group policy predicates

* refactor(plugin-sdk): split removed subpath records

* refactor(secrets): remove retired collector barrel

* test(plugin-sdk): tighten wildcard surface pin

* refactor(plugin-sdk): retire matrix facade metadata

* style(plugin-sdk): format facade metadata

* fix(ci): load channel setup contracts from source

Repair the main-owned regression from 99d662473c (Peter Steinberger): the new env-contract test could consume stale ignored dist metadata instead of the checked-in plugin declaration.

* test(plugin-sdk): refresh API baseline after rebase
2026-08-12 12:41:27 -07:00

133 lines
4.6 KiB
TypeScript

import { readFile, mkdir } from "node:fs/promises";
import path from "node:path";
import {
onInternalDiagnosticEvent,
resetDiagnosticEventsForTest,
type DiagnosticEventPayload,
} from "../../../../src/infra/diagnostic-events.js";
import {
createDiagnosticTraceContext,
runWithDiagnosticTraceContext,
} from "../../../../src/infra/diagnostic-trace-context.js";
import { getChildLogger, resetLogger, setLoggerOverride } from "../../../../src/logging/logger.js";
import { testApi } from "../../../../src/logging/logger.test-support.js";
import { createQaScriptEvidenceWriter } from "./script-evidence.js";
function artifactBase(argv: readonly string[]): string {
const index = argv.indexOf("--artifact-base");
const value = index >= 0 ? argv[index + 1] : undefined;
if (!value) {
throw new Error("--artifact-base is required");
}
return path.resolve(value);
}
function rotatedPath(file: string): string {
const ext = path.extname(file);
return `${file.slice(0, -ext.length)}.1${ext}`;
}
export async function runLoggingFileBoundary(outputRoot: string) {
await mkdir(outputRoot, { recursive: true });
const logPath = path.join(outputRoot, "openclaw.jsonl");
const trace = createDiagnosticTraceContext({
traceId: "4bf92f3577b34da6a3ce929d0e0e4736",
spanId: "00f067aa0ba902b7",
parentSpanId: "1111111111111111",
traceFlags: "01",
});
const diagnostics: Extract<DiagnosticEventPayload, { type: "log.record" }>[] = [];
resetDiagnosticEventsForTest();
resetLogger();
testApi.resetFileLogTransportForTests();
setLoggerOverride({ level: "info", file: logPath, maxFileBytes: 512 });
const unsubscribe = onInternalDiagnosticEvent((event) => {
if (event.type === "log.record") {
diagnostics.push(event);
}
});
try {
runWithDiagnosticTraceContext(trace, () => {
const logger = getChildLogger({ subsystem: "qa-file-boundary" });
logger.info(`rotation-fill-${"x".repeat(700)}`);
logger.info({ marker: "correlated" }, "qa-correlated-record");
});
await testApi.flushFileLogQueueForTests();
await new Promise<void>((resolve) => {
setImmediate(resolve);
});
const current = (await readFile(logPath, "utf8"))
.trim()
.split("\n")
.map((line) => JSON.parse(line));
const archived = (await readFile(rotatedPath(logPath), "utf8"))
.trim()
.split("\n")
.map((line) => JSON.parse(line));
const fileRecord = current.find(
(record: Record<string, unknown>) => record.message === "qa-correlated-record",
) as Record<string, unknown> | undefined;
const diagnostic = diagnostics.find((event) => event.message === "qa-correlated-record");
if (!fileRecord || !diagnostic) {
throw new Error("correlated file and diagnostic records were not both emitted");
}
const expected = {
traceId: trace.traceId,
spanId: trace.spanId,
parentSpanId: trace.parentSpanId,
traceFlags: trace.traceFlags,
};
for (const [key, value] of Object.entries(expected)) {
if (fileRecord[key] !== value || diagnostic.trace?.[key as keyof typeof expected] !== value) {
throw new Error(`trace correlation mismatch for ${key}`);
}
}
return { currentRecords: current.length, archivedRecords: archived.length, trace: expected };
} finally {
unsubscribe();
setLoggerOverride(null);
resetLogger();
testApi.resetFileLogTransportForTests();
resetDiagnosticEventsForTest();
}
}
async function main() {
const repoRoot = process.cwd();
const outputRoot = artifactBase(process.argv.slice(2));
const startedAt = Date.now();
const writer = createQaScriptEvidenceWriter({
artifactBase: outputRoot,
logFileName: "logging-file-boundary.log",
primaryModel: "none",
providerMode: "mock-openai",
repoRoot,
target: {
id: "logging-file-boundary",
sourcePath: "qa/scenarios/runtime/logging-file-boundary.yaml",
title: "Logging file boundary",
codeRefs: [
"test/e2e/qa-lab/runtime/logging-file-boundary-runtime.ts",
"src/logging/logger-file-transport.ts",
],
},
});
try {
const result = await runLoggingFileBoundary(outputRoot);
writer.appendLog(`${JSON.stringify(result)}\n`);
await writer.write({ durationMs: Date.now() - startedAt, status: "pass" });
} catch (error) {
writer.appendLog(`${String(error)}\n`);
await writer.write({
details: error instanceof Error ? error.message : String(error),
durationMs: Date.now() - startedAt,
status: "fail",
});
throw error;
}
}
if (import.meta.url === new URL(process.argv[1] ?? "", "file:").href) {
await main();
}