Files
2026-05-27 23:47:53 +01:00

504 lines
16 KiB
TypeScript

/**
* Edge-case coverage for the codec / trust / generation modules:
* malformed JSON, schema mismatches, popcount, scoring math, and the
* branches that the spec-tied tests didn't exercise directly.
*/
import { describe, expect, it } from "@suaveplan/testing/runner";
import {
AdvertiseThrottle,
chunkIdsToRawBitset,
DMP_CODES,
DmpError,
decodeAdvertisePayload,
decodeErrorPayload,
decodeRequestPayload,
decodeResponsePayload,
encodeAdvertisePayload,
encodeBitsetFromChunkIds,
encodeErrorPayload,
encodeFramedBitset,
encodeRequestPayload,
encodeResponsePayload,
GenerationTracker,
popcount,
rawBitsetToChunkIds,
selectForm,
shouldSkip,
type TrustEntry,
TrustMap,
} from "../src/index.js";
const FILE_ID = "e".repeat(64);
describe("popcount", () => {
it("counts zero", { timeout: 5000 }, () => {
expect(popcount(new Uint8Array([0, 0, 0]))).toBe(0);
});
it("counts mixed", { timeout: 5000 }, () => {
expect(popcount(new Uint8Array([0xff, 0x01, 0x80]))).toBe(8 + 1 + 1);
});
});
describe("chunkIdsToRawBitset edge cases", () => {
it("rejects non-integer bitLength", { timeout: 5000 }, () => {
try {
chunkIdsToRawBitset([0], 1.5);
throw new Error("expected rejection");
} catch (err) {
expect((err as DmpError).code).toBe(
DMP_CODES.BITSET_LENGTH_MISMATCH
);
}
});
it("rejects negative bitLength", { timeout: 5000 }, () => {
expect(() => chunkIdsToRawBitset([], -1)).toThrow();
});
});
describe("rawBitsetToChunkIds edge cases", () => {
it("rejects non-zero padding bits", { timeout: 5000 }, () => {
const raw = new Uint8Array([0xff]);
try {
rawBitsetToChunkIds(raw, 4);
throw new Error("expected rejection");
} catch (err) {
expect((err as DmpError).code).toBe(
DMP_CODES.BITSET_PADDING_NONZERO
);
}
});
it("rejects byte-length / bit-length mismatch", { timeout: 5000 }, () => {
const raw = new Uint8Array([0]);
try {
rawBitsetToChunkIds(raw, 16);
throw new Error("expected rejection");
} catch (err) {
expect((err as DmpError).code).toBe(
DMP_CODES.BITSET_LENGTH_MISMATCH
);
}
});
});
describe("encodeFramedBitset rejects bad inputs", () => {
it("rejects non-zero padding at encode time", { timeout: 5000 }, () => {
const raw = new Uint8Array([0xff]);
try {
encodeFramedBitset(raw, 4);
throw new Error("expected rejection");
} catch (err) {
expect((err as DmpError).code).toBe(
DMP_CODES.BITSET_PADDING_NONZERO
);
}
});
});
describe("Codec malformed JSON paths", () => {
it("decodeRequestPayload rejects malformed JSON", { timeout: 5000 }, () => {
try {
decodeRequestPayload(new TextEncoder().encode("not json"));
throw new Error("expected rejection");
} catch (err) {
expect((err as DmpError).code).toBe(DMP_CODES.ENVELOPE_MALFORMED);
}
});
it("decodeAdvertisePayload rejects malformed JSON", {
timeout: 5000,
}, () => {
try {
decodeAdvertisePayload(new TextEncoder().encode("not json"));
throw new Error("expected rejection");
} catch (err) {
expect((err as DmpError).code).toBe(DMP_CODES.ENVELOPE_MALFORMED);
}
});
it("decodeResponsePayload rejects malformed JSON", {
timeout: 5000,
}, () => {
try {
decodeResponsePayload(new TextEncoder().encode("not json"));
throw new Error("expected rejection");
} catch (err) {
expect((err as DmpError).code).toBe(DMP_CODES.ENVELOPE_MALFORMED);
}
});
});
describe("Codec unwrapWire passthrough on non-object", () => {
it("decodeAdvertisePayload rejects bare null", { timeout: 5000 }, () => {
const wire = new TextEncoder().encode(JSON.stringify(null));
try {
decodeAdvertisePayload(wire);
throw new Error("expected rejection");
} catch (err) {
expect((err as DmpError).code).toBe(DMP_CODES.ENVELOPE_MALFORMED);
}
});
it("decodeRequestPayload rejects array", { timeout: 5000 }, () => {
const wire = new TextEncoder().encode(JSON.stringify([1, 2, 3]));
try {
decodeRequestPayload(wire);
throw new Error("expected rejection");
} catch (err) {
expect((err as DmpError).code).toBe(DMP_CODES.ENVELOPE_MALFORMED);
}
});
it("decodeResponsePayload rejects bare object", { timeout: 5000 }, () => {
const wire = new TextEncoder().encode(JSON.stringify({ x: 1 }));
try {
decodeResponsePayload(wire);
throw new Error("expected rejection");
} catch (err) {
expect((err as DmpError).code).toBe(DMP_CODES.ENVELOPE_MALFORMED);
}
});
});
describe("Codec encode-time validation", () => {
it("encodeRequestPayload rejects malformed input", {
timeout: 5000,
}, () => {
try {
encodeRequestPayload({
fileId: "not-hex",
request: { kind: "whole" },
priority: "normal",
});
throw new Error("expected rejection");
} catch (err) {
expect((err as DmpError).code).toBe(DMP_CODES.ENVELOPE_MALFORMED);
}
});
it("encodeResponsePayload rejects bad presence", { timeout: 5000 }, () => {
try {
encodeResponsePayload({
fileId: FILE_ID,
chunks: [],
presence: new Uint8Array(2).fill(0xff), // missing magic
generation: 1,
});
throw new Error("expected rejection");
} catch (err) {
expect((err as DmpError).code).toBe(DMP_CODES.CODEC_MISMATCH);
}
});
it("encodeAdvertisePayload rejects bad presence", { timeout: 5000 }, () => {
try {
encodeAdvertisePayload({
fileId: FILE_ID,
presence: new Uint8Array(20).fill(0xff),
totalChunks: 8,
generation: 1,
timestamp: 0,
});
throw new Error("expected rejection");
} catch (err) {
expect((err as DmpError).code).toBe(DMP_CODES.CODEC_MISMATCH);
}
});
it("encodeErrorPayload rejects malformed input", { timeout: 5000 }, () => {
try {
encodeErrorPayload({
fileId: "non-hex-bad-id!",
correlationId: "x",
code: "INTERNAL",
});
throw new Error("expected rejection");
} catch (err) {
expect((err as DmpError).code).toBe(DMP_CODES.ENVELOPE_MALFORMED);
}
});
it("decodeErrorPayload accepts a clean envelope", { timeout: 5000 }, () => {
const wire = encodeErrorPayload({
fileId: FILE_ID,
correlationId: "abc",
code: "INTERNAL",
});
const back = decodeErrorPayload(wire);
expect(back.code).toBe("INTERNAL");
});
it("encodeRequest rejects bitset without magic", { timeout: 5000 }, () => {
try {
encodeRequestPayload({
fileId: FILE_ID,
request: {
kind: "bitset",
bytes: new Uint8Array(4).fill(0),
},
priority: "normal",
});
throw new Error("expected rejection");
} catch (err) {
expect((err as DmpError).code).toBe(DMP_CODES.CODEC_MISMATCH);
}
});
});
describe("encodeBitsetFromChunkIds (high-level helper)", () => {
it("frames a chunk-id list via the canonical pipeline", {
timeout: 5000,
}, () => {
const framed = encodeBitsetFromChunkIds([3, 7], 16);
expect(framed.length).toBeGreaterThan(0);
});
it("derives bitLength from max id when not supplied", {
timeout: 5000,
}, () => {
const framed = encodeBitsetFromChunkIds([10]);
expect(framed.length).toBeGreaterThan(0);
});
});
describe("selectForm bitLength override", () => {
it("uses caller-supplied bitLength when present", { timeout: 5000 }, () => {
const ids = Array.from({ length: 80 }, (_, i) => i);
const r = selectForm(ids, { bitLength: 200 });
expect(r.kind).toBe("bitset");
});
});
describe("TrustMap arithmetic", () => {
it("score reflects miss / advertised ratio", { timeout: 5000 }, () => {
const t = new TrustMap();
t.recordAdvertised("p", "f", 10);
t.recordMissing("p", "f", 1);
const e = t.get("p", "f");
expect(e.score).toBeCloseTo(0.9, 4);
});
});
describe("decodeAdvertisePayload bitset length cross-check", () => {
it("rejects wire where presence bitLength ≠ totalChunks", {
timeout: 5000,
}, () => {
const presence = encodeFramedBitset(chunkIdsToRawBitset([0, 1], 8), 8);
// Hand-build a wire envelope where totalChunks (16) doesn't
// match the bitset's embedded bitLength (8).
const wire = new TextEncoder().encode(
JSON.stringify({
fileId: FILE_ID,
presence: { _b: btoa(String.fromCharCode(...presence)) },
totalChunks: 16,
generation: 1,
timestamp: 0,
})
);
try {
decodeAdvertisePayload(wire);
throw new Error("expected mismatch");
} catch (err) {
expect((err as DmpError).code).toBe(
DMP_CODES.BITSET_LENGTH_MISMATCH
);
}
});
});
describe("DMP-01 — unknown kind rejection", () => {
it("decodeRequestPayload rejects unknown kind with UNKNOWN_REQUEST_KIND", {
timeout: 5000,
}, () => {
const wire = new TextEncoder().encode(
JSON.stringify({
fileId: FILE_ID,
request: { kind: "unknown" },
priority: "normal",
})
);
try {
decodeRequestPayload(wire);
throw new Error("expected rejection");
} catch (err) {
expect((err as DmpError).code).toBe(DMP_CODES.UNKNOWN_REQUEST_KIND);
}
});
});
describe("Tiny coverage gaps", () => {
it("encodeRequest direct call rejects empty specific", {
timeout: 5000,
}, () => {
const wire = new TextEncoder().encode(
JSON.stringify({
fileId: FILE_ID,
request: { kind: "specific", chunkIds: [] },
priority: "normal",
})
);
try {
decodeRequestPayload(wire);
throw new Error("expected rejection");
} catch (err) {
expect((err as DmpError).code).toBe(DMP_CODES.EMPTY_REQUEST);
}
});
it("encodeRequest function exposed and rejects empty specific", {
timeout: 5000,
}, async () => {
const { encodeRequest } = await import("../src/index.js");
try {
encodeRequest({ kind: "specific", chunkIds: [] });
throw new Error("expected rejection");
} catch (err) {
expect((err as DmpError).code).toBe(DMP_CODES.EMPTY_REQUEST);
}
});
it("empty bitset (bitLength 0) round-trips cleanly", {
timeout: 5000,
}, () => {
const raw = new Uint8Array(0);
const framed = encodeFramedBitset(raw, 0);
const decoded = encodeFramedBitset(raw, 0);
expect(decoded).toEqual(framed);
// popcount of an empty array
expect(popcount(raw)).toBe(0);
});
it("selectForm with non-monotonic ids covers branch", {
timeout: 5000,
}, () => {
const r = selectForm([5, 3, 7, 1], { threshold: 2 });
expect(r.kind).toBe("bitset");
});
it("encodeBitsetFromChunkIds with non-monotonic ids", {
timeout: 5000,
}, () => {
const framed = encodeBitsetFromChunkIds([10, 3, 7]);
expect(framed.length).toBeGreaterThan(0);
});
it("TrustMap `size` getter is exposed", { timeout: 5000 }, () => {
const t = new TrustMap();
t.recordAdvertised("a", "b", 1);
expect(t.size).toBe(1);
});
it("GenerationTracker `size` getter is exposed", {
timeout: 5000,
}, () => {
const g = new GenerationTracker();
g.observe("p", "f", 1);
expect(g.size).toBe(1);
});
it("AdvertiseThrottle `windowMs` getter is exposed", {
timeout: 5000,
}, () => {
const t = new AdvertiseThrottle({ clock: () => 0, windowMs: 1234 });
expect(t.windowMs).toBe(1234);
});
it("Throttle.hasPending returns false for unknown key", {
timeout: 5000,
}, () => {
const t = new AdvertiseThrottle({ clock: () => 0, windowMs: 1000 });
expect(t.hasPending("never-seen", "f")).toBe(false);
});
it("Throttle.clearPending no-ops for unknown key", {
timeout: 5000,
}, () => {
const t = new AdvertiseThrottle({ clock: () => 0, windowMs: 1000 });
// Should not throw.
t.clearPending("never-seen", "f");
expect(t.size).toBe(0);
});
it("Throttle.dropNeighbor uses default windowMs when none supplied", {
timeout: 5000,
}, () => {
const t = new AdvertiseThrottle({ clock: () => 0 });
expect(t.windowMs).toBeGreaterThan(0);
});
it("computeScore returns 1 when advertised === 0 (defence-in-depth)", {
timeout: 5000,
}, () => {
const t = new TrustMap();
// Record a missing without any prior advertise.
t.recordMissing("ghost", "f", 5);
expect(t.get("ghost", "f").score).toBe(1);
});
it("probabilityOfSkip returns 0 for advertised === 0", {
timeout: 5000,
}, async () => {
const { probabilityOfSkip } = await import("../src/index.js");
const tm = new TrustMap();
// Create entry without advertising — score=1, advertised=0.
const e = tm.get("p", "f");
expect(probabilityOfSkip(e)).toBe(0);
});
it("shouldSkip: probability strictly between 0 and 1 hits rng path", {
timeout: 5000,
}, () => {
const t = new TrustMap();
t.recordAdvertised("p", "f", 100);
t.recordMissing("p", "f", 6); // 0.06 miss rate; p = 0.2
const e = t.get("p", "f");
// shouldSkip falls through to rng.nextFloat() < 0.2 — both
// branches matter for coverage.
const draws = [0.1, 0.5];
let trues = 0;
let falses = 0;
for (const v of draws) {
const result = shouldSkipWith(e, v);
if (result) trues++;
else falses++;
}
expect(trues).toBe(1);
expect(falses).toBe(1);
});
it("score formula for advertised > 0 returns the ratio", {
timeout: 5000,
}, () => {
const t = new TrustMap();
t.recordAdvertised("p", "f", 4);
t.recordMissing("p", "f", 1);
expect(t.get("p", "f").score).toBeCloseTo(0.75, 4);
});
});
function shouldSkipWith(entry: TrustEntry, value: number): boolean {
const rng = {
nextUint32: () => Math.floor(value * 2 ** 32),
nextFloat: () => value,
bytes: (n: number) => new Uint8Array(n),
};
return shouldSkip(entry, rng);
}
describe("Generation negative path", () => {
it("generation past u32 max rejected", { timeout: 5000 }, () => {
const wire = new TextEncoder().encode(
JSON.stringify({
fileId: FILE_ID,
presence: {
_b: btoa(String.fromCharCode(...new Uint8Array(0))),
},
totalChunks: 0,
generation: 0x1_00_00_00_00,
timestamp: 0,
})
);
try {
decodeAdvertisePayload(wire);
throw new Error("expected rejection");
} catch (err) {
expect(err).toBeInstanceOf(DmpError);
}
});
});