Files
H100PowerManger/ci/build-test.sh
T

199 lines
7.4 KiB
Bash
Executable File

#!/bin/bash
#=======================================================================
# FILE: ci/build-test.sh
# DESC: Build the project, run unit tests + a startup smoke test, and
# generate a visual test report (markdown + junit.xml + html).
# Executed INSIDE the aarch64 build container (ci/Dockerfile).
#=======================================================================
set -uo pipefail
SRC_DIR="${SRC_DIR:-/src}"
cd "${SRC_DIR}"
REPORT_DIR="${SRC_DIR}/reports"
mkdir -p "${REPORT_DIR}"
ARCH="$(uname -m)"
COMMIT="$(git -C "${SRC_DIR}" rev-parse --short HEAD 2>/dev/null || echo "${GITHUB_SHA:-unknown}")"
BUILD_DATE="$(date -u +'%Y-%m-%d %H:%M:%S UTC')"
#-----------------------------------------------------------------------
# Result trackers
#-----------------------------------------------------------------------
BUILD_OK=0; SQLITE_OK=0; SMOKE_OK=0
BUILD_TIME=0; SQLITE_TIME=0; SMOKE_TIME=0
now_ms() { date +%s; }
#-----------------------------------------------------------------------
# 1. Build
#-----------------------------------------------------------------------
echo ">>> Building (aarch64, Release)..."
rm -rf build
mkdir -p build
cd build
t0=$(now_ms)
if cmake -DCMAKE_BUILD_TYPE=Release .. > /tmp/cmake.log 2>&1 \
&& make -j"$(nproc)" > /tmp/make.log 2>&1; then
BUILD_OK=1
else
echo "--- build failed ---" >&2
tail -40 /tmp/make.log >&2
fi
BUILD_TIME=$(( $(now_ms) - t0 ))
cd "${SRC_DIR}"
BIN_DIR="${SRC_DIR}/bin"
if [ "${BUILD_OK}" = "1" ]; then
echo ">>> Build artifacts:"
ls -la "${BIN_DIR}"
fi
#-----------------------------------------------------------------------
# 2. Unit test (SQLiteTest)
#-----------------------------------------------------------------------
if [ "${BUILD_OK}" = "1" ]; then
echo ">>> Running unit test: SQLiteTest"
t0=$(now_ms)
if "${BIN_DIR}/SQLiteTest" > /tmp/sqlitetest.log 2>&1; then
SQLITE_OK=1
echo ">>> SQLiteTest passed"
else
echo ">>> SQLiteTest FAILED" >&2
tail -40 /tmp/sqlitetest.log >&2
fi
SQLITE_TIME=$(( $(now_ms) - t0 ))
fi
#-----------------------------------------------------------------------
# 3. Startup smoke test: MOOSDB + pPowerManger liveness
#-----------------------------------------------------------------------
if [ "${BUILD_OK}" = "1" ]; then
echo ">>> Smoke test: launch MOOSDB + pPowerManger"
MOOSDB="$(command -v MOOSDB || true)"
if [ -z "${MOOSDB}" ]; then
MOOSDB="$(ls /opt/moos-ivp/bin/MOOSDB 2>/dev/null || true)"
fi
MISSION_FILE="/tmp/smoke.moos"
cat > "${MISSION_FILE}" <<EOF
ServerHost = localhost
ServerPort = 9000
Community = h100smoke
ProcessConfig = pPowerManger
{
AppTick = 4
CommsTick = 4
log_level = INFO
log_file = /tmp/pPowerManger_smoke.log
}
EOF
cd "${BIN_DIR}"
t0=$(now_ms)
"${MOOSDB}" --moos_suicide_disable --moos_no_colour "${MISSION_FILE}" \
> /tmp/moosdb_smoke.log 2>&1 &
MOOSDB_PID=$!
sleep 3
./pPowerManger "${MISSION_FILE}" > /tmp/pm_smoke.log 2>&1 &
PM_PID=$!
sleep 5
if kill -0 "${PM_PID}" 2>/dev/null; then
SMOKE_OK=1
echo ">>> Smoke test PASSED (pPowerManger alive after 5s)"
else
echo ">>> Smoke test FAILED (pPowerManger exited)" >&2
fi
kill "${PM_PID}" "${MOOSDB_PID}" 2>/dev/null || true
wait "${PM_PID}" "${MOOSDB_PID}" 2>/dev/null || true
SMOKE_TIME=$(( $(now_ms) - t0 ))
cd "${SRC_DIR}"
fi
#-----------------------------------------------------------------------
# 4. Generate visual test report
#-----------------------------------------------------------------------
mark() { [ "$1" = "1" ] && echo "✅ 通过" || echo "❌ 失败"; }
ALL_OK=0
[ "${BUILD_OK}" = "1" ] && [ "${SQLITE_OK}" = "1" ] && [ "${SMOKE_OK}" = "1" ] && ALL_OK=1
# --- Markdown report ---
cat > "${REPORT_DIR}/test-report.md" <<EOF
## H100PowerManger CI 测试报告
| 步骤 | 结果 | 耗时 |
| :--- | :--- | :--- |
| 构建 (${ARCH}) | $(mark ${BUILD_OK}) | ${BUILD_TIME}s |
| 单元测试 SQLiteTest | $(mark ${SQLITE_OK}) | ${SQLITE_TIME}s |
| 冒烟测试 MOOSDB+pPowerManger | $(mark ${SMOKE_OK}) | ${SMOKE_TIME}s |
**总体结论: $([ "${ALL_OK}" = "1" ] && echo "✅ 全部通过" || echo "❌ 存在失败")**
- 架构: \`${ARCH}\`
- Commit: \`${COMMIT}\`
- 时间: ${BUILD_DATE}
EOF
# --- JUnit XML report (for Gitea test-report rendering) ---
cat > "${REPORT_DIR}/junit.xml" <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<testsuites name="H100PowerManger" tests="3" failures="$([ "${ALL_OK}" = "1" ] && echo 0 || echo 1)" time="$((BUILD_TIME+SQLITE_TIME+SMOKE_TIME))">
<testsuite name="H100PowerManger CI" tests="3" failures="$([ "${ALL_OK}" = "1" ] && echo 0 || echo 1)" time="$((BUILD_TIME+SQLITE_TIME+SMOKE_TIME))">
<testcase name="build_${ARCH}" classname="ci.build" time="${BUILD_TIME}">
$([ "${BUILD_OK}" = "1" ] || echo "<failure message=\"build failed\"/>")
</testcase>
<testcase name="SQLiteTest" classname="ci.unit" time="${SQLITE_TIME}">
$([ "${SQLITE_OK}" = "1" ] || echo "<failure message=\"SQLiteTest failed\"/>")
</testcase>
<testcase name="SmokeTest_MOOSDB_pPowerManger" classname="ci.smoke" time="${SMOKE_TIME}">
$([ "${SMOKE_OK}" = "1" ] || echo "<failure message=\"smoke test failed\"/>")
</testcase>
</testsuite>
</testsuites>
EOF
# --- Self-contained HTML report ---
status_html() {
[ "$1" = "1" ] && echo '<span style="color:#1a7f37;font-weight:600">✔ PASS</span>' \
|| echo '<span style="color:#cf222e;font-weight:600">✖ FAIL</span>'
}
cat > "${REPORT_DIR}/test-report.html" <<EOF
<!DOCTYPE html>
<html lang="zh-CN"><head><meta charset="utf-8"><title>H100PowerManger 测试报告</title>
<style>
body{font-family:-apple-system,Segoe UI,Roboto,Helvetica,Arial,sans-serif;max-width:720px;margin:40px auto;color:#1f2328;line-height:1.6}
h1{font-size:22px} h2{font-size:16px;border-bottom:1px solid #d0d7de;padding-bottom:6px}
table{border-collapse:collapse;width:100%;margin:12px 0}
th,td{border:1px solid #d0d7de;padding:8px 12px;text-align:left}
th{background:#f6f8fa}
.ok{background:#e6ffec} .fail{background:#ffebe9}
.meta{color:#57606a;font-size:13px}
.badge{display:inline-block;padding:4px 12px;border-radius:20px;font-weight:700}
.badge.ok{background:#1a7f37;color:#fff} .badge.fail{background:#cf222e;color:#fff}
</style></head><body>
<h1>H100PowerManger CI 测试报告</h1>
<p class="meta">架构 <code>${ARCH}</code> &middot; Commit <code>${COMMIT}</code> &middot; ${BUILD_DATE}</p>
<p>$([ "${ALL_OK}" = "1" ] && echo '<span class="badge ok">全部通过</span>' || echo '<span class="badge fail">存在失败</span>')</p>
<table>
<tr><th>步骤</th><th>结果</th><th>耗时</th></tr>
<tr class="$([ "${BUILD_OK}" = "1" ] && echo ok || echo fail)"><td>构建 (${ARCH})</td><td>$(status_html ${BUILD_OK})</td><td>${BUILD_TIME}s</td></tr>
<tr class="$([ "${SQLITE_OK}" = "1" ] && echo ok || echo fail)"><td>单元测试 SQLiteTest</td><td>$(status_html ${SQLITE_OK})</td><td>${SQLITE_TIME}s</td></tr>
<tr class="$([ "${SMOKE_OK}" = "1" ] && echo ok || echo fail)"><td>冒烟测试 MOOSDB+pPowerManger</td><td>$(status_html ${SMOKE_OK})</td><td>${SMOKE_TIME}s</td></tr>
</table>
</body></html>
EOF
echo ">>> Reports generated in ${REPORT_DIR}:"
ls -la "${REPORT_DIR}"
#-----------------------------------------------------------------------
# 5. Exit status
#-----------------------------------------------------------------------
[ "${ALL_OK}" = "1" ]