From e25b706c56596396f45e5372a4cd4f6e2e133ee7 Mon Sep 17 00:00:00 2001 From: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> Date: Thu, 10 Sep 2026 19:13:05 -0300 Subject: [PATCH] test(lease): re-inventory hard-lease call sites after the pipeline extraction MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Four drifts, all from PRs merged into the tip on 2026-09-07: - #12867 extracted chatCore.ts's streaming execution loop into chatCore/providerExecutionPipeline.ts. Its two getProviderCredentials() sites now go through the injected `connection.getProviderCredentials` handle, which the bare-identifier AST scan never saw — the sites would have left the inventory unnoticed. Count property-access calls too and inventory the new file. - #12867 also re-expressed the codex 429 managed-lease fence: the inline `provider === "codex" && !managedLease` became `allowAccountRotation: !managedLease && …` in chatCore.ts, gated in the pipeline as `canRotateAccount`. Assert both halves of that seam instead of the vanished inline form. - #12746 moved combo.ts's getProviderConnectionById into combo/executeTargetGates.ts (class B, unchanged). - #12805 added the Grok Build reset-credit path: src/lib/usage/grokResetCredits.ts (class B — same isConnectionUnavailableToAuxiliaryActivity fence as its codex sibling, so it also joins auxiliaryIsolationSources) and src/app/api/usage/codex-reset-credit/route.ts (class C — resolves the connection's provider to pick a library, never to serve a request). Also pin CATALOG_BUILD_TIMEOUT_MS in models-catalog-route.test.ts: #12627's 8s cold-build bound is sized for a warm production process, and a tsx test runner building the full catalog from a fresh SQLite file crosses it (10-13s observed), returning a `catalog_build_timeout` error body with no `data` array. The bound's own behavior stays covered by 12627-catalog-inflight-timeout.test.ts. --- ...ard-session-lease-bypass-inventory.test.ts | 70 ++++++++++++++----- tests/unit/models-catalog-route.test.ts | 8 +++ 2 files changed, 59 insertions(+), 19 deletions(-) diff --git a/tests/unit/hard-session-lease-bypass-inventory.test.ts b/tests/unit/hard-session-lease-bypass-inventory.test.ts index 97e713a0c7..5b89f59225 100644 --- a/tests/unit/hard-session-lease-bypass-inventory.test.ts +++ b/tests/unit/hard-session-lease-bypass-inventory.test.ts @@ -13,7 +13,12 @@ type BypassClass = "A" | "B" | "C"; const EXPECTED: Record> = { credential: { - "open-sse/handlers/chatCore.ts": 2, + // #12867 extracted chatCore.ts's streaming provider-execution loop into + // chatCore/providerExecutionPipeline.ts. Its two getProviderCredentials() + // sites (codex 429 rotation, antigravity BYOP rotation) moved with it and are + // now reached through the injected `connection.getProviderCredentials` handle, + // so countCalls() also inventories property-access calls. + "open-sse/handlers/chatCore/providerExecutionPipeline.ts": 2, "open-sse/services/imageCombo.ts": 1, "open-sse/services/speechCombo.ts": 1, "open-sse/services/videoCombo.ts": 2, @@ -88,8 +93,9 @@ const EXPECTED: Record> = { "open-sse/services/antigravityFamilyCooldown.ts": 1, // v3.8.50 back-merge additions (f95b03d7): combo routing infra and the // volcengine-plan binding/auto-sync services query connections the same - // way as their classified siblings. - "open-sse/services/combo.ts": 1, + // way as their classified siblings. #12746 split executeTarget out of + // combo.ts, moving this lookup into combo/executeTargetGates.ts unchanged. + "open-sse/services/combo/executeTargetGates.ts": 1, "open-sse/services/combo/providerWildcard.ts": 1, "open-sse/services/tokenRefresh.ts": 1, "src/lib/providers/volcPlanAutoSyncBackfill.ts": 1, @@ -127,6 +133,11 @@ const EXPECTED: Record> = { "src/app/api/translator/send/route.ts": 1, "src/app/api/translator/translate/route.ts": 1, "src/app/api/usage/call-logs/route.ts": 1, + // #12805: the reset-credit route resolves the connection's PROVIDER to pick + // the codex or grok-cli library; the exclusive-lease fence itself lives in + // those libraries (both listed in auxiliaryIsolationSources below). It never + // selects a connection to serve a request, so it stays class C. + "src/app/api/usage/codex-reset-credit/route.ts": 1, "src/app/api/usage/quota/route.ts": 1, "src/app/api/usage/utilization/route.ts": 1, "src/app/api/v1/vscode/[token]/api/tags/route.ts": 1, @@ -174,6 +185,9 @@ const EXPECTED: Record> = { "src/lib/usage/callLogs.ts": 1, "src/lib/usage/codexResetCredits.ts": 1, "src/lib/usage/comboScoringInspector.ts": 1, + // #12805: Grok Build sibling of codexResetCredits.ts — same auxiliary-activity + // fence in front of the same connection lookup, so same class B. + "src/lib/usage/grokResetCredits.ts": 1, "src/lib/usage/providerLimits.ts": 4, "src/lib/usage/resilienceExplain.ts": 1, "src/lib/usage/usageStats.ts": 1, @@ -212,10 +226,9 @@ const CLASSIFICATION: Record> = { [ "open-sse/handlers/autoComboCandidates.ts", "open-sse/handlers/chatCore.ts", - "open-sse/services/combo.ts", "open-sse/services/alibabaFreeTier.ts", "open-sse/services/alibabaFreeTierQuotaFetcher.ts", - "open-sse/services/combo.ts", + "open-sse/services/combo/executeTargetGates.ts", "open-sse/services/combo/providerWildcard.ts", "open-sse/services/tokenRefresh.ts", "src/app/api/translator/send/route.ts", @@ -224,6 +237,7 @@ const CLASSIFICATION: Record> = { "src/lib/providers/volcenginePlanBinding.ts", "src/lib/services/quotaAutoPing.ts", "src/lib/usage/codexResetCredits.ts", + "src/lib/usage/grokResetCredits.ts", "src/lib/usage/providerLimits.ts", "src/lib/vncSession/service.ts", "src/lib/warmupScheduler.ts", @@ -260,14 +274,13 @@ function countCalls(): Record> { const key = file.split(path.sep).join("/"); actual[kind][key] = (actual[kind][key] ?? 0) + 1; }; + const isCredentialName = (name: string) => + name === "getProviderCredentials" || name === "getProviderCredentialsWithQuotaPreflight"; const visit = (node: ts.Node): void => { if (ts.isCallExpression(node)) { const expression = node.expression; if (ts.isIdentifier(expression)) { - if ( - expression.text === "getProviderCredentials" || - expression.text === "getProviderCredentialsWithQuotaPreflight" - ) { + if (isCredentialName(expression.text)) { increment("credential"); } if ( @@ -276,15 +289,22 @@ function countCalls(): Record> { ) { increment("connection"); } - } else if ( - ts.isPropertyAccessExpression(expression) && - expression.name.text === "execute" && - ts.isIdentifier(expression.expression) && - ["executor", "fallbackExecutor", "providerExecutor", "streamExecutor"].includes( - expression.expression.text - ) - ) { - increment("executor"); + } else if (ts.isPropertyAccessExpression(expression)) { + // #12867: the extracted execution pipeline reaches the resolver through an + // injected handle (`connection.getProviderCredentials(...)`), so a + // bare-identifier scan alone would let those sites leave the inventory. + if (isCredentialName(expression.name.text)) { + increment("credential"); + } + if ( + expression.name.text === "execute" && + ts.isIdentifier(expression.expression) && + ["executor", "fallbackExecutor", "providerExecutor", "streamExecutor"].includes( + expression.expression.text + ) + ) { + increment("executor"); + } } } ts.forEachChild(node, visit); @@ -312,6 +332,10 @@ test("managed request surfaces are fenced centrally or rejected before independe path.join(REPO_ROOT, "src/app/api/internal/codex-responses-ws/route.ts"), "utf8" ); + const executionPipeline = fs.readFileSync( + path.join(REPO_ROOT, "open-sse/handlers/chatCore/providerExecutionPipeline.ts"), + "utf8" + ); const internalKeys = fs.readFileSync(path.join(REPO_ROOT, "src/lib/db/apiKeys.ts"), "utf8"); const auxiliaryIsolationSources = [ "src/app/api/providers/[id]/models/route.ts", @@ -320,6 +344,7 @@ test("managed request surfaces are fenced centrally or rejected before independe "src/lib/api/modelTestRunner.ts", "src/lib/services/quotaAutoPing.ts", "src/lib/usage/codexResetCredits.ts", + "src/lib/usage/grokResetCredits.ts", "src/lib/vncSession/service.ts", "src/lib/warmupScheduler.ts", "src/shared/services/modelSyncScheduler.ts", @@ -336,7 +361,14 @@ test("managed request surfaces are fenced centrally or rejected before independe core, /assertManagedLeaseFence\(getExecutionConnectionId\(getExecutionCredentials\(\)\)\)/ ); - assert.match(core, /provider === "codex" &&\s*!managedLease/); + // #12867 moved the codex 429 account-rotation out of chatCore.ts into + // chatCore/providerExecutionPipeline.ts. The managed-lease fence moved with it: + // the inline `provider === "codex" && !managedLease` became the policy flag + // chatCore computes and the pipeline gates every rotation on. Assert both halves + // so the fence cannot be dropped on either side of that seam. + assert.match(core, /allowAccountRotation:\s*!managedLease\b/); + assert.match(executionPipeline, /canRotateAccount\s*=\s*policy\.allowAccountRotation\b/); + assert.match(executionPipeline, /canRotateAccount &&\s*target\.provider === "codex"/); assert.match(ws, /LEASE_UNSUPPORTED_TRANSPORT/); assert.match(internalKeys, /!k\.scopes\?\.includes\(EXCLUSIVE_LEASE_SCOPE\)/); for (const source of auxiliaryIsolationSources) { diff --git a/tests/unit/models-catalog-route.test.ts b/tests/unit/models-catalog-route.test.ts index cfecc23c96..9fc3584a2d 100644 --- a/tests/unit/models-catalog-route.test.ts +++ b/tests/unit/models-catalog-route.test.ts @@ -7,6 +7,14 @@ import path from "node:path"; const TEST_DATA_DIR = fs.mkdtempSync(path.join(os.tmpdir(), "omniroute-model-catalog-")); process.env.DATA_DIR = TEST_DATA_DIR; process.env.API_KEY_SECRET = process.env.API_KEY_SECRET || "catalog-test-secret"; +// #12627 bounds a cold catalog build at 8s and, with no last-good response to fall +// back on, surfaces `catalog_build_timeout` as an error body — no `data` array. That +// bound is sized for a warm production process; a tsx-transpiled test runner building +// the full 500+ model catalog from a fresh SQLite file on a loaded CI box crosses it +// (10-13s observed), which turned the assertions below into a load-dependent flake. +// Raise it here so these cases test catalog CONTENT; the timeout behavior itself is +// covered by tests/unit/12627-catalog-inflight-timeout.test.ts. +process.env.CATALOG_BUILD_TIMEOUT_MS = process.env.CATALOG_BUILD_TIMEOUT_MS || "120000"; const core = await import("../../src/lib/db/core.ts"); const providersDb = await import("../../src/lib/db/providers.ts");