mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-12 21:53:00 -06:00
dceb2c343c
* 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
133 lines
4.6 KiB
TypeScript
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();
|
|
}
|