- scripts/verify.sh:把「带齐六个环境变量、且必须 0 skip」这条纪律固化下来 * DSN 自己从 conf/app-test.ini 取,不把口令写进脚本 * 库名不含 test 就拒跑(指到维护库会多出「users 不存在」+ 一堆假 skip) * 数 SKIP,非 0 直接失败 —— 不带环境变量时 go test 依然回 ok,最容易被当成通过 * 支持 --fast / --race / --cover / --pkg / --run - tools/:删掉 6 个一次性探针(git 历史里可翻)和误入库的 __pycache__, 只留在用的 4 个工具并补 README;.gitignore 补 __pycache__ / *.pyc - audit-2026-09-21.md:全量排查报告(含 11 批修复记录与收尾审查)
138 lines
4.9 KiB
Bash
138 lines
4.9 KiB
Bash
#!/usr/bin/env bash
|
||
#
|
||
# 一键验收:把「必须带六个环境变量、且必须 0 skip」这条纪律固化下来。
|
||
#
|
||
# ./scripts/verify.sh # 全量验收(默认,约 8 分钟)
|
||
# ./scripts/verify.sh --fast # 只做 gofmt / vet / build(约 20 秒)
|
||
# ./scripts/verify.sh --race # 全量 + -race(更慢,需 mingw 在 PATH)
|
||
# ./scripts/verify.sh --cover # 全量 + 覆盖率
|
||
# ./scripts/verify.sh --pkg ./internal/web/ --run 'TestMapPreview' # 定点跑
|
||
#
|
||
# 退出码:0 = 全绿且 0 skip;非 0 = 有失败或有跳过。
|
||
|
||
set -u -o pipefail
|
||
|
||
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||
cd "$ROOT"
|
||
|
||
ABS="$ROOT"
|
||
command -v pwd >/dev/null && ABS="$(pwd -W 2>/dev/null || pwd)"
|
||
|
||
CONF="${ROND_TEST_CONF:-conf/app-test.ini}"
|
||
ROND_SRC="${ROND_SRC:-$ABS/data/20260914_151649.rondbackup}"
|
||
FOG_SRC="${FOG_SRC:-$ABS/data/Snapshot-20260914T154839+0800.fwss}"
|
||
OUT="$ABS/storage/.verify"
|
||
CLEAN_OUT="$OUT/acceptance-clean.rondbackup"
|
||
LOG="$OUT/verify.log"
|
||
|
||
FAST=0; RACE=0; COVER=0; PKGS="./..."; RUN=""
|
||
|
||
while [ $# -gt 0 ]; do
|
||
case "$1" in
|
||
--fast) FAST=1 ;;
|
||
--race) RACE=1 ;;
|
||
--cover) COVER=1 ;;
|
||
--pkg) PKGS="${2:?--pkg 后面要给包路径}"; shift ;;
|
||
--run) RUN="${2:?--run 后面要给正则}"; shift ;;
|
||
*) echo "未知参数:$1" >&2; exit 2 ;;
|
||
esac
|
||
shift
|
||
done
|
||
|
||
fail() { echo "✗ $*" >&2; exit 1; }
|
||
ok() { echo "✓ $*"; }
|
||
|
||
echo "== 仓库:$ROOT"
|
||
|
||
if [ "$FAST" = 1 ]; then
|
||
unformatted="$(gofmt -l internal/ main.go 2>&1)"
|
||
[ -n "$unformatted" ] && fail "gofmt 不干净(注意 CRLF 会假警):$(echo "$unformatted" | tr '\n' ' ')"
|
||
ok "gofmt"
|
||
go vet ./... || fail "go vet"
|
||
ok "go vet"
|
||
go build ./... || fail "go build"
|
||
ok "go build"
|
||
exit 0
|
||
fi
|
||
|
||
# --- 六个环境变量 ---------------------------------------------------------------
|
||
[ -f "$CONF" ] || fail "找不到 $CONF"
|
||
[ -f "$ROND_SRC" ] || fail "找不到备份包 ROND_SRC=$ROND_SRC"
|
||
[ -f "$FOG_SRC" ] || fail "找不到迷雾快照 FOG_SRC=$FOG_SRC"
|
||
|
||
if [ -n "${ROND_DSN:-}" ]; then
|
||
DSN="$ROND_DSN"
|
||
else
|
||
DSN="$(grep -m1 -iE '^[[:space:]]*dsn[[:space:]]*=' "$CONF" | sed 's/^[^=]*=[[:space:]]*//' | tr -d '\r\n')"
|
||
fi
|
||
[ -n "$DSN" ] || fail "没能从 $CONF 取到 dsn(也不在环境里),别把口令写进脚本"
|
||
|
||
# 指到维护库 postgres 会多出「users 不存在」+ 一堆 stats 假 skip,直接拦住
|
||
DBNAME="$(printf '%s' "$DSN" | sed -E 's#^[^/]*//[^/]*/([^/?]+).*#\1#')"
|
||
case "$DBNAME" in
|
||
test|*test*) : ;;
|
||
*) fail "ROND_DSN 指向的库名是 '$DBNAME',不含 test —— 验收必须用应用测试库(rond_fog_test)" ;;
|
||
esac
|
||
|
||
export ROND_TEST_CONF="$CONF" ROND_SRC FOG_SRC ROND_DSN="$DSN"
|
||
export ROND_CLEAN_OUT="$CLEAN_OUT" ROND_EXPORT="$CLEAN_OUT"
|
||
|
||
mkdir -p "$OUT"
|
||
echo "== 库:$DBNAME 备份:$(basename "$ROND_SRC") / $(basename "$FOG_SRC")"
|
||
|
||
GOFLAGS_EXTRA=""
|
||
[ "$RACE" = 1 ] && GOFLAGS_EXTRA="$GOFLAGS_EXTRA -race"
|
||
[ "$COVER" = 1 ] && GOFLAGS_EXTRA="$GOFLAGS_EXTRA -cover"
|
||
|
||
if [ "$RACE" = 1 ] && command -v gcc >/dev/null 2>&1; then :; else
|
||
for d in "$HOME/scoop/apps/mingw/current/bin"; do
|
||
[ -d "$d" ] && export PATH="$d:$PATH"
|
||
done
|
||
fi
|
||
if [ "$RACE" = 1 ] && ! command -v gcc >/dev/null 2>&1; then
|
||
fail "-race 需要 C 编译器:scoop install mingw,或把 mingw 的 bin 加进 PATH"
|
||
fi
|
||
|
||
# --- 第一段:先产出一份「纯净往返包」,第二段要读它 ------------------------------
|
||
if [ -z "$RUN" ] && [ "$PKGS" = "./..." ]; then
|
||
echo "== 第一段:导出纯净往返包"
|
||
if ! go test -count=1 -run '^TestMovementCleanExport$' -v ./internal/web/ 2>&1 | tee "$OUT/stage1.log" | grep -E '^(--- (PASS|FAIL|SKIP)|ok|FAIL)'; then
|
||
fail "第一段导出失败,见 $OUT/stage1.log"
|
||
fi
|
||
grep -q '^--- PASS' "$OUT/stage1.log" || fail "TestMovementCleanExport 没跑起来(被 skip 了?)"
|
||
ok "纯净往返包已生成:$(basename "$CLEAN_OUT")"
|
||
fi
|
||
|
||
# --- 第二段:全量(或定点)------------------------------------------------------
|
||
RUNARG=""
|
||
[ -n "$RUN" ] && RUNARG="-run $RUN"
|
||
echo "== 第二段:go test -count=1 -v $GOFLAGS_EXTRA $RUNARG $PKGS"
|
||
# shellcheck disable=SC2086
|
||
go test -count=1 -v $GOFLAGS_EXTRA -timeout 2400s $RUNARG $PKGS >"$LOG" 2>&1
|
||
RC=$?
|
||
|
||
PASS=$(grep -c '^--- PASS' "$LOG" || true)
|
||
FAILN=$(grep -c '^--- FAIL' "$LOG" || true)
|
||
SKIP=$(grep -c '^--- SKIP' "$LOG" || true)
|
||
BADPKG=$(grep -c '^FAIL' "$LOG" || true)
|
||
|
||
echo "== 结果:PASS=$PASS FAIL=$FAILN SKIP=$SKIP 非ok包=$BADPKG"
|
||
echo "== 日志:$LOG"
|
||
|
||
if [ "$SKIP" != 0 ]; then
|
||
echo "-- 以下用例被跳过(=没跑。门控测试缺环境变量时 go test 依然回 ok,别当通过看)--"
|
||
grep -n -B1 '^--- SKIP' "$LOG" | head -40
|
||
fi
|
||
if [ "$FAILN" != 0 ] || [ "$BADPKG" != 0 ]; then
|
||
echo "-- 失败明细(前 40 行)--"
|
||
grep -n -B2 '^--- FAIL' "$LOG" | head -40
|
||
fi
|
||
|
||
if [ "$RC" != 0 ] || [ "$FAILN" != 0 ] || [ "$BADPKG" != 0 ]; then
|
||
fail "有失败"
|
||
fi
|
||
if [ "$SKIP" != 0 ]; then
|
||
fail "有 $SKIP 个用例被跳过 ⇒ 这次不算验收过"
|
||
fi
|
||
ok "全绿且 0 skip(PASS=$PASS)"
|