Files
lijiaoqiao/scripts/ci/token_runtime_readiness_check.sh

214 lines
7.8 KiB
Bash
Executable File
Raw Permalink 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.
#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "$0")/../.." && pwd)"
DATE_TAG="${1:-$(date +%F)}"
OUT_DIR="${ROOT_DIR}/reports/gates"
mkdir -p "${OUT_DIR}"
TS_TIME="$(date +%H%M%S)"
REPORT_FILE="${OUT_DIR}/token_runtime_readiness_${DATE_TAG}_${TS_TIME}.md"
LOG_FILE="${OUT_DIR}/token_runtime_readiness_${DATE_TAG}_${TS_TIME}.log"
GO_BIN="${ROOT_DIR}/.tools/go-current/bin/go"
if [[ ! -x "${GO_BIN}" ]]; then
GO_BIN="$(command -v go || true)"
fi
if [[ -z "${GO_BIN}" ]]; then
echo "[FAIL] go binary not found" | tee -a "${LOG_FILE}"
exit 1
fi
CHECK_IDS=()
CHECK_STATUS=()
CHECK_DESC=()
CHECK_EVIDENCE=()
add_check() {
CHECK_IDS+=("$1")
CHECK_STATUS+=("$2")
CHECK_DESC+=("$3")
CHECK_EVIDENCE+=("$4")
}
check_file() {
local id="$1"
local desc="$2"
local file="$3"
if [[ -f "${file}" ]]; then
add_check "${id}" "PASS" "${desc}" "${file}"
else
add_check "${id}" "FAIL" "${desc}" "${file} (missing)"
fi
}
check_pattern() {
local id="$1"
local desc="$2"
local file="$3"
local pattern="$4"
if [[ -f "${file}" ]] && grep -Eq "${pattern}" "${file}"; then
add_check "${id}" "PASS" "${desc}" "${file}"
else
add_check "${id}" "FAIL" "${desc}" "${file} (pattern missing)"
fi
}
check_file "TOK-REAL-001-C1" "Token API 可执行入口存在" "${ROOT_DIR}/platform-token-runtime/cmd/platform-token-runtime/main.go"
check_file "TOK-REAL-001-C2" "Token HTTP 契约处理实现存在" "${ROOT_DIR}/platform-token-runtime/internal/httpapi/token_api.go"
check_file "TOK-REAL-001-C3" "Token 生命周期运行时实现存在" "${ROOT_DIR}/platform-token-runtime/internal/auth/service/inmemory_runtime.go"
check_file "TOK-REAL-001-C4" "TOK 生命周期可执行测试存在" "${ROOT_DIR}/platform-token-runtime/internal/token/lifecycle_executable_test.go"
check_file "TOK-REAL-001-C5" "TOK 审计可执行测试存在" "${ROOT_DIR}/platform-token-runtime/internal/token/audit_executable_test.go"
check_file "TOK-REAL-003-C1" "可部署镜像构建工件存在" "${ROOT_DIR}/platform-token-runtime/Dockerfile"
check_file "TOK-REAL-003-C2" "平台 token OpenAPI 契约存在" "${ROOT_DIR}/docs/platform_token_api_contract_openapi_draft_v1_2026-03-29.yaml"
check_pattern "TOK-REAL-002-C1" "审计事件查询接口已落地OpenAPI" "${ROOT_DIR}/docs/platform_token_api_contract_openapi_draft_v1_2026-03-29.yaml" "/api/v1/platform/tokens/audit-events:"
check_pattern "TOK-REAL-002-C2" "审计事件查询接口已落地(代码)" "${ROOT_DIR}/platform-token-runtime/internal/httpapi/token_api.go" "handleAuditEvents"
check_file "TOK-REAL-003-C3" "token runtime 持久化表结构工件存在" "${ROOT_DIR}/sql/postgresql/token_runtime_schema_v1.sql"
GO_TEST_LOG="${OUT_DIR}/token_runtime_go_test_${DATE_TAG}_${TS_TIME}.log"
if (cd "${ROOT_DIR}/platform-token-runtime" && export PATH="$(dirname "${GO_BIN}"):$PATH" && export GOCACHE="${ROOT_DIR}/.tools/go-cache" && export GOPATH="${ROOT_DIR}/.tools/go" && "${GO_BIN}" test ./... >"${GO_TEST_LOG}" 2>&1); then
add_check "TOK-REAL-001-C6" "PASS" "Token runtime 测试通过" "${GO_TEST_LOG}"
else
add_check "TOK-REAL-001-C6" "FAIL" "Token runtime 测试通过" "${GO_TEST_LOG}"
fi
GO_BUILD_LOG="${OUT_DIR}/token_runtime_go_build_${DATE_TAG}_${TS_TIME}.log"
BIN_PATH="${OUT_DIR}/token_runtime_bin_${DATE_TAG}_${TS_TIME}"
if (cd "${ROOT_DIR}/platform-token-runtime" && export PATH="$(dirname "${GO_BIN}"):$PATH" && export GOCACHE="${ROOT_DIR}/.tools/go-cache" && export GOPATH="${ROOT_DIR}/.tools/go" && "${GO_BIN}" build -o "${BIN_PATH}" ./cmd/platform-token-runtime >"${GO_BUILD_LOG}" 2>&1); then
add_check "TOK-REAL-001-C7" "PASS" "Token runtime 可构建" "${GO_BUILD_LOG}"
else
add_check "TOK-REAL-001-C7" "FAIL" "Token runtime 可构建" "${GO_BUILD_LOG}"
fi
SMOKE_LOG="${OUT_DIR}/token_runtime_smoke_${DATE_TAG}_${TS_TIME}.log"
is_port_in_use() {
local port="$1"
ss -ltn | awk '{print $4}' | grep -Eq "[:.]${port}$"
}
pick_smoke_port() {
local base="${1:-18082}"
local max_tries="${2:-50}"
local p="${base}"
local i=0
while [[ "${i}" -lt "${max_tries}" ]]; do
if ! is_port_in_use "${p}"; then
echo "${p}"
return 0
fi
p=$((p + 1))
i=$((i + 1))
done
return 1
}
SMOKE_PORT_BASE="${TOKEN_RUNTIME_SMOKE_PORT:-18082}"
if ! SMOKE_PORT="$(pick_smoke_port "${SMOKE_PORT_BASE}" "50")"; then
echo "[FAIL] no available smoke port from ${SMOKE_PORT_BASE} within 50 tries" > "${SMOKE_LOG}"
add_check "TOK-REAL-001-C8" "FAIL" "Token runtime 本地可运行冒烟通过" "${SMOKE_LOG}"
SMOKE_PORT=""
fi
if [[ "${ENABLE_TOKEN_RUNTIME_SMOKE:-0}" == "1" ]]; then
if [[ -n "${SMOKE_PORT}" ]]; then
set +e
(
echo "[INFO] start token runtime smoke on :${SMOKE_PORT}"
TOKEN_RUNTIME_ADDR=":${SMOKE_PORT}" "${BIN_PATH}" >"${SMOKE_LOG}.server" 2>&1 &
pid=$!
trap 'kill "${pid}" >/dev/null 2>&1 || true' EXIT
ready=0
for _ in {1..20}; do
if curl -sS -m 2 "http://127.0.0.1:${SMOKE_PORT}/actuator/health" | grep -q '\"UP\"'; then
ready=1
break
fi
sleep 0.2
done
if [[ "${ready}" -ne 1 ]]; then
echo "[FAIL] health check failed"
exit 1
fi
issue_code="$(curl -sS -m 3 -o "${SMOKE_LOG}.issue.json" -w "%{http_code}" \
-X POST "http://127.0.0.1:${SMOKE_PORT}/api/v1/platform/tokens/issue" \
-H "Content-Type: application/json" \
-H "X-Request-Id: req-smoke-issue" \
-H "Idempotency-Key: idem-smoke-issue" \
-d '{"subject_id":"smoke-user","role":"owner","ttl_seconds":300,"scope":["supply:*"]}')"
if [[ "${issue_code}" != "201" ]]; then
echo "[FAIL] issue status=${issue_code}"
exit 1
fi
audit_code="$(curl -sS -m 3 -o "${SMOKE_LOG}.audit.json" -w "%{http_code}" \
"http://127.0.0.1:${SMOKE_PORT}/api/v1/platform/tokens/audit-events?request_id=req-smoke-issue&limit=5" \
-H "X-Request-Id: req-smoke-audit")"
if [[ "${audit_code}" != "200" ]]; then
echo "[FAIL] audit query status=${audit_code}"
exit 1
fi
if ! grep -q '"event_name"' "${SMOKE_LOG}.audit.json"; then
echo "[FAIL] audit query payload missing event_name"
exit 1
fi
echo "[PASS] smoke passed"
) >"${SMOKE_LOG}" 2>&1
smoke_rc=$?
set -e
if [[ "${smoke_rc}" -eq 0 ]]; then
add_check "TOK-REAL-001-C8" "PASS" "Token runtime 本地可运行冒烟通过" "${SMOKE_LOG}"
else
add_check "TOK-REAL-001-C8" "FAIL" "Token runtime 本地可运行冒烟通过" "${SMOKE_LOG}"
fi
fi
else
add_check "TOK-REAL-001-C8" "PASS" "Token runtime 本地可运行冒烟(默认跳过,可通过 ENABLE_TOKEN_RUNTIME_SMOKE=1 开启)" "N/A"
fi
TOTAL="${#CHECK_IDS[@]}"
PASS_CNT=0
for status in "${CHECK_STATUS[@]}"; do
if [[ "${status}" == "PASS" ]]; then
PASS_CNT=$((PASS_CNT + 1))
fi
done
READINESS_PCT="$(awk -v p="${PASS_CNT}" -v t="${TOTAL}" 'BEGIN{if(t==0){printf "0.00"}else{printf "%.2f", (p/t)*100}}')"
RESULT="PASS"
if [[ "${READINESS_PCT}" != "100.00" ]]; then
RESULT="FAIL"
fi
{
echo "# Token Runtime Readiness Check (${DATE_TAG})"
echo
echo "- 时间戳:${DATE_TAG}_${TS_TIME}"
echo "- 指标M-021 token_runtime_readiness_pct"
echo "- 结果:**${RESULT}**"
echo "- 数值:${READINESS_PCT}% (${PASS_CNT}/${TOTAL})"
echo
echo "| 检查项 | 结果 | 说明 | 证据 |"
echo "|---|---|---|---|"
for i in "${!CHECK_IDS[@]}"; do
echo "| ${CHECK_IDS[$i]} | ${CHECK_STATUS[$i]} | ${CHECK_DESC[$i]} | ${CHECK_EVIDENCE[$i]} |"
done
echo
echo "## 结论"
echo
echo "1. 本报告仅评估 token 运行态实现就绪度,不替代真实 staging 联调结论。"
echo "2. 真实放行仍需结合 M-013~M-016、SUP-004~SUP-007 与 PHASE-07 实测。"
} > "${REPORT_FILE}"
{
echo "[INFO] report=${REPORT_FILE}"
echo "[INFO] readiness_pct=${READINESS_PCT}"
echo "[RESULT] ${RESULT}"
} | tee -a "${LOG_FILE}"
if [[ "${RESULT}" != "PASS" ]]; then
exit 1
fi