Commit Graph

3 Commits

Author SHA1 Message Date
wandering1 7efa58d9a1 network: 台架 IP 迁到 192.168.31.100,并把重复写死的值收进单一真源
CI / 静态门禁 (pre-commit) (push) Failing after 25s
CI / 主机侧单测 (MSVC) (push) Successful in 48s
分两段(用户裁定 2026-11-02):先做地址迁移,再把同类字面量收敛成
单一真源,以后再改地址只动一处。

一、IP 迁移 192.168.1.100 → 192.168.31.100(gw 同步 → .31.1)
- 工厂默认:Drivers/BSP/NETCFG/net_cfg.c 的 NET_CFG_DEF_IP/_GW
- 注释/文档示例、主机与板级测试、台架 py 脚本、两份 sim_config.ini
- 字节序教学点同步换算 hex:0x6401A8C0 → 0x641FA8C0(内存
  C0 A8 1F 64),旧版示例引文与历史 Trap 记录按冻结纪律不动
- UI 黄金基准:网口设置 4 态 + shot_info 共 5 张 .bin 由
  check_content_pages.py --update 重刷(渲染值 IP 变了,属预期变更)
- 保留判定:客户点表引用(IEC104/继电保护规划)、芯片手册摘录、
  日期冻结的变更记录行、已退役台架档案 MDK-ARM/retracted_bench_*

二、单一真源收口(A+B+C+D,用户批准全做)
- 新建 test/host/bench_defaults.py:台架 py 默认值唯一定义点
  (DEVICE_IP/DEVICE_GW/PC_IP/NET_BCAST),22 个脚本改为引用;
  MDK-ARM 两探针与 scripts/board_ui_nav.py 经 sys.path shim 引入
- test/board/net_test_task.h 新增 TEST_PC_PEER_IP,板测三处
  PHASE*_REMOTE_IP 改引该宏(保留 -D 覆盖);Phase1 断言改
  memcmp 数组比较,数组各只出现一次
- simulator/tests/check_content_pages.py 从 net_cfg.c 正则解析
  NET_CFG_DEF_* 推导期望值(解析失败即报错、不静默兜底),
  脚本内台架 IP 字面量清零
- 装饰性注释去具体值(net_cfg.h/net_socket.h/net_socket.c/
  net_socket_sim.c);字节序教学 hex 对刻意保留为唯一写值点
- 刻意不动:主机单测夹具 IP(逐文件钉住的任意值是正确测试
  实践)、文档正文 IP(那是文档内容本身)

顺带:scripts/gen_task_table.py 规范串清掉「,B5」——编号清退提交
72b4b094 改了受管区没重跑生成器,task-table 门禁因此一直红

验证:产品 @build 0/0;CH395F 套件开关构建 0/0 后还原产品态;
6 套主机单测 rc=0;content_pages(含宏推导路径)/菜单 8 态/
推流位比对全 PASS;bom-drift 99 无漂移;doc-links/coding-standard/
cppcheck 绿;py_compile 23 文件 + --help 冒烟(含 shim 绝对路径)
2026-11-02 14:46:42 +08:00
wandering1 924ac3d428 test(host): 断言字面量统一纯 ASCII,30 文件 1535 行
用户裁定「统一」。口径就是 AGENTS 铁律:字符串字面量必须纯 ASCII
(无 BOM 文件里奇数个汉字会吞掉结束引号,偶数才侥幸通过),中文只写注释。
四名队友按目录分四组并行、写范围互斥:net_socket 418 行(6 文件)、
console_log/sys_log_mcu/soe_store/cfg_file_store_mcu 268 行(4 文件)、
11 个存量套件 404 行 + adc_input 89 行、iec104 与 lftpd 与 NET 四套等 356 行
(9 文件)。runner 的 .py 文档串不在口径内(Python 源不经 ARMCC 代码页)。

两套口径必须分清:粗口径(按行切引号)普查 = 34 文件 / 1,552 行;严格口径
(状态机剥掉块/行注释与字符常量后再取字符串字面量)= 30 文件 / 1,535 行。
差值那 4 个文件的命中全在注释里(ns_peers.c、net_socket/stub/ns_rtos.h、
common/ch395f_fake.h、common/fatfs_fake.c)——按口径一处都不该改,改了等于
把中文从注释里搬走、正好违背口径。粗口径绝不能当交付判据,否则要么白改
注释、要么留下「这行为什么没改」的悬案。

Lead 独立终检(不采信自报)五条硬判据,结果 30 文件漂移 0:① 每文件 TC 号
集合与 HEAD 逐字相同 ② 断言宏调用点数不变 ③ 行数与 HEAD 完全相等(专抓
整文件回写把尾部含 main() 吃掉的截断,第 1 轮真发生过两次)④ 剥注释后代码区
非 ASCII 字符 = 0 ⑤ 字节卫生(BOM 与 HEAD 一致、无 CR、无 U+FFFD、单尾换行)。
另用「逐行把字面量整体替换成空串后与 HEAD 必须逐行相等」机械证明只改了字面量;
各套 --module 覆盖率与断言数逐字不变(net_socket 887/889·53/53、console_log
199/200·16/16、sys_log_mcu 324/326·13/13、adc_input 103/103、sys_clock 100/100)
→ 生产码零改动,基线不需重登。

闸拦下一处真实回归(我的验收器没抓到):ns_s6_edges.c 翻译时把一个上一轮
已整改成平实描述的编号又写回了 CHECK 标签。原因很清楚:「只改字面量」并不
等于「只改无害内容」,标签里完全可以带进未登记族的编号形态;而 Lead 的自动
验收器只比对了 TC 形 id 集合,未覆盖 L/E/N/S/TRAP 等族。教训:批量改标签的
守卫必须加一条「新串不得出现任何已登记前缀族之外的编号形态」,且结构不变式
只覆盖自己想到的维度时不能替代真闸。
Lead 自查另清掉 126 处写坏的反斜杠(JS→Python 转义层数翻倍,把 markdown
反引号写成反斜杠+反引号),恰好发生在记录这条教训的那一节里。

文档:docs/测试说明/主机单测覆盖率口径.md §9 新增「第 2 轮」小节(两套口径对照
表、五条终检判据、六条手法含「转换说明符序列必须逐位相同」取代「禁止裸 %」、
三条协作纪律含先改板再派工与临时文件带组前缀、后续项 3 条)+ 变更记录一行。

后续项(本轮不做):把剥注释词法扫描器收进 scripts 当门禁(需用户点头并先定
test/ 是否纳入 coding-standard);iec104 的简写编号归族(牵 id_registry,
不能顺手做);替换器加「编号形态白名单」校验。

gate: pre-commit run --all-files -> 39 hooks, 37 Passed; failed = mem-numbers +
mem-budget(受管快照与本树 .map 的漂移,属第 1 轮生产码改动的遗留,非本批
增量)。本批只碰 test/host/**,不进 Keil 编译面也不进模拟器 CMake,**RAM/Flash
增量 = 0**;实测水位 RW_IRAM1 57.4%、RW_CCM 87.9%,均低于 92% 红线。
id-check 0 台账外新账(可判定 84.63% > 基线 82.6%);test-coverage 33/33 全绿;
cppcheck / coding-standard / bsp-err / layer-deps / doc-links 全 Passed。
按仓内分支约定 --no-verify 提交,台账 --write 回填留待主工作树合并后。
2026-10-24 21:00:17 +08:00
wandering1 a0c261b5ee test(NET/lftpd): lftpd 控制通道模块(35 条),FTP 一套四块全部进分母
新增 test/host/lftpd/,lftpd.c 覆盖 304/473 = 64.3%。做法是把生产源整个 #include 进
TU,于是命令表 commands[]、17 个 static cmd_* 与 handle_control_channel 都能直接驱动:
假 inet 层给"脚本化命令行队列 + 响应记录",假 io 层给"极简内存视图 + 可注入失败",
认证与配置当可注入黑盒(认证本身有 test/host/ftp_auth 的 10 条专测,不重复验)。

钉住的契约(都是真机上贵、却难按需复现的那几类):
- STOR 传到一半写失败必须 **unlink 半成品**:否则 Flash 上永久留个坏文件,现场表现
  是"升级包传坏了再也传不上去"。真机要卡准"传一半掐线"的时机,这里注一个短写就行。
- 数据通道是单连接 socket:LIST/RETR/STOR 用完必须关监听并把 data_socket 复位成 -1;
  accept 失败要报 425 不留残口,会话退出(QUIT 或对端断线)时 cleanup 也要关掉还没
  用的被动监听。漏一次就是下一条命令拿着上一个号继续 accept,偶发连不上。
- 命令名缓冲只有 command_tmp[4+1],前置判断 if (index >= 5) 就是防 memcpy 越界;
  恰好 5 个字符必须被拒(改一行这条就响)。
- 认证前置白名单:未登录只放行 USER/PASS/QUIT/FEAT/SYST/NOOP,其余一律 530;口令错
  必须清 auth_user_ok 强制重走 USER;被锁与口令错都只回 530,不给攻击者区分提示;
  配置读不到时 USER 无法匹配、PASS 直接 530(fail-closed)。
- 写开关([ftp] write_en=0)必须在**碰文件之前**挡住 STOR/DELE,且不去 accept 数据
  通道;DELE 不许删目录。
- 227/229 编码:IP 经 net_htonl 后按高字节到低字节排(就是点分序),端口高/低两字节;
  拿不到本机 IP 时要把刚建的监听关掉。FEAT 多行:首行 211-、四条能力无状态码、末行
  211 结束(共 6 条响应)。
- 220 欢迎没送达(对端已走)就直接收工,不空转读命令;该留痕按真实分级算 INFO 而不是
  ERROR(真实 private/lftpd_log.h 把 lftpd_log_peer 归到 INFO:任何人连 21 端口就走
  就能无限制造固件级 ERROR,还会撞掉 @test 的 Forbidden 标记 [ERR])。
- 传输循环每轮喂狗(lftpd_task_wd_beat 计数可断言)。

主机侧两个必要的兼容处理(都写在桩注释里,不是随手改):
1. lftpd.c 会 include ff.h,而这份 FatFs 在 Windows 支路上把 winsock.h 拉进来,它带
   "#define s_addr S_un.S_addr" 的 BSD 兼容宏,会把真实 net_types.h 里的字段声明
   uint32_t s_addr; 展开成 uint32_t S_un.S_addr; 直接炸(实测 C2143 在 "." 前缺 ";")。
   桩里只 #undef 这个污染宏,让固件那份结构体定义原样参与编译,被测代码读的还是真字段。
2. 引号 include 先从 lftpd.c 自己目录找 private/lftpd_log.h,桩目录赢不过它——于是
   顺着用真实那份(它只是把 lftpd_log_* 映射成 DBG_*),只桩最底下的 dbg_log.h。这样
   真实日志分级也一起被编译验证,比我自己重写一套更对。

自查(35 条里前两轮红了 4 条,全是**我的期望/前置态写错**,实现均正确):未登录时
FOO 被白名单以 530 拦掉测不到 502 分派;227 的 IP 顺序我把 htonl 前后搞反;FEAT 是
6 条响应我按 5 条索引;PASV 之后走完整会话会被 cleanup 关掉监听(那正是 006 要验的
行为),观察 PASV 留下的状态必须直调 cmd_pasv。

覆盖率与台账:套件 26 → 27 全绿;files_tested 30 → 31;未触及 .c 36 → 35;分母
4,072 → 4,545 行。**总体 line_rate 88.4% → 85.9% 是摊薄不是回退**(64.3% 的文件进
了分母),按 §5 口径要盯 files_tested/files_untested——它从 19 一路涨到 31。
恒等式 35 = 1(P1 剩 iec104_serv.c) + 5(P2) + 29(P3)。编号补建 TC-HOST-LFTPD
(游标 034),族数 20 → 21。

自查门禁:test-cppcheck Passed;check_ids --strict 通过;doc-links 35 处(= 存量);
9 个文件 BOM/CR/U+FFFD/行尾逐项净。零生产代码改动,未跑 @build。--all-files 仍只有
mem-numbers / mem-budget(.map 台账漂移,等 Lead 合并后统一回填)与 ui-golden
(ref/*.bin 不入库)三条失败,与本分支改动无关。
2026-10-23 23:44:52 +08:00