/*
Unit tests for otlp converter.pbt covering convertAccumulatedToOtlp — property-based tests (DNA-41).
- Not a contract source of truth — the module under test owns the authoritative behavior; fixtures are minimal scaffolding only.
- RFC-1311: Compass header sweep — declares the otlp suite's contract for test-file scaffold coverage.
*/
import { describe, it, expect } from "vitest";
import fc from "fast-check";
import { convertAccumulatedToOtlp, type AccumulatedPoint } from "../otlp-converter.ts";
const START_TIME = "1751884500000000000";
const metricNameArb = fc.constantFrom(
"warpgogol_factory_smoke_total",
"warpgogol_factory_command_runs_total",
"warpgogol_probe_up",
"warpgogol_probe_ttfb_seconds",
"warpgogol_factory_command_duration_seconds",
);
const kindArb = fc.constantFrom<"counter" | "gauge" | "histogram">("counter", "gauge", "histogram");
const pointArb: fc.Arbitrary = fc.record({
name: metricNameArb,
labels: fc.dictionary(fc.string({ maxLength: 10 }), fc.string({ maxLength: 20 })),
value: fc.double({ min: 0, max: 1000, noDefaultInfinity: true, noNaN: true }),
kind: kindArb,
});
const pointsArb = fc.array(pointArb, { maxLength: 50 });
describe("convertAccumulatedToOtlp — property-based tests (DNA-41)", () => {
it("bucket counts sum equals total points per histogram metric", () => {
fc.assert(
fc.property(pointsArb, (points) => {
const result = convertAccumulatedToOtlp(points, START_TIME);
for (const otlp of result) {
if (otlp.kind === "histogram" && otlp.histogramPoints) {
const hp = otlp.histogramPoints[0]!;
const bucketSum = hp.bucketCounts.reduce((acc, c) => acc + Number(c), 0);
const histogramPoints = points.filter((p) => p.name === otlp.name);
expect(bucketSum).toBe(histogramPoints.length);
expect(hp.count).toBe(String(histogramPoints.length));
}
}
}),
);
});
it("output metric names are a subset of input metric names", () => {
fc.assert(
fc.property(pointsArb, (points) => {
const result = convertAccumulatedToOtlp(points, START_TIME);
const inputNames = new Set(points.map((p) => p.name));
for (const otlp of result) {
expect(inputNames.has(otlp.name)).toBe(true);
}
}),
);
});
it("each output metric appears exactly once (grouping is stable)", () => {
fc.assert(
fc.property(pointsArb, (points) => {
const result = convertAccumulatedToOtlp(points, START_TIME);
const outputNames = result.map((r) => r.name);
const uniqueNames = new Set(outputNames);
expect(outputNames.length).toBe(uniqueNames.size);
}),
);
});
it("empty input always produces empty output", () => {
fc.assert(
fc.property(pointsArb, (points) => {
if (points.length === 0) {
const result = convertAccumulatedToOtlp(points, START_TIME);
expect(result).toEqual([]);
}
}),
);
});
});