Files
wiki/tasks/orchestrator/reports/dev-2026-06-04-fix-webhook-secret-isolation.md
2026-06-05 00:10:01 +03:00

98 lines
5.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Dev Report: fix-webhook-secret-isolation
Дата: 2026-06-04
Статус: DONE
## Задача
Исправить кросс-файловую утечку webhook-секрета через синглтон settings (Pydantic).
pytest tests/ давал 10 failed/284 passed (assert 401==200). Нужно: 0 failed.
Работать в ветке `fix/isolate-webhook-tests-from-plane`, добавить коммит поверх 7bbab9c, e856e09.
## Сделано
- [x] Прочитал ТЗ полностью
- [x] Подключился к серверу slin@82.22.50.71, перешёл на ветку
- [x] Изучил текущий conftest.py и образец из test_webhook_dedup.py:80-81
- [x] Добавил autouse-фикстуру `_reset_webhook_secrets` в tests/conftest.py
- [x] Обнаружил вторую скрытую проблему (db_path тоже протекает)
- [x] Расширил фикстуру — добавил изоляцию db_path
- [x] Прогнал полный pytest tests/ = **294 passed, 0 failed**
- [x] Проверил dedup тесты отдельно = 9 passed (HMAC/401 живы)
- [x] Проверил test_webhooks.py отдельно = 16 passed
- [x] git commit + push в ветку
- [x] CI job = success ✅
## Изменённые файлы
- `tests/conftest.py` — добавлена autouse-фикстура `_reset_webhook_secrets`
## Результат
```
294 passed, 4 warnings in 6.03s (было: 10 failed, 284 passed)
```
HMAC/dedup тесты:
```
tests/test_webhook_dedup.py: 9 passed (включая 401-тесты на строках 268, 278)
```
test_webhooks.py:
```
16 passed
```
CI job: **success** (2026-06-05T00:00:38+03:00, было failures с 2026-06-04)
git log:
```
1baae81 test: reset webhook secret per-test to fix cross-file isolation (CI green)
e856e09 test: migrate sequential_ids test to In Progress contract
7bbab9c test: isolate webhook tests from live Plane API (fix CI)
```
## Проблемы и решения
### Проблема 1 (ожидаемая): webhook-секрет
**Причина:** settings (Pydantic синглтон) создаётся при первом import src.config. Порядок
импорта тестов — алфавитный. test_webhook_dedup.py импортируется первым и не устанавливает
`ORCH_*_WEBHOOK_SECRET=""` жёстко (устанавливает через `os.environ.setdefault`). В итоге
если в среде есть реальный секрет — settings.{gitea,plane}_webhook_secret ≠ "" и HMAC включается.
**Решение:** monkeypatch.setattr перед каждым тестом сбрасывает оба секрета в "".
Тесты 268,278 в test_webhook_dedup.py перекрывают это своим monkeypatch внутри теста —
порядок: autouse conftest → autouse модульные → тест-код; monkeypatch стекируется.
### Проблема 2 (обнаружена в процессе): db_path
**Причина:** Аналогичная утечка через settings.db_path. test_webhook_dedup.py импортируется
первым, устанавливает `os.environ["ORCH_DB_PATH"] = "/tmp/test_orchestrator_dedup.db"`,
settings создаётся с этим значением. test_webhooks.py импортируется позже и устанавливает
env в `/tmp/test_orchestrator.db`НО settings уже создан, поэтому settings.db_path
остаётся = dedup.db.
Следствие: setup_db в test_webhooks.py удаляет `_test_db_webhooks` (которого нет),
а фактическая БД — dedup.db — не очищается между тестами. Два теста подряд используют
ветку `feature/ET-011-test`, в БД остаётся задача со стадией review после первого теста,
второй тест вставляет новую задачу но `get_task_by_repo_branch()` без ORDER BY может
вернуть старую задачу → `current_stage != "development"``notify_qg_failure` не
вызывается → тест test_gitea_ci_failure_on_development_notifies_qg_failure падает.
Это было скрыто за assert 401==200 (первый assert в тесте не проходил). Стало видно
после устранения первой проблемы.
**Решение:** В той же autouse фикстуре добавляем:
```python
db_path_env = os.environ.get("ORCH_DB_PATH", "")
if db_path_env:
monkeypatch.setattr(db_mod.settings, "db_path", db_path_env, raising=False)
```
`os.environ["ORCH_DB_PATH"]` = последнее присвоенное значение после всех импортов =
`/tmp/test_orchestrator.db` (test_webhooks.py импортируется последним алфавитно). Тесты
dedup перекрывают это своим monkeypatch.setattr в их `setup_db` фикстуре — работает корректно.
### Почему не нарушаются 401/HMAC тесты
Монопатч conftest autouse (`_reset_webhook_secrets`) применяется ПЕРЕД `setup_db` из
test_webhook_dedup. В тестах 268,278 monkeypatch.setattr вызывается ВНУТРИ теста
(после setup). monkeypatch стекирует патчи — последний выигрывает. После теста —
все откатываются в обратном порядке. autouse фикстура conftest повторно применяется
перед следующим тестом.
## Следующий шаг
PR #27 готов к ревью координатором (Стримом). НЕ мержить самостоятельно.