feat: make check-full — check, dbml-check, интеграционные тесты против compose, docker build, web; .env.test на порты compose

Цели docker-build, web-check, check-infra (подсказка «make up»); .env.test переведён на 5432/4222/9000 (R-19),
test_config и README обновлены. Цикл миграций входит в test-integration и отдельным шагом не дублируется.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Andrey Epifancev 2026-10-04 00:58:57 +04:00
parent 0b4fa3a819
commit 81bb79e600
5 changed files with 78 additions and 17 deletions

View File

@ -5,7 +5,7 @@ COMPOSE_FILE ?= ../docs/dev/docker-compose.yml
# DBML относительно api/: и в основном workspace, и в worktree .wt/<срез>/ это соседний docs/ # DBML относительно api/: и в основном workspace, и в worktree .wt/<срез>/ это соседний docs/
DBML ?= ../../docs/model/data-model-v5.13.dbml DBML ?= ../../docs/model/data-model-v5.13.dbml
.PHONY: venv lint test test-integration dbml-check migration-cycle check check-full up migrate seed seed-dev .PHONY: venv lint test test-integration dbml-check migration-cycle check check-infra docker-build web-check check-full up migrate seed seed-dev
# Python 3.11 (версия платформы); внутренние пакеты raisa_* вне банка недоступны — пропускаем их # Python 3.11 (версия платформы); внутренние пакеты raisa_* вне банка недоступны — пропускаем их
venv: venv:
@ -29,14 +29,31 @@ dbml-check:
cd api && $(BIN)/python scripts/check_dbml_vs_orm.py $(DBML) cd api && $(BIN)/python scripts/check_dbml_vs_orm.py $(DBML)
# Миграции на временной БД (spec data-model): upgrade head -> downgrade base -> upgrade head, пустой autogenerate, # Миграции на временной БД (spec data-model): upgrade head -> downgrade base -> upgrade head, пустой autogenerate,
# схема после миграции = create_all ORM. Подключается в check-full (задача 25) # схема после миграции = create_all ORM. Входит в test-integration, отдельно запускается для быстрой проверки миграций
migration-cycle: migration-cycle:
cd api && $(BIN)/pytest -m integration tests/test_migrations.py cd api && $(BIN)/pytest -m integration tests/test_migrations.py
check: lint test check: lint test
# TODO (задача 25): добавить фронт (lint/test/build web/), проверку миграций с нуля и откат, актуальность OpenAPI # Быстрая проверка доступности PostgreSQL и NATS из api/.env.test (порты compose); иначе — подсказка поднять инфраструктуру
check-full: check dbml-check test-integration check-infra:
cd api && $(BIN)/python scripts/check_infra.py
# Сборка образа из корня репозитория (Dockerfile — бэкенд)
docker-build:
docker build -t arm-core .
# Фронт: установка зависимостей (raisa-* без Nexus пропускаются как optionalDependencies), biome, типы, сборка
web-check:
cd web && npm install
cd web && npx biome check src
cd web && npx tsc --noEmit
cd web && npm run build
# Полная проверка перед PR. Порядок: быстрые без БД (check, dbml-check), затем БД/NATS из compose (test-integration),
# затем docker, затем web. Цикл миграций upgrade -> downgrade -> upgrade на чистой БД входит в test-integration
# (tests/test_migrations.py), поэтому отдельным шагом не гоняется: второй запуск только удлинил бы прогон
check-full: check dbml-check check-infra test-integration docker-build web-check
up: up:
docker compose -f $(COMPOSE_FILE) up -d docker compose -f $(COMPOSE_FILE) up -d

View File

@ -246,9 +246,11 @@ docker compose -f ../docs/dev/docker-compose.yml down -v # полный сб
| `make dbml-check` | сверка ORM с `../docs/model/data-model-v5.13.dbml` | | `make dbml-check` | сверка ORM с `../docs/model/data-model-v5.13.dbml` |
| `make migration-cycle` | миграции на временной БД: `upgrade head` → `downgrade base` → `upgrade head`, пустой autogenerate | | `make migration-cycle` | миграции на временной БД: `upgrade head` → `downgrade base` → `upgrade head`, пустой autogenerate |
| `make check` | быстрая проверка без Docker: `lint` + `test` | | `make check` | быстрая проверка без Docker: `lint` + `test` |
| `make check-full` | `check` + `dbml-check` + `test-integration`; выполняется перед PR (нужна поднятая инфраструктура) | | `make docker-build` | сборка образа: `docker build -t arm-core .` |
| `make web-check` | фронт: `npm install`, `biome check src`, `tsc --noEmit`, `npm run build` |
| `make check-infra` | быстрая проверка, что PostgreSQL и NATS из compose доступны (иначе: `make up`) |
| `make check-full` | полная проверка перед PR: `check` + `dbml-check` + `check-infra` + `test-integration` (в нём цикл миграций) + `docker-build` + `web-check`; нужна поднятая инфраструктура (`make up`) и Docker |
`make check-full` пока не включает проверки фронта, OpenAPI и откат миграций отдельным шагом (задача 25 среза).
### Тесты ### Тесты
@ -256,10 +258,9 @@ docker compose -f ../docs/dev/docker-compose.yml down -v # полный сб
- **Интеграционные** (`make test-integration`) требуют PostgreSQL, тесты обмена через NATS — ещё и NATS. Рабочую БД - **Интеграционные** (`make test-integration`) требуют PostgreSQL, тесты обмена через NATS — ещё и NATS. Рабочую БД
`armka` они не трогают: на каждую сессию pytest создаётся свежая БД `armcore_pytest_<hex>`, мигрируется `alembic` `armka` они не трогают: на каждую сессию pytest создаётся свежая БД `armcore_pytest_<hex>`, мигрируется `alembic`
и удаляется в конце. Параметры подключения берутся из `api/.env.test` (`pytest.ini` задаёт `ENV_FILE=.env.test`). и удаляется в конце. Параметры подключения берутся из `api/.env.test` (`pytest.ini` задаёт `ENV_FILE=.env.test`).
Сейчас этот файл указывает на временную тестовую инфраструктуру (PostgreSQL `55432`, NATS `54222`, MinIO `59000`), Файл указывает на стандартные порты и учётные данные compose из `../docs/dev` (PostgreSQL `5432`, NATS `4222`,
а не на стандартные порты compose: чтобы гонять интеграционные тесты против `make up`, поправьте порты в MinIO `9000`), поэтому после `make up` тесты работают «из коробки». То же относится к `make migration-cycle` и
`api/.env.test` на `5432`, `4222`, `9000` (не коммитьте это изменение без согласования). То же относится к `make check-full`: они тоже читают `.env.test` через `pytest.ini`.
`make migration-cycle` и `make check-full`: они тоже читают `.env.test` через `pytest.ini`.
- **Реальные данные** — репозиторий `../fixtures/` (путь можно задать переменной `ARM_KA_FIXTURES`). Тесты с маркером - **Реальные данные** — репозиторий `../fixtures/` (путь можно задать переменной `ARM_KA_FIXTURES`). Тесты с маркером
`fixtures` без каталога пропускаются с понятной причиной. `fixtures` без каталога пропускаются с понятной причиной.

View File

@ -1,18 +1,19 @@
# Окружение тестов (pytest.ini: ENV_FILE=.env.test). Только тестовые значения, секретов здесь нет. # Окружение тестов (pytest.ini: ENV_FILE=.env.test). Только тестовые значения, секретов здесь нет.
# Порты — временная тестовая инфраструктура: PostgreSQL 55432, NATS 54222, MinIO 59000. # Порты и учётные данные — стандартные для docs/dev/docker-compose.yml (PostgreSQL 5432, NATS 4222, MinIO 9000):
# после `make up` тесты работают без правок. Рабочую БД тесты не трогают (создают armcore_pytest_<hex>).
DEBUG=true DEBUG=true
OPENBAO__DATABASE__DATABASE_URL=postgresql+asyncpg://armka:armka@localhost:55432/armka OPENBAO__DATABASE__DATABASE_URL=postgresql+asyncpg://armka:armka@localhost:5432/armka
OPENBAO__MINIO__MINIO_URL=localhost:59000 OPENBAO__MINIO__MINIO_URL=localhost:9000
OPENBAO__MINIO__MINIO_ADMIN_LOGIN=minioadmin OPENBAO__MINIO__MINIO_ADMIN_LOGIN=minioadmin
OPENBAO__MINIO__MINIO_ADMIN_PASSWORD=minioadmin OPENBAO__MINIO__MINIO_ADMIN_PASSWORD=minioadmin
OPENBAO__MINIO__MINIO_BUCKET=arm-ka OPENBAO__MINIO__MINIO_BUCKET=arm-ka
# false — MinIO по http (docker compose); по умолчанию true (https, как на платформе) # false — MinIO по http (docker compose); по умолчанию true (https, как на платформе)
OPENBAO__MINIO__MINIO_SECURE=false OPENBAO__MINIO__MINIO_SECURE=false
OPENBAO__NATS__NATS_URL=nats://localhost:54222 OPENBAO__NATS__NATS_URL=nats://localhost:4222
OPENBAO__NATS__NATS_SEED= OPENBAO__NATS__NATS_SEED=
OPENBAO__NATS__NATS_JWT= OPENBAO__NATS__NATS_JWT=

View File

@ -0,0 +1,42 @@
"""Быстрая проверка доступности PostgreSQL и NATS из `.env.test` (порты docker-compose из docs/dev).
Нужна `make check-full`, чтобы вместо длинного трейсбека pytest сразу подсказать: «поднимите инфраструктуру: make up».
Только TCP-подключение, без аутентификации; коды: 0 — доступны, 1 — недоступны.
"""
import socket
import sys
from pathlib import Path
from urllib.parse import urlparse
from dotenv import dotenv_values
ENV_FILE = Path(__file__).resolve().parent.parent / ".env.test"
KEYS = ("OPENBAO__DATABASE__DATABASE_URL", "OPENBAO__NATS__NATS_URL")
def unreachable(urls: list[str]) -> list[str]:
"""Адреса host:port, к которым не удалось подключиться."""
bad: list[str] = []
for url in urls:
parsed = urlparse(url)
host, port = parsed.hostname or "localhost", parsed.port or 0
try:
with socket.create_connection((host, port), timeout=3):
pass
except OSError:
bad.append(f"{host}:{port}")
return bad
def main() -> int:
env = dotenv_values(ENV_FILE)
bad = unreachable([env[key] or "" for key in KEYS])
if bad:
print(f"Инфраструктура недоступна ({', '.join(bad)}): поднимите её командой make up", file=sys.stderr)
return 1
return 0
if __name__ == "__main__":
sys.exit(main())

View File

@ -20,10 +20,10 @@ def clean_env(monkeypatch: pytest.MonkeyPatch) -> pytest.MonkeyPatch:
def test_env_test_is_read(clean_env: pytest.MonkeyPatch) -> None: def test_env_test_is_read(clean_env: pytest.MonkeyPatch) -> None:
""".env.test читается: порты временной тестовой инфраструктуры.""" """.env.test читается: стандартные порты docker-compose из docs/dev."""
s = Settings(_env_file=API_DIR / ".env.test") # type: ignore[call-arg] s = Settings(_env_file=API_DIR / ".env.test") # type: ignore[call-arg]
assert s.OPENBAO.DATABASE.DATABASE_URL.endswith("localhost:55432/armka") assert s.OPENBAO.DATABASE.DATABASE_URL.endswith("localhost:5432/armka")
assert s.OPENBAO.NATS.NATS_URL == "nats://localhost:54222" assert s.OPENBAO.NATS.NATS_URL == "nats://localhost:4222"
assert s.AUTH_DEV_ISSUER is True assert s.AUTH_DEV_ISSUER is True
assert s.NATS_ENABLED is False assert s.NATS_ENABLED is False
assert s.OPENBAO.MINIO.MINIO_SECURE is False assert s.OPENBAO.MINIO.MINIO_SECURE is False