fix(cli): recover child json from dumps and artifacts
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { mkdtemp, writeFile } from "node:fs/promises";
|
||||
import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { test } from "bun:test";
|
||||
|
||||
import { resolveCliChildJsonObject } from "./cli-child-json-recovery";
|
||||
|
||||
test("child JSON recovery reads full JSON from CLI stdout dump wrapper", async () => {
|
||||
const dir = await mkdtemp(join(tmpdir(), "unidesk-cli-child-json-dump-"));
|
||||
const dumpPath = join(dir, "dump.json");
|
||||
await writeFile(dumpPath, JSON.stringify({ ok: true, data: { contract: "full-json" } }) + "\n");
|
||||
|
||||
const wrapper = {
|
||||
ok: true,
|
||||
command: "fixture",
|
||||
data: {
|
||||
outputTruncated: true,
|
||||
reason: "stdout-json-bytes-exceeded-threshold",
|
||||
dump: { path: dumpPath },
|
||||
},
|
||||
};
|
||||
const resolved = resolveCliChildJsonObject({
|
||||
stdout: JSON.stringify(wrapper),
|
||||
requestedStdoutType: "fixture JSON",
|
||||
});
|
||||
|
||||
assert.equal(resolved.source, "dump");
|
||||
assert.equal(resolved.parsed?.ok, true);
|
||||
assert.deepEqual(resolved.parsed?.data, { contract: "full-json" });
|
||||
assert.equal(resolved.diagnostics.stdoutKind, "dump-wrapper");
|
||||
assert.equal(resolved.diagnostics.dumpPath, dumpPath);
|
||||
assert.equal(resolved.diagnostics.dumpReadOk, true);
|
||||
assert.equal(resolved.diagnostics.dumpJsonOk, true);
|
||||
});
|
||||
|
||||
test("child JSON recovery falls back to artifact after trans truncation summary", () => {
|
||||
const summary = {
|
||||
code: "ssh-truncation-summary",
|
||||
exitCode: 0,
|
||||
timedOut: false,
|
||||
stdout: {
|
||||
stream: "stdout",
|
||||
thresholdBytes: 10240,
|
||||
observedBytesAtTruncation: 165000,
|
||||
forwardedBytes: 10240,
|
||||
dumpPath: null,
|
||||
dumpError: null,
|
||||
},
|
||||
};
|
||||
const resolved = resolveCliChildJsonObject({
|
||||
stdout: `UNIDESK_SSH_TRUNCATION_SUMMARY ${JSON.stringify(summary)}\n`,
|
||||
requestedStdoutType: "web-probe observe analyze compact JSON",
|
||||
artifactFallback: {
|
||||
path: "analysis/report.json",
|
||||
nextCommand: "bun scripts/cli.ts web-probe observe collect webobs-fixture --view files --file analysis/report.json",
|
||||
read: () => ({ ok: true, value: { ok: true, reportJsonPath: "analysis/report.json" }, reason: "analysis-artifact-contract" }),
|
||||
},
|
||||
});
|
||||
|
||||
assert.equal(resolved.source, "artifact");
|
||||
assert.equal(resolved.parsed?.ok, true);
|
||||
assert.equal(resolved.diagnostics.stdoutKind, "ssh-truncation-summary");
|
||||
assert.equal(resolved.diagnostics.fallbackReason, "stdout-trans-truncated");
|
||||
const artifact = resolved.diagnostics.artifact as Record<string, unknown>;
|
||||
assert.equal(artifact.ok, true);
|
||||
assert.equal(artifact.nextCommand, "bun scripts/cli.ts web-probe observe collect webobs-fixture --view files --file analysis/report.json");
|
||||
});
|
||||
|
||||
test("child JSON recovery falls back to artifact when stdout is not JSON", () => {
|
||||
const resolved = resolveCliChildJsonObject({
|
||||
stdout: "remote helper wrote a bounded text summary instead of JSON",
|
||||
requestedStdoutType: "web-probe observe analyze compact JSON",
|
||||
artifactFallback: {
|
||||
path: "analysis/report.json",
|
||||
nextCommand: "collect report",
|
||||
read: () => ({ ok: true, value: { ok: true, counts: { network: 9 }, reportJsonPath: "analysis/report.json" } }),
|
||||
},
|
||||
});
|
||||
|
||||
assert.equal(resolved.source, "artifact");
|
||||
assert.equal(resolved.parsed?.ok, true);
|
||||
assert.deepEqual(resolved.parsed?.counts, { network: 9 });
|
||||
assert.equal(resolved.diagnostics.stdoutKind, "non-json");
|
||||
assert.equal(resolved.diagnostics.fallbackReason, "stdout-not-json");
|
||||
});
|
||||
|
||||
test("child JSON recovery reports artifact fallback failure when stdout is unusable and artifact is missing", () => {
|
||||
const resolved = resolveCliChildJsonObject({
|
||||
stdout: "not json",
|
||||
requestedStdoutType: "web-probe observe analyze compact JSON",
|
||||
artifactFallback: {
|
||||
path: "analysis/report.json",
|
||||
nextCommand: "collect report",
|
||||
read: () => ({ ok: false, reason: "artifact-missing", path: "analysis/report.json" }),
|
||||
},
|
||||
});
|
||||
|
||||
assert.equal(resolved.parsed, null);
|
||||
assert.equal(resolved.source, null);
|
||||
assert.equal(resolved.diagnostics.stdoutKind, "non-json");
|
||||
assert.equal(resolved.diagnostics.fallbackReason, "stdout-not-json");
|
||||
const artifact = resolved.diagnostics.artifact as Record<string, unknown>;
|
||||
assert.equal(artifact.ok, false);
|
||||
assert.equal(artifact.reason, "artifact-missing");
|
||||
assert.equal(artifact.path, "analysis/report.json");
|
||||
assert.equal(artifact.nextCommand, "collect report");
|
||||
});
|
||||
Reference in New Issue
Block a user