Imported as a linear vendor commit so forge rebases do not replay the upstream root tree. git-subtree-dir: third_party/pi git-subtree-split: d981de1229ef899957bbe968bc8dcda02a21f477
77 lines
2.1 KiB
TypeScript
77 lines
2.1 KiB
TypeScript
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
import { AdaptivePublisher } from "../../src/harness/utils/adaptive-publisher.ts";
|
|
|
|
afterEach(() => {
|
|
vi.useRealTimers();
|
|
});
|
|
|
|
describe("AdaptivePublisher", () => {
|
|
it("bounds event count and spaces large publications by encoded size", () => {
|
|
vi.useFakeTimers();
|
|
vi.setSystemTime(0);
|
|
let value = "a";
|
|
const updates: string[] = [];
|
|
const publisher = new AdaptivePublisher({
|
|
snapshot: () => value,
|
|
update: (_previous, current) => current,
|
|
measure: (update) => update.length,
|
|
publish: (update) => updates.push(update),
|
|
onError: (error) => {
|
|
throw error;
|
|
},
|
|
minIntervalMs: 100,
|
|
targetBytesPerSecond: 100,
|
|
});
|
|
|
|
publisher.markDirty();
|
|
value = "x".repeat(100);
|
|
publisher.markDirty();
|
|
vi.advanceTimersByTime(100);
|
|
expect(updates).toEqual(["a", "x".repeat(100)]);
|
|
|
|
value = "held";
|
|
publisher.markDirty();
|
|
vi.advanceTimersByTime(999);
|
|
expect(updates).toHaveLength(2);
|
|
vi.advanceTimersByTime(1);
|
|
expect(updates).toEqual(["a", "x".repeat(100), "held"]);
|
|
});
|
|
|
|
it("commits its baseline before a consumer throws", () => {
|
|
vi.useFakeTimers();
|
|
vi.setSystemTime(0);
|
|
let value = "a";
|
|
const updates: Array<{ previous: string | undefined; current: string }> = [];
|
|
let throwAfterApply = false;
|
|
const publisher = new AdaptivePublisher({
|
|
snapshot: () => value,
|
|
update: (previous, current) => ({ previous, current }),
|
|
measure: () => 1,
|
|
publish: (update) => {
|
|
updates.push(update);
|
|
if (throwAfterApply) throw new Error("consumer failed after apply");
|
|
},
|
|
onError: () => {},
|
|
minIntervalMs: 100,
|
|
targetBytesPerSecond: 100,
|
|
});
|
|
|
|
publisher.markDirty();
|
|
vi.advanceTimersByTime(100);
|
|
value = "ab";
|
|
throwAfterApply = true;
|
|
expect(() => publisher.markDirty()).toThrow("consumer failed after apply");
|
|
publisher.flush(true);
|
|
expect(updates).toEqual([
|
|
{ previous: undefined, current: "a" },
|
|
{ previous: "a", current: "ab" },
|
|
]);
|
|
|
|
throwAfterApply = false;
|
|
vi.advanceTimersByTime(100);
|
|
value = "abc";
|
|
publisher.markDirty();
|
|
expect(updates.at(-1)).toEqual({ previous: "ab", current: "abc" });
|
|
});
|
|
});
|