Files
STM32F4-Base/test/host/net_cfg/run_unit_test.py
T
super_agent_bot ad7338365c
CI / 静态门禁 (pre-commit) (push) Failing after 6m14s
CI / 主机侧单测 (MSVC) (push) Successful in 54s
CI / 静态门禁 (pre-commit) (pull_request) Failing after 4m35s
CI / 主机侧单测 (MSVC) (pull_request) Successful in 47s
feat(sntp): 板端 SNTP 校时接入——coreSNTP 序列化器 + [sntp] 段 + 设置页(#73)
- vendored coreSNTP v2.0.0 序列化器(MIT,仅 serializer+LICENSE,零堆),
  48 字节报文编解码在库,节奏与准入判据在本方(RFC 4330 §10 调研口径)
- App/sync/time_sntp.c 挂 timeSyncTask 的 8888 事件循环,等待切片 ≤50 ms,
  不饿任务狗与 IWDG;懒建 UDP socket,代际变化/禁用/死错误码即关闭归还
- 防伪 = OriginTimestamp 逐位等于发出时 T1(含低 16 位随机小数位);
  mode/stratum/闰秒指示/KoD 按 RFC 拒收;DENY·RSTR 换服务器、RATE 只退避
- 主备轮换 + 失败指数退避(5 s 起、60 s 封顶)+ 首轮 1~5 分钟随机错峰;
  成功恢复 poll_min 周期(1~1440 分,出厂默认 60,默认不启用不发包)
- 钟面 = 本地时间:UTC+8 固定偏移落 sys_clock_set_unix(§1.1 时基裁定,
  第三个写入口,装置仍不存时区);|offset|<2 s 只记日志不步进,冷启动或
  更大偏差步进并回写 SD2506,留痕 [SNTP] step 与 syslog OPER
- 首个校验通过的同步置 SYS_EVT_TIMESYNC_READY(就绪位,消费方按需 NoClear)
- [sntp] 配置段(enable/server1/server2/poll_min)属主 sntp_cfg.c,
  注册在 net_cfg_load();UI 页 31「SNTP 设置」(密码叶):启用开关 +
  主/备服务器 octet 编辑 + 周期(分) + 保存,复用 net_cfg_save_request 链
- 测试与门禁:test/host/sntp 新套件(报文/防伪/KoD/退避周期/阶跃域/配置
  注册表)、net_cfg 与 time_sync 套件补 fake、黄金参考 66→74 张零漂移、
  字符集 228 字、Keil 0 错 0 警(RO +5,848 B 含字体)、覆盖率基线回填
- 文档:墙钟维护说明 §16、网络配置说明 [sntp] 节、配置文件设计说明变更记录、
  产品需求 FR-TIME-3 与 8.3/9.1.2 台账、UI 补齐规划/UI补齐 31 叶口径、
  登记簿销项并登记「SNTP 校时真机判据」等台架(PC 时间源 192.168.31.161/.13)
2026-11-04 16:20:22 +08:00

63 lines
3.1 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 -*-
"""网络配置(net_cfg)的主机侧纯逻辑单元测试运行器(纯标准库)。
做什么:
用本机 MSVC 编译 test/host/net_cfg/net_cfg_test.c(它以 #include 纳入
**生产源文件** Drivers/BSP/NETCFG/net_cfg.c),在 PC 上离线跑出厂默认、
注册幂等、load/save 错误通道、跨任务保存交接状态机、MAC 三态优先级、
IPv4 定长格式化,失败即非 0 退出。零硬件、零烧录、毫秒级。
工具链探测 / INCLUDE-LIB 拼接 / 编译运行 / 退出码判定全部委托给通用 harness
`test/host/common/unit_test_harness.py`(本文件只做声明)。
为什么要主机侧单测(而不是只用台架):
保存链跨三个任务(uiTask 投递 → defaultTask 写盘 → netTask 重建网络):
"写盘期间又投递一次"与"写盘失败却重建网络"这两条真机上要靠手速 + 故障注入
才碰得到,错了就是"改 IP 不生效 / 保存失败网络被无端重建";MAC 三态优先级
写错会静默用错 MAC(同网段冲突,只表现为偶发丢包);net_cfg_fmt_ipv4 的定长
11 字符是 UI 光标按固定偏移定位的前提。三条都在 PC 上钉死,且不占 MCU RAM。
桩的边界(细节见测试单元文件头):
配置文件引擎用**真实头**(接口原汁)+ 测试单元内的可控实现;[ftp] 段的
ftp_cfg_register 只计数——它归 test/host/ftp_cfg/ 模块,两边不互相顶包。
sntp_cfg.c 是分层门禁后的纯数据本体,随 net_cfg.c 一并编译入 TU,
[sntp] 段描述符(键表/偏移/工厂默认)由假引擎截获断言——段注册契约
的机器钉在本模块(TC-NETCFG-005/006b..d/007)。
用法(仓库根目录):
python test/host/net_cfg/run_unit_test.py
或统一用 .venv: & '.venv\Scripts\python.exe' test/host/net_cfg/run_unit_test.py
退出码:0=PASS / 1=测试失败 / 2=环境错误(找不到编译器 / 编译失败 / 无汇总行)。
设计依据:docs/子系统设计/网络配置说明.md、docs/测试说明/单元测试/主机单测覆盖率口径.md §9 P1
创建日期:2026-10-23
"""
import os
import sys
HERE = os.path.dirname(os.path.abspath(__file__))
ROOT = os.path.dirname(os.path.dirname(os.path.dirname(HERE)))
# harness 位于 test/host/common/
sys.path.insert(0, os.path.join(ROOT, "test", "host", "common"))
from unit_test_harness import TestBuild, run_host_unit_test # noqa: E402
# 顺序敏感:stub 必须**先于**生产目录,才能覆盖 dbg_log.h。cfg_file.h 用真实头
# (接口契约原汁,引擎改签名即编译期报错),net_cfg.h / ftp_cfg.h 亦用真实头。
BUILD = TestBuild(
name="NET Config Tests",
src=os.path.join(HERE, "net_cfg_test.c"),
include_dirs=[
os.path.join(HERE, "stub"),
os.path.join(ROOT, "Drivers", "BSP", "NETCFG"),
os.path.join(ROOT, "App", "cfg"),
HERE,
],
summary_marker="=== NET Config Tests:",
)
if __name__ == "__main__":
sys.exit(run_host_unit_test(BUILD))