From 547b2b6b99f2093b15ec3f329079521266ee610c Mon Sep 17 00:00:00 2001 From: zjk <1553836110@qq.com> Date: Fri, 14 Aug 2026 16:44:44 +0800 Subject: [PATCH] =?UTF-8?q?CI=EF=BC=9A=E8=87=AA=E5=8A=A8=E8=BE=93=E5=87=BA?= =?UTF-8?q?=E5=8F=AF=E8=A7=86=E5=8C=96=E6=B5=8B=E8=AF=95=E6=8A=A5=E5=91=8A?= =?UTF-8?q?=EF=BC=88markdown=20=E6=91=98=E8=A6=81=20+=20JUnit=20XML=20+=20?= =?UTF-8?q?=E8=87=AA=E5=8C=85=E5=90=AB=20HTML=EF=BC=89=EF=BC=8C=E5=B9=B6?= =?UTF-8?q?=E6=8E=A8=E9=80=81=E5=88=B0=20test-reports=20=E5=88=86=E6=94=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitea/workflows/ci.yml | 43 +++++++-- .gitignore | 3 + ci/build-test.sh | 200 ++++++++++++++++++++++++++++++---------- 3 files changed, 190 insertions(+), 56 deletions(-) diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index 0b938a1..f130902 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -77,19 +77,50 @@ jobs: - name: Build & test inside arm64 container timeout-minutes: 30 run: | - set -euo pipefail CID="h100-ci-test" docker rm -f "$CID" >/dev/null 2>&1 || true docker create --name "$CID" --platform linux/arm64 "$CI_IMAGE" /bin/sh -c 'sleep 7200' >/dev/null docker cp "$PWD/." "$CID:/src/" docker start "$CID" >/dev/null + # Run build + tests (capture exit code, don't fail the step here so + # we can still collect the report on failure) docker exec "$CID" /src/ci/build-test.sh - mkdir -p bin - docker cp "$CID:/src/bin/pPowerManger" bin/pPowerManger - docker cp "$CID:/src/bin/pPMtest" bin/pPMtest - docker cp "$CID:/src/bin/SQLiteTest" bin/SQLiteTest + TEST_RC=$? + mkdir -p bin reports + docker cp "$CID:/src/bin/pPowerManger" bin/pPowerManger 2>/dev/null || true + docker cp "$CID:/src/bin/pPMtest" bin/pPMtest 2>/dev/null || true + docker cp "$CID:/src/bin/SQLiteTest" bin/SQLiteTest 2>/dev/null || true + docker cp "$CID:/src/reports/." reports/ 2>/dev/null || true docker rm -f "$CID" >/dev/null 2>&1 || true - ls -la bin/ + echo "--- bin/ ---"; ls -la bin/ 2>/dev/null || true + echo "--- reports/ ---"; ls -la reports/ 2>/dev/null || true + exit "$TEST_RC" + + #------------------------------------------------------------------- + # Publish visual test report (runs even if tests failed) + #------------------------------------------------------------------- + - name: Publish test report + if: always() + run: | + SUMMARY_FILE="${GITHUB_STEP_SUMMARY:-/tmp/step_summary.md}" + if [ -f reports/test-report.md ]; then + cat reports/test-report.md >> "$SUMMARY_FILE" + else + echo "## H100PowerManger CI" >> "$SUMMARY_FILE" + echo "测试报告未生成(构建阶段失败)" >> "$SUMMARY_FILE" + fi + + # Persist reports to a dedicated branch (main push only) + if [ "${GITHUB_REF:-}" = "refs/heads/main" ] && [ -d reports ]; then + git config user.name "CI Bot" + git config user.email "ci@localhost" + git checkout --orphan test-reports >/dev/null 2>&1 || git checkout test-reports >/dev/null 2>&1 || true + git rm -rf . >/dev/null 2>&1 || true + cp -f reports/test-report.md reports/test-report.html reports/junit.xml . 2>/dev/null || true + git add -A >/dev/null 2>&1 || true + git commit -m "CI test report ${GITHUB_SHA:-}" >/dev/null 2>&1 || true + git push -f origin test-reports >/dev/null 2>&1 || echo "WARN: failed to push test-reports branch" + fi #------------------------------------------------------------------- # Deploy the cross-built binary to the RK3588 board (push only) diff --git a/.gitignore b/.gitignore index 286dd79..35143d4 100644 --- a/.gitignore +++ b/.gitignore @@ -250,3 +250,6 @@ bin/ccuState.txt bin/pPowerManger bin/SQLiteTest bin/pPMtest + +# CI test reports +reports/ diff --git a/ci/build-test.sh b/ci/build-test.sh index c647c0f..995f0e6 100755 --- a/ci/build-test.sh +++ b/ci/build-test.sh @@ -1,14 +1,30 @@ #!/bin/bash #======================================================================= # FILE: ci/build-test.sh -# DESC: Build the project, run unit tests and a startup smoke test. +# 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 -euo pipefail +set -uo pipefail SRC_DIR="${SRC_DIR:-/src}" cd "${SRC_DIR}" +REPORT_DIR="${SRC_DIR}/reports" +mkdir -p "${REPORT_DIR}" + +ARCH="$(uname -m)" +COMMIT="${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 #----------------------------------------------------------------------- @@ -16,39 +32,52 @@ echo ">>> Building (aarch64, Release)..." rm -rf build mkdir -p build cd build -cmake -DCMAKE_BUILD_TYPE=Release .. -make -j"$(nproc)" +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" -echo ">>> Build artifacts:" -ls -la "${BIN_DIR}" +if [ "${BUILD_OK}" = "1" ]; then + echo ">>> Build artifacts:" + ls -la "${BIN_DIR}" +fi #----------------------------------------------------------------------- # 2. Unit test (SQLiteTest) #----------------------------------------------------------------------- -echo ">>> Running unit test: SQLiteTest" -"${BIN_DIR}/SQLiteTest" -echo ">>> SQLiteTest passed" +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 #----------------------------------------------------------------------- -echo ">>> Smoke test: launch MOOSDB + pPowerManger" +if [ "${BUILD_OK}" = "1" ]; then + echo ">>> Smoke test: launch MOOSDB + pPowerManger" -# Locate MOOSDB (installed by MOOS build) -MOOSDB="$(command -v MOOSDB || true)" -if [ -z "${MOOSDB}" ]; then - MOOSDB="$(ls /opt/moos-ivp/bin/MOOSDB 2>/dev/null || true)" -fi -if [ -z "${MOOSDB}" ] || [ ! -x "${MOOSDB}" ]; then - echo "ERROR: MOOSDB not found" >&2 - exit 1 -fi -echo "Using MOOSDB: ${MOOSDB}" + MOOSDB="$(command -v MOOSDB || true)" + if [ -z "${MOOSDB}" ]; then + MOOSDB="$(ls /opt/moos-ivp/bin/MOOSDB 2>/dev/null || true)" + fi -# Minimal mission file for MOOSDB + pPowerManger -MISSION_FILE="/tmp/smoke.moos" -cat > "${MISSION_FILE}" < "${MISSION_FILE}" <>> Smoke diagnostics" -getent protocols tcp >/dev/null 2>&1 && echo "getprotobyname(tcp) OK" || echo "getprotobyname(tcp) FAILED" -getent hosts localhost >/dev/null 2>&1 && echo "gethostbyname(localhost) OK" || echo "gethostbyname(localhost) FAILED" -echo "ulimit -n: $(ulimit -n)" + "${MOOSDB}" --moos_suicide_disable --moos_no_colour "${MISSION_FILE}" \ + > /tmp/moosdb_smoke.log 2>&1 & + MOOSDB_PID=$! + sleep 3 -"${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 "${MOOSDB_PID}" 2>/dev/null; then - echo "--- MOOSDB crashed at startup; log: ---" - cat /tmp/moosdb_smoke.log -fi + 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 -./pPowerManger "${MISSION_FILE}" > /tmp/pm_smoke.log 2>&1 & -PM_PID=$! -sleep 5 - -if kill -0 "${PM_PID}" 2>/dev/null; then - echo ">>> Smoke test PASSED (pPowerManger alive after 5s)" kill "${PM_PID}" "${MOOSDB_PID}" 2>/dev/null || true wait "${PM_PID}" "${MOOSDB_PID}" 2>/dev/null || true - exit 0 -else - echo ">>> Smoke test FAILED (pPowerManger exited)" >&2 - echo "--- pPowerManger log ---" >&2 - cat /tmp/pm_smoke.log >&2 || true - echo "--- MOOSDB log ---" >&2 - cat /tmp/moosdb_smoke.log >&2 || true - kill "${MOOSDB_PID}" 2>/dev/null || true - exit 1 + 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" < "${REPORT_DIR}/junit.xml" < + + + + $([ "${BUILD_OK}" = "1" ] || echo "") + + + $([ "${SQLITE_OK}" = "1" ] || echo "") + + + $([ "${SMOKE_OK}" = "1" ] || echo "") + + + +EOF + +# --- Self-contained HTML report --- +status_html() { + [ "$1" = "1" ] && echo '✔ PASS' \ + || echo '✖ FAIL' +} +cat > "${REPORT_DIR}/test-report.html" < +H100PowerManger 测试报告 + +

H100PowerManger CI 测试报告

+

架构 ${ARCH} · Commit ${COMMIT} · ${BUILD_DATE}

+

$([ "${ALL_OK}" = "1" ] && echo '全部通过' || echo '存在失败')

+ + + + + +
步骤结果耗时
构建 (${ARCH})$(status_html ${BUILD_OK})${BUILD_TIME}s
单元测试 SQLiteTest$(status_html ${SQLITE_OK})${SQLITE_TIME}s
冒烟测试 MOOSDB+pPowerManger$(status_html ${SMOKE_OK})${SMOKE_TIME}s
+ +EOF + +echo ">>> Reports generated in ${REPORT_DIR}:" +ls -la "${REPORT_DIR}" + +#----------------------------------------------------------------------- +# 5. Exit status +#----------------------------------------------------------------------- +[ "${ALL_OK}" = "1" ]