From d032431a5fc9c331d28dd8af62461d20f8d80c8d Mon Sep 17 00:00:00 2001 From: Diego Rodrigues de Sa e Souza Date: Thu, 17 Sep 2026 10:46:17 -0300 Subject: [PATCH] test(catalog): stop the yield guard from dying on production's build budget (#13906) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit tests/unit/9147-catalog-eventloop-yield.test.ts exists to prove the /v1/models builder yields to the event loop while assembling a catalog-scale dataset. It asserts res.status === 200 first, and only then the two checks that carry the invariant: the max event-loop gap and the traversal to the last seeded model. The case did not set CATALOG_BUILD_TIMEOUT_MS, so it inherited production's 8s cold-path budget. When the seeded build overruns that on a loaded runner, getUnifiedModelsResponse answers 503 catalog_build_timeout and the status check fails BEFORE either real assertion runs — the guard goes silently dead exactly when the machine is under the load that would make a pin most visible. CI hit it at 8350ms, right at the bound. Measured on the release tip, pristine file, 3 runs at load ~21: 2 pass with max gaps of 247ms and 180ms, 1 fails with 503 !== 200 — roughly a 1-in-3 flake, and the flake has nothing to do with yielding. Pinning a 120s budget lets the invariant be evaluated. The 800ms gap bound is untouched, and with the budget pinned the builder measures 261ms (idle) to 790ms (loaded) against it — still failing a true pin, which is seconds. Build-latency budgeting is a separate concern from this case. Refs #12732 --- tests/unit/9147-catalog-eventloop-yield.test.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/unit/9147-catalog-eventloop-yield.test.ts b/tests/unit/9147-catalog-eventloop-yield.test.ts index 45c6bd68db..85991c49a9 100644 --- a/tests/unit/9147-catalog-eventloop-yield.test.ts +++ b/tests/unit/9147-catalog-eventloop-yield.test.ts @@ -7,6 +7,16 @@ import path from "node:path"; const TEST_DATA_DIR = fs.mkdtempSync(path.join(os.tmpdir(), "omniroute-9147-")); process.env.DATA_DIR = TEST_DATA_DIR; process.env.API_KEY_SECRET = process.env.API_KEY_SECRET || "catalog-9147-test-secret"; +// This case measures whether the builder YIELDS, not how fast it finishes. The +// production cold-path budget (CATALOG_BUILD_TIMEOUT_MS, 8s) is not the subject: +// when the seeded catalog-scale build overruns it, getUnifiedModelsResponse +// answers 503 `catalog_build_timeout` and the two assertions that actually guard +// the invariant — the max event-loop gap and the traversal to the last seeded +// model — are never reached, because the status check precedes them. That is how +// this guard went silently dead on loaded runners (CI observed 8350ms, right at +// the bound). Pin a budget far above any healthy build so the yield invariant is +// evaluated; build-latency budgeting is a separate concern from this test. +process.env.CATALOG_BUILD_TIMEOUT_MS = "120000"; const core = await import("../../src/lib/db/core.ts"); const apiKeysDb = await import("../../src/lib/db/apiKeys.ts");