#!/bin/bash # CI Integration Tests Job 主脚本 # 包含:依赖安装、ffmpeg安装、Redis启动、PG启动、迁移、测试、清理、覆盖率 set -eu echo "=== CI Integration Tests 开始 ===" # --- 安装依赖 --- echo "" echo "=== 安装 Python 依赖 ===" python3 -m pip install -q -r requirements-base.txt python3 -m pip install -q -r requirements.txt python3 -m pip install -q -r requirements-dev.txt python3 -m pip install -q pytest-rerunfailures pytest --version # --- 安装 ffmpeg --- echo "" echo "=== 安装 ffmpeg ===" bash scripts/ci/step_install_ffmpeg.sh # --- 启动 Redis --- echo "" echo "=== 启动 Redis ===" REDIS_CONTAINER="ci-redis-${GITHUB_RUN_ID:-$$}" docker rm -f "$REDIS_CONTAINER" 2>/dev/null || true docker run -d --name "$REDIS_CONTAINER" \ -P \ --health-cmd "redis-cli ping" \ --health-interval 2s \ --health-timeout 2s \ --health-retries 10 \ redis:7-alpine REDIS_PORT=$(docker port "$REDIS_CONTAINER" 6379/tcp | cut -d: -f2) echo "Redis port: $REDIS_PORT" export REDIS_URL="redis://127.0.0.1:$REDIS_PORT/0" for i in $(seq 1 15); do if docker inspect --format='{{.State.Health.Status}}' "$REDIS_CONTAINER" 2>/dev/null | grep -q healthy; then echo "Redis is ready on port $REDIS_PORT" break fi echo "Waiting for Redis... ($i/15)" sleep 2 done docker inspect --format='{{.State.Health.Status}}' "$REDIS_CONTAINER" | grep -q healthy # 额外验证:确保从宿主侧通过映射端口实际能连上 Redis for i in $(seq 1 20); do if python3 -c "import socket; s=socket.socket(); s.settimeout(2); s.connect(('127.0.0.1', $REDIS_PORT)); s.close()" 2>/dev/null; then echo "TCP connectivity to Redis confirmed on port $REDIS_PORT" break fi echo "Waiting for TCP connectivity to Redis on port $REDIS_PORT... ($i/20)" sleep 2 done python3 -c "import socket; s=socket.socket(); s.settimeout(2); s.connect(('127.0.0.1', $REDIS_PORT)); s.close()" # --- 启动 PostgreSQL --- echo "" echo "=== 启动 PostgreSQL ===" PG_CONTAINER="ci-pg-${GITHUB_RUN_ID:-$$}" docker rm -f "$PG_CONTAINER" 2>/dev/null || true docker run -d --name "$PG_CONTAINER" \ --shm-size=256m \ -e POSTGRES_USER=postgres \ -e POSTGRES_PASSWORD=postgres \ -e POSTGRES_DB=xiaoxia_saas \ -P \ --health-cmd "pg_isready -U postgres" \ --health-interval 5s \ --health-timeout 5s \ --health-retries 12 \ postgres:16 PG_PORT=$(docker port "$PG_CONTAINER" 5432/tcp | cut -d: -f2) echo "PostgreSQL port: $PG_PORT" export DATABASE_URL="postgresql+psycopg://postgres:postgres@127.0.0.1:$PG_PORT/xiaoxia_saas" for i in $(seq 1 30); do if docker inspect --format='{{.State.Health.Status}}' "$PG_CONTAINER" 2>/dev/null | grep -q healthy; then echo "PostgreSQL is ready on port $PG_PORT" break fi echo "Waiting for PostgreSQL... ($i/30)" sleep 2 done docker inspect --format='{{.State.Health.Status}}' "$PG_CONTAINER" | grep -q healthy # 额外验证:确保从宿主侧通过映射端口实际能连上 PG(端口映射可能有延迟) for i in $(seq 1 30); do if python3 -c "import socket; s=socket.socket(); s.settimeout(2); s.connect(('127.0.0.1', $PG_PORT)); s.close()" 2>/dev/null; then echo "TCP connectivity to PostgreSQL confirmed on port $PG_PORT" break fi echo "Waiting for TCP connectivity to PostgreSQL on port $PG_PORT... ($i/30)" sleep 2 done python3 -c "import socket; s=socket.socket(); s.settimeout(2); s.connect(('127.0.0.1', $PG_PORT)); s.close()" # --- 执行迁移 --- echo "" echo "=== 执行 Alembic 迁移 ===" PYTHONPATH="$PWD/apps/api:$PWD" python3 -m alembic upgrade head echo "✅ 迁移完成" # --- 运行集成测试 --- echo "" echo "=== 运行集成测试 ===" PYTHONPATH="$PWD/apps/api:$PWD" python3 -m coverage run \ --source=apps/api/app,packages \ --omit="*/migrations/*,*/tests/*,*/test_*.py,*/site-packages/*" \ --branch \ -m pytest tests/integration -q --timeout=60 -x --reruns 2 --reruns-delay 1 -m "not performance" python3 -m coverage report --show-missing python3 -m coverage xml -o coverage.xml python3 -m coverage report --fail-under=40 > /dev/null echo "✅ 集成测试通过" # --- API 性能基线测试(仅告警) --- echo "" echo "=== API 性能基线测试(仅告警) ===" set +e PERF_OUTPUT=$(mktemp) PYTHONPATH="$PWD/apps/api:$PWD" python3 -m pytest tests/integration/test_api_performance.py \ -v --timeout=120 -p no:cacheprovider 2>&1 | tee "$PERF_OUTPUT" echo "" echo "=== 性能测试摘要 ===" grep "PERF_STATS:" "$PERF_OUTPUT" || echo "PERF_STATS: 未找到统计数据" grep "PERF_RESULT:" "$PERF_OUTPUT" || echo "PERF_RESULT: 未找到详细结果" TOTAL=$(grep -c "PERF_RESULT:" "$PERF_OUTPUT" || echo 0) PASSED=$(grep "PERF_RESULT: PASS" "$PERF_OUTPUT" | wc -l) FAILED=$(grep "PERF_RESULT: FAIL" "$PERF_OUTPUT" | wc -l) echo "" echo "性能测试结果: $PASSED/$TOTAL 通过, $FAILED 未达标" if [ "$FAILED" -gt 0 ]; then echo "" echo "⚠️ 警告: $FAILED 个接口性能未达标" fi rm -f "$PERF_OUTPUT" set -e # --- 清理 --- echo "" echo "=== 清理容器 ===" docker rm -f "$PG_CONTAINER" 2>/dev/null || true docker rm -f "$REDIS_CONTAINER" 2>/dev/null || true echo "✅ 清理完成" # --- 覆盖率汇总 --- echo "" echo "=== 覆盖率汇总 ===" set +e python3 scripts/ci_coverage_summary.py set -e echo "" echo "=== CI Integration Tests 全部通过 ✅ ==="