mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-10-20 17:57:38 +00:00
插件化改造前置:把'绝不回归'变成机器可验证的硬约束。 - 透传特征化:anthropic 逐字节/SSE 逐事件、openai、gemini 路径与错误透传 - 计费不变量:5m/1h 双档缓存价、倍率叠加顺序、overages、端到端金额与配额增量 - 调度不变量:粘性会话、failover 10/3/3 完整循环、并发槽配平、等待队列 - 热路径基准基线 + scripts/bench-baseline.sh(allocs 严格/ns 15%/基准缺失 FAIL) - Makefile test-invariants 目标 + CI invariants job;修复失效的 test-e2e 脚本引用 - .gitignore:放行 backend/scripts 与 docs/plugin-architecture(既有白名单模式) 注:本分支按整体门禁验证(部分测试夹具引用后续提交的签名,中间提交不保证独立编译)。
103 lines
4.1 KiB
Bash
103 lines
4.1 KiB
Bash
#!/usr/bin/env bash
|
|
# Phase-0 TASK-005 热路径基准采集与对比(插件化改造回归安全网)。
|
|
#
|
|
# 用法:
|
|
# ./scripts/bench-baseline.sh collect # 采集基线 -> testdata/bench/baseline.txt
|
|
# ./scripts/bench-baseline.sh compare # 当前代码 vs 基线,违反阈值时退出码 1
|
|
#
|
|
# 对比策略(每个基准按多次采样的均值比较):
|
|
# - allocs/op 严格:增加 > ALLOC_TOLERANCE(默认 0)即失败
|
|
# - ns/op 宽松:劣化 > TIME_TOLERANCE_PCT%(默认 15,吸收 runner 抖动)
|
|
# 环境变量:BENCH_COUNT(采样次数,默认 6)、TIME_TOLERANCE_PCT、ALLOC_TOLERANCE
|
|
#
|
|
# 注意:基线与对比应在同类机器上进行;换机器/换 Go 版本后请重新 collect
|
|
# (环境信息记录在 testdata/bench/baseline.env.txt)。
|
|
|
|
set -euo pipefail
|
|
cd "$(dirname "$0")/.."
|
|
|
|
PATTERN='BenchmarkGatewayForward|BenchmarkGatewayService_ParseSSEUsage|BenchmarkParseClaudeUsageFromResponseBody'
|
|
PKGS='./internal/service/'
|
|
BASELINE=testdata/bench/baseline.txt
|
|
COUNT="${BENCH_COUNT:-6}"
|
|
TIME_TOLERANCE_PCT="${TIME_TOLERANCE_PCT:-15}"
|
|
ALLOC_TOLERANCE="${ALLOC_TOLERANCE:-0}"
|
|
|
|
run_bench() {
|
|
go test -tags=unit -run '^$' -bench "$PATTERN" -benchmem -count="$COUNT" "$PKGS"
|
|
}
|
|
|
|
# 从基准输出中提取每个基准的均值:name mean_ns mean_allocs
|
|
# ns 与 allocs 独立计数;缺任一指标(如未带 -benchmem)的基准跳过并警告,
|
|
# 避免除零产生 inf/nan 静默污染对比结果。
|
|
summarize() {
|
|
awk '/^Benchmark/ {
|
|
name=$1; sub(/-[0-9]+$/, "", name)
|
|
for (i=2; i<=NF; i++) {
|
|
if ($(i)=="ns/op") { ns[name]+=$(i-1); nns[name]++ }
|
|
if ($(i)=="allocs/op") { al[name]+=$(i-1); nal[name]++ }
|
|
}
|
|
}
|
|
END {
|
|
for (k in nns) {
|
|
if (nns[k]>0 && nal[k]>0) printf "%s %.2f %.2f\n", k, ns[k]/nns[k], al[k]/nal[k]
|
|
else print "warn: skip " k " (missing ns/op or allocs/op samples, run with -benchmem)" > "/dev/stderr"
|
|
}
|
|
}' "$1" | sort
|
|
}
|
|
|
|
case "${1:-}" in
|
|
collect)
|
|
mkdir -p "$(dirname "$BASELINE")"
|
|
{
|
|
echo "go: $(go version)"
|
|
echo "cpu: $(grep -m1 'model name' /proc/cpuinfo 2>/dev/null | cut -d: -f2- | xargs || echo unknown)"
|
|
echo "date: $(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
|
echo "count: $COUNT"
|
|
} > "$(dirname "$BASELINE")/baseline.env.txt"
|
|
run_bench | tee "$BASELINE"
|
|
echo "基线已写入 $BASELINE"
|
|
;;
|
|
compare)
|
|
[ -f "$BASELINE" ] || { echo "缺少基线 $BASELINE,先运行: $0 collect" >&2; exit 2; }
|
|
new="$(mktemp)"
|
|
run_bench | tee "$new"
|
|
echo
|
|
if command -v benchstat >/dev/null 2>&1; then
|
|
benchstat "$BASELINE" "$new" || true
|
|
echo
|
|
fi
|
|
base_sum="$(mktemp)"; new_sum="$(mktemp)"
|
|
summarize "$BASELINE" > "$base_sum"
|
|
summarize "$new" > "$new_sum"
|
|
# 基准名集合对比(审计 F-1):join 只输出两侧共有的基准,增删/改名若不检查
|
|
# 会被静默丢弃,造成"基准消失但 compare 仍绿"的假阴性。
|
|
added="$(join -v2 "$base_sum" "$new_sum" | awk '{print $1}')"
|
|
missing="$(join -v1 "$base_sum" "$new_sum" | awk '{print $1}')"
|
|
table_status=0
|
|
join "$base_sum" "$new_sum" | awk -v tp="$TIME_TOLERANCE_PCT" -v at="$ALLOC_TOLERANCE" '
|
|
{
|
|
name=$1; bns=$2; bal=$3; nns=$4; nal=$5
|
|
dns = (bns>0) ? (nns-bns)/bns*100 : 0
|
|
dal = nal-bal
|
|
status="ok"
|
|
if (dal > at) { status="FAIL(allocs/op +" dal ")"; fail=1 }
|
|
else if (dns > tp) { status="FAIL(ns/op +" sprintf("%.1f", dns) "%)"; fail=1 }
|
|
printf "%-60s ns/op %10.0f -> %10.0f (%+6.1f%%) allocs/op %7.1f -> %7.1f %s\n", name, bns, nns, dns, bal, nal, status
|
|
}
|
|
END { exit fail ? 1 : 0 }' || table_status=$?
|
|
if [ -n "$added" ]; then
|
|
printf 'warn: 以下基准在基线中不存在,未参与对比(新增基准请重新 collect 基线):\n%s\n' "$added" >&2
|
|
fi
|
|
if [ -n "$missing" ]; then
|
|
printf 'FAIL: 基线中的以下基准在本次运行缺失(被删除/改名?回归网已失效,须修复或重新 collect):\n%s\n' "$missing" >&2
|
|
exit 1
|
|
fi
|
|
exit "$table_status"
|
|
;;
|
|
*)
|
|
echo "用法: $0 {collect|compare}" >&2
|
|
exit 2
|
|
;;
|
|
esac
|