Files
MeowOS-For-R3P2/scripts/build/test_build_devkit.sh
T
AskaEth adaed09f94 fix(devkit): M24 r2 评审 — 交付完整性闸门 + 补 sysctl + time64 文档更正
P2-1(与 P1 同类):licenses/ 与 README 缺失仍会假成功。
- 新增 meta_complete()/verify_meta():MANIFEST + README + 五份许可证副本
  (procps COPYING/COPYING.LIB、ncurses、lsof、musl-COPYRIGHT)缺一即不完整
- 纳入 skip 条件与 --verify-only;产物未变但 meta 缺失时就地 write_meta 补全(不重编),
  构建树不在则退回全量重建
- 回归测试新增 T6(删 licenses 后 --with-sources 必须恢复)、T7(--verify-only 必须拒绝)、
  T8(删 README 后恢复);共 20 项全过

P2-2:README.txt/MANIFEST.txt 的卡上路径全错(写成 ../src、scripts/build/…)。
- 全部改为卡内相对路径:src/、licenses/、MANIFEST.txt、src/DEVKIT.md、src/build_devkit.sh
- README 增加「目录内容」段并注明 src/ 是生成目录、勿手放文件

P2-3:valgrind 的排除理由(“无 MIPS32 后端”)是错的 —— 官方支持 MIPS32/Linux。
- 改为「未尝试」:交叉构建需 autotools + 目标 vDSO 细节、产物 10MB+,56MB 单核不实用

P2-4:busybox 1.31 实测有 pgrep/kill/killall,没有 pkill、没有 sysctl。
- 表格改准确;pgrep 保留(增量有限不交付);pkill 写明「busybox 无此 applet,
  killall 只能部分替代,本轮未做」
- 新增交付 sysctl(procps 4.0.4,148184 B,静态):MANIFEST/verify-only/真机
  (sysctl -a 428 键、kernel.hostname/panic 读取、-n)均已验证

P2-5:free -s <小数> 也受 time64 影响(usleep 亚秒被抹平),文档说反了。
- DEVKIT §9 增加一行(free -s 0.5 实测 0s、free -s 1 实测 1s);README 同步;
  “收益只有 vmstat -t 一列”改为包含 free -s

P3:
1. §9 机制改准:内核只写 8 字节 → tv_sec 高 32 位是内核写入的 nsec、offset 8 的
   tv_nsec 才是未初始化;nanosleep 是把 tv_sec 高半字当 nsec 读(0)
2. 删掉脚本里 top 的旧错误归因(时长溢出/59.4 GiB),与 DEVKIT 对齐
3. 测试耗时改为「热缓存约 15s,冷启动 1–2 分钟」(实测 28s 含多次构建/修复路径)
4. --verify-only 依赖清单写全(file/readelf/sha256sum/awk/sed/grep/wc/cut/basename)
5. licenses/ 增加 musl-COPYRIGHT(zig env → libc/musl/COPYRIGHT,取不到即失败),§6 补一行
6. htop 说明改准:亚秒刷新走 ncurses halfdelay()(select + 32 位 timeval),大概率不受
   time64 影响;受影响的是时钟显示与部分采样(仍注明未做运行时验证)
7. README/脚本注明 src/ 是生成目录
8. LGPL 摘要改为「源码(§6a) 或 共享库(§6b) 或 书面要约(§6c)」
9. ltrace/sysstat 从「不可行」改为「未做(成本高)」,与 perf 的硬阻塞区分

验证:test_build_devkit.sh 20/20;--verify-only 通过(7 个二进制 + MANIFEST + 5 份许可证);
独立工作区离线重建 64s/0 下载,七个 sha256 与前一次逐字节一致;设备实测 sysctl 与其余六项正常。
2026-11-06 19:53:45 +08:00

122 lines
5.6 KiB
Bash
Executable File
Raw 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.
#!/bin/bash
# ============================================================================
# test_build_devkit.sh — build_devkit.sh 的回归测试(不重编)
#
# 耗时:热缓存约 15 秒;若需冷启动基线重建(首次运行/源码未缓存)约 1–2 分钟。
#
# 覆盖:
# r1 P1 回归点 —— stamp 命中(跳过编译)时,--with-sources 必须真正产出 src/
# r2 P2-1 —— licenses/README 被删后 --with-sources 必须恢复,
# --verify-only 必须拒绝缺许可证的交付
# MANIFEST 内容漂移检测、src/ 缺文件与内容漂移自愈
#
# 前置:MEOW_DEVKIT_WORK 里已有一次构建(脚本会先跑一次增量构建,命中则秒回;
# 缓存缺失时会联网下载/编译,第一次运行约 1 分钟)。
#
# 用法:bash scripts/build/test_build_devkit.sh [-v]
# 退出码 0 = 全过;非 0 = 用例失败数。
# ============================================================================
set -u
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
SCRIPT="$ROOT/scripts/build/build_devkit.sh"
export MEOW_DEVKIT_WORK="${MEOW_DEVKIT_WORK:-$HOME/.cache/meow-devkit}"
OUT="$ROOT/fw_apps/devkit"
TMP="$MEOW_DEVKIT_WORK/test-tmp"
VERBOSE=0
[ "${1:-}" = "-v" ] && VERBOSE=1
PASS=0
FAILN=0
pass() { PASS=$((PASS + 1)); printf 'PASS %s\n' "$*"; }
fail() { FAILN=$((FAILN + 1)); printf 'FAIL %s\n' "$*"; }
run() { # run <说明> <命令...>
local desc="$1"; shift
local log="$TMP/last.log"
if "$@" >"$log" 2>&1; then
[ "$VERBOSE" = 1 ] && sed 's/^/ | /' "$log"
return 0
fi
printf ' 命令失败: %s\n' "$*"
sed 's/^/ | /' "$log" | tail -20
return 1
}
mkdir -p "$TMP"
# 无论成败都恢复现场,别把测试的破坏留在产物目录里
restore() {
[ -f "$TMP/MANIFEST.txt.bak" ] && cp "$TMP/MANIFEST.txt.bak" "$OUT/MANIFEST.txt"
rm -rf "$TMP"
}
trap restore EXIT
echo "== 0) 确保基线构建(幂等;已构建则秒回)"
run "基线构建" bash "$SCRIPT" || { echo "!!! 基线构建失败,后续用例无意义"; exit 1; }
pass "基线构建"
echo "== 1) P1 回归:stamp 命中 + --with-sources 必须产出 src/"
rm -rf "$OUT/src"
run "普通重跑(应命中 stamp 且不建 src/)" bash "$SCRIPT" || fail "T1a 普通重跑"
[ ! -d "$OUT/src" ] && pass "T1a 普通重跑不创建 src/(符合预期)" || fail "T1a 普通重跑意外创建了 src/"
run "--with-sources(stamp 命中路径)" bash "$SCRIPT" --with-sources || fail "T1b --with-sources 退出码非 0"
for f in ncurses-6.5.tar.gz procps-ng-4.0.4.tar.xz lsof-4.99.4.tar.xz build_devkit.sh DEVKIT.md; do
[ -s "$OUT/src/$f" ] && pass "T1b src/$f 存在且非空" || fail "T1b 缺 src/$f(P1 未修好)"
done
echo "== 2) 缺文件自愈:删掉构建脚本后再 --with-sources"
rm -f "$OUT/src/build_devkit.sh"
run "--with-sources 补齐" bash "$SCRIPT" --with-sources || fail "T2 --with-sources 退出码非 0"
[ -s "$OUT/src/build_devkit.sh" ] && pass "T2 src/build_devkit.sh 被补回" || fail "T2 未补回 src/build_devkit.sh"
echo "== 3) 内容漂移自愈:把 src 里的源码包改坏"
printf 'tamper\n' >> "$OUT/src/ncurses-6.5.tar.gz"
run "--with-sources 重铺" bash "$SCRIPT" --with-sources || fail "T3 --with-sources 退出码非 0"
if cmp -s "$OUT/src/ncurses-6.5.tar.gz" "$MEOW_DEVKIT_WORK/src/ncurses-6.5.tar.gz"; then
pass "T3 被改坏的源码包已恢复成钉住版本"
else
fail "T3 源码包未恢复"
fi
echo "== 4) --verify-only:正常通过"
run "--verify-only" bash "$SCRIPT" --verify-only && pass "T4a --verify-only 通过" || fail "T4a --verify-only 失败"
echo "== 5) --verify-only:能查出 MANIFEST 内容漂移"
cp "$OUT/MANIFEST.txt" "$TMP/MANIFEST.txt.bak"
awk 'BEGIN{done=0} { if (!done && $1=="vmstat") { $NF="0000000000000000000000000000000000000000000000000000000000000000"; done=1 } print }' \
"$TMP/MANIFEST.txt.bak" > "$OUT/MANIFEST.txt"
if run "--verify-only(MANIFEST 被篡改)" bash "$SCRIPT" --verify-only; then
fail "T5 --verify-only 未发现 MANIFEST sha 被篡改"
else
pass "T5 --verify-only 正确拒绝被篡改的 MANIFEST"
fi
cp "$TMP/MANIFEST.txt.bak" "$OUT/MANIFEST.txt"
run "--verify-only(恢复后)" bash "$SCRIPT" --verify-only && pass "T5b 恢复后重新通过" || fail "T5b 恢复后仍失败"
echo "== 6) 交付完整性:删 licenses/ 后 --with-sources 必须恢复"
LICENSES="procps-ng-4.0.4-COPYING procps-ng-4.0.4-COPYING.LIB ncurses-6.5-COPYING lsof-4.99.4-COPYING musl-COPYRIGHT"
rm -rf "$OUT/licenses"
run "--with-sources 补 licenses" bash "$SCRIPT" --with-sources || fail "T6 --with-sources 退出码非 0"
for f in $LICENSES; do
[ -s "$OUT/licenses/$f" ] && pass "T6 licenses/$f 已恢复" || fail "T6 缺 licenses/$f"
done
echo "== 7) --verify-only 必须拒绝缺 licenses 的交付"
rm -rf "$OUT/licenses"
if run "--verify-only(缺 licenses)" bash "$SCRIPT" --verify-only; then
fail "T7 --verify-only 未发现 licenses/ 缺失"
else
pass "T7 --verify-only 正确拒绝缺 licenses 的交付"
fi
run "--with-sources 恢复" bash "$SCRIPT" --with-sources || fail "T7 --with-sources 恢复失败"
run "--verify-only(恢复后)" bash "$SCRIPT" --verify-only && pass "T7b 恢复后通过" || fail "T7b 恢复后仍失败"
echo "== 8) 交付完整性:删 README.txt 后 --with-sources 必须恢复"
rm -f "$OUT/README.txt"
run "--with-sources 补 README" bash "$SCRIPT" --with-sources || fail "T8 --with-sources 退出码非 0"
[ -s "$OUT/README.txt" ] && pass "T8 README.txt 已恢复" || fail "T8 README.txt 未恢复"
echo
printf '== 结果: %d 通过, %d 失败\n' "$PASS" "$FAILN"
[ "$FAILN" = 0 ]