From e7fb55464713a1a964d314e6a34037cd99e9568c Mon Sep 17 00:00:00 2001 From: Dotta <34892728+cryppadotta@users.noreply.github.com> Date: Thu, 5 Nov 2026 22:23:35 -0600 Subject: [PATCH] test(server): load setup-token route modules during suite setup (#19398) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The setup-token login route lets an owner sign in to Claude for a sandbox environment > - The route suite `server/src/routes/setup-token-route.test.ts` fails on CI in pull requests that do not touch it > - The first test in the suite times out at 15000 ms, and the other 29 tests pass > - The first test pays the one-time import cost of the agent route graph inside its own test budget > - This pull request moves that import to suite setup, which has a 30000 ms hook budget > - The benefit is a stable server shard with no change to what the tests prove ## Linked Issues or Issue Description **What happened?** A survey of failed `PR` workflow runs found intermittent failures of one test in pull requests that do not touch this area: ``` FAIL src/routes/setup-token-route.test.ts > company-and-environment setup-token route — full path > drives start, status, prompt, code, and completion with no agent id Error: Test timed out in 15000ms. ``` Examples: jobs 127423956746 and 127457298585 (shard `general-server-without-chat` 12/12). The survey counted 5 such failures. **Expected behavior** The full-path test passes on every run. The test budget measures the route behavior, not the module import. **Steps to reproduce** Run the unchanged suite on master while all CPU cores are busy: ```sh cd server node load.mjs 24 pnpm exec vitest run src/routes/setup-token-route.test.ts --reporter=verbose ``` `load.mjs` starts 24 busy-loop Node processes and runs the command. The first test fails at 15005 ms. **Root cause** `createApp()` called `vi.importActual("../routes/agents.js")` and four other modules on each call. The first call loads and transforms the full agent route graph. I timed it: `createApp()` took 11670 ms of the 11698 ms test on an idle machine. The HTTP steps took less than 30 ms. On a loaded CI runner the import alone crossed the 15000 ms test budget. Later tests reused the module cache, so only the first test failed. ## What Changed - Add `loadRouteModules()`, which imports the route and logger modules. - Call it once in the suite `beforeAll`, after `vi.resetModules()` and the mock registration. The hook budget is 30000 ms in `server/vitest.config.ts`. - `createApp()` now reuses the loaded modules. Each test still builds a fresh Express app, a fresh transport, and a fresh log capture. - This follows the pattern in `server/src/__tests__/agent-skills-routes.test.ts` (#16396). - No timeout changes, no retries, no skips. ## Verification Red, on master, with 24 busy-loop processes on an 18-core machine: ``` × ... drives start, status, prompt, code, and completion with no agent id 15005ms ``` Also red on an idle machine on 1 of 3 runs (15006 ms; the other runs took 11790 ms and 13748 ms). Green, with this change: - Idle, 3 runs: 30/30 tests pass. The first test takes 42 to 46 ms. - With 24 busy-loop processes: 30/30 tests pass. The first test takes 40 ms. The file takes 19.4 s in total. ```sh cd server pnpm exec vitest run src/routes/setup-token-route.test.ts --reporter=verbose ``` `tsc --noEmit -p server` reports no errors in this file. ## Risks - Low risk. The change touches one test file only. - The import cost now counts against the 30000 ms hook budget. Locally it is 12 to 15 s idle. The mocks register before the import, as before, so each test sees the same mocked services. ## Model Used - Claude Opus 5.5 (`claude-opus-5-5`), Anthropic, used through Claude Code with tool use (shell, file edits) and extended reasoning. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 5.5 --- server/src/routes/setup-token-route.test.ts | 28 +++++++++++++-------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/server/src/routes/setup-token-route.test.ts b/server/src/routes/setup-token-route.test.ts index 97357ef7966..b101fdd276a 100644 --- a/server/src/routes/setup-token-route.test.ts +++ b/server/src/routes/setup-token-route.test.ts @@ -361,6 +361,20 @@ function buildTransport(opts: { onSubmit?: "complete" | "throw" | "pending" } = // --- App builder with a capturing request logger ----------------------------- +function loadRouteModules() { + return Promise.all([ + vi.importActual("../routes/agents.js"), + vi.importActual("../middleware/index.js"), + vi.importActual("pino"), + vi.importActual("pino-http"), + vi.importActual( + "../middleware/redact-sensitive.js", + ), + ]); +} + +let routeModules: Awaited>; + interface AppHandle { app: express.Express; logLines: string[]; @@ -372,16 +386,7 @@ async function createApp(opts: { confidentialEdgeTlsTerminated?: boolean; transport?: TransportHandle; } = {}): Promise { - const [{ agentRoutes }, { errorHandler }, pinoModule, pinoHttpModule, redactModule] = - await Promise.all([ - vi.importActual("../routes/agents.js"), - vi.importActual("../middleware/index.js"), - vi.importActual("pino"), - vi.importActual("pino-http"), - vi.importActual( - "../middleware/redact-sensitive.js", - ), - ]); + const [{ agentRoutes }, { errorHandler }, pinoModule, pinoHttpModule, redactModule] = routeModules; const { pino } = pinoModule; const { pinoHttp } = pinoHttpModule; const { redactSensitive } = redactModule; @@ -465,9 +470,10 @@ async function settle(): Promise { } } -beforeAll(() => { +beforeAll(async () => { vi.resetModules(); registerModuleMocks(); + routeModules = await loadRouteModules(); }); beforeEach(() => {