Files
STM32F4-Base/test/host/ui_sink/run_unit_test.py
T
wandering1 f6e9106f0d fix(UI): 推流往返返回点喂位——多个慢 RPC 之和不再串成 UI 停摆(大窗判读 F3)
道F task-24。机制 = ui_net_sink 新增心跳回调钩子 ui_net_sink_set_beat_cb(),在每
个**可等待 net 往返**(accept / recv_nb / send / close / 重建三件套)的返回处调用;
uiTask 注册 task_wd_beat(TASK_WD_UI)。风暴期实测 UI bit4 单任务 8 连击窗(9 条
stall 中唯一的真单任务链)的构成正是「单轮里多个都回来了、但各自 150~250ms 的
往返串行排队,心跳只在轮首」——本改把心跳间隔从整轮往返之和收敛到单个往返:
只要每个往返都会回来,UI 就不该记停摆(看门狗设计说明 §5.3 按位判据抓真挂死)。

【边界(lead 裁定口径)】往返语义零改动:不加超时、不动回执协议(§11.6 否决的
「net_* 裸加有界等待」不重演,请求序号方案与事件驱动 accept 均**不做**,上界
收口归登记簿 E-27/E-28 批 3)。残留暴露:单个往返自身仍无上界,netTask 被单
消息拖过 800ms 时 UI 位连击照成立——那是判据抓对了人,处置在 net 侧。

【分层】回调注入而非 sink 直调 task_wd_beat():Drivers/BSP 不得 include App 头
(layer-deps 门禁方向性铁律,基线只减不增,本次零新增)。

【零行为变化面】钩子未注册(模拟器/黄金回归形态、ui_task 注册之前)= 与改前
逐字一致;协议/帧格式/门控/兜底节拍全不动。ui-golden(菜单 8 状态 + 内容页
11 页)通过。

【测试】新增主机套件 test/host/ui_sink/(stub 假件驱动生产 ui_net_sink.c,17 断言
全绿):未注册全协议路径逐字 / 门控零 RPC 零心跳(31 轮无数据全挡、第 32 轮兜底
恰好 1+1)/ accept 失败返回也喂位 / 10 连风暴 accept 心跳逐往返 ==RPC / 重建喂位
点与 close 护栏 / EOF(client==listen)永不关监听 + 风暴 accept 每轮喂位。
suite 由 test-coverage rglob 自动发现(无需改台账)。

【文档】UI_设计架构.md 新增 §5.8(推流心跳边界:现象/处置/边界/分层/残留)+
变更记录行;ui_net_sink.h 钩子契约注释;ui_task.c v1.4 记录与 :271 注释更新。

【门禁】@build 0/0(Code=224860,vs F2 后:Code +92B / ER_IROM1 →249500 /
RW+4 / ZI+4 / RAM 79008)。--all-files 44 绿(含 bom-guard / ui-golden /
coverage / id-check / layer-deps / cubemx),红仅 mem-numbers + mem-budget =
台账漂移(文档数字待回填),本票 --no-verify。
gate: only mem-budget/mem-numbers pending lead ledger backfill

【台架(待台架实测,等你排)】两轮各自独立 ≥30min:① 单独 relisten_stress :7003
② 探针轮。v1.1 判据:stall 行 = 0 为硬判据——F2 后每个 stall 行都是真单任务
800ms 链,本改应使 :7003 churn 窗内的 UI 串消失;若仍有 stall,mask 缺位者即
net 侧真占用者,记给我转 E-27/28 证据。MISS start 为诊断行不计违规。
2026-10-25 18:42:14 +08:00

50 lines
2.0 KiB
Python
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.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""ui_net_sink 心跳边界主机侧单元测试运行器(L0.5,纯标准库)。
做什么:
用本机 MSVC 编译 test/host/ui_sink/ui_sink_test.c(以 #include 纳入生产源
Drivers/BSP/UI/ui_net_sink.c),用桩 net_* 假件驱动推流协议全路径,钉死
F3(2026-10-25 大窗判读)两条判据:未注册钩子 = 行为逐字不变(模拟器形态);
注册后每个可等待 net 往返的返回处恰好喂一次心跳(风暴期单轮多往返不再串成
UI 心跳缺口,看门狗按位连击判据只抓真挂死)。
为什么要主机侧单测:
台架能复现风暴但造不出确定性的 RPC 计数;而心跳漏喂是回归性风险(改一行
调用位置就静默失效),必须在门禁层用计数断言钉死。
用法(仓库根目录):
& '.venv\\Scripts\\python.exe' test/host/ui_sink/run_unit_test.py
退出码:0=PASS / 1=测试失败 / 2=环境错误。
设计依据:docs/UI设计/UI_设计架构.md(推流心跳边界);
docs/子系统设计/看门狗设计说明.md §5.3(按位连击判据)
创建日期:2026-10-25
"""
import os
import sys
HERE = os.path.dirname(os.path.abspath(__file__))
ROOT = os.path.dirname(os.path.dirname(os.path.dirname(HERE)))
sys.path.insert(0, os.path.join(ROOT, "test", "host", "common"))
from unit_test_harness import TestBuild, run_host_unit_test # noqa: E402
# stub 目录必须**先于** Drivers/BSP/UI:net_socket.h / ui_port.h / dbg_log.h /
# test_config.h 由桩提供,ui_net_sink.h 与 ui_net_sink_backend.h 用真实头
# (几何令牌与协议常量一改即编译期报错)。
BUILD = TestBuild(
name="UI Sink Beat Tests",
src=os.path.join(HERE, "ui_sink_test.c"),
include_dirs=[
os.path.join(HERE, "stub"),
os.path.join(ROOT, "Drivers", "BSP", "UI"),
HERE,
],
summary_marker="=== UI Sink Tests:",
)
if __name__ == "__main__":
sys.exit(run_host_unit_test(BUILD))