From e162b8fab5cc885d92ae56e8716205384d5e8ccd Mon Sep 17 00:00:00 2001 From: Ivan Gerasimov Date: Fri, 18 Sep 2026 16:28:47 +0300 Subject: [PATCH] =?UTF-8?q?fix:=20test=5Fdb.py=20=D0=B2=D0=B5=D1=88=D0=B0?= =?UTF-8?q?=D0=BB=20make=20test,=20=D0=BA=D0=BE=D0=B3=D0=B4=D0=B0=20Postgr?= =?UTF-8?q?es=20=D0=BD=D0=B5=D0=B4=D0=BE=D1=81=D1=82=D1=83=D0=BF=D0=B5?= =?UTF-8?q?=D0=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit engine.connect() без таймаута — у asyncpg он не задан по умолчанию — висел на TCP-таймауте ОС вместо быстрого отказа. test_profile.py уже чинил ровно эту проблему сокетным пробником, test_db.py — исходный файл с той же логикой — остался с висящим вариантом. Нашлось руками: Docker недоступен в этой сессии WSL, и make test встал намертво вместо 54 пропущенных тестов. --- backend/tests/test_db.py | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/backend/tests/test_db.py b/backend/tests/test_db.py index a85a75e..71cba9a 100644 --- a/backend/tests/test_db.py +++ b/backend/tests/test_db.py @@ -17,15 +17,23 @@ from app.db.models import Group, Scenario, Session, Trainee @pytest.fixture async def db(): """Свой движок на каждый тест: глобальный в app.db.base кэшируется и - привязывается к первому событийному циклу, а pytest даёт новый на каждый тест.""" - engine = create_async_engine(get_settings().database_url, poolclass=None) - try: - async with engine.connect() as probe: - await probe.execute(text("select 1")) - except Exception as exc: # noqa: BLE001 — важен факт недоступности, не причина - await engine.dispose() - pytest.skip(f"Postgres недоступен ({type(exc).__name__}) — подними `make dev`") + привязывается к первому событийному циклу, а pytest даёт новый на каждый тест. + Доступность проверяется подключением к порту, а не через engine.connect(): + у asyncpg нет таймаута по умолчанию, и когда Postgres действительно недоступен + (Docker не поднят), connect() висит на TCP-таймауте ОС — минуты, а не секунды, + и `make test` зависает вместо того, чтобы пропустить тест. Тот же баг был + когда-то и в test_profile.py — здесь чинится тем же способом.""" + import socket + from urllib.parse import urlparse + + url = urlparse(get_settings().database_url) + try: + socket.create_connection((url.hostname or "localhost", url.port or 5432), timeout=2).close() + except OSError as exc: + pytest.skip(f"Postgres недоступен ({exc}) — подними `make dev`") + + engine = create_async_engine(get_settings().database_url, poolclass=None) maker = async_sessionmaker(engine, expire_on_commit=False) async with maker() as session: yield session