manual: инструкция «как пользоваться»; watch: первичный проход, коллекции по правилу ядра; приёмка: контур демона
This commit is contained in:
+59
-3
@@ -8,8 +8,10 @@
|
||||
# Контуры:
|
||||
# 1. Юнит-тесты всех модулей (gradle test --rerun-tasks).
|
||||
# 2. Мутационная проверка тестов (e2e/mutation_check.py) — тесты обязаны падать на сломанном коде.
|
||||
# 3. Сквозной recall@5 на эталонном корпусе (e2e/run_e2e.py).
|
||||
# 4. MCP-протокол живым клиентом (scripts/mcp_probe.py), включая холодный старт.
|
||||
# 3. Сквозной индекс эталонного корпуса: идемпотентность и ровно 3 коллекции.
|
||||
# 4. Сквозной recall@5 на эталонном корпусе (e2e/run_e2e.py).
|
||||
# 5. Демон слежения: первичный проход, 3 базы, отсутствие «locked» при параллельном чтении.
|
||||
# 6. MCP-протокол живым клиентом (scripts/mcp_probe.py), включая холодный старт.
|
||||
set -uo pipefail
|
||||
|
||||
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
@@ -81,7 +83,61 @@ if python3 e2e/run_e2e.py --cli "$CLI" --root "$CORPUS" --k 5 > /tmp/memo-e2e.lo
|
||||
else
|
||||
echo "ПРОВАЛ recall:"; tail -25 /tmp/memo-e2e.log; FAILED+=("recall"); fi
|
||||
|
||||
section "5. MCP: протокол + холодный старт"
|
||||
section "5. демон слежения (memo-watch)"
|
||||
# Демон проверяется отдельным контуром: три его дефекта (6 баз вместо 3, отсутствие первичного
|
||||
# прохода, «locked» при параллельном чтении) прошли мимо юнит-тестов и зелёной приёмки.
|
||||
WATCH="$ROOT/memo-watch/build/install/memo-watch/bin/memo-watch"
|
||||
WROOT=/tmp/memo-accept-watch
|
||||
rm -rf "$WROOT"; cp -r "$CORPUS" "$WROOT"
|
||||
find "$WROOT" -name .memo -type d -prune -exec rm -rf {} + 2>/dev/null
|
||||
"$WATCH" "$WROOT" > /tmp/memo-watch.log 2>&1 &
|
||||
WPID=$!
|
||||
WOK=1
|
||||
# ждём не «на глаз», а по факту: пока в каждой коллекции не появятся чанки (максимум 120 с)
|
||||
for _ in $(seq 1 120); do
|
||||
READY=$(python3 - "$WROOT" <<'EOF'
|
||||
import sqlite3, glob, sys
|
||||
root = sys.argv[1]
|
||||
dbs = sorted(glob.glob(root + "/**/.memo/index.db", recursive=True))
|
||||
if len(dbs) != 3:
|
||||
print(0); raise SystemExit
|
||||
n = 0
|
||||
for db in dbs:
|
||||
try:
|
||||
c = sqlite3.connect("file:" + db + "?mode=ro", uri=True)
|
||||
if c.execute("SELECT COUNT(*) FROM chunks").fetchone()[0] > 0: n += 1
|
||||
c.close()
|
||||
except Exception:
|
||||
pass
|
||||
print(n)
|
||||
EOF
|
||||
)
|
||||
[ "$READY" = "3" ] && break
|
||||
sleep 1
|
||||
done
|
||||
WDBS=$(find "$WROOT" -name index.db | wc -l)
|
||||
echo " баз индекса : $WDBS (ожидается 3)"
|
||||
if [ "$WDBS" != "3" ]; then
|
||||
echo "ПРОВАЛ: демон завёл $WDBS баз вместо 3"; WOK=0
|
||||
fi
|
||||
if [ "$READY" = "3" ]; then
|
||||
echo "OK первичный проход: все 3 коллекции наполнены сразу после старта"
|
||||
else
|
||||
echo "ПРОВАЛ: первичного прохода нет — наполнено коллекций: $READY из 3"; WOK=0
|
||||
fi
|
||||
# параллельно с работающим демоном — тот же файл читаем поиском
|
||||
WSEARCH=$("$CLI" search "$WROOT/life/books" "кто ведёт рассказ в романе" --k 1 2>&1)
|
||||
if echo "$WSEARCH" | grep -qi "locked"; then
|
||||
echo "ПРОВАЛ: database is locked при чтении во время работы демона"; WOK=0
|
||||
elif [ -n "$WSEARCH" ]; then
|
||||
echo "OK поиск при работающем демоне отвечает без locked"
|
||||
else
|
||||
echo "ПРОВАЛ: поиск при работающем демоне ничего не вернул"; WOK=0
|
||||
fi
|
||||
kill "$WPID" 2>/dev/null; wait "$WPID" 2>/dev/null
|
||||
[ "$WOK" = "1" ] || FAILED+=("демон слежения")
|
||||
|
||||
section "6. 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
|
||||
|
||||
Reference in New Issue
Block a user