import { mkdirSync, writeFileSync } from "node:fs"; import { join } from "node:path"; import { tmpdir } from "node:os"; import { describe, expect, test } from "bun:test"; import { resolveSentinelChildJson } from "./hwlab-node-web-sentinel-cicd-shared"; import { sentinelDeliveryStatus, type SentinelCicdState } from "./hwlab-node-web-sentinel-cicd"; describe("sentinel CI/CD child JSON recovery", () => { test("recovers remote probe JSON from trans truncation dump", () => { const dir = join(tmpdir(), `unidesk-sentinel-cicd-${Date.now()}-${process.pid}`); mkdirSync(dir, { recursive: true }); const dumpPath = join(dir, "stdout.json"); writeFileSync(dumpPath, JSON.stringify({ ok: true, present: true, digest: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", valuesRedacted: true, })); const summary = { stdout: { stream: "stdout", truncated: true, dumpPath, valuesRedacted: true, }, valuesRedacted: true, }; const resolved = resolveSentinelChildJson({ stdout: "tail fragment that is not json", stderr: `UNIDESK_SSH_TRUNCATION_SUMMARY ${JSON.stringify(summary)}\n`, exitCode: 0, timedOut: false, }, "web-probe-sentinel-test-probe"); expect(resolved.parsed?.ok).toBe(true); expect(resolved.parsed?.present).toBe(true); expect(resolved.diagnostics.stdoutKind).toBe("ssh-truncation-summary"); expect(resolved.diagnostics.dumpPath).toBe(dumpPath); expect(resolved.diagnostics.source).toBe("dump"); }); }); test("sentinel delivery status distinguishes cadence convergence without blocking", () => { const commit = "f87cd3ac8fd2494f9dfed51e7d8ececd3fc42939"; const state = { sourceHead: { commit } } as unknown as SentinelCicdState; const base = { sourceMirror: { ok: true }, registry: { probe: { present: true } }, gitMirror: { ok: true }, gitops: { ok: true, sourceCommit: commit, schedule: "0 */2 * * *", revision: "gitops-revision" }, argo: { ok: true, syncStatus: "Synced", healthStatus: "Healthy" }, runtime: { ok: true, probe: { deployment: { sourceCommit: commit } } }, }; const converging = sentinelDeliveryStatus(state, { ...base, cadence: { ok: false, probe: { schedule: "0 * * * *" } } }, "pipeline-run"); expect(converging.outcome).toBe("converging"); expect(converging.blocking).toBe(false); const converged = sentinelDeliveryStatus(state, { ...base, cadence: { ok: true, probe: { schedule: "0 */2 * * *" } } }, "pipeline-run"); expect(converged.outcome).toBe("converged"); expect(converged.desiredSourceCommit).toBe(commit); });