Files
9router/tests/unit/proxy-pool-fitness.test.js

82 lines
2.9 KiB
JavaScript

import { describe, it, expect, beforeEach } from "vitest";
import {
markPoolUnfit,
clearPoolUnfit,
clearAllPoolUnfit,
isPoolFit,
fitPoolIds,
poolFitnessSnapshot,
pruneExpired,
resetPoolFitness,
} from "open-sse/services/proxyPoolFitness.js";
import { pickProxyPoolId } from "../../src/lib/network/connectionProxy.js";
describe("proxy pool fitness registry", () => {
beforeEach(() => resetPoolFitness());
it("marks a pool unfit for a scope and prunes on expiry", () => {
markPoolUnfit("p1", "freebuff::gpt-5.6-luna", Date.now() + 60_000, "limited_ip");
expect(isPoolFit("p1", "freebuff::gpt-5.6-luna")).toBe(false);
expect(isPoolFit("p1", "freebuff::other-model")).toBe(true);
expect(isPoolFit("p2", "freebuff::gpt-5.6-luna")).toBe(true);
markPoolUnfit("p1", "freebuff::gpt-5.6-luna", Date.now() - 1000); // expired
expect(isPoolFit("p1", "freebuff::gpt-5.6-luna")).toBe(true); // pruned on read
});
it("provider-wide mark (provider::*) covers any model lookup", () => {
markPoolUnfit("p1", "opencode::*", Date.now() + 60_000, "manual");
expect(isPoolFit("p1", "opencode::sonnet-4.6")).toBe(false);
expect(isPoolFit("p1", "freebuff::gpt-5.6-luna")).toBe(true);
});
it("fitPoolIds filters unfit pools; snapshot drops expired marks", () => {
markPoolUnfit("p1", "fb::m1", Date.now() + 60_000);
markPoolUnfit("p1", "fb::m2", Date.now() - 1000); // expired
expect(fitPoolIds(["p1", "p2"], "fb::m1")).toEqual(["p2"]);
const snap = poolFitnessSnapshot();
expect(snap.p1["fb::m1"]).toBeDefined();
expect(snap.p1["fb::m2"]).toBeUndefined();
});
it("does not reuse a pool when every smart candidate is unfit", () => {
markPoolUnfit("p1", "freebuff::openai/gpt-5.6-luna", Date.now() + 60_000, "limited_ip");
markPoolUnfit("p2", "freebuff::openai/gpt-5.6-luna", Date.now() + 60_000, "limited_ip");
expect(pickProxyPoolId(
["p1", "p2"],
"smart",
"freebuff",
{ scope: "freebuff::openai/gpt-5.6-luna" },
)).toBeNull();
});
it("preserves fail-open smart fallback for non-Freebuff providers", () => {
markPoolUnfit("p1", "opencode::sonnet-4.6", Date.now() + 60_000, "ip-limit");
markPoolUnfit("p2", "opencode::sonnet-4.6", Date.now() + 60_000, "ip-limit");
expect(pickProxyPoolId(
["p1", "p2"],
"smart",
"opencode",
{ scope: "opencode::sonnet-4.6" },
)).toBe("p1");
});
it("clear per scope, clear-all per provider, clear-all global, pruneExpired", () => {
markPoolUnfit("p1", "freebuff::m1", Date.now() + 60_000);
markPoolUnfit("p1", "kiro::m3", Date.now() + 60_000);
clearPoolUnfit("p1", "freebuff::m1");
expect(isPoolFit("p1", "freebuff::m1")).toBe(true);
clearAllPoolUnfit("kiro");
expect(poolFitnessSnapshot().p1).toBeUndefined();
markPoolUnfit("p2", "x::y", Date.now() - 1000);
expect(pruneExpired()).toBe(1);
expect(poolFitnessSnapshot()).toEqual({});
});
});