82 lines
2.7 KiB
TypeScript
82 lines
2.7 KiB
TypeScript
import assert from "node:assert/strict";
|
|
import { test } from "bun:test";
|
|
|
|
import { classifyQuickVerifyCleanupStep, quickVerifyCleanupFindings } from "./hwlab-node-web-sentinel-p5-observe";
|
|
|
|
function forceStopStep(observer: Record<string, unknown>): Record<string, unknown> {
|
|
return {
|
|
phase: "observe-stop-after-terminal",
|
|
ok: false,
|
|
payload: {
|
|
ok: false,
|
|
status: "blocked",
|
|
forceReason: "graceful-stop-not-consumed",
|
|
observer: {
|
|
command: "web-probe-observe force-stop",
|
|
...observer,
|
|
},
|
|
valuesRedacted: true,
|
|
},
|
|
valuesRedacted: true,
|
|
};
|
|
}
|
|
|
|
test("quick verify cleanup downgrades abandoned graceful stop when force stop confirms not alive", () => {
|
|
const step = forceStopStep({
|
|
aliveBefore: true,
|
|
aliveAfter: false,
|
|
termSent: true,
|
|
killSent: true,
|
|
pendingAbandoned: 1,
|
|
processingAbandoned: 0,
|
|
});
|
|
|
|
const cleanup = classifyQuickVerifyCleanupStep(step);
|
|
assert.equal(cleanup.cleanupClass, "bounded-force-stop");
|
|
assert.equal(cleanup.gracefulStopOk, false);
|
|
assert.equal(cleanup.forceStopOk, true);
|
|
assert.equal(cleanup.aliveAfter, false);
|
|
assert.equal(cleanup.pendingAbandoned, 1);
|
|
const findings = quickVerifyCleanupFindings(step);
|
|
assert.equal(findings.length, 1);
|
|
assert.equal(findings[0]?.id, "observer-graceful-stop-timeout-force-stop-succeeded");
|
|
assert.equal(findings[0]?.severity, "warning");
|
|
});
|
|
|
|
test("quick verify cleanup emits process-alive code when force stop leaves observer alive", () => {
|
|
const step = forceStopStep({
|
|
aliveBefore: true,
|
|
aliveAfter: true,
|
|
termSent: true,
|
|
killSent: false,
|
|
pendingAbandoned: 0,
|
|
processingAbandoned: 1,
|
|
});
|
|
|
|
const cleanup = classifyQuickVerifyCleanupStep(step);
|
|
const findings = quickVerifyCleanupFindings(step);
|
|
assert.equal(cleanup.cleanupClass, "observer-stop-failed");
|
|
assert.equal(cleanup.forceStopOk, false);
|
|
assert.equal(cleanup.aliveAfter, true);
|
|
assert.equal(findings.length, 1);
|
|
assert.equal(findings[0]?.id, "observer-force-stop-left-process-alive");
|
|
assert.match(String(findings[0]?.evidenceSummary), /aliveAfter=true/u);
|
|
});
|
|
|
|
test("quick verify cleanup emits evidence-gap code when stopped state cannot be confirmed", () => {
|
|
const step = forceStopStep({
|
|
aliveBefore: true,
|
|
termSent: true,
|
|
killSent: true,
|
|
pendingAbandoned: 1,
|
|
processingAbandoned: 0,
|
|
});
|
|
|
|
const cleanup = classifyQuickVerifyCleanupStep(step);
|
|
const findings = quickVerifyCleanupFindings(step);
|
|
assert.equal(cleanup.cleanupClass, "observer-stop-failed");
|
|
assert.equal(cleanup.aliveAfter, null);
|
|
assert.equal(findings.length, 1);
|
|
assert.equal(findings[0]?.id, "observer-cleanup-evidence-missing");
|
|
});
|