fix(tradein): молча задеселекченный тест починен, deselect снят (#2722) #2729

Merged
bot-backend merged 1 commit from fix/2722-search-cache-deselect into main 2026-08-06 11:30:43 +00:00
Collaborator

Summary

Побочный пункт #2722: «молча задеселекченный тест — тот же класс, что каталог вне CI». Оценил и починил — оказалось, что деселект держался на неверном объяснении.

Что утверждал комментарий в ci-tradein.yml

test_search_cache_hit падает ТОЛЬКО в whole-suite ordering (401 vs 200; в изоляции проходит) — global-state leak из другого test-модуля

Что показал замер (окружение с реально установленными зависимостями, uv sync --frozen)

Прогон Результат
Только этот узел (pytest tests/test_search_api.py::test_search_cache_hit) 1 failed, assert 401 == 200
Весь сьют без deselect'а 1 failed, 3749 passed — тот же тест, тот же 401

Обе половины объяснения неверны: тест падает всегда, ordering ни при чём. «Красное» здесь означает именно красное, а не «не собралось» — остальные 3749 тестов в том же прогоне зелёные.

Настоящая причина

test_search_cache_hit — единственный тест в своём файле, который ходит по HTTP: он поднимает TestClient(app) и делает POST /api/v1/search без заголовка X-Authenticated-User. RBAC-гард на запрос без него отвечает 401 — ровно тот инвариант, который отдельно зафиксирован в tests/test_estimate_idor.py (там есть тест с буквальным названием «No X-Authenticated-User header → 401»).

Причина в тесте, а не в порядке и не в продукте. Правка — один заголовок по идиоме самого репозитория. Продуктовый код и конфигурация авторизации не тронуты.

Следствие

Deselect больше не нужен и снят из ci-tradein.yml: полный прогон tradein-backend без единого исключения3750 passed, 9 skipped, 0 failed.

В шаге pytest оставлено явное правило на будущее: не deselect'ить молча — чинить или помечать xfail с причиной в коде, где её видно рядом с тестом.

Что НЕ тронуто

Экземпляр того же deselect'а в deploy-tradein.yml (post-merge test-job) — тот файл правит открытый #2680, лезть туда не стал. Расхождение безвредно: pre-merge гейт тест теперь гоняет, post-merge просто пропустит заведомо зелёный.

Test plan

  • pytest tests/test_search_api.py → 16 passed (был 1 failed)
  • Полный uv run pytest -q без deselect'ов → 3750 passed, 9 skipped, 0 failed
  • ruff check + ruff format --check из tradein-mvp/backend → чисто
  • CI Trade-In / backend-tests на этом PR — гоняет уже без deselect'а

Refs #2722

## Summary Побочный пункт #2722: «молча задеселекченный тест — тот же класс, что каталог вне CI». Оценил и починил — оказалось, что деселект держался на неверном объяснении. ### Что утверждал комментарий в `ci-tradein.yml` > test_search_cache_hit падает **ТОЛЬКО** в whole-suite ordering (401 vs 200; **в изоляции проходит**) — global-state leak из другого test-модуля ### Что показал замер (окружение с реально установленными зависимостями, `uv sync --frozen`) | Прогон | Результат | |---|---| | Только этот узел (`pytest tests/test_search_api.py::test_search_cache_hit`) | **1 failed**, `assert 401 == 200` | | Весь сьют без deselect'а | **1 failed**, 3749 passed — тот же тест, тот же 401 | Обе половины объяснения неверны: тест падает всегда, ordering ни при чём. «Красное» здесь означает именно красное, а не «не собралось» — остальные 3749 тестов в том же прогоне зелёные. ### Настоящая причина `test_search_cache_hit` — единственный тест в своём файле, который ходит по HTTP: он поднимает `TestClient(app)` и делает `POST /api/v1/search` **без заголовка `X-Authenticated-User`**. RBAC-гард на запрос без него отвечает 401 — ровно тот инвариант, который отдельно зафиксирован в `tests/test_estimate_idor.py` (там есть тест с буквальным названием «No X-Authenticated-User header → 401»). Причина в тесте, а не в порядке и не в продукте. Правка — один заголовок по идиоме самого репозитория. **Продуктовый код и конфигурация авторизации не тронуты.** ### Следствие Deselect больше не нужен и снят из `ci-tradein.yml`: полный прогон tradein-backend **без единого исключения** → **3750 passed, 9 skipped, 0 failed**. В шаге pytest оставлено явное правило на будущее: не deselect'ить молча — чинить или помечать `xfail` с причиной в коде, где её видно рядом с тестом. ### Что НЕ тронуто Экземпляр того же deselect'а в `deploy-tradein.yml` (post-merge test-job) — тот файл правит открытый **#2680**, лезть туда не стал. Расхождение безвредно: pre-merge гейт тест теперь гоняет, post-merge просто пропустит заведомо зелёный. ## Test plan - [x] `pytest tests/test_search_api.py` → 16 passed (был 1 failed) - [x] Полный `uv run pytest -q` без deselect'ов → **3750 passed, 9 skipped, 0 failed** - [x] `ruff check` + `ruff format --check` из `tradein-mvp/backend` → чисто - [ ] `CI Trade-In / backend-tests` на этом PR — гоняет уже без deselect'а Refs #2722
bot-backend added 1 commit 2026-08-06 11:24:09 +00:00
fix(tradein): молча задеселекченный тест починен, deselect снят (#2722)
All checks were successful
CI Trade-In / changes (pull_request) Successful in 7s
CI / changes (pull_request) Successful in 8s
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
CI Trade-In / browser-tests (pull_request) Successful in 47s
CI Trade-In / frontend-checks (pull_request) Successful in 1m9s
CI Trade-In / backend-tests (pull_request) Successful in 3m12s
b8e33d981d
test_search_cache_hit был исключён из обоих пайплайнов с пояснением «падает
ТОЛЬКО в whole-suite ordering (401 vs 200; в изоляции проходит) — global-state
leak из другого test-модуля». Замер в полностью установленном окружении
опровергает обе половины: тест падает и в изоляции тоже — прогон одного этого
узла даёт 1 failed, тот же 401.

Причина не в порядке, а в самом тесте: он единственный в своём файле ходит по
HTTP и делает POST /api/v1/search БЕЗ заголовка X-Authenticated-User, а RBAC-гард
на запрос без него отвечает 401 — ровно тот инвариант, который отдельно
зафиксирован в tests/test_estimate_idor.py («No X-Authenticated-User header →
401»). Правка — один заголовок по идиоме самого репозитория; продуктовый код и
конфигурация авторизации не тронуты.

После этого deselect не нужен: полный прогон tradein-backend без единого
исключения даёт 3750 passed, 9 skipped, 0 failed.

Почему это часть #2722, а не отдельная уборка: задеселекченный тест — тот же
класс дефекта, что каталог вне пайплайна. Чек зелёный, знание о выключенной
проверке живёт в YAML, а не рядом с тестом, и следующий читатель наследует
неверное объяснение вместо симптома. В шаге pytest оставлено явное правило на
будущее: не deselect'ить молча — чинить или помечать xfail с причиной в коде.

Экземпляр того же deselect'а в deploy-tradein.yml не тронут: тот файл правит
открытый #2680. Расхождение безвредно — pre-merge гейт тест теперь гоняет.

Refs #2722
bot-backend merged commit 02b256288d into main 2026-08-06 11:30:43 +00:00
bot-backend deleted branch fix/2722-search-cache-deselect 2026-08-06 11:30:43 +00:00
Sign in to join this conversation.
No reviewers
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: lekss361/gendesign#2729
No description provided.