Files
hyperframes/packages/cli/src/telemetry/renderObservability.test.ts
T
Vance Ingalls a5cbb78ff9 feat(engine,producer,cli): capture failing dB/frame index on drawElement verify fallback
de_fallback_reason only told you the fallback happened (blank/psnr/oom/
capture_error), not the failing PSNR or frame index — that data existed as
text inside the thrown error's message and was discarded on the way to
telemetry. DrawElementVerificationError now carries structured
frameIndex/failedDb/verifyThresholdDb; the orchestrator reads them via the
new getDrawElementVerificationDetails helper instead of regexing message
text, and both telemetry surfaces (the render_complete perfSummary path and
the crash-survival RenderCaptureObservability mirror) emit
de_fallback_failed_db / de_fallback_frame_index.

Needed to distinguish "32dB vs the 32dB threshold, tune it" from "12dB real
corruption, investigate" during the parallel-router soak — currently that
distinction is invisible.
2026-07-14 23:29:49 -07:00

127 lines
4.9 KiB
TypeScript

import { describe, expect, it } from "vitest";
import type { RenderObservabilitySummary } from "@hyperframes/producer";
import { renderObservabilityTelemetryPayload } from "./renderObservability.js";
function makeSummary(
capture: Partial<RenderObservabilitySummary["capture"]>,
): RenderObservabilitySummary {
return {
events: [],
eventCount: 0,
browserDiagnostics: {
total: 0,
errors: 0,
pageErrors: 0,
requestFailed: 0,
httpErrors: 0,
navigationStarts: 0,
navigationFailures: 0,
consoleErrors: 0,
consoleWarnings: 0,
},
capture: { forceScreenshot: false, captureMode: "beginframe", ...capture },
};
}
describe("renderObservabilityTelemetryPayload — render-reliability counters", () => {
it("maps the transient-retry and OOM counters through to the telemetry payload", () => {
const payload = renderObservabilityTelemetryPayload(
makeSummary({ transientRetries: 2, memoryExhaustionDetected: true }),
);
expect(payload.captureTransientRetries).toBe(2);
expect(payload.captureMemoryExhaustionDetected).toBe(true);
});
it("leaves the counters undefined when the render didn't retry or OOM", () => {
const payload = renderObservabilityTelemetryPayload(makeSummary({}));
expect(payload.captureTransientRetries).toBeUndefined();
expect(payload.captureMemoryExhaustionDetected).toBeUndefined();
});
});
describe("renderObservabilityTelemetryPayload — DE inversion/router cohort (failure-path visibility)", () => {
it("maps the router cohort and its pre-router worker count", () => {
const payload = renderObservabilityTelemetryPayload(
makeSummary({ deParallelRouter: "routed", dePreRouterWorkers: 2 }),
);
expect(payload.captureDeParallelRouter).toBe("routed");
expect(payload.captureDePreRouterWorkers).toBe(2);
expect(payload.captureDeWorkerInversion).toBeUndefined();
expect(payload.captureDePreInversionWorkers).toBeUndefined();
});
it("maps the inversion cohort and its pre-inversion worker count", () => {
const payload = renderObservabilityTelemetryPayload(
makeSummary({ deWorkerInversion: "inverted", dePreInversionWorkers: 4 }),
);
expect(payload.captureDeWorkerInversion).toBe("inverted");
expect(payload.captureDePreInversionWorkers).toBe(4);
expect(payload.captureDeParallelRouter).toBeUndefined();
});
it("carries deSelfVerifyFallback so a hard failure mid-verify is still visible", () => {
const payload = renderObservabilityTelemetryPayload(
makeSummary({ deParallelRouter: "routed", deSelfVerifyFallback: true }),
);
expect(payload.captureDeSelfVerifyFallback).toBe(true);
});
it("carries deFallbackReason so a render that fails AFTER an OOM-triggered fallback attempt is distinguishable from one that never attempted a fallback", () => {
const payload = renderObservabilityTelemetryPayload(
makeSummary({
deParallelRouter: "routed",
deSelfVerifyFallback: false,
deFallbackReason: "oom",
}),
);
expect(payload.captureDeFallbackReason).toBe("oom");
});
it("leaves deFallbackReason undefined when no fallback was ever attempted", () => {
const payload = renderObservabilityTelemetryPayload(makeSummary({}));
expect(payload.captureDeFallbackReason).toBeUndefined();
});
it("carries the failing dB and frame index for a psnr fallback, still visible on a hard failure", () => {
const payload = renderObservabilityTelemetryPayload(
makeSummary({
deParallelRouter: "routed",
deFallbackReason: "psnr",
deFallbackFailedDb: 28.4,
deFallbackFrameIndex: 649,
}),
);
expect(payload.captureDeFallbackFailedDb).toBe(28.4);
expect(payload.captureDeFallbackFrameIndex).toBe(649);
});
it("leaves failedDb undefined for a blank/oom/capture_error fallback (no PSNR score exists)", () => {
const payload = renderObservabilityTelemetryPayload(
makeSummary({ deFallbackReason: "oom", deFallbackFrameIndex: undefined }),
);
expect(payload.captureDeFallbackFailedDb).toBeUndefined();
expect(payload.captureDeFallbackFrameIndex).toBeUndefined();
});
});
describe("renderObservabilityTelemetryPayload — non-DE parallel-stream router", () => {
it("maps the router outcome", () => {
const payload = renderObservabilityTelemetryPayload(
makeSummary({ captureParallelStream: "beginframe" }),
);
expect(payload.captureParallelStream).toBe("beginframe");
});
it("maps the passive eligible_off cohort-sizing signal", () => {
const payload = renderObservabilityTelemetryPayload(
makeSummary({ captureParallelStream: "eligible_off" }),
);
expect(payload.captureParallelStream).toBe("eligible_off");
});
it("stays undefined when the router never fired", () => {
const payload = renderObservabilityTelemetryPayload(makeSummary({}));
expect(payload.captureParallelStream).toBeUndefined();
});
});