Netpulse_SasS/scripts/dbtest.sh
byrsapty 954be1d643
All checks were successful
CI / hygiene (push) Successful in 9s
CI / web (push) Successful in 1m15s
CI / server (push) Successful in 1m34s
CI / agent (push) Successful in 2m59s
Ескалації: закриваю те, що минулого разу закрив наполовину
За другою рецензією:

* scripts/dbtest.sh писав у шапці «не напрямляйте на робочу базу» й
  нічого для цього не робив — перевірено, пішов котити міграції на базу
  з бойовим іменем. Тепер вимагає probe/test в імені.
* sendText ковтав помилку, тож журнал ескалацій писав «надіслано» на
  сходинці, жодне повідомлення якої не дійшло. Три результати замість
  двох: no_channels, failed, sent.
* stopped_at IS NULL рятував лише від ack; гасіння правилом і
  ResolveMissing рядка драбини не чіпають, і сходинка дзвонила за
  погашеним алертом. Додано перевірку стану алерту в тому ж UPDATE.
* escalate() блокував весь тік движка — мертвий вебхук одного кабінету
  зупиняв обчислення правил усім. Винесено в RunEscalations.
* алерт, народжений під заглушенням, не сповіщався ніколи: ні при
  народженні, ні коли вікно скінчилось. Тепер перехід suppressed→firing
  сповіщається, а драбина рахує час від першого сповіщення.
* alr.rules.channel_ids приймав чужі канали, глушачи і сповіщення, і
  драбину. Перевірка як для сходинок; DeleteChannel чистить посилання.

І перше, що зловив прогін проти справжньої бази: nil-зріз каналів їде
явним NULL повз DEFAULT '{}' — правило без каналів давало 500.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 17:44:38 +03:00

106 lines
5.6 KiB
Bash
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.

#!/bin/sh
# Прогін тестів проти СПРАВЖНЬОЇ бази.
#
# ЧОМУ ЦЕ ОКРЕМИЙ СКРИПТ
#
# Тести проти бази мовчки пропускаються без NETPULSE_TEST_DSN — і саме
# тому вони півтора року нічого не перевіряли: `go test ./...` показував
# «ok», а всередині кожного з них стояв t.Skip. «Пропущено» в підсумку
# виглядає рівно як «пройдено», і це найдорожча тиха відмова в проєкті:
# перевірка ізоляції кабінетів, стелі тарифу, гасіння алертів і драбин
# ескалації існували, компілювались і не виконувались.
#
# scripts/check.sh лишається швидким (без Docker і без бази) — його
# ганяють на кожну правку. Цей скрипт повільніший і потребує Postgres,
# тож викликається окремо: перед розгортанням і в CI.
#
# БАЗА МУСИТЬ БУТИ ОДНОРАЗОВОЮ. Тести пишуть, видаляють і перемикають
# ролі, а перед ними ще й котяться міграції — зокрема ті, яких у робочій
# базі ще не має бути. І це не побажання в коментарі: рівно так гине
# бойова база, коли в профілі шелла лишився експортований
# NETPULSE_TEST_DSN зі вчорашнього налагодження. Тому нижче стоїть
# перевірка імені, а не заклик до обережності.
#
# ВИКОРИСТАННЯ
# scripts/dbtest.sh # підніме свій Postgres
# NETPULSE_TEST_DSN=... scripts/dbtest.sh # проти готової бази,
# # ім'я якої містить probe/test
#
set -u
SRC="$(cd "$(dirname "$0")/.." && pwd)"
OWN_DB=0
NAME=""
# Ім'я бази має саме казати, що вона одноразова. Перевірка навмисно
# дурна й невідмикна: розумніша (маркерна таблиця, прапорець згоди)
# перекладає рішення на людину рівно в той момент, коли людина поспішає.
guard_disposable() {
db=$(printf '%s' "$1" | sed -e 's/?.*$//' -e 's#.*/##')
case "$db" in
*probe*|*test*) return 0 ;;
esac
echo "!!! NETPULSE_TEST_DSN вказує на базу «$db»." >&2
echo " Тести пишуть, видаляють і котять міграції — база мусить бути" >&2
echo " одноразовою, і її імʼя має містити «probe» або «test»." >&2
echo " Якщо це чернетка — перейменуйте базу. Якщо ні — ви щойно мало" >&2
echo " не накотили міграції на робочу базу." >&2
exit 1
}
if [ -z "${NETPULSE_TEST_DSN:-}" ]; then
# Своя база на час прогону. Порт випадковий-таки ні: фіксований, але
# нетиповий, щоб не зіткнутись із локальним Postgres розробника.
PORT=${NETPULSE_TEST_PORT:-55433}
# Імʼя з номером процесу: два прогони поруч (другий термінал, дві
# задачі на одному раннері) інакше вбивали б бази один одному, і
# падіння виглядало б як помилка зʼєднання нізвідки.
NAME="netpulse-dbtest-$$"
echo "== піднімаю одноразовий Postgres :$PORT"
docker run -d --name "$NAME" -p "$PORT:5432" \
-e POSTGRES_USER=netpulse -e POSTGRES_PASSWORD=probe \
-e POSTGRES_DB=netpulse_probe \
timescale/timescaledb:2.17.2-pg16 >/dev/null || exit 1
OWN_DB=1
NETPULSE_TEST_DSN="postgres://netpulse:probe@127.0.0.1:$PORT/netpulse_probe?sslmode=disable"
export NETPULSE_TEST_DSN
n=0
until docker exec "$NAME" pg_isready -h 127.0.0.1 -U netpulse >/dev/null 2>&1; do
n=$((n+1)); [ "$n" -gt 60 ] && { echo "база не піднялась"; exit 1; }
sleep 1
done
else
guard_disposable "$NETPULSE_TEST_DSN"
fi
# Своя база зноситься лише після ЗЕЛЕНОГО прогону. Після червоного вона
# лишається: подивитись, що саме опинилось у таблицях, — єдиний спосіб
# зрозуміти половину падінь, а знесена база забирає цю можливість рівно
# тоді, коли вона потрібна.
cleanup() {
[ "$OWN_DB" = 1 ] || return 0
if [ "${rc:-1}" = 0 ]; then
docker rm -f "$NAME" >/dev/null 2>&1
else
echo
echo "база лишилась для розбору: docker exec -it $NAME psql -U netpulse netpulse_probe"
echo "прибрати: docker rm -f $NAME"
fi
return 0
}
trap cleanup EXIT INT TERM
echo "== накат міграцій"
( cd "$SRC/server" && NETPULSE_DSN="$NETPULSE_TEST_DSN" go run ./cmd/netpulse-migrate ) || exit 1
echo "== тести"
( cd "$SRC/server" && go test ./internal/... -count=1 )
rc=$?
echo
if [ "$rc" = 0 ]; then
echo "усе зелене проти бази"
else
echo "!!! тести проти бази не пройшли"
fi
exit $rc