109 lines
5.3 KiB
Bash
Executable File
109 lines
5.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Единый приёмочный прогон memo. Запускает ВСЁ, что должен пройти проект, и печатает
|
|
# один вердикт. Возвращает 0, если все контуры зелёные.
|
|
#
|
|
# bash scripts/accept.sh # полный прогон
|
|
# bash scripts/accept.sh --fast # без мутационной проверки (она самая долгая)
|
|
#
|
|
# Контуры:
|
|
# 1. Юнит-тесты всех модулей (gradle test --rerun-tasks).
|
|
# 2. Мутационная проверка тестов (e2e/mutation_check.py) — тесты обязаны падать на сломанном коде.
|
|
# 3. Сквозной recall@5 на эталонном корпусе (e2e/run_e2e.py).
|
|
# 4. MCP-протокол живым клиентом (scripts/mcp_probe.py), включая холодный старт.
|
|
set -uo pipefail
|
|
|
|
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
cd "$ROOT"
|
|
|
|
CORPUS="${MEMO_CORPUS:-/root/WORK/memo-e2e}"
|
|
export MEMO_MODEL_DIR="${MEMO_MODEL_DIR:-$ROOT/models/siglip2}"
|
|
FAST=0
|
|
[ "${1:-}" = "--fast" ] && FAST=1
|
|
|
|
FAILED=()
|
|
|
|
section() { printf '\n=== %s ===\n' "$1"; }
|
|
|
|
section "0. сборка"
|
|
if ./gradlew installDist -q >/tmp/memo-build.log 2>&1; then
|
|
echo "OK сборка и установка дистрибутивов"
|
|
else
|
|
echo "ПРОВАЛ сборки:"; tail -30 /tmp/memo-build.log; FAILED+=("сборка"); fi
|
|
|
|
CLI="$ROOT/memo-cli/build/install/memo/bin/memo"
|
|
MCP="$ROOT/memo-mcp/build/install/memo-mcp/bin/memo-mcp"
|
|
|
|
section "1. юнит-тесты"
|
|
if ./gradlew test --rerun-tasks >/tmp/memo-test.log 2>&1; then
|
|
python3 - <<'EOF'
|
|
import glob, xml.etree.ElementTree as ET
|
|
tot = fail = 0
|
|
for f in glob.glob('**/build/test-results/test/*.xml', recursive=True):
|
|
r = ET.parse(f).getroot()
|
|
tot += int(r.get('tests') or 0); fail += int(r.get('failures') or 0) + int(r.get('errors') or 0)
|
|
print(f"OK тестов {tot}, провалов {fail}")
|
|
EOF
|
|
else
|
|
echo "ПРОВАЛ тестов:"; grep -E "FAILED|error:" /tmp/memo-test.log | head -20; FAILED+=("тесты"); fi
|
|
|
|
if [ "$FAST" = "0" ]; then
|
|
section "2. мутационная проверка"
|
|
python3 e2e/mutation_check.py --gradle ./gradlew > /tmp/memo-mut.log 2>&1
|
|
MUT_RC=$?
|
|
if [ "$MUT_RC" = "0" ]; then
|
|
echo "OK все мутации убиты"
|
|
elif [ "$MUT_RC" = "2" ]; then
|
|
echo "ПРОВАЛ: таблица мутаций недействительна (no-op или неприменимая мутация)"
|
|
grep -E "ОШИБКА ТАБЛИЦЫ|ПРОВАЛ" /tmp/memo-mut.log | head -10; FAILED+=("таблица мутаций")
|
|
else
|
|
echo "ПРОВАЛ: есть выжившие мутации"; tail -20 /tmp/memo-mut.log; FAILED+=("мутации"); fi
|
|
fi
|
|
|
|
section "3. сквозной индекс эталонного корпуса"
|
|
# .memo лежит не только на верхнем уровне (life/books, work/jira), поэтому ищем по дереву,
|
|
# иначе часть баз переживает очистку и прогон перестаёт быть чистым.
|
|
find "$CORPUS" -name .memo -type d -prune -exec rm -rf {} + 2>/dev/null
|
|
FIRST=$("$CLI" index "$CORPUS" 2>&1 | tail -1)
|
|
SECOND=$("$CLI" index "$CORPUS" 2>&1 | tail -1)
|
|
DBS=$(find "$CORPUS" -name index.db | wc -l)
|
|
echo " первый прогон : $FIRST"
|
|
echo " второй прогон : $SECOND"
|
|
echo " баз индекса : $DBS (ожидается 3)"
|
|
if echo "$SECOND" | grep -q "итого: 0 обновлено" && [ "$DBS" = "3" ]; then
|
|
echo "OK индексация идемпотентна, коллекций 3"
|
|
else
|
|
echo "ПРОВАЛ индексации (ожидалось «итого: 0 обновлено» и 3 базы)"; FAILED+=("индексация"); fi
|
|
|
|
section "4. recall@5"
|
|
if python3 e2e/run_e2e.py --cli "$CLI" --root "$CORPUS" --k 5 > /tmp/memo-e2e.log 2>&1 \
|
|
&& grep -q "ИТОГ: ПРОЙДЕНО" /tmp/memo-e2e.log; then
|
|
grep -E "^(sem|lex):" /tmp/memo-e2e.log; echo "OK recall"
|
|
else
|
|
echo "ПРОВАЛ recall:"; tail -25 /tmp/memo-e2e.log; FAILED+=("recall"); fi
|
|
|
|
section "5. MCP: протокол + холодный старт"
|
|
COLD=/tmp/memo-accept-cold
|
|
rm -rf "$COLD"; cp -r "$CORPUS" "$COLD"
|
|
find "$COLD" -name .memo -type d -prune -exec rm -rf {} + 2>/dev/null
|
|
if python3 scripts/mcp_probe.py --cmd "$MCP" \
|
|
--call memo_search \
|
|
--args "{\"path\":\"$COLD/infra\",\"query\":\"основа для разрешения имён в сети\",\"k\":3}" \
|
|
> /tmp/memo-mcp.log 2>&1; then
|
|
if grep -q "коллекции не найдены" /tmp/memo-mcp.log; then
|
|
echo "ПРОВАЛ: холодный старт не индексирует"; FAILED+=("MCP холодный старт")
|
|
else
|
|
echo "OK MCP: протокол отвечает, холодный старт индексирует"
|
|
grep -E "^OK" /tmp/memo-mcp.log | sed 's/^/ /'
|
|
fi
|
|
else
|
|
echo "ПРОВАЛ MCP:"; tail -20 /tmp/memo-mcp.log; FAILED+=("MCP протокол"); fi
|
|
|
|
section "ВЕРДИКТ"
|
|
if [ ${#FAILED[@]} -eq 0 ]; then
|
|
echo "ПРОЙДЕНО — все контуры зелёные"
|
|
exit 0
|
|
else
|
|
printf 'ПРОВАЛ — контуры: %s\n' "$(IFS=', '; echo "${FAILED[*]}")"
|
|
exit 1
|
|
fi
|