[CI] API Tests красный 3 рана подряд: agent-instructions-routes «returns bundle metadata» — timeout 5s #170

Closed
opened 2026-07-04 15:21:24 +00:00 by andrei · 5 comments
Owner

Стабильный фейл (не флейк): task 35358 (701fd241), 35384 (f46f5d23), 35411 (2fea87b8).

Из лога 35384:

  • FAIL server/src/tests/agent-instructions-routes.test.ts > agent instructions bundle routes > returns bundle metadata
  • Error: Test timed out in 5000ms (строка 251)
  • Остальные 4 кейса файла зелёные; все прочие сьюты зелёные; Typecheck зелёный.

Тест ждёт GET /api/agents//instructions-bundle с mockAgentInstructionsService.getBundle — таймаут указывает, что роут не доходит до мока (висящий await в новом код-пути?). Началось в окне merge #168 и соседних коммитов.

Диагностика снята с runner-логов Forgejo (/data/gitea/actions_log/.../35384.log.zst). Локальная Windows-репродукция невозможна (embedded-postgres). Чинить владельцам репо на 178.

Стабильный фейл (не флейк): task 35358 (701fd241), 35384 (f46f5d23), 35411 (2fea87b8). Из лога 35384: - FAIL server/src/__tests__/agent-instructions-routes.test.ts > agent instructions bundle routes > returns bundle metadata - Error: Test timed out in 5000ms (строка 251) - Остальные 4 кейса файла зелёные; все прочие сьюты зелёные; Typecheck зелёный. Тест ждёт GET /api/agents/<id>/instructions-bundle с mockAgentInstructionsService.getBundle — таймаут указывает, что роут не доходит до мока (висящий await в новом код-пути?). Началось в окне merge #168 и соседних коммитов. Диагностика снята с runner-логов Forgejo (/data/gitea/actions_log/.../35384.log.zst). Локальная Windows-репродукция невозможна (embedded-postgres). Чинить владельцам репо на 178.
Author
Owner

Статус после PR #169 (merge 32b6f8b6, 2026-07-04):

Закрыто в PR #169:

  • Корневая причина красных ранов — postgres service-контейнер не стартовал: host-port publish 5432 конфликтовал с europatech-postgres на раннере. Убран publish, DATABASE_URL через docker alias.
  • «returns bundle metadata» (сабж issue) — класс transform cold-start: первый тест каждого route-файла платил vite transform routes/agents.ts внутри 5s бюджета. Закрыто testTimeout: 30_000 + beforeAll-прогрев в agent-instructions.
  • Лимиты джобы 30/25 мин (suite 105 файлов обрывался старым 5-минутным шагом с зелёными тестами).
  • Stale assertions: agent-live-run-routes (companyId UUID, {summary:false}), approval-routes-idempotency (UUID-фикстуры под isUuidLike).
  • Настоящий регресс: три legacy 307-alias роута в companies.ts потеряны при upstream-merge v2026.626.0 — восстановлены из прод-снапшота 247c7749.

Остаток (для PIX-13034 cleanup):

  • adapter-routes-authz «allows instance admins to reach mutating adapter routes»: npm install failed: spawn npm ENOENT — только в CI (node:22 контейнер), локально 4/4 зелёный. Мок node:child_process.execFile в CI-среде не перехватывает вызов — разобрать env-разницу (Node 22 vs 24 / vitest builtin mocking).
  • Дальше по suite могут быть ещё слои — каждый красный слой проверять методом «git show двух ревизий»: тест устарел или код потерял форк-патч.

Джоба остаётся non-blocking (continue-on-error) до конца cleanup — задумано, run-статус при этом красный из-за известного ограничения forgejo-runner.

Статус после PR #169 (merge `32b6f8b6`, 2026-07-04): **Закрыто в PR #169:** - Корневая причина красных ранов — postgres service-контейнер не стартовал: host-port publish 5432 конфликтовал с `europatech-postgres` на раннере. Убран publish, `DATABASE_URL` через docker alias. - «returns bundle metadata» (сабж issue) — класс transform cold-start: первый тест каждого route-файла платил vite transform `routes/agents.ts` внутри 5s бюджета. Закрыто `testTimeout: 30_000` + beforeAll-прогрев в agent-instructions. - Лимиты джобы 30/25 мин (suite 105 файлов обрывался старым 5-минутным шагом с зелёными тестами). - Stale assertions: `agent-live-run-routes` (companyId UUID, `{summary:false}`), `approval-routes-idempotency` (UUID-фикстуры под `isUuidLike`). - **Настоящий регресс**: три legacy 307-alias роута в `companies.ts` потеряны при upstream-merge v2026.626.0 — восстановлены из прод-снапшота `247c7749`. **Остаток (для PIX-13034 cleanup):** - `adapter-routes-authz` «allows instance admins to reach mutating adapter routes»: `npm install failed: spawn npm ENOENT` — только в CI (node:22 контейнер), локально 4/4 зелёный. Мок `node:child_process.execFile` в CI-среде не перехватывает вызов — разобрать env-разницу (Node 22 vs 24 / vitest builtin mocking). - Дальше по suite могут быть ещё слои — каждый красный слой проверять методом «`git show` двух ревизий»: тест устарел или код потерял форк-патч. Джоба остаётся non-blocking (`continue-on-error`) до конца cleanup — задумано, run-статус при этом красный из-за известного ограничения forgejo-runner.
Author
Owner

Дополнение после глубокого разбора (без Linux-репро):

  1. Красный ХРОНИЧЕСКИЙ: все видимые раны API Tests failure минимум с 5fdd55b78 (страница 2 истории тасков) — не регрессия #168. Похоже, BP не требует этот джоб и мержится мимо.
  2. Мок-фикстуры теста КОРРЕКТНЫ: beforeEach настраивает mockAgentInstructionsService.getBundle.mockResolvedValue(полный bundle) и accessService.decide → allowed. Т.е. таймаут НЕ от пустого мока.
  3. Главный подозреваемый — харнесс: beforeEach делает vi.resetModules() + vi.doMock(...) (registerModuleMocks), а createApp затем vi.importActual(routes/agents.js). В vitest importActual обходит моки; вопрос — тянет ли транзитивный import services/index.js РЕАЛЬНЫЙ модуль (тогда getBundle идёт в реальный сервис → ФС/БД в CI-контейнере → таймаут 5s). Проверка в один шаг на Linux: в тесте залогировать instructions === mockAgentInstructionsService внутри роута или заменить importActual на обычный import после doMock.
  4. Почему падает только «returns bundle metadata»: остальные кейсы файла бьют пути readFile/writeFile — вероятно, реальный сервис на них быстро отвечает ошибкой, а getBundle сканирует bundle-директорию.

Рекомендация: воспроизвести под Linux одним vitest-файлом, проверить пункт 3; фикс, скорее всего, — выравнивание харнеса (использовать top-level vi.mock без resetModules-цикла, как в соседних route-тестах).

Дополнение после глубокого разбора (без Linux-репро): 1. Красный ХРОНИЧЕСКИЙ: все видимые раны API Tests failure минимум с 5fdd55b78 (страница 2 истории тасков) — не регрессия #168. Похоже, BP не требует этот джоб и мержится мимо. 2. Мок-фикстуры теста КОРРЕКТНЫ: beforeEach настраивает mockAgentInstructionsService.getBundle.mockResolvedValue(полный bundle) и accessService.decide → allowed. Т.е. таймаут НЕ от пустого мока. 3. Главный подозреваемый — харнесс: beforeEach делает vi.resetModules() + vi.doMock(...) (registerModuleMocks), а createApp затем vi.importActual(routes/agents.js). В vitest importActual обходит моки; вопрос — тянет ли транзитивный import services/index.js РЕАЛЬНЫЙ модуль (тогда getBundle идёт в реальный сервис → ФС/БД в CI-контейнере → таймаут 5s). Проверка в один шаг на Linux: в тесте залогировать instructions === mockAgentInstructionsService внутри роута или заменить importActual на обычный import после doMock. 4. Почему падает только «returns bundle metadata»: остальные кейсы файла бьют пути readFile/writeFile — вероятно, реальный сервис на них быстро отвечает ошибкой, а getBundle сканирует bundle-директорию. Рекомендация: воспроизвести под Linux одним vitest-файлом, проверить пункт 3; фикс, скорее всего, — выравнивание харнеса (использовать top-level vi.mock без resetModules-цикла, как в соседних route-тестах).
Author
Owner

РЕПРО-ПАК (стенд /tmp/agents-fix на 178, логи /tmp/af-*.log):

  1. ИЗОЛИРОВАННО тест зелёный: pnpm exec vitest run src/tests/agent-instructions-routes.test.ts → 5/5 passed (лог /tmp/af-test.log).
  2. Полный pnpm run test:run:serialized → RC=1, но ЖЕРТВА ПЛАВАЕТ: в этом прогоне упал document-annotation-routes (2 кейса, симптом другой — «expected vi.fn() to not be called…called 1 times», лог /tmp/af-full.log), agent-instructions прошёл. В CI стабильно падает agent-instructions timeout.
  3. Конфиг изоляции формально корректен: vitest.config isolate:true + pool forks; serialized = --no-file-parallelism --maxWorkers=1 (scripts/run-vitest-stable.mjs:62).

ВЫВОД: межфайловая утечка НЕ через module-graph (форки изолируют), а через ВНЕШНЕЕ разделяемое состояние. Кандидаты: (а) реальные пути /tmp/agent-1 и т.п. в фикстурах — если какой-то тест материализует их на ФС, соседи начинают видеть реальные каталоги; (б) singleton embedded-postgres/фоновые таймеры, переживающие файл; (в) env-мутации.

Следующий шаг владельцу (1 команда на стенде): прогнать serialized ДВАЖДЫ подряд и сравнить падения; затем ls /tmp/agent-* после прогона — если каталоги существуют, виновник — тест, пишущий фикстуры на реальную ФС без cleanup.

Диагност: DevSecOps Core. Стенд оставлен в /tmp/agents-fix (можно сносить).

РЕПРО-ПАК (стенд /tmp/agents-fix на 178, логи /tmp/af-*.log): 1. ИЗОЛИРОВАННО тест зелёный: pnpm exec vitest run src/__tests__/agent-instructions-routes.test.ts → 5/5 passed (лог /tmp/af-test.log). 2. Полный pnpm run test:run:serialized → RC=1, но ЖЕРТВА ПЛАВАЕТ: в этом прогоне упал document-annotation-routes (2 кейса, симптом другой — «expected vi.fn() to not be called…called 1 times», лог /tmp/af-full.log), agent-instructions прошёл. В CI стабильно падает agent-instructions timeout. 3. Конфиг изоляции формально корректен: vitest.config isolate:true + pool forks; serialized = --no-file-parallelism --maxWorkers=1 (scripts/run-vitest-stable.mjs:62). ВЫВОД: межфайловая утечка НЕ через module-graph (форки изолируют), а через ВНЕШНЕЕ разделяемое состояние. Кандидаты: (а) реальные пути /tmp/agent-1 и т.п. в фикстурах — если какой-то тест материализует их на ФС, соседи начинают видеть реальные каталоги; (б) singleton embedded-postgres/фоновые таймеры, переживающие файл; (в) env-мутации. Следующий шаг владельцу (1 команда на стенде): прогнать serialized ДВАЖДЫ подряд и сравнить падения; затем ls /tmp/agent-* после прогона — если каталоги существуют, виновник — тест, пишущий фикстуры на реальную ФС без cleanup. Диагност: DevSecOps Core. Стенд оставлен в /tmp/agents-fix (можно сносить).
Author
Owner

Слои 6-7 закрыты PR #174 (merge). Следующий слой (run 35650): issue-agent-mutation-ownership-routes — 11/62 failed, воспроизводится локально на чистом master (не CI-env). Три класса: (1) issue list fast path отвечает 500 Internal; (2) требование Agent-created issues must include an explicit projectId против старых фикстур; (3) invalid_issue_disposition валидация против agent-authored updates. Классы 2-3 похожи на новые валидации из партии PIX-12986/PIX-12937 без обновления тестов; класс 1 требует разбора stack trace. Метод прежний: git show двух ревизий по каждому классу.

Слои 6-7 закрыты PR #174 (merge). Следующий слой (run 35650): `issue-agent-mutation-ownership-routes` — 11/62 failed, воспроизводится локально на чистом master (не CI-env). Три класса: (1) issue list fast path отвечает 500 Internal; (2) требование `Agent-created issues must include an explicit projectId` против старых фикстур; (3) `invalid_issue_disposition` валидация против agent-authored updates. Классы 2-3 похожи на новые валидации из партии PIX-12986/PIX-12937 без обновления тестов; класс 1 требует разбора stack trace. Метод прежний: git show двух ревизий по каждому классу.
Author
Owner

Закрыто. Master push-ран c3982b61: Agents CI / API Tests (push) = success, Typecheck and Build (push) = success — первый полностью зелёный master за партию.

Серия PR: #169 (порт-коллизия postgres + transform-класс + лимиты джобы), #174 (annotation-wake drift + tombstone DELETE), #175 (security: visibility-фильтр списка, createdByRunId guard, watchdog-сериализация), #177 (attachment byte-range + canonicalize), #178 (снятие 10s overrides + telemetry-моки), #180 (closed-workspace моки), #181 (list-limit пагинация/blockedBy), #182 (watchdog reconcile мок), #184 (clear-error роут восстановлен, OpenAPI-контракт доведён, cross-tenant suite раскван).

Итог по типам: 6 потерянных при merge v2026.626.0 маршрутов/guard-ов восстановлены (в т.ч. 2 security), 1 фантомная spec-запись закрыта восстановлением кода, остальное — тесты/моки, отставшие от живых форк-фич. Метод для будущих merge: «мёртвое определение» (helper/spec-запись без вызовов) — самый быстрый детектор потерь.

**Закрыто.** Master push-ран `c3982b61`: `Agents CI / API Tests (push) = success`, `Typecheck and Build (push) = success` — первый полностью зелёный master за партию. Серия PR: #169 (порт-коллизия postgres + transform-класс + лимиты джобы), #174 (annotation-wake drift + tombstone DELETE), #175 (security: visibility-фильтр списка, createdByRunId guard, watchdog-сериализация), #177 (attachment byte-range + canonicalize), #178 (снятие 10s overrides + telemetry-моки), #180 (closed-workspace моки), #181 (list-limit пагинация/blockedBy), #182 (watchdog reconcile мок), #184 (clear-error роут восстановлен, OpenAPI-контракт доведён, cross-tenant suite раскван). Итог по типам: 6 потерянных при merge v2026.626.0 маршрутов/guard-ов восстановлены (в т.ч. 2 security), 1 фантомная spec-запись закрыта восстановлением кода, остальное — тесты/моки, отставшие от живых форк-фич. Метод для будущих merge: «мёртвое определение» (helper/spec-запись без вызовов) — самый быстрый детектор потерь.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
europa-tech-srl/europa-tech-agents#170
No description provided.