Files
MeowOS-For-R3P2/patch_v2/meow_powermgr/test_powermgr.sh
T
MeowOS 0cae95c9cc powermgr 期2: 历史采样环/功耗分解top/电源事件流 + mp2731电流接入 + BT·WiFi分档细化
- history: 30s 节拍内存环形(RING_N=480≈4h)存 pct/est_mw/充电态/屏幕态/亮度,
  不落盘重启清零(板载写磨损不考虑); IPC MSG_PM_HISTORY(0xD4)/D5, CLI history[N]
- top: estimate breakdown 分量实时占比排序视图(2s 刷新, Ctrl-C 退,
  MEOW_PM_TOP_ONCE=1 一次输出供测试); CLI top
- events: 插拔充电器/低电阈值穿越(15%/5%/回20%)/亮灭屏/背光跳变(≥30%);
  App 前后台无可轮询导出点→诚实标注不支持(语言, 期3接 launcher)
  IPC MSG_PM_EVENTS(0xD6)/D7, CLI events[N]
- 模型: 系数路径迁 /data/meow/powermgr/power_model.conf(=/usr/data symlink,
  组件持久化目录定案); WiFi 增未关联(carrier=0→unassoc)分档; BT 细化
  rfkill+hciconfig ACL(up/connected, 有界子进程 900ms 超时, 不可用回退 up)
- mp2731 current_now 接入: 充电态实测 charge_mw=cc_voltage×current/1e9,
  charge_confidence=measured(消费侧无实测节点仍 estimated, 条件写清)
- IPC 0xD4-D7 号段本文件局部定(不动 meow_launcherd/meow_ipc.h, 严守只动本目录)

验证: 宿主 aarch64 54 PASS + qemu-mipsel 54 PASS; 交叉 -Wall -Wextra -Werror 0 warning;
固件阈值 <200KB 达标(133KB); BSS 37.6KB 起见 RSS<1MB 达标
2026-09-01 22:13:42 +08:00

221 lines
9.9 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_powermgr.sh — meow_powermgr 宿主桩测试(假 sysfs/procfs 节点,MEOW_*_DIR env 覆盖)。
# 用法:./test_powermgr.sh [host二进制路径](默认 ./meow_powermgr_host;可传 mipsel 二进制 + QEMU 前缀)
# QEMU="qemu-mipsel" ./test_powermgr.sh ./meow_powermgr # qemu 验证
set -u
cd "$(dirname "$0")"
BIN="${1:-./meow_powermgr_host}"
Q="${QEMU:-}"
T=$(mktemp -d /tmp/pmtest.XXXXXX)
trap 'kill $DPID 2>/dev/null; rm -rf "$T"' EXIT
PASS=0; FAIL=0
ck() { # ck <名> <期望子串> <实际>
if echo "$3" | grep -qF "$2"; then PASS=$((PASS+1)); echo "PASS $1";
else FAIL=$((FAIL+1)); echo "FAIL $1: 期望含 [$2] 实际=[$3]"; fi
}
# ---- 搭假节点 ----
PS="$T/ps"; BL="$T/bl"; NET="$T/net"; RF="$T/rfkill"; BT="$T/bt"
mkdir -p "$PS/battery" "$PS/mp2731-charger" "$PS/fusb302-typec-source" "$PS/ac" \
"$BL" "$NET/wlan0" "$RF/rfkill0" "$BT/hci0"
echo 94 > "$PS/battery/capacity"
echo Discharging > "$PS/battery/status"
echo 4275000 > "$PS/battery/voltage_now"
echo Good > "$PS/battery/health"
echo Li-ion > "$PS/battery/technology"
echo Discharging > "$PS/mp2731-charger/status" # 权威链
echo 300 > "$PS/mp2731-charger/temp"
echo 0 > "$PS/fusb302-typec-source/online"
echo 0 > "$PS/ac/online"
echo 101 > "$BL/max_brightness" # R3 Pro II 实测量程 0-101
echo 50 > "$BL/actual_brightness" # 中档(49%)
echo 50 > "$BL/brightness"
echo up > "$NET/wlan0/operstate"
echo 1 > "$NET/wlan0/carrier" # 已关联(carrier 0=未关联)
echo bluetooth > "$RF/rfkill0/type"
echo 1 > "$RF/rfkill0/soft" # BT 被 soft 块 → off
cat > "$T/netdev" <<'EOF'
Inter-| Receive | Transmit
face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed
wlan0: 1000000 1000 0 0 0 0 0 0 2000000 1000 0 0 0 0 0 0
EOF
echo "cpu 100 0 100 800 0 0 0 0 0 0" > "$T/proc_stat"
echo meow > "$T/boot_mode"
ENVS="MEOW_PS_DIR=$PS MEOW_BL_DIR=$BL MEOW_NET_DIR=$NET MEOW_RFKILL_DIR=$RF MEOW_BT_DIR=$BT
MEOW_NETDEV=$T/netdev MEOW_PROC_STAT=$T/proc_stat MEOW_BOOT_MODE=$T/boot_mode
MEOW_PM_MODEL=$T/model.conf MEOW_AUDIO_SOCK=$T/no_audio.sock MEOW_PM_SOCK=$T/pm.sock
MEOW_PM_NO_HCICONFIG=1"
ln -sf "$(readlink -f "$BIN")" "$T/meow_power" # argv[0] 双形态
# ---- T1: 守护直读(无守护 → 降级直读) ----
OUT=$(env $ENVS $Q "$T/meow_power" status 2>/dev/null)
ck T1a "state=Discharging cap=94%" "$OUT"
echo "$OUT" | grep -q "mv=4275" && { PASS=$((PASS+1)); echo "PASS T1b mv"; } || { FAIL=$((FAIL+1)); echo "FAIL T1b: $OUT"; }
ck T1c "health=Good" "$OUT"
ck T1d "charger_temp=30.0C" "$OUT"
ck T1e "rate=null" "$OUT"
ck T1f "src=direct" "$OUT"
# ---- T2: 起守护,IPC 路径 ----
env $ENVS MEOW_PM_SAMPLE_SEC=1 MEOW_PM_MIN_SPAN_SEC=2 $Q "$BIN" --sock "$T/pm.sock" >"$T/daemon.log" 2>&1 &
DPID=$!
for i in $(seq 1 30); do [ -S "$T/pm.sock" ] && break; sleep 0.2; done
[ -S "$T/pm.sock" ] || { echo "FAIL T0: daemon socket 未出现"; cat "$T/daemon.log"; exit 1; }
PASS=$((PASS+1)); echo "PASS T0 daemon up"
OUT=$(env $ENVS $Q "$T/meow_power" status 2>/dev/null)
ck T2a "src=daemon" "$OUT"
ck T2b "cap=94%" "$OUT"
ck T2c "mode=meow" "$OUT"
# ---- T3: 容量差分速率(94→93,span≥2s)→ rate/est_left=derived ----
echo 93 > "$PS/battery/capacity"
sleep 4
OUT=$(env $ENVS $Q "$T/meow_power" status 2>/dev/null)
ck T3a "conf=derived" "$OUT"
ck T3b "est_left=" "$OUT"
echo "$OUT" | grep -q "rate=-" && { PASS=$((PASS+1)); echo "PASS T3c 放电速率为负"; } || { FAIL=$((FAIL+1)); echo "FAIL T3c: $OUT"; }
# ---- T4: estimate(模型合成;中档背光+面板+wifi idle+bt off+audio unknown) ----
OUT=$(env $ENVS $Q "$T/meow_power" estimate 2>/dev/null)
ck T4a "confidence=estimated" "$OUT"
ck T4b "待真机标定" "$OUT"
ck T4c "backlight=450" "$OUT" # 49% → 中档 450
ck T4d "panel=80" "$OUT"
ck T4e "bt=0(off)" "$OUT" # rfkill soft=1 → off
ck T4f "audio=0(unknown)" "$OUT" # 无 audiod → unknown 0mW
# est_mw = 300(base)+450+80+200(wifi idle)+0+0+cpu(0,静态proc_stat)=1030
ck T4g "est_mw=1030" "$OUT"
# ---- T5: wifi 传输档(netdev 增量 >4096/拍 → tx=600) ----
sed -i 's/wlan0: 1000000/wlan0: 1999999/; s/ 2000000 / 2999999 /' "$T/netdev"
sleep 3
OUT=$(env $ENVS $Q "$T/meow_power" estimate 2>/dev/null)
ck T5a "wifi=600(tx)" "$OUT"
# ---- T5b: wifi 未关联(carrier=0)→ unassoc 档 ----
echo 0 > "$NET/wlan0/carrier"
sleep 2
OUT=$(env $ENVS $Q "$T/meow_power" estimate 2>/dev/null)
ck T5b "wifi=80(unassoc)" "$OUT"
echo 1 > "$NET/wlan0/carrier"
# ---- T5c: BT up(rfkill 未软块 + hci0 存在;host 无 hciconfig → 回退 up) ----
echo 0 > "$RF/rfkill0/soft"
sleep 2
OUT=$(env $ENVS $Q "$T/meow_power" estimate 2>/dev/null)
ck T5c "bt=60(up)" "$OUT"
echo 1 > "$RF/rfkill0/soft"
# ---- T6: 息屏(actual_brightness=0)→ 背光/面板归零 ----
echo 0 > "$BL/actual_brightness"
OUT=$(env $ENVS $Q "$T/meow_power" estimate 2>/dev/null)
ck T6a "backlight=0" "$OUT"
ck T6b "panel=0" "$OUT"
echo 50 > "$BL/actual_brightness"
# ---- T7: 模型 conf 覆盖 ----
printf '# test\nbaseline_mw=999\nwifi_idle_mw=111\n' > "$T/model.conf"
OUT=$(env $ENVS $Q "$T/meow_power" model 2>/dev/null)
ck T7a "baseline_mw=999" "$OUT"
ck T7b "wifi_idle_mw=111" "$OUT"
ck T7c "bl_high_mw=900" "$OUT" # 未覆盖键留默认
rm -f "$T/model.conf"
# ---- T8: HibyOS 只读降级(不施估算;电池仍可读) ----
echo hiby > "$T/boot_mode"
sleep 2 # 等守护下一拍热切换
OUT=$(env $ENVS $Q "$T/meow_power" estimate 2>/dev/null)
ck T8a "HibyOS 只读模式" "$OUT"
OUT=$(env $ENVS $Q "$T/meow_power" status 2>/dev/null)
ck T8b "cap=93%" "$OUT" # 只读模式电池采样不受影响
ck T8c "mode=readonly" "$OUT"
echo meow > "$T/boot_mode"
sleep 2
OUT=$(env $ENVS $Q "$T/meow_power" estimate 2>/dev/null)
ck T8d "est_mw=" "$OUT" # 热切换回全功能
# ---- T9: 期 2 CLI — history(守护采样环)/policy(期3桩) ----
sleep 1 # 再采几拍,history 有样本
OUT=$(env $ENVS $Q "$T/meow_power" history 2>&1)
ck T9a "history:" "$OUT"
ck T9b "采样点" "$OUT"
ck T9c "est_mW" "$OUT"
echo "$OUT" | grep -q "守护不可达" && { FAIL=$((FAIL+1)); echo "FAIL T9d 应走守护"; } || { PASS=$((PASS+1)); echo "PASS T9d via-daemon"; }
OUT=$(env $ENVS $Q "$T/meow_power" policy 2>&1)
ck T9e "期 3" "$OUT"
# ---- T10: meow_powermgr 名直调子命令也走 CLI ----
OUT=$(env $ENVS $Q "$BIN" model 2>/dev/null)
ck T10a "nominal_mah=1600" "$OUT"
# ---- T13: mp2731 current_now 充电功率实测接入(期 2 项 5)----
echo Charging > "$PS/mp2731-charger/status"
echo 1500000 > "$PS/mp2731-charger/current_now"
echo 4200000 > "$PS/mp2731-charger/constant_charge_voltage"
sleep 2
OUT=$(env $ENVS $Q "$T/meow_power" estimate 2>/dev/null)
ck T13a "charge=+6300mW" "$OUT" # 4.2V×1.5A=6.3W
ck T13b "confidence=measured" "$OUT" # 充电功率升 measured
OUT=$(env $ENVS $Q "$T/meow_power" status 2>/dev/null)
ck T13c "state=Charging" "$OUT" # 权威链 mp2731=Charging
echo Discharging > "$PS/mp2731-charger/status"
echo 0 > "$PS/mp2731-charger/current_now"
sleep 2
OUT=$(env $ENVS $Q "$T/meow_power" estimate 2>/dev/null)
ck T13d "charge=null" "$OUT" # 放电 → 无实测轨
# ---- T14: 电源事件流(充电器插拔 + 息屏,App 前后台诚实标注不支持)----
OUT=$(env $ENVS $Q "$T/meow_power" events 2>&1)
ck T14a "events:" "$OUT"
ck T14b "charger" "$OUT" # 插/拔充电器事件 tag
echo 0 > "$BL/actual_brightness" # 息屏 → screen 事件
sleep 2
OUT=$(env $ENVS $Q "$T/meow_power" events 2>&1)
ck T14c "screen" "$OUT"
ck T14d "息屏" "$OUT"
echo 50 > "$BL/actual_brightness" # 恢复亮屏(供后测)
# ---- T15: top 功耗分解实时排序(一次输出)----
OUT=$(env $ENVS MEOW_PM_TOP_ONCE=1 $Q "$T/meow_power" top 2>/dev/null)
ck T15a "功耗分解" "$OUT"
ck T15b "screen" "$OUT"
ck T15c "baseline" "$OUT"
echo "$OUT" | grep -q "cpu" && { PASS=$((PASS+1)); echo "PASS T15d cpu行"; } || { FAIL=$((FAIL+1)); echo "FAIL T15d"; }
# ---- T16: 模型系数路径(新定案 /data/meow/powermgr/power_model.conf)----
ENVS_NM=$(echo "$ENVS" | tr ' ' '\n' | grep -v '^MEOW_PM_MODEL=' | tr '\n' ' ')
OUT=$(env $ENVS_NM $Q "$T/meow_power" model 2>/dev/null)
ck T16a "powermgr/power_model.conf" "$OUT"
# ---- T11: 守护停 → CLI 自动降级直读不崩 ----
kill $DPID 2>/dev/null; wait $DPID 2>/dev/null; DPID=""
sleep 1
OUT=$(env $ENVS $Q "$T/meow_power" status 2>/dev/null)
ck T11a "src=direct" "$OUT"
ck T11b "cap=93%" "$OUT"
# ---- T12: audiod 在场时音频链分量(真 audiod 二进制当桩:无 HELLO 直接 QUERY 协议) ----
AUDIOD_BIN=../meow_audiod/meow_audiod_host
[ -n "$Q" ] && AUDIOD_BIN=../meow_audiod/meow_audiod
if [ -x "$AUDIOD_BIN" ]; then
env MEOW_AUDIO_FORCE=1 MEOW_AUDIO_SOCK="$T/audio.sock" MEOW_AUDIO_OUT="$T/a.wav" \
MEOW_AUDIO_SINK=null $Q "$AUDIOD_BIN" --sock "$T/audio.sock" >"$T/audiod.log" 2>&1 &
APID=$!
for i in $(seq 1 30); do [ -S "$T/audio.sock" ] && break; sleep 0.2; done
env $ENVS MEOW_AUDIO_SOCK="$T/audio.sock" MEOW_PM_SAMPLE_SEC=1 MEOW_PM_MIN_SPAN_SEC=2 \
MEOW_PM_SOCK="$T/pm2.sock" $Q "$BIN" --sock "$T/pm2.sock" >"$T/daemon2.log" 2>&1 &
DPID=$!
for i in $(seq 1 30); do [ -S "$T/pm2.sock" ] && break; sleep 0.2; done
OUT=$(env $ENVS MEOW_AUDIO_SOCK="$T/audio.sock" MEOW_PM_SOCK="$T/pm2.sock" $Q "$T/meow_power" estimate 2>/dev/null)
ck T12a "audio=50(idle)" "$OUT" # audiod 在场无流 → 静态档 50
kill $DPID $APID 2>/dev/null; wait 2>/dev/null; DPID=""
else
echo "SKIP T12 (无 audiod 二进制 $AUDIOD_BIN)"
fi
echo "=============================="
echo "PASS=$PASS FAIL=$FAIL"
[ $FAIL -eq 0 ]