test(NET): net_select 模块(21 条)与 NET 域首份 ch395f 桩,登记两处死路径
P1 的 NET 四块开了第一块:新增 test/host/net_select/,21 条断言全部 MSVC 编译
通过并 PASS。net_select.c 一个芯片函数都不调,所以它是四块里唯一不需要假芯片的,
先把它拿下,顺带把 NET 域的桩骨架立起来。
钉住的契约:
- 就绪位回写:入参集合里未就绪的 fd 必须被清掉,只留就绪的(POSIX 语义);未请求
的集合不被写回、可以传 NULL。
- 状态准入:LISTENING 即使 readable 也不算可读(accept 语义不在这层);ESTABLISHED
+ send_ready 才可写;CONNECTING 时 send_ready 不作数。
- 边界:nfds 为 0 / 负 / 超过 NET_MAX_SOCKETS 都返回 -1(不许扫出 socket 表外)。
- 超时算术:tv_usec 是**整除截断**(1999us 当 1ms 而不是 2ms);timeout=NULL 时
无限等并由对端事件唤醒;poll 的 timeout=0 首轮即退、每轮先清 revents。
用可控 tick(每问一次 +1)+ 可控 osDelay(计数、可指定轮数后造一个就绪 socket)
把这些变成确定性轮数,台架上根本构造不出"没人来连时该怎么退"。
照出两处**死路径**(只登记,未改语义;全库唯一调用点 test/board/net_test_task.c
传的是 NULL 与非零 tv,今天没有受害者):
1. net_select 的 timeout = {0,0} 换算出 timeout_ms = 0,而退出条件写的是
if ((timeout_ms > 0) && (已用时 >= timeout_ms)) → **超时 0 永不触发退出**,退化成
无限等;POSIX 在这里必须立刻返回 0。同文件 net_poll_events 写的 timeout >= 0
是对的,两条并排放着正好是对照。风险面:谁拿它当"非阻塞查一遍",netTask 就
回不到主循环,而 netTask 在 IWDG required_mask 里。
2. exceptfds 是恒为空的死参数:循环体开头 p_sock == NULL → continue 先跳过,
check_socket_error 的 NULL 分支从 select 里到不了。按 POSIX 直觉用它收异常的人
会永远什么都收不到。
两处都用"现状桩"钉成改了会响(用例名里写明不是期望行为)。另修掉我自己写错的一条
用例:给 timeout=NULL 又没有就绪 fd,直接死循环——已在假 osDelay 里加了 500 轮
保险(跑飞就 exit(2)),因为挂死的测试会把 exe 文件名占住、让后续构建报 LNK1104。
桩的边界写死在文件头:net_select.h / net_types.h / net_config.h 用真实头(net_sock_t
字段名与 NET_SOCK_STATE_* 一改即编译期报错);main.h / cmsis_os.h / FreeRTOS.h /
task.h 是本目录桩;新建的 ch395f.h 是**空壳**,只服务不调芯片函数的文件——
net_pending / net_events / net_listener 直接调十余处 ch395f_*,要的是可脚本化返回的
假芯片,不要把这个空壳当成"NET 域桩已就绪"。
覆盖率:套件 21 → 22 全绿;files_tested 25 → 26;未触及 .c 41 → 40;分母 3,332 →
3,446 行;net_select.c 97/114(85.1%)。恒等式更新为 40 = 6(P1 剩) + 5(P2) + 29(P3)。
编号按 B 层口径补建 TC-HOST-NETSEL(游标 019),TC-HOST 族现共 16 族;注册表仍只
做增量插入。
自查:test-cppcheck Passed;check_ids --strict 通过;doc-links = 35 处(= 存量);
BOM/CR/U+FFFD/行尾逐项净。本增量零生产代码改动,未跑 @build。--all-files 仍只有
mem-numbers / mem-budget(.map 台账漂移,等 Lead 合并后统一回填)与 ui-golden
(ref/*.bin 不入库,新 worktree 天生没有黄金参考)三条失败,与本分支无关。
This commit is contained in:
+18
-2
@@ -225,8 +225,24 @@
|
||||
| FTP 一套(4 块里 2 块) | 🟡 部分 | `test/host/lftpd_io`(33 条,含 `lftpd_string.c`) |
|
||||
`lftpd_io.c` **85/159 = 53.5%**、`lftpd_string.c` 8/10;`read/write/close/stat/unlink/readdir`
|
||||
未测(要先把假 `FIL/FILINFO` 的字段语义做实,否则断言落在假件自己写的规则上) |
|
||||
| `lftpd.c` / `lftpd_inet.c` | ⬜ 未开始 | — | 需假 `net_socket` 层(`time_sync`/stub 里那份可扩展) |
|
||||
| NET 四块 / 104 服务层 | ⬜ 未开始 | — | **必须先新建 `stub/ch395f.h`** |
|
||||
| NET 四块之一:`net_select.c` | ✅ 完成 | `test/host/net_select`(21 条) | `net_select.c` 97/114 = **85.1%** |
|
||||
| `lftpd.c` / `lftpd_inet.c` | ⬜ 未开始 | — | 需假 `net_socket` 层(`time_sync`/stub 那份可扩展) |
|
||||
| NET 剩下三块(`net_pending`/`net_events`/`net_listener`) | ⬜ 未开始 | — |
|
||||
本批新建的 `stub/ch395f.h` 是**空壳**,只服务"不调芯片函数"的文件;这三块直接调
|
||||
`ch395f_*` 十余处,要的是能脚本化返回的**假芯片**,不是这个空壳 |
|
||||
| 104 服务层 | ⬜ 未开始 | — | 桩最省(复用 `cmsis_os2.h` + `net_socket.h`) |
|
||||
|
||||
本批照出的两处**现状**(只登记、**未改语义**;全库唯一调用点 `test/board/net_test_task.c`
|
||||
传的是 NULL 与非零 tv,今天没有受害者):
|
||||
|
||||
1. `net_select` 的 `timeout = {0, 0}` 换算出 `timeout_ms = 0`,而退出条件写的是
|
||||
`if ((timeout_ms > 0) && (已用时 >= timeout_ms))` → **超时 0 永不触发退出**,退化成
|
||||
无限等(POSIX 语义是立刻返回 0)。`net_poll_events` 的 `timeout >= 0` 写对了,
|
||||
两条并排放着正好是对照。风险面:谁拿它当"非阻塞查一遍",netTask 就再也回不到
|
||||
主循环,而 netTask 在 IWDG `required_mask` 里。
|
||||
2. `exceptfds` 是**恒为空的死参数**:循环体开头 `p_sock == NULL → continue` 先跳过,
|
||||
`check_socket_error` 的 NULL 分支从 select 里到不了。按 POSIX 直觉用它收异常的人
|
||||
会永远什么都收不到。修法:continue 之前先判异常,或在 `net_select.h` 写明不支持异常集。
|
||||
|
||||
数字:套件 16 → **21**、`files_tested` 19 → **25**、未触及 125 → 119(`.c` 47 → **41**,
|
||||
恒等式 `41 = 7(P1 剩) + 5(P2) + 29(P3)` 仍然咬合)、分母 2,893 → **3,332** 插桩行。
|
||||
|
||||
Reference in New Issue
Block a user