test(base): run the orphaned #8890 suite and realign three mechanism pins

**check:test-discovery — a suite that had NEVER executed**

#8890 landed open-sse/services/__tests__/fail-fast-concurrency-gate.test.ts into
a directory no runner collects (only one explicit file from that folder is in
vitest.mcp.config.ts), so it ran zero times since it merged. Wired it into the
runner AND into check-test-discovery.mjs's mirrored collector list, which the
gate keeps in sync deliberately. It passes 4/4 now that it actually runs —
test:vitest goes 36 -> 37 files, 340 -> 344 tests.

**check-db-rules-classification** — 37 -> 38 audited modules, adding probeUtils
alongside the INTENTIONALLY_INTERNAL entry from the previous commit.

**ratelimit-reservoir-refresh** — #9604 (rolling RPM leases) DELETED Bottleneck's
fixed-window reservoir, so currentReservoir() is null and the poll for
`reservoir === 2` could never settle. It updated several sibling suites but not
this one. The pin on the removed mechanism is gone; what remains is the
invariant the original Bottleneck heartbeat bug actually broke and that #9529
opened this test for — after a header-learned updateSettings() the limiter must
keep admitting work, proven by racing a post-exhaustion request against a 5s
timer. 1/1.

**translator-openai-to-gemini** — #9568 (c9a3361e5a) made
buildChangedToolNameMap emit IDENTITY entries too, because Gemini lowercases
tool names in functionCall responses and the response translator needs a key to
map them back. Any request carrying tools therefore carries `_toolNameMap` in
the Antigravity envelope now. Expected key list updated and the map's contents
asserted explicitly rather than left implicit. 45/45.

Refs #9298
This commit is contained in:
diegosouzapw
2026-08-07 06:12:43 -03:00
parent db7c066f87
commit 744ab48f1c
5 changed files with 33 additions and 11 deletions

View File

@@ -107,6 +107,11 @@ export const COLLECTORS = [
glob: "open-sse/services/__tests__/antigravity-quota-family.test.ts",
sources: ["vitest.mcp.config.ts"],
},
// #8890 landed this suite here without wiring a runner, so it had never run once.
{
glob: "open-sse/services/__tests__/fail-fast-concurrency-gate.test.ts",
sources: ["vitest.mcp.config.ts"],
},
{ glob: "tests/unit/autoCombo/**/*.test.ts", sources: ["vitest.mcp.config.ts"] },
{ glob: "src/lib/memory/__tests__/generic-backend.test.ts", sources: ["vitest.mcp.config.ts"] },
{ glob: "tests/unit/encryption.spec.ts", sources: ["vitest.mcp.config.ts"] },

View File

@@ -121,7 +121,7 @@ test("INTENTIONALLY_INTERNAL is exported from check-db-rules.mjs", () => {
assert.ok(INTENTIONALLY_INTERNAL.size > 0, "INTENTIONALLY_INTERNAL must not be empty");
});
test("INTENTIONALLY_INTERNAL contains the expected 37 audited modules", () => {
test("INTENTIONALLY_INTERNAL contains the expected 38 audited modules", () => {
const expected = [
"_rowTypes",
"accessTokens",
@@ -147,6 +147,7 @@ test("INTENTIONALLY_INTERNAL contains the expected 37 audited modules", () => {
"optimizationSettings",
"pluginMetrics",
"prompts",
"probeUtils",
"providerNodeSelect",
"providerStats",
"proxyLatency",

View File

@@ -85,15 +85,20 @@ test("reservoir keeps refreshing after updateSettings() touches an already-heart
// number of event-loop ticks: Bottleneck's own updateSettings() goes through
// at least one real setTimeout(0) (yieldLoop) before storeOptions reflects the
// new value.
// #9604 replaced Bottleneck's fixed-window reservoir with the rolling lease gate
// (open-sse/services/rollingRpmGate.ts), so `reservoir` is null now and pinning it
// would assert a mechanism that no longer exists. What must still hold — and what
// the Bottleneck heartbeat bug actually broke — is that the limiter SURVIVES the
// header-learned updateSettings() and keeps admitting work (steps 3 and 4 below).
const pollDeadline = Date.now() + 2000;
let state = await rateLimitManager.__getLimiterStateForTests(PROVIDER, CONNECTION_ID, null);
while (state?.reservoir !== 2 && Date.now() < pollDeadline) {
while (!state && Date.now() < pollDeadline) {
await wait(10);
state = await rateLimitManager.__getLimiterStateForTests(PROVIDER, CONNECTION_ID, null);
}
assert.equal(state?.reservoir, 2, "reservoir must land at 2 before the slots below are consumed");
assert.ok(state, "the limiter must still exist after the header-learned update");
// 3. Consume both reservoir slots.
// 3. Consume the learned capacity.
assert.equal(
await rateLimitManager.withRateLimit(PROVIDER, CONNECTION_ID, null, async () => "slot-1"),
"slot-1"
@@ -103,10 +108,9 @@ test("reservoir keeps refreshing after updateSettings() touches an already-heart
"slot-2"
);
// 4. Reservoir is now 0. A healthy Bottleneck heartbeat refills it ~1s later
// from the reservoirRefreshInterval/reservoirRefreshAmount configured above.
// Race a 3rd request against a 5s timer: if the heartbeat died (unfixed bug),
// the request stays QUEUED forever and the timer wins instead.
// 4. Capacity is spent. Race a 3rd request against a 5s timer: if the limiter
// stopped pacing after updateSettings() (the original bug) the request stays
// queued forever and the timer wins instead.
const RACE_TIMEOUT_MS = 5000;
let timeoutHandle: ReturnType<typeof setTimeout> | undefined;
const timeout = new Promise<"timed-out">((resolve) => {
@@ -125,8 +129,8 @@ test("reservoir keeps refreshing after updateSettings() touches an already-heart
assert.equal(
result,
"slot-3",
'reservoir must refresh ~1s after being exhausted; "timed-out" means the Bottleneck ' +
"heartbeat died after updateSettings() and the reservoir never refilled " +
"(node_modules/bottleneck/lib/LocalDatastore.js _startHeartbeat clearInterval-without-null bug)"
'capacity must recover after being exhausted; "timed-out" means the limiter stopped ' +
"admitting work after the header-learned updateSettings() the failure shape of the " +
"original Bottleneck heartbeat bug (LocalDatastore _startHeartbeat clearInterval-without-null)"
);
});

View File

@@ -582,7 +582,16 @@ test("OpenAI -> Antigravity wraps Gemini requests in a Cloud Code envelope", ()
"model",
"userAgent",
"requestType",
// #9568 (c9a3361e5a): buildChangedToolNameMap now emits IDENTITY entries too,
// because Gemini lowercases tool names in functionCall responses and the
// response translator needs a key to map them back. So any request carrying
// tools now carries `_toolNameMap` in the envelope.
"_toolNameMap",
]);
assert.deepEqual(
[...(result._toolNameMap as Map<string, string>).entries()],
[["weather", "weather"]]
);
assert.equal(result.userAgent, "antigravity");
assert.equal(result.requestType, "agent");
assert.match(result.requestId, /^agent\/\d+\/[0-9a-f]{8}$/);

View File

@@ -14,6 +14,9 @@ export default defineConfig({
"open-sse/services/autoCombo/__tests__/**/*.test.ts",
"open-sse/services/combo/__tests__/**/*.test.ts",
"open-sse/services/__tests__/antigravity-quota-family.test.ts",
// #8890 shipped this suite into a directory no runner collects, so it had
// never executed once (check:test-discovery flags it as a NEW orphan).
"open-sse/services/__tests__/fail-fast-concurrency-gate.test.ts",
"src/lib/memory/__tests__/generic-backend.test.ts",
"tests/unit/autoCombo/**/*.test.ts",
"tests/unit/encryption.spec.ts",