diff --git a/api/run_server.py b/api/run_server.py index 37a9775..7715863 100644 --- a/api/run_server.py +++ b/api/run_server.py @@ -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() diff --git a/api/src/__init__.py b/api/src/__init__.py index 97b1796..9cc1d91 100644 --- a/api/src/__init__.py +++ b/api/src/__init__.py @@ -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`). +""" diff --git a/api/tests/conftest.py b/api/tests/conftest.py index a5c3825..94f60e8 100644 --- a/api/tests/conftest.py +++ b/api/tests/conftest.py @@ -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() diff --git a/api/tests/unit/test_emulator.py b/api/tests/unit/test_emulator.py index 26e454a..098775a 100644 --- a/api/tests/unit/test_emulator.py +++ b/api/tests/unit/test_emulator.py @@ -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