[PIX-13084] fix(server): устранить гонку мока в issue-agent-mutation-ownership-routes.test.ts #189
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "agent/fullstack/pix-13084"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Что сделано
issue-agent-mutation-ownership-routes.test.tsзаменил конкурентныйPromise.all([vi.importActual(middleware), vi.importActual(routes/issues)])на последовательныеawait— убрал единственное отличие этого файла от соседних (external-object-routes.test.ts,issue-attachment-routes.test.ts), где такой гонки не наблюдалось.heartbeatService.cancelScheduledRetriesForIssue(нужен маршрутуroutes/issues.ts:6608), который раньше падал сTypeError: ... is not a functionи глушился внутреннимtry/catch.Зачем
CI-лог упавшего прогона (job 51272 / task 35830, API Tests) показал, что 11 из 62 тестов упали не из-за коллизии тестовых данных (литеральных UUID), а потому что реальный, немоканный сервисный код (
taskWatchdogService.reconcileForIssueAndAncestors,heartbeat.cancelScheduledRetriesForIssue) исполнился поверх фейковогоdb-мока —vi.doMock("../services/index.js", ...)не успел примениться к моменту резолва маршрута. Отсюдаdb.execute is not a functionв логах и цепочка assertion-failures (expected 200 to be 403,expected 422 to be 200и т.п.) — реальные бизнес-правила (например, обязательныйprojectId) сработали вместо замоканных заглушек.Это НЕ известная гонка act-runner (PIX-13081, "network not found") и НЕ дефект самого продакшен-кода — локально файл стабильно зелёный (62/62), в этом же CI-прогоне до и после падали/проходили десятки других route-suite файлов без проблем. Разница именно этого файла — конкурентный импорт двух самых больших модулей репо (
routes/issues.ts~8600 строк,middleware/index.js) в самом крупном route-suite (62 теста, ~90 вызововcreateApp()за прогон), что даёт больше всего шансов поймать редкую гонку резолва модулей на перегруженном self-hosted раннере.План тестирования
npx vitest run src/__tests__/issue-agent-mutation-ownership-routes.test.ts— 62/62 зелёные, WARN про "not a function" в логе больше нет.pnpm --filter @paperclipai/server typecheck— 0 ошибок.pnpm typecheck(весь workspace) прогнан pre-push хуком — зелёный.Где могу ошибаться
continue-on-error: trueи НЕ входит в обязательные status checks для мержа в master (только "PR Quality Gates" и "Agents CI / Typecheck and Build") — то есть PR #187 фактически не блокируется этим падением технически, хотя создаёт шум в CI.Promise.allпаттерн есть ещё вexternal-object-routes.test.tsиissue-attachment-routes.test.ts— они пока не падали в CI, поэтому намеренно не трогал их в этом PR (не относится к PIX-13084), но при повторении проблемы там стоит применить тот же фикс.CI-лог job 51272/task 35830 показал, что при 11 падениях в файле реально выполнялся немоканный сервисный код (taskWatchdogService.reconcileForIssueAndAncestors и heartbeat.cancelScheduledRetriesForIssue) поверх фейкового db — то есть vi.doMock("../services/index.js", ...) не применился к моменту резолва маршрута. Единственное отличие этого файла от похожих (external-object-routes, issue-attachment-routes) — конкурентный Promise.all([vi.importActual(middleware), vi.importActual(routes/issues)]) для двух самых крупных модулей в самом большом route-suite (62 теста, ~90 вызовов createApp() за прогон). Заменил на последовательные await, убрав окно для гонки резолва модулей на нагруженном раннере. Заодно добавил недостающий мок heartbeatService.cancelScheduledRetriesForIssue (routes/issues.ts:6608) — раньше вызов падал с "not a function" и глушился try/catch, оставляя WARN в логах теста без явного покрытия.