#!/usr/bin/env bash # 真实 40250 服务器端到端冒烟测试。 # # 用法: # ./script/live_smoke_test.sh # ./script/live_smoke_test.sh --no-build # ./script/live_smoke_test.sh --no-mutations # ./script/live_smoke_test.sh --no-reconnect # # 账号和密码优先从环境变量读取;未提供时安全地交互输入,不写入脚本。 set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" REPO="$(cd "$SCRIPT_DIR/.." && pwd)" APP="$REPO/build/export/mtgodot-poc.app" EXECUTABLE="$APP/Contents/MacOS/mtgodot-poc" ARTIFACT_DIR="$REPO/build/live-smoke" LOG="$ARTIFACT_DIR/live-smoke.log" REPORT="$ARTIFACT_DIR/live-smoke-report.json" CONFIG_FILE="${MT_SMOKE_CONFIG:-$REPO/.env.live-smoke.local}" BUILD=1 MUTATIONS=1 RECONNECT=1 usage() { cat <<'EOF' 用法: ./script/live_smoke_test.sh [选项] 选项: --no-build 使用现有 APP,不重新打包 --no-mutations 只做登录、进游戏和数据读取,不发送移动/聊天/重连包 --no-reconnect 做移动和聊天,但跳过重连 --help 显示帮助 环境变量: MT_ACCOUNT / MT_PASSWORD 可预先提供账号密码,未提供时交互输入 MT_CHAR_SLOT=N 指定角色槽位;不设置时自动选择第一个角色 EOF } while [ "$#" -gt 0 ]; do case "$1" in --no-build) BUILD=0 ;; --no-mutations) MUTATIONS=0 ;; --no-reconnect) RECONNECT=0 ;; --help) usage; exit 0 ;; *) echo "未知选项: $1" >&2; usage >&2; exit 2 ;; esac shift done cd "$REPO" mkdir -p "$ARTIFACT_DIR" if [ -f "$CONFIG_FILE" ]; then # shellcheck disable=SC1090 . "$CONFIG_FILE" fi if [ -z "${MT_ACCOUNT:-}" ]; then read -r -p "账号: " MT_ACCOUNT fi if [ -z "${MT_PASSWORD:-}" ]; then read -r -s -p "密码: " MT_PASSWORD echo fi if [ -z "${MT_ACCOUNT:-}" ] || [ -z "${MT_PASSWORD:-}" ]; then echo "账号和密码不能为空" >&2 exit 2 fi if [ "$BUILD" -eq 1 ]; then echo "== build release ==" ./build-macos-client.sh release fi if [ ! -x "$EXECUTABLE" ]; then echo "找不到可执行 APP:$EXECUTABLE" >&2 echo "请先运行 ./build-macos-client.sh release" >&2 exit 2 fi echo "== check server ports ==" for port in 11000 13002; do if ! nc -G 3 -z 192.168.21.203 "$port" >/dev/null 2>&1; then echo "服务器端口不可达:192.168.21.203:$port" >&2 exit 3 fi done pkill -x mtgodot-poc 2>/dev/null || true export MT_PROTOCOL=classic export MT_AUTOLOGIN=1 export MT_TEST_MODE=smoke export MT_ACCOUNT export MT_PASSWORD export MT_SMOKE_MUTATIONS="$MUTATIONS" export MT_SMOKE_RECONNECT="$RECONNECT" export MT_TEST_REPORT="$REPORT" rm -f "$REPORT" echo "== run live smoke ==" echo "log: $LOG" echo "report: $REPORT" set +e "$EXECUTABLE" 2>&1 | tee "$LOG" APP_STATUS=${PIPESTATUS[0]} set -e if [ ! -f "$REPORT" ]; then echo "未生成本次测试报告,APP 可能在测试状态机启动前崩溃。" >&2 echo "LIVE_SMOKE RESULT: FAIL (missing report)" >&2 exit 4 fi echo "== report ==" if command -v jq >/dev/null 2>&1; then REPORT_STATUS=$(jq -r '.status // empty' "$REPORT") jq -r '"status=" + .status, "duration=" + (.duration_seconds|tostring) + "s", ( .failures[]? | "failure=" + . )' "$REPORT" else REPORT_STATUS="" if grep -q '"status"[[:space:]]*:[[:space:]]*"PASS"' "$REPORT"; then REPORT_STATUS=PASS fi grep -E '"status"|"failures"' "$REPORT" || true fi if [ "$APP_STATUS" -ne 0 ]; then echo "LIVE_SMOKE RESULT: FAIL (APP exit=$APP_STATUS)" >&2 echo "最近的崩溃报告:" ls -1t "$HOME/Library/Logs/DiagnosticReports/mtgodot-poc-"*.ips 2>/dev/null | head -n 3 || true exit "$APP_STATUS" fi if [ "$REPORT_STATUS" != "PASS" ]; then echo "LIVE_SMOKE RESULT: FAIL (report status=$REPORT_STATUS)" >&2 exit 1 fi echo "LIVE_SMOKE RESULT: PASS"