Skip to content

✅ test(e2e): 建立真机 Provisioning 与配对旅程 - #307

Open
JunLang-7 wants to merge 9 commits into
1024XEngineer:mainfrom
JunLang-7:feat/287-hil-provisioning-pairing
Open

✅ test(e2e): 建立真机 Provisioning 与配对旅程#307
JunLang-7 wants to merge 9 commits into
1024XEngineer:mainfrom
JunLang-7:feat/287-hil-provisioning-pairing

Conversation

@JunLang-7

@JunLang-7 JunLang-7 commented Aug 19, 2026

Copy link
Copy Markdown
Collaborator

目标结果

建立首条接入共享 Runner 的 ESP32-S3 provisioning/auth/pairing HIL journey,并覆盖 PCB 正式 Profile 的真实设备生命周期。

主要变更

  • 新增设备描述与设备/串口双重跨进程租约,同一硬件一次只允许一个 run;
  • flash 前只读芯片分区表和 ESP-IDF otadata 双 sector,严格核对设备描述、正式 Profile、构建 metadata,并选择真实活动 OTA 槽;
  • 只允许 application-only write-flash + verify-flash,不写 bootloader、partition table、NVS、otadata、assets/model;
  • 使用 esptool 5 兼容命令;子进程无法启动稳定归类为 infrastructure;
  • 严格要求 provisioned -> Wi-Fi ready -> SNTP synced -> Gateway TLS/auth ready;
  • 严格要求 matching scope、六位 code、pending -> expired;设备重复上报 pending 时保持幂等,不误判为乱序;
  • 临时 Gateway device ID 绑定 runId,正常、失败、timeout 和 interrupt 通过 Runner cleanup 执行恢复、身份吊销和 lease 释放;
  • HIL 清理预算按真实远端 Gateway revoke 延长至 30 秒,Host 仍为 5 秒;
  • evidence 增加严格 hil_im_pairing 白名单;失败结果不会错误声称硬件 evidence;
  • 启动错误和 SNTP marker 使用稳定、脱敏的公共日志信号。

验证

  • 全量 Python 测试:182 passed,1 skipped;
  • Ruff 0.12.7 全仓 format/check 通过,C++ clang-format 门禁通过;
  • PCB 已接入,真机只读探测成功:ESP32-S3,分区表与 pcb Profile 精确匹配;
  • 测试板已从 PR feat(schedule): 新增定时提醒服务 #301 遗留的 Schema v5 回到 Schema v4,并确认 STORAGE_READY schema_version=4;
  • 当前真实活动应用槽为 ota_1;application-only flash 和芯片回读校验通过;
  • 完整真实 HIL run 8652f086ec7d94b0f52d3a71bdad8b4a 通过:
    • readiness:provisioned, wifi_ready, sntp_synced, ready
    • pairing:scope_matched, code_valid, pending, expired
    • prepare/run/assert/collect/cleanup 全部 passed
    • hardware_verified=true,evidence scope=hil_im_pairing
  • Gateway 临时设备已确认 revoked,本地 serial/device leases 已释放。
  • 成功 evidence 路径:/private/tmp/issue-287-hil-success.HE1xit/evidence/evidence-8652f086ec7d94b0f52d3a71bdad8b4a.json

真实环境覆盖说明

本 PR 已有 PCB 的完整 provisioning/auth/pairing HIL 成功 evidence。SparkBot 仍仅覆盖共享 Runner contract 和 Profile guard,不声称其真实设备 journey 已通过。

非目标

  • 不自动化真实微信 pending -> confirmed;继续由 [IM] 端到端真机与真实平台验收 #132 验收;
  • 不验证 Linx、ASR、TTS、物理声学、显示或按键体验;
  • 不在本 PR 修改 nightly/required CI 分层门禁。

风险与回退

  • 设备布局或 Profile 任一不符时在 flash 前 fail closed;
  • 无设备/租约冲突归类为 device/infrastructure,不伪装为产品失败;
  • 可从 Runner registry 移除 im-pairing journey 回退,不改变产品协议或状态机;
  • HIL evidence 与 contract-only evidence 明确隔离,Host/Mock 不会被标记为硬件验证。

Closes #287
Refs #283 #132

SparkBot 真机尝试(2026-08-19)

已接入 /dev/cu.usbmodem14401 并完成只读芯片/分区探测:ESP32-S3 rev 0.2,MAC 98:a3:16:c7:81:b0。本次未烧录任何内容,失败发生在本地构建尺寸检查:固件 voicelife.bin0x2d8a80,现有 factory 分区为 0x2d0000,超出 0x8a80 字节;因此未进入 provision/pairing,hardware_verified=false。串口和设备 lease 均在 cleanup 释放。

完整明文日志与 evidence:/private/tmp/issue-287-sparkbot-hil-retry.jTiwrQ/run.log/private/tmp/issue-287-sparkbot-hil-retry.jTiwrQ/evidence/evidence-659d20838af77105c1dd2d4879448edb.json。这不是 SparkBot HIL 通过证据;扩大 factory 或迁移分区表需要单独的硬件迁移授权,当前 PR 不宣称已完成。

通过设备与串口双重租约、只读分区 Profile guard 和 application-only flash,阻止并发占用及交叉刷写。

复用既有 provisioning、readiness 与 pairing 边界,严格判定 Wi-Fi、SNTP、Gateway auth 和 pending 到 expired,并在所有路径吊销临时身份、复位设备和释放租约。

Host/Python 171 项测试与 72 项 CTest 通过;当前环境无已连接真机,因此未生成 SparkBot/PCB 硬件成功证据。

Closes 1024XEngineer#287

Refs 1024XEngineer#283 1024XEngineer#132
@codecov

codecov Bot commented Aug 19, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@fennoai fennoai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

本次审查覆盖了设备/Profile guard、HIL adapter 生命周期、provisioning/配对解析以及 evidence 白名单。相关 83 个 Python 测试通过;另外用最小复现验证了注册补偿、cleanup deadline 和超时分类路径。当前实现仍可能在失败路径遗留临时 Gateway 身份,且短 cleanup 超时会跳过后续租约释放;设备探测超时也会被误报为设备故障。

View job run

Comment thread scripts/e2e_hil_adapters.py
Comment thread scripts/e2e_hil_adapters.py Outdated
Comment thread scripts/e2e_hil_adapters.py
在远端注册前登记可预测设备 ID 的撤销补偿,避免 SSH 或响应校验失败后遗留 active 测试身份。

将本地租约与临时目录标记为无需远端 deadline 的 cleanup,使 revoke 超时后仍能释放关键本地资源;同时保留探测和构建的 timeout 分类。

新增回归测试并通过 175 项 Python、72 项 CTest 及 Ruff 检查。

Refs 1024XEngineer#287
使用 esptool 5 的连字符命令,并将 HIL 子进程启动失败稳定归类为 infrastructure。\n\n新增命令范围与错误分类回归测试;PCB application-only flash 及芯片回读哈希已实测通过。\n\nRefs 1024XEngineer#287
对齐 Ruff 0.12.7 的格式化输出。

Refs 1024XEngineer#287
合并 mock 与异常断言上下文,满足 Ruff SIM117。\n\n验证:Ruff 0.12.7 format/check 与 HIL adapter 单测通过。\n\nRefs 1024XEngineer#287
对齐 Runner adapter 选择分支的 Ruff 0.12.7 格式。

验证:Ruff 0.12.7 format/check 与相关 Python 测试通过。

Refs 1024XEngineer#287
@JunLang-7
JunLang-7 force-pushed the feat/287-hil-provisioning-pairing branch from cc92dc7 to d0be95e Compare August 19, 2026 03:37
真实设备会重复上报 pending,旧状态机将正常生命周期误判为乱序;远端 Gateway revoke 也可能超过 5 秒,导致成功 journey 被清理超时覆盖。

允许重复 pending 幂等观测,失败结果降级为 contract-only evidence,并为 HIL 使用 30 秒清理预算;同时修正 PCB 活动 OTA 槽选择、SNTP/启动失败 marker 和串口路径处理。

182 个 Python 测试通过,Ruff 0.12.7 与全量格式门禁通过;Schema v4 PCB 真实 HIL run 8652f086ec7d94b0f52d3a71bdad8b4a 的 provisioning、readiness、pairing、evidence、cleanup 全部通过。

Refs 1024XEngineer#287
本机 clang-format 22 与 CI 固定的 clang-format 18 对短 block 的格式化结果不同,导致格式任务失败。

恢复为 CI 18.1.8 的单行输出;使用同版本执行全量格式脚本已通过。

Refs 1024XEngineer#287
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Engineering] 建立 ESP32-S3 Provisioning 与配对 HIL E2E

1 participant