#!/usr/bin/env bash # Прогон юнит-тестов всех сервисов в изолированных python:3.11-slim контейнерах. # # Тесты бьют по ЧИСТОЙ логике детекции и форматирования и не требуют внешней # инфраструктуры (БД/Redis/RabbitMQ/GPU/Ollama) — поэтому гоняются одинаково на # машине разработчика и в CI. Запуск в контейнере не засоряет хост зависимостями. # # Использование: # scripts/run_tests.sh # все сервисы # scripts/run_tests.sh worker-gost # только один сервис # # PIP_INDEX_URL можно переопределить (по умолчанию — Tsinghua-зеркало, т.к. # pypi.org из LAN недоступен). set -euo pipefail MIRROR="${PIP_INDEX_URL:-https://pypi.tuna.tsinghua.edu.cn/simple/}" ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" IMAGE="python:3.11-slim" # относительный-путь:apt-пакеты (нужны faiss-cpu → libgomp1) SERVICES=( "services/worker-indexer:" "services/worker-gost:" "services/worker-gpu:libgomp1" "scripts/parsers:" ) run_service() { local dir_rel="$1" apt_pkgs="$2" local dir="$ROOT/$dir_rel" local name="${dir_rel##*/}" if [[ ! -f "$dir/requirements-test.txt" ]]; then echo "⚠ $name: нет requirements-test.txt — пропуск" return 0 fi echo "──────────────────────────────────────────────" echo "▶ Тесты: $name" echo "──────────────────────────────────────────────" docker run --rm \ -v "$dir":/app -w /app \ -e PIP_INDEX_URL="$MIRROR" \ -e PIP_DISABLE_PIP_VERSION_CHECK=1 \ "$IMAGE" bash -c " set -e ${apt_pkgs:+apt-get update -qq && apt-get install -y -qq --no-install-recommends $apt_pkgs >/dev/null && rm -rf /var/lib/apt/lists/*} pip install --no-cache-dir --timeout 60 -q -r requirements-test.txt python -m pytest " } FILTER="${1:-}" failed=0 for entry in "${SERVICES[@]}"; do dir_rel="${entry%%:*}" apt="${entry#*:}" name="${dir_rel##*/}" [[ -n "$FILTER" && "$FILTER" != "$name" ]] && continue if ! run_service "$dir_rel" "$apt"; then failed=1 echo "✗ $name: тесты упали" fi done echo "══════════════════════════════════════════════" if [[ $failed -eq 0 ]]; then echo "✅ Все юнит-тесты прошли" else echo "❌ Есть упавшие тесты" exit 1 fi