Files
schedule/tests/test_deploy.py
Vladislav Kopnin 34b975da69 Перенос в master всего, кроме админки: ТОП-группы, порядок групп, запуск без Docker
Админка осталась отдельной ветвью admin-panel; в master её нет (ни кода, ни
страниц, ни переменных окружения, ни тома настроек).

Что перенесено:
- parsing: имена групп вида «ИВТ-ТОП-11БО» распознаются, порядок групп = порядок
  столбцов таблицы (похожие заголовки с пробелами группой не считаются);
- main: GET /groups отдаёт группы в порядке столбцов; интервал обновления из
  SCHEDULE_INTERVAL_MINUTES (со старым SCHEDULE_CACHE_TTL как fallback);
- cache: по интервалу сверяем modified — если файл не менялся, не скачиваем;
  при загрузке считаем sha256 и пишем в лог и /status, изменился ли файл;
- source: запросы к Яндекс.Диску с no-cache и меткой времени;
- frontend: ответы API с Cache-Control: no-store, общий .env из корня проекта
  (и backend, и frontend), страницы/прокси админки нет;
- Dockerfile/compose/.env.example: без ADMIN_* и без тома настроек; в api-образ
  попадают все модули backend (проверяется тестом test_deploy);
- Makefile: make help/venv/run/run-api/run-front/test + docker-цели — «make run»
  поднимает всё локально без Docker;
- README: быстрый старт, полный список зависимостей, запуск локально и в Docker;
- deploy/: пример nginx и инструкция «второй стенд рядом с основным».

Тесты: 114 (удалены админские), все зелёные.
2026-10-06 15:15:44 +03:00

41 lines
1.7 KiB
Python
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.

"""Проверки сборки образов: все нужные файлы должны копироваться.
Ошибка «в Dockerfile забыли COPY какого-то модуля» роняет контейнер на импорте,
а тесты из исходников её не видят (они запускаются из рабочей копии). Ловим
статически, без docker.
"""
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
DOCKERFILE = ROOT / "Dockerfile"
COMPOSE = ROOT / "docker-compose.yml"
def _stage(name: str) -> str:
dockerfile = DOCKERFILE.read_text(encoding="utf-8")
part = dockerfile.split(f"FROM base AS {name}", 1)[1]
for other in ("api", "frontend"):
if other != name:
part = part.split(f"FROM base AS {other}", 1)[0]
return part
def test_api_image_copies_every_backend_module():
stage = _stage("api")
for module in sorted((ROOT / "src" / "backend").glob("*.py")):
assert module.name in stage, f"{module.name} не копируется в образ api"
assert "src/backend/schedule" in stage, "пакет schedule не копируется в образ api"
def test_frontend_image_copies_static():
stage = _stage("frontend")
for path in ("src/frontend/main.py", "src/frontend/static"):
assert path in stage, f"{path} не копируется в образ frontend"
def test_compose_passes_required_env():
compose = COMPOSE.read_text(encoding="utf-8")
for var in ("SCHEDULE_LINK", "SCHEDULE_INTERVAL_MINUTES", "SCHEDULE_API"):
assert var in compose, f"{var} не передаётся контейнерам"