Срез 0 [fix C-1]: пакет src не создаёт приложение — эмулятор стартует без настроек шлюза

`api/src/__init__.py` оставлен только с docstring: `python -m src.scan_emulator` больше не импортирует `src.app`
и не требует `OPENBAO__*`. `run_server.py` импортирует `app` из `src.app`, `get_settings` — из `src.core.config`.
Регрессионный тест: subprocess эмулятора с окружением только PATH/ENV_FILE/SCAN_HOTFOLDER_PATH -> код 2,
сообщение про корень горячей папки, без ValidationError.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Andrey Epifancev 2026-10-04 05:01:16 +04:00
parent 58bcae2a57
commit ad3fb34dba
4 changed files with 36 additions and 9 deletions

View File

@ -1,6 +1,7 @@
import uvicorn
from src import app, get_settings
from src.app import app
from src.core.config import get_settings
if __name__ == "__main__":
settings = get_settings()

View File

@ -1,7 +1,5 @@
from .app import app
from .core.config import get_settings
"""Пакет сервиса scan-gateway.
__all__ = [
"app",
"get_settings",
]
Импорт пакета не создаёт приложение и не читает настройки шлюза: эмулятор (`python -m src.scan_emulator`) запускается
без переменных `OPENBAO__*`. Приложение — `src.app:app` (точка входа — `run_server.py`).
"""

View File

@ -1,5 +1,5 @@
"""Общие фикстуры. Окружение тестов — `api/.env.test`: его подключает pytest.ini (`ENV_FILE=.env.test`, путь от
каталога api/), поэтому `import src` (он создаёт приложение) работает без своей настройки окружения
каталога api/), поэтому `import src.app` (он создаёт приложение) работает без своей настройки окружения
и без инфраструктуры."""
import sys
@ -12,7 +12,7 @@ from loguru import logger
@pytest.fixture(autouse=True)
def _fresh_settings():
"""get_settings кэшируется (lru_cache): сбрасываем кэш до и после каждого теста."""
# Импорт отложен намеренно: `import src` создаёт приложение и читает окружение
# Импорт отложен намеренно: модули тестов импортируют `src.app`, а он создаёт приложение и читает окружение
from src.core.config import get_settings # noqa: PLC0415
get_settings.cache_clear()

View File

@ -5,7 +5,10 @@
"""
import json
import os
import shutil
import subprocess
import sys
import threading
import uuid
from collections.abc import Iterator
@ -392,3 +395,28 @@ class TestMain:
threading.Timer(0.3, stop.set).start()
assert main(stop) == 0
assert hf.answer_path(job_id).is_file()
def test_module_starts_without_gateway_settings(self, tmp_path: Path) -> None:
"""C-1: `python -m src.scan_emulator` не читает настройки шлюза — импорт пакета `src` не создаёт приложение.
Окружение — только PATH, пустой ENV_FILE и несуществующий корень: ожидается штатный отказ эмулятора (код 2,
сообщение про корень горячей папки), а не `ValidationError` настроек шлюза (`OPENBAO`).
"""
env = {
"PATH": os.environ.get("PATH", ""),
"ENV_FILE": str(tmp_path / "none.env"),
"SCAN_HOTFOLDER_PATH": str(tmp_path / "missing"),
}
proc = subprocess.run(
[sys.executable, "-m", "src.scan_emulator"],
cwd=API_DIR,
env=env,
capture_output=True,
text=True,
timeout=60,
check=False,
)
assert proc.returncode == 2, proc.stderr
assert "корень горячей папки" in proc.stderr
assert "ValidationError" not in proc.stderr
assert "OPENBAO" not in proc.stderr