Files
anti-plagiarism/scripts/run_tests.sh
jze9 ecc10a4413 test: юнит-суит L1/L2/L3 + ГОСТ (41 тест) и гейт в CI перед деплоем
Первый настоящий автоматический тест-суит проекта — раньше регрессии ловились
руками. Покрыта чистая логика детекции и форматирования (без БД/Redis/GPU/Ollama):

- worker-indexer: L1 Winnowing (точные совпадения, идемпотентность отпечатка,
  диапазон signed int64) и L2 MinHash LSH (шинглы, Jaccard, near-duplicate +
  upsert через in-memory-фолбэк).
- worker-gpu: L3 FAISS — возврат doc_id из PostgreSQL (IndexIDMap2),
  идемпотентность add_vectors (remove-before-add, без дублей), self-match ≈ 1,
  ранжирование. Прямо стережёт баги, из-за которых индекс переписывался.
- worker-gost: ГОСТ 7.1-2003 и 7.0.5-2008 — авторы (≤3 / 4+ «и др.»/et al.),
  статья/книга/web, DOI, порядок сортировки кириллица→латиница, стр. в ссылке.

Обвязка: per-service pytest.ini/conftest/requirements-test. scripts/run_tests.sh
гоняет тесты в изолированных python:3.11-slim контейнерах (не засоряя хост),
через Tsinghua-зеркало. CI: job `test` теперь гейтит `deploy` (needs: test) —
падение тестов блокирует прод-деплой. make test / make test-one SVC=...

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-11 17:11:08 +05:00

68 lines
2.7 KiB
Bash
Executable File
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.
#!/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"
# service:apt-пакеты (нужны faiss-cpu → libgomp1)
SERVICES=(
"worker-indexer:"
"worker-gost:"
"worker-gpu:libgomp1"
)
run_service() {
local svc="$1" apt_pkgs="$2"
local dir="$ROOT/services/$svc"
if [[ ! -f "$dir/requirements-test.txt" ]]; then
echo "⚠ $svc: нет requirements-test.txt — пропуск"
return 0
fi
echo "──────────────────────────────────────────────"
echo "▶ Тесты: $svc"
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
svc="${entry%%:*}"
apt="${entry#*:}"
[[ -n "$FILTER" && "$FILTER" != "$svc" ]] && continue
if ! run_service "$svc" "$apt"; then
failed=1
echo "✗ $svc: тесты упали"
fi
done
echo "══════════════════════════════════════════════"
if [[ $failed -eq 0 ]]; then
echo "✅ Все юнит-тесты прошли"
else
echo "❌ Есть упавшие тесты"
exit 1
fi