feat(web-probe): migrate observe actions to child json recovery
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
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 { resolveWebObserveActionJson } from "./web-probe-observe-actions";
|
||||
|
||||
test("web observe action JSON recovery accepts concrete start contract", () => {
|
||||
const resolved = resolveWebObserveActionJson({
|
||||
stdout: JSON.stringify({
|
||||
ok: true,
|
||||
command: "web-probe-observe start",
|
||||
jobId: "webobs-fixture",
|
||||
stateDir: ".state/web-observe/JD01/v03/fixture",
|
||||
valuesRedacted: true,
|
||||
}),
|
||||
stderr: "",
|
||||
exitCode: 0,
|
||||
timedOut: false,
|
||||
}, "start");
|
||||
|
||||
assert.equal(resolved.source, "stdout");
|
||||
assert.equal(resolved.parsed?.jobId, "webobs-fixture");
|
||||
assert.equal(resolved.diagnostics.stdoutContractAccepted, true);
|
||||
});
|
||||
|
||||
test("web observe action JSON recovery reads dump wrapper for status contract", async () => {
|
||||
const dir = await mkdtemp(join(tmpdir(), "unidesk-web-observe-status-dump-"));
|
||||
const dumpPath = join(dir, "status.json");
|
||||
await writeFile(dumpPath, JSON.stringify({
|
||||
ok: true,
|
||||
status: "running",
|
||||
jobId: "webobs-fixture",
|
||||
heartbeat: { status: "running" },
|
||||
diagnostics: { heartbeatStale: false },
|
||||
}) + "\n");
|
||||
|
||||
const resolved = resolveWebObserveActionJson({
|
||||
stdout: JSON.stringify({
|
||||
ok: true,
|
||||
data: {
|
||||
outputTruncated: true,
|
||||
reason: "stdout-json-bytes-exceeded-threshold",
|
||||
dump: { path: dumpPath },
|
||||
},
|
||||
}),
|
||||
stderr: "",
|
||||
exitCode: 0,
|
||||
timedOut: false,
|
||||
}, "status");
|
||||
|
||||
assert.equal(resolved.source, "dump");
|
||||
assert.equal(resolved.parsed?.jobId, "webobs-fixture");
|
||||
assert.equal(resolved.diagnostics.stdoutKind, "dump-wrapper");
|
||||
assert.equal(resolved.diagnostics.dumpPath, dumpPath);
|
||||
});
|
||||
|
||||
test("web observe action JSON recovery reads SSH truncation summary dump for command contract", async () => {
|
||||
const dir = await mkdtemp(join(tmpdir(), "unidesk-web-observe-command-dump-"));
|
||||
const dumpPath = join(dir, "command.json");
|
||||
await writeFile(dumpPath, JSON.stringify({
|
||||
ok: true,
|
||||
queued: false,
|
||||
waitTimedOut: false,
|
||||
commandId: "cmd-fixture",
|
||||
}) + "\n");
|
||||
const summary = {
|
||||
code: "ssh-truncation-summary",
|
||||
stdout: {
|
||||
stream: "stdout",
|
||||
dumpPath,
|
||||
forwardedBytes: 10240,
|
||||
thresholdBytes: 10240,
|
||||
},
|
||||
};
|
||||
|
||||
const resolved = resolveWebObserveActionJson({
|
||||
stdout: `UNIDESK_SSH_TRUNCATION_SUMMARY ${JSON.stringify(summary)}\n`,
|
||||
stderr: "",
|
||||
exitCode: 0,
|
||||
timedOut: false,
|
||||
}, "command");
|
||||
|
||||
assert.equal(resolved.source, "dump");
|
||||
assert.equal(resolved.parsed?.commandId, "cmd-fixture");
|
||||
assert.equal(resolved.diagnostics.stdoutKind, "ssh-truncation-summary");
|
||||
assert.equal(resolved.diagnostics.dumpPath, dumpPath);
|
||||
});
|
||||
|
||||
test("web observe action JSON recovery rejects ok-only action contract", () => {
|
||||
const resolved = resolveWebObserveActionJson({
|
||||
stdout: JSON.stringify({ ok: true }),
|
||||
stderr: "",
|
||||
exitCode: 0,
|
||||
timedOut: false,
|
||||
}, "start");
|
||||
|
||||
assert.equal(resolved.parsed, null);
|
||||
assert.equal(resolved.source, null);
|
||||
assert.equal(resolved.diagnostics.stdoutKind, "json");
|
||||
assert.equal(resolved.diagnostics.fallbackReason, "stdout-json-contract-invalid");
|
||||
assert.equal(resolved.diagnostics.stdoutContractAccepted, false);
|
||||
});
|
||||
Reference in New Issue
Block a user