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 回填留待主工作树合并后。
This commit is contained in:
@@ -222,10 +222,10 @@ static void tc_101_byteorder(void)
|
||||
{
|
||||
reset_all();
|
||||
|
||||
CHECK(net_htons(0x1234U) == 0x3412U, "TC-NETSOCK-101a htons 换端");
|
||||
CHECK(net_ntohs(net_htons(80U)) == 80U, "TC-NETSOCK-101b htons/ntohs 互逆");
|
||||
CHECK(net_htonl(0x01020304U) == 0x04030201U, "TC-NETSOCK-101c htonl 换端");
|
||||
CHECK(net_ntohl(net_htonl(0xDEADBEEFU)) == 0xDEADBEEFU, "TC-NETSOCK-101d htonl/ntohl 互逆");
|
||||
CHECK(net_htons(0x1234U) == 0x3412U, "TC-NETSOCK-101a htons byte swap");
|
||||
CHECK(net_ntohs(net_htons(80U)) == 80U, "TC-NETSOCK-101b htons/ntohs are inverses");
|
||||
CHECK(net_htonl(0x01020304U) == 0x04030201U, "TC-NETSOCK-101c htonl byte swap");
|
||||
CHECK(net_ntohl(net_htonl(0xDEADBEEFU)) == 0xDEADBEEFU, "TC-NETSOCK-101d htonl/ntohl are inverses");
|
||||
}
|
||||
|
||||
static void tc_102_parse_ip(void)
|
||||
@@ -236,12 +236,12 @@ static void tc_102_parse_ip(void)
|
||||
|
||||
(void)memset(a, 0xEE, sizeof(a));
|
||||
parse_ip_string(NULL, a);
|
||||
CHECK(a[0] == 0xEEU, "TC-NETSOCK-102a parse_ip_string(NULL) 直接返回,不写目标缓冲");
|
||||
CHECK(a[0] == 0xEEU, "TC-NETSOCK-102a parse_ip_string(NULL) returns at once, target buffer untouched");
|
||||
parse_ip_string("192.168.1.100", a);
|
||||
CHECK(a[0] == 192U && a[1] == 168U && a[2] == 1U && a[3] == 100U,
|
||||
"TC-NETSOCK-102b parse_ip_string 段 0 落在 [0](芯片 set_ip_addr 要的顺位)");
|
||||
"TC-NETSOCK-102b parse_ip_string puts segment 0 at [0] (the order chip set_ip_addr wants)");
|
||||
parse_ip_string("10.20.30.40", NULL); /* 只验不崩 */
|
||||
CHECK(1, "TC-NETSOCK-102c parse_ip_string 目标为 NULL 不崩");
|
||||
CHECK(1, "TC-NETSOCK-102c parse_ip_string with NULL target does not crash");
|
||||
}
|
||||
|
||||
static void tc_103_alloc_and_getsock(void)
|
||||
@@ -253,11 +253,11 @@ static void tc_103_alloc_and_getsock(void)
|
||||
reset_all();
|
||||
|
||||
CHECK(net_get_sock(-1) == NULL && net_get_sock(NET_MAX_SOCKETS) == NULL,
|
||||
"TC-NETSOCK-103a net_get_sock 越界返 NULL(含负数)");
|
||||
CHECK(net_get_sock(0) == NULL, "TC-NETSOCK-103b 未分配的槽位返 NULL");
|
||||
"TC-NETSOCK-103a net_get_sock out of range returns NULL (incl. negative)");
|
||||
CHECK(net_get_sock(0) == NULL, "TC-NETSOCK-103b unallocated slot returns NULL");
|
||||
CHECK(net_sock_raw(3) == &s_net_socks[3],
|
||||
"TC-NETSOCK-103c net_sock_raw 不判 in_use(对账必须看到 CLOSED 槽位)");
|
||||
CHECK(net_sock_state(0) == -1, "TC-NETSOCK-103d 未占用 sock_state 返 -1 且不设 errno");
|
||||
"TC-NETSOCK-103c net_sock_raw skips the in_use check (reconciler must see CLOSED slots)");
|
||||
CHECK(net_sock_state(0) == -1, "TC-NETSOCK-103d unused sock_state returns -1 and leaves errno alone");
|
||||
|
||||
/* 逐个占满:alloc_socket 线性扫描首个空闲槽 */
|
||||
for (i = 0; i < NET_MAX_SOCKETS; i++) {
|
||||
@@ -266,9 +266,9 @@ static void tc_103_alloc_and_getsock(void)
|
||||
break;
|
||||
}
|
||||
}
|
||||
CHECK(i == NET_MAX_SOCKETS, "TC-NETSOCK-103e alloc_socket 按序分配 0..7");
|
||||
CHECK(i == NET_MAX_SOCKETS, "TC-NETSOCK-103e alloc_socket hands out 0..7 in order");
|
||||
p = net_get_sock(0);
|
||||
CHECK(p != NULL && p->in_use == 1U, "TC-NETSOCK-103f 分配的槽位 in_use=1");
|
||||
CHECK(p != NULL && p->in_use == 1U, "TC-NETSOCK-103f allocated slot has in_use=1");
|
||||
|
||||
reset_all();
|
||||
}
|
||||
@@ -281,20 +281,20 @@ static void tc_104_socket_no_inherit(void)
|
||||
reset_all();
|
||||
|
||||
fd = net_socket(NET_AF_INET, NET_SOCK_STREAM);
|
||||
CHECK(fd == 0, "TC-NETSOCK-104a net_socket 返回首个空闲 fd");
|
||||
CHECK(fd == 0, "TC-NETSOCK-104a net_socket returns the first free fd");
|
||||
p = &s_net_socks[fd];
|
||||
CHECK(p->ch395_sock == (uint8_t)fd, "TC-NETSOCK-104b 芯片 Socket 号与描述符一一对应");
|
||||
CHECK(p->ch395_sock == (uint8_t)fd, "TC-NETSOCK-104b chip socket number maps one-to-one to the descriptor");
|
||||
CHECK(p->state == NET_SOCK_STATE_CREATED && p->type == NET_SOCK_STREAM,
|
||||
"TC-NETSOCK-104c 初态 CREATED + 类型记下");
|
||||
"TC-NETSOCK-104c initial state CREATED with type recorded");
|
||||
CHECK(p->send_ready == 1U && p->readable == 0U,
|
||||
"TC-NETSOCK-104d 初态:发送缓冲视为空闲、无可读");
|
||||
"TC-NETSOCK-104d initial state: send buffer seen as free, nothing readable");
|
||||
/* 三条"新 fd 不得继承"的定案,逐条钉(都是真机上静默出错的形态) */
|
||||
CHECK(p->blocking == 1U, "TC-NETSOCK-104e blocking 默认必须显式置 1(BSD 语义)");
|
||||
CHECK(p->released_abnormal == 0U, "TC-NETSOCK-104f 不得继承上一条的释放原因(TRAP-NET-18)");
|
||||
CHECK(p->session_dead == 0U, "TC-NETSOCK-104g 不得继承上一条的会话结束电平(N-32 P1)");
|
||||
CHECK(p->blocking == 1U, "TC-NETSOCK-104e blocking must default to explicitly 1 (BSD semantics)");
|
||||
CHECK(p->released_abnormal == 0U, "TC-NETSOCK-104f must not inherit the previous release reason (TRAP-NET-18)");
|
||||
CHECK(p->session_dead == 0U, "TC-NETSOCK-104g must not inherit the previous session-dead level (N-32 P1)");
|
||||
CHECK(g_peers.listener_clear_calls == 1 && g_peers.pending_clear_calls == 1 &&
|
||||
g_peers.send_clear_calls == 1,
|
||||
"TC-NETSOCK-104h 新 fd 必须清监听重试 + 两张挂起表(各一次)");
|
||||
"TC-NETSOCK-104h new fd clears listener retry and both pending tables (once each)");
|
||||
|
||||
/* 脏槽位复用:把上一条会话的残留写进去,再看新建是否清干净 */
|
||||
p->blocking = 0U;
|
||||
@@ -307,17 +307,17 @@ static void tc_104_socket_no_inherit(void)
|
||||
* 本场景没绑消息队列,公开入口会先撞上"队列未创建"的 NET_ERR,
|
||||
* 而那属于分片 3 的断言面(TC-NETSOCK-110h)。close 的清零主路径在 net_close_locked。 */
|
||||
CHECK(net_close_sock(&s_net_socks[fd]) == 0,
|
||||
"TC-NETSOCK-104i net_close_sock 成功(close 的 memset 是清零主路径)");
|
||||
"TC-NETSOCK-104i net_close_sock succeeds (its memset is the main reset path)");
|
||||
fd = net_socket(NET_AF_INET, NET_SOCK_STREAM);
|
||||
p = &s_net_socks[fd];
|
||||
CHECK(fd == 0 && p->blocking == 1U && p->released_abnormal == 0U &&
|
||||
p->session_dead == 0U && p->readable == 0U && p->send_ready == 1U &&
|
||||
p->event_cb == NULL,
|
||||
"TC-NETSOCK-104j 复用同一槽位:残留字段全部不得带走");
|
||||
"TC-NETSOCK-104j reusing the slot: no leftover field may carry over");
|
||||
/* 地址族不支持 → INVAL(在 alloc 之前,不占槽) */
|
||||
CHECK(net_socket(NET_AF_INET6, NET_SOCK_STREAM) == -1 &&
|
||||
net_get_errno() == NET_ERR_INVAL && s_net_socks[1].in_use == 0U,
|
||||
"TC-NETSOCK-104k 非 INET 地址族 → INVAL 且不占槽位");
|
||||
"TC-NETSOCK-104k non-INET address family -> INVAL and no slot taken");
|
||||
|
||||
reset_all();
|
||||
}
|
||||
@@ -336,22 +336,22 @@ static void tc_105_bind(void)
|
||||
in.sin_addr.s_addr = net_inet_addr("192.168.1.100");
|
||||
|
||||
CHECK(net_bind(-1, (struct net_sockaddr *)&in, sizeof(in)) == -1 &&
|
||||
net_get_errno() == NET_ERR_BADF, "TC-NETSOCK-105a 越界 fd → BADF");
|
||||
net_get_errno() == NET_ERR_BADF, "TC-NETSOCK-105a out of range fd -> BADF");
|
||||
CHECK(net_bind(0, (struct net_sockaddr *)&in, sizeof(in)) == -1 &&
|
||||
net_get_errno() == NET_ERR_BADF, "TC-NETSOCK-105b 未创建就 bind → BADF");
|
||||
net_get_errno() == NET_ERR_BADF, "TC-NETSOCK-105b bind before socket -> BADF");
|
||||
|
||||
fd = net_socket(NET_AF_INET, NET_SOCK_STREAM);
|
||||
CHECK(net_bind(fd, NULL, sizeof(in)) == -1 && net_get_errno() == NET_ERR_INVAL,
|
||||
"TC-NETSOCK-105c addr 为 NULL → INVAL");
|
||||
"TC-NETSOCK-105c addr NULL -> INVAL");
|
||||
CHECK(net_bind(fd, (struct net_sockaddr *)&in, 1) == -1 &&
|
||||
net_get_errno() == NET_ERR_INVAL, "TC-NETSOCK-105d addrlen 不足 → INVAL");
|
||||
net_get_errno() == NET_ERR_INVAL, "TC-NETSOCK-105d addrlen too small -> INVAL");
|
||||
CHECK(net_bind(fd, (struct net_sockaddr *)&in, sizeof(in)) == 0,
|
||||
"TC-NETSOCK-105e TCP bind 成功");
|
||||
"TC-NETSOCK-105e TCP bind succeeds");
|
||||
CHECK(s_net_socks[fd].local_port == 2404U &&
|
||||
s_net_socks[fd].state == NET_SOCK_STATE_BOUND,
|
||||
"TC-NETSOCK-105f TCP 只记端口转主机序 + 进 BOUND,不碰芯片");
|
||||
"TC-NETSOCK-105f TCP bind only stores host-order port and goes BOUND, no chip touch");
|
||||
CHECK(g_chip.set_port_calls == 0 && g_chip.open_calls == 0,
|
||||
"TC-NETSOCK-105g TCP bind 期间不得下发源端口/开芯片 Socket(打开留给 listen)");
|
||||
"TC-NETSOCK-105g bind must not set source port or open the chip socket (open belongs to listen)");
|
||||
|
||||
/* port=0 → 动态端口 49152 起,并推进 */
|
||||
reset_all();
|
||||
@@ -360,16 +360,16 @@ static void tc_105_bind(void)
|
||||
fd = net_socket(NET_AF_INET, NET_SOCK_STREAM);
|
||||
rc = net_bind(fd, (struct net_sockaddr *)&in, sizeof(in));
|
||||
CHECK(rc == 0 && s_net_socks[fd].local_port == 49152U,
|
||||
"TC-NETSOCK-105h port=0 → 分配 49152");
|
||||
"TC-NETSOCK-105h port=0 allocates 49152");
|
||||
CHECK(s_dynamic_port == 49153U,
|
||||
"TC-NETSOCK-105h2 计数器已推进到 49153(分配即推进,不留重复)");
|
||||
"TC-NETSOCK-105h2 counter already advanced to 49153 (advance on allocate, never reuse)");
|
||||
(void)net_socket(NET_AF_INET, NET_SOCK_STREAM); /* 只创建不 bind */
|
||||
CHECK(s_dynamic_port == 49153U,
|
||||
"TC-NETSOCK-105i3 创建 socket **不**消耗动态端口(只有 bind 消耗)");
|
||||
"TC-NETSOCK-105i3 creating a socket does NOT consume a dynamic port (only bind does)");
|
||||
fd = net_socket(NET_AF_INET, NET_SOCK_STREAM);
|
||||
rc = net_bind(fd, (struct net_sockaddr *)&in, sizeof(in));
|
||||
CHECK(rc == 0 && s_net_socks[fd].local_port == 49153U && s_dynamic_port == 49154U,
|
||||
"TC-NETSOCK-105i 第二次 bind 拿下一个端口(不会把同一个端口发两次)");
|
||||
"TC-NETSOCK-105i second bind gets the next port (same port never issued twice)");
|
||||
|
||||
/* 回绕:把计数器压到 65535,分配后应回 49152(不是 0——0 会让芯片按"未绑定"处理) */
|
||||
s_dynamic_port = 65535U;
|
||||
@@ -378,7 +378,7 @@ static void tc_105_bind(void)
|
||||
fd = net_socket(NET_AF_INET, NET_SOCK_STREAM);
|
||||
rc = net_bind(fd, (struct net_sockaddr *)&in, sizeof(in));
|
||||
CHECK(rc == 0 && s_net_socks[fd].local_port == 65535U && s_dynamic_port == 49152U,
|
||||
"TC-NETSOCK-105j 动态端口越过 65535 回绕到 49152(不回 0)");
|
||||
"TC-NETSOCK-105j dynamic port wraps from 65535 back to 49152 (never to 0)");
|
||||
}
|
||||
|
||||
static void tc_106_bind_udp(void)
|
||||
@@ -393,23 +393,23 @@ static void tc_106_bind_udp(void)
|
||||
|
||||
/* UDP:bind 就直接开芯片侧(无监听态),且必须配 DesIP=255.255.255.255 收任意源 */
|
||||
fd = net_socket(NET_AF_INET, NET_SOCK_DGRAM);
|
||||
CHECK(net_bind(fd, (struct net_sockaddr *)&in, sizeof(in)) == 0, "TC-NETSOCK-106a UDP bind 成功");
|
||||
CHECK(s_net_socks[fd].state == NET_SOCK_STATE_UDP_OPEN, "TC-NETSOCK-106b UDP 直接进 UDP_OPEN");
|
||||
CHECK(net_bind(fd, (struct net_sockaddr *)&in, sizeof(in)) == 0, "TC-NETSOCK-106a UDP bind succeeds");
|
||||
CHECK(s_net_socks[fd].state == NET_SOCK_STATE_UDP_OPEN, "TC-NETSOCK-106b UDP goes straight to UDP_OPEN");
|
||||
CHECK(g_chip.set_proto_calls == 1 && g_chip.last_proto == CH395F_PROTO_TYPE_UDP,
|
||||
"TC-NETSOCK-106c 协议下发为 UDP(不是 TCP)");
|
||||
"TC-NETSOCK-106c protocol set to UDP (not TCP)");
|
||||
CHECK(g_chip.set_port_calls == 1 && g_chip.last_port == 8888U,
|
||||
"TC-NETSOCK-106d 源端口随 bind 下发");
|
||||
"TC-NETSOCK-106d source port delivered with bind");
|
||||
CHECK(g_fx.des_ip[0][0] == 0xFFU && g_fx.des_ip[0][1] == 0xFFU &&
|
||||
g_fx.des_ip[0][2] == 0xFFU && g_fx.des_ip[0][3] == 0xFFU &&
|
||||
g_fx.des_port[0] == 0U,
|
||||
"TC-NETSOCK-106e UDP Server 模式:DesIP=全 FF + 目的端口 0(否则只收单一对端)");
|
||||
CHECK(g_chip.open_calls == 1, "TC-NETSOCK-106f UDP bind 开一次芯片 Socket");
|
||||
"TC-NETSOCK-106e UDP server mode: DesIP all FF and dest port 0 (else only one peer is received)");
|
||||
CHECK(g_chip.open_calls == 1, "TC-NETSOCK-106f UDP bind opens the chip socket once");
|
||||
|
||||
/* 槽位 >=4 必须补设收发缓冲(net_init 已配过,这里是兜底):布局 6 块/槽 */
|
||||
reset_all();
|
||||
fd = net_socket(NET_AF_INET, NET_SOCK_DGRAM);
|
||||
CHECK(fd == 0, "TC-NETSOCK-106g 先拿 fd0(对照:不补缓冲)");
|
||||
CHECK(g_fxchip.set_recv_buf_calls == 0, "TC-NETSOCK-106h fd<4 的 UDP bind 不重设缓冲");
|
||||
CHECK(fd == 0, "TC-NETSOCK-106g take fd0 first (control case: no buffer reconfig)");
|
||||
CHECK(g_fxchip.set_recv_buf_calls == 0, "TC-NETSOCK-106h UDP bind on fd<4 does not reconfigure buffers");
|
||||
|
||||
reset_all();
|
||||
for (fd = 0; fd < 4; fd++) {
|
||||
@@ -421,7 +421,7 @@ static void tc_106_bind_udp(void)
|
||||
g_fx.recv_blk_cnt[4] == (uint8_t)CH395F_RECV_BLOCKS &&
|
||||
g_fx.send_blk_start[4] == (uint8_t)(4 * 6 + (int)CH395F_RECV_BLOCKS) &&
|
||||
g_fx.send_blk_cnt[4] == (uint8_t)CH395F_SEND_BLOCKS,
|
||||
"TC-NETSOCK-106i fd>=4 兜底重设收发缓冲,块布局与 net_init 同构(6 块/槽)");
|
||||
"TC-NETSOCK-106i fd>=4 falls back to reconfiguring rx/tx buffers, same 6-block layout as net_init");
|
||||
|
||||
/* open 失败 → BUSY 且留在原状态(不得谎报 UDP_OPEN) */
|
||||
reset_all();
|
||||
@@ -431,7 +431,7 @@ static void tc_106_bind_udp(void)
|
||||
net_get_errno() == NET_ERR_BUSY &&
|
||||
s_net_socks[fd].state != NET_SOCK_STATE_UDP_OPEN &&
|
||||
g_ns_error_count == 1,
|
||||
"TC-NETSOCK-106j UDP open 失败 → BUSY + 留痕 + 状态不前进");
|
||||
"TC-NETSOCK-106j UDP open failure -> BUSY plus error log and state does not advance");
|
||||
}
|
||||
|
||||
static void tc_107_peer_and_localname(void)
|
||||
@@ -445,40 +445,40 @@ static void tc_107_peer_and_localname(void)
|
||||
(void)net_init("192.168.1.100", "255.255.255.0", "192.168.1.1", NULL);
|
||||
|
||||
CHECK(net_getsockname(-1, sa, &addrlen) == -1 && net_get_errno() == NET_ERR_BADF,
|
||||
"TC-NETSOCK-107a getsockname 越界 → BADF");
|
||||
"TC-NETSOCK-107a getsockname out of range -> BADF");
|
||||
CHECK(net_getsockname(0, sa, &addrlen) == -1 && net_get_errno() == NET_ERR_BADF,
|
||||
"TC-NETSOCK-107b 未用且 CLOSED 的槽 → BADF");
|
||||
"TC-NETSOCK-107b unused CLOSED slot -> BADF");
|
||||
|
||||
fd = net_socket(NET_AF_INET, NET_SOCK_STREAM);
|
||||
(void)memset(&in, 0, sizeof(in));
|
||||
in.sin_port = net_htons(7003);
|
||||
CHECK(net_bind(fd, sa, (int)sizeof(in)) == 0, "TC-NETSOCK-107c bind 前置成功");
|
||||
CHECK(net_bind(fd, sa, (int)sizeof(in)) == 0, "TC-NETSOCK-107c bind precondition ok");
|
||||
addrlen = (int)sizeof(in);
|
||||
(void)memset(&in, 0, sizeof(in));
|
||||
CHECK(net_getsockname(fd, sa, &addrlen) == 0, "TC-NETSOCK-107d getsockname 成功");
|
||||
CHECK(net_getsockname(fd, sa, &addrlen) == 0, "TC-NETSOCK-107d getsockname succeeds");
|
||||
CHECK(in.sin_family == NET_AF_INET && net_ntohs(in.sin_port) == 7003U &&
|
||||
addrlen == (int)sizeof(in),
|
||||
"TC-NETSOCK-107e 回填族/端口(网络序)/长度");
|
||||
"TC-NETSOCK-107e fills family, port (network order) and length");
|
||||
/* 钉**具体顺位**而不是二选一:getsockname 走的是「首段在最低字节」这一族
|
||||
* (与 net_inet_ntoa、net_events 的 remote_ip 同族),所以 192.168.1.100 =
|
||||
* 0x6401A8C0。net_inet_addr 返回的是另一族(首段在最高字节,0xC0A80164),
|
||||
* 两族不互逆——已作为疑似缺陷报出,这里刻意不写成「两个都行」。 */
|
||||
CHECK(in.sin_addr.s_addr == 0x6401A8C0U,
|
||||
"TC-NETSOCK-107f 本机 IP 顺位=首段在最低字节(与 ntoa 同族;net_inet_addr 是另一族)");
|
||||
"TC-NETSOCK-107f local IP byte order = first octet in low byte (ntoa family)");
|
||||
|
||||
addrlen = 1;
|
||||
CHECK(net_getsockname(fd, sa, &addrlen) == -1 && net_get_errno() == NET_ERR_INVAL,
|
||||
"TC-NETSOCK-107g 长度不足 → INVAL");
|
||||
"TC-NETSOCK-107g length too small -> INVAL");
|
||||
CHECK(net_getsockname(fd, sa, NULL) == -1 && net_get_errno() == NET_ERR_INVAL,
|
||||
"TC-NETSOCK-107h addrlen 为 NULL → INVAL");
|
||||
"TC-NETSOCK-107h addrlen NULL -> INVAL");
|
||||
|
||||
/* getpeername:没有 CONNECT 回读过对端 → NOTCONN(不发 SPI 是它的卖点) */
|
||||
(void)memset(&in, 0, sizeof(in));
|
||||
addrlen = (int)sizeof(in);
|
||||
CHECK(net_getpeername(fd, sa, &addrlen) == -1 && net_get_errno() == NET_ERR_NOTCONN,
|
||||
"TC-NETSOCK-107i 尚无对端 → NOTCONN(remote_port==0 判据)");
|
||||
"TC-NETSOCK-107i no peer yet -> NOTCONN (judged by remote_port==0)");
|
||||
CHECK(g_chip.get_status_calls == 0 && g_fxchip.glob_calls == 0,
|
||||
"TC-NETSOCK-107j getpeername 纯读缓存,不发任何芯片事务");
|
||||
"TC-NETSOCK-107j getpeername only reads the cache, issues no chip transactions");
|
||||
|
||||
s_net_socks[fd].remote_port = 51999U;
|
||||
s_net_socks[fd].remote_ip = 0x0B01A8C0U;
|
||||
@@ -487,14 +487,14 @@ static void tc_107_peer_and_localname(void)
|
||||
CHECK(net_getpeername(fd, sa, &addrlen) == 0 &&
|
||||
net_ntohs(in.sin_port) == 51999U && in.sin_addr.s_addr == 0x0B01A8C0U &&
|
||||
in.sin_family == NET_AF_INET,
|
||||
"TC-NETSOCK-107k getpeername 回填缓存的对端 IP:端口");
|
||||
"TC-NETSOCK-107k getpeername fills the cached peer IP and port");
|
||||
CHECK(net_getpeername(-1, sa, &addrlen) == -1 && net_get_errno() == NET_ERR_BADF,
|
||||
"TC-NETSOCK-107l getpeername 越界 → BADF");
|
||||
"TC-NETSOCK-107l getpeername out of range -> BADF");
|
||||
CHECK(net_getpeername(5, sa, &addrlen) == -1 && net_get_errno() == NET_ERR_BADF,
|
||||
"TC-NETSOCK-107m getpeername 未在用 → BADF");
|
||||
"TC-NETSOCK-107m getpeername on unused fd -> BADF");
|
||||
addrlen = 2;
|
||||
CHECK(net_getpeername(fd, sa, &addrlen) == -1 && net_get_errno() == NET_ERR_INVAL,
|
||||
"TC-NETSOCK-107n getpeername 长度不足 → INVAL");
|
||||
"TC-NETSOCK-107n getpeername length too small -> INVAL");
|
||||
|
||||
reset_all();
|
||||
}
|
||||
@@ -506,31 +506,31 @@ static void tc_108_sockprops(void)
|
||||
|
||||
reset_all();
|
||||
CHECK(net_setblocking(-1, 1) == -1 && net_get_errno() == NET_ERR_BADF,
|
||||
"TC-NETSOCK-108a setblocking 越界 → BADF");
|
||||
"TC-NETSOCK-108a setblocking out of range -> BADF");
|
||||
CHECK(net_setblocking(0, 1) == -1 && net_get_errno() == NET_ERR_BADF,
|
||||
"TC-NETSOCK-108b 未占用 → BADF");
|
||||
"TC-NETSOCK-108b not in use -> BADF");
|
||||
CHECK(net_set_event_cb(-1, NULL, NULL) == -1 && net_get_errno() == NET_ERR_BADF,
|
||||
"TC-NETSOCK-108c set_event_cb 越界 → BADF");
|
||||
"TC-NETSOCK-108c set_event_cb out of range -> BADF");
|
||||
CHECK(net_set_event_cb(0, NULL, NULL) == -1 && net_get_errno() == NET_ERR_BADF,
|
||||
"TC-NETSOCK-108d set_event_cb 未占用 → BADF");
|
||||
"TC-NETSOCK-108d set_event_cb not in use -> BADF");
|
||||
|
||||
fd = net_socket(NET_AF_INET, NET_SOCK_STREAM);
|
||||
CHECK(net_setblocking(fd, 0) == 0 && s_net_socks[fd].blocking == 0U,
|
||||
"TC-NETSOCK-108e setblocking(0) 落属性(模式挂控制块,不是单次参数)");
|
||||
"TC-NETSOCK-108e setblocking(0) sets the attribute (mode lives in the control block, not per call)");
|
||||
CHECK(net_setblocking(fd, 5) == 0 && s_net_socks[fd].blocking == 1U,
|
||||
"TC-NETSOCK-108f 非 0 一律视为阻塞");
|
||||
"TC-NETSOCK-108f any non-zero value counts as blocking");
|
||||
CHECK(net_set_event_cb(fd, (net_event_cb_t)0x1234, &arg) == 0 &&
|
||||
s_net_socks[fd].event_cb == (net_event_cb_t)0x1234 &&
|
||||
s_net_socks[fd].event_arg == &arg,
|
||||
"TC-NETSOCK-108g 注册回调与用户参数");
|
||||
"TC-NETSOCK-108g registers callback and user argument");
|
||||
CHECK(net_set_event_cb(fd, NULL, NULL) == 0 && s_net_socks[fd].event_cb == NULL,
|
||||
"TC-NETSOCK-108h cb=NULL 取消注册");
|
||||
"TC-NETSOCK-108h cb=NULL unregisters");
|
||||
s_net_socks[fd].state = NET_SOCK_STATE_ESTABLISHED;
|
||||
CHECK(net_sock_state(fd) == (int)NET_SOCK_STATE_ESTABLISHED,
|
||||
"TC-NETSOCK-108i sock_state 返状态快照");
|
||||
CHECK(net_sock_state(NET_MAX_SOCKETS) == -1, "TC-NETSOCK-108j sock_state 越界 -1");
|
||||
"TC-NETSOCK-108i sock_state returns the state snapshot");
|
||||
CHECK(net_sock_state(NET_MAX_SOCKETS) == -1, "TC-NETSOCK-108j sock_state out of range -> -1");
|
||||
s_net_socks[fd].in_use = 0U;
|
||||
CHECK(net_sock_state(fd) == -1, "TC-NETSOCK-108k sock_state 未占用 -1");
|
||||
CHECK(net_sock_state(fd) == -1, "TC-NETSOCK-108k sock_state on unused fd -> -1");
|
||||
|
||||
reset_all();
|
||||
}
|
||||
@@ -538,10 +538,10 @@ static void tc_108_sockprops(void)
|
||||
static void tc_109_generation(void)
|
||||
{
|
||||
reset_all();
|
||||
CHECK(net_get_generation() == 0U, "TC-NETSOCK-109a 初值 0");
|
||||
CHECK(net_get_generation() == 0U, "TC-NETSOCK-109a initial value 0");
|
||||
net_generation_inc();
|
||||
net_generation_inc();
|
||||
CHECK(net_get_generation() == 2U, "TC-NETSOCK-109b 每次网络重建 +1(服务据此重建监听)");
|
||||
CHECK(net_get_generation() == 2U, "TC-NETSOCK-109b each network rebuild adds 1 (services rebuild listeners from it)");
|
||||
reset_all();
|
||||
}
|
||||
|
||||
@@ -551,33 +551,33 @@ static void tc_110_queue_adopt(void)
|
||||
static int q2;
|
||||
|
||||
reset_all();
|
||||
CHECK(net_msg_queue_adopt(NULL) == -1, "TC-NETSOCK-110a 空句柄 → -1");
|
||||
CHECK(net_msg_queue_adopt((osMessageQueueId_t)&q1) == 0, "TC-NETSOCK-110b 首次绑定成功");
|
||||
CHECK(net_msg_queue_adopt(NULL) == -1, "TC-NETSOCK-110a NULL handle -> -1");
|
||||
CHECK(net_msg_queue_adopt((osMessageQueueId_t)&q1) == 0, "TC-NETSOCK-110b first binding succeeds");
|
||||
CHECK(net_msg_queue_adopt((osMessageQueueId_t)&q2) == -1,
|
||||
"TC-NETSOCK-110c 重复绑定必须被拒(不静默换句柄)");
|
||||
"TC-NETSOCK-110c rebinding must be refused (no silent handle swap)");
|
||||
CHECK(s_net_msg_queue == (osMessageQueueId_t)&q1,
|
||||
"TC-NETSOCK-110d 重复绑定**保留首次**句柄——换掉会让已入队请求永不处理");
|
||||
"TC-NETSOCK-110d rebinding keeps the FIRST handle - swapping would strand queued requests forever");
|
||||
/* 未绑定时所有公开 API 一律 NET_ERR,而不是崩在空句柄上 */
|
||||
reset_all();
|
||||
CHECK(net_listen(0) == -1 && net_get_errno() == NET_ERR,
|
||||
"TC-NETSOCK-110e 未绑定队列:net_listen → NET_ERR");
|
||||
"TC-NETSOCK-110e without a bound queue: net_listen -> NET_ERR");
|
||||
CHECK(net_recv(0, NULL, 0, 0) == -1 && net_get_errno() == NET_ERR,
|
||||
"TC-NETSOCK-110f 未绑定队列:net_recv → NET_ERR(越界检查在队检查之前)");
|
||||
"TC-NETSOCK-110f without a bound queue: net_recv -> NET_ERR (range check precedes queue check)");
|
||||
CHECK(net_send(0, "x", 1, 0) == -1 && net_get_errno() == NET_ERR,
|
||||
"TC-NETSOCK-110g 未绑定队列:net_send → NET_ERR");
|
||||
"TC-NETSOCK-110g without a bound queue: net_send -> NET_ERR");
|
||||
CHECK(net_close(0) == -1 && net_get_errno() == NET_ERR,
|
||||
"TC-NETSOCK-110h 未绑定队列:net_close → NET_ERR");
|
||||
"TC-NETSOCK-110h without a bound queue: net_close -> NET_ERR");
|
||||
CHECK(net_drop_conn(0) == -1 && net_get_errno() == NET_ERR,
|
||||
"TC-NETSOCK-110i 未绑定队列:net_drop_conn → NET_ERR");
|
||||
"TC-NETSOCK-110i without a bound queue: net_drop_conn -> NET_ERR");
|
||||
CHECK(net_recv_to(0, NULL, 0, 10U) == -1 && net_get_errno() == NET_ERR,
|
||||
"TC-NETSOCK-110j 未绑定队列:net_recv_to → NET_ERR");
|
||||
"TC-NETSOCK-110j without a bound queue: net_recv_to -> NET_ERR");
|
||||
CHECK(net_accept(0, NULL, NULL) == -1 && net_get_errno() == NET_ERR,
|
||||
"TC-NETSOCK-110k 未绑定队列:net_accept → NET_ERR");
|
||||
"TC-NETSOCK-110k without a bound queue: net_accept -> NET_ERR");
|
||||
CHECK(net_connect(0, NULL, 0) == -1 && net_get_errno() == NET_ERR,
|
||||
"TC-NETSOCK-110l 未绑定队列:net_connect → NET_ERR");
|
||||
"TC-NETSOCK-110l without a bound queue: net_connect -> NET_ERR");
|
||||
/* 越界优先于"未初始化":调用方拿到的码要能区分"我传错了"和"网还没起来" */
|
||||
CHECK(net_send(NET_MAX_SOCKETS, "x", 1, 0) == -1 && net_get_errno() == NET_ERR_BADF,
|
||||
"TC-NETSOCK-110m 越界检查先于队列检查 → BADF");
|
||||
"TC-NETSOCK-110m range check before queue check -> BADF");
|
||||
reset_all();
|
||||
}
|
||||
|
||||
@@ -592,10 +592,10 @@ static void tc_120_errno_slot_per_task(void)
|
||||
g_ns_cur_task = (TaskHandle_t)&g_ns_task_caller;
|
||||
(void)net_set_errno(NET_ERR_BADF);
|
||||
CHECK(net_get_errno() == NET_ERR_BADF && s_net_errno_slots[0].owner == NULL,
|
||||
"TC-NETSOCK-120a 内核未运行 → 用 [0] 槽且**不占槽**(不写 owner)");
|
||||
"TC-NETSOCK-120a kernel not running -> uses slot [0] and takes no slot (owner not written)");
|
||||
g_ns_cur_task = (TaskHandle_t)&g_ns_task_net;
|
||||
CHECK(net_get_errno() == NET_ERR_BADF,
|
||||
"TC-NETSOCK-120b 内核未运行时所有任务共享 [0] 槽(退化语义)");
|
||||
"TC-NETSOCK-120b with the kernel down all tasks share slot [0] (degraded semantics)");
|
||||
|
||||
/* 内核在跑:每个任务自己的槽位 */
|
||||
g_ns_kernel_state = osKernelRunning;
|
||||
@@ -605,15 +605,15 @@ static void tc_120_errno_slot_per_task(void)
|
||||
(void)net_set_errno(NET_ERR_TIMEDOUT);
|
||||
g_ns_cur_task = (TaskHandle_t)&g_ns_task_net;
|
||||
CHECK(net_get_errno() == NET_OK,
|
||||
"TC-NETSOCK-120c 另一个任务读不到 caller 的码(E-03 的正面表述)");
|
||||
"TC-NETSOCK-120c another task cannot read the caller code (the positive wording of E-03)");
|
||||
(void)net_set_errno(NET_ERR_WOULDBLOCK);
|
||||
CHECK(net_get_errno() == NET_ERR_WOULDBLOCK, "TC-NETSOCK-120d 本任务读自己的码");
|
||||
CHECK(net_get_errno() == NET_ERR_WOULDBLOCK, "TC-NETSOCK-120d a task reads its own code");
|
||||
g_ns_cur_task = (TaskHandle_t)&g_ns_task_caller;
|
||||
CHECK(net_get_errno() == NET_ERR_TIMEDOUT,
|
||||
"TC-NETSOCK-120e 互不覆写:caller 的码没被 netTask 抢走(旧实现的红线)");
|
||||
"TC-NETSOCK-120e no cross overwrite: caller code survives the netTask write (old red line)");
|
||||
/* 临界区:两个任务各占一次槽 → 两次进入、两次退出,绝不泄漏嵌套计数 */
|
||||
CHECK(g_ns_crit_enter == 2 && g_ns_crit_exit == 2 && ns_os_crit_depth() == 0,
|
||||
"TC-NETSOCK-120f 每次**首次占槽**进一次临界区且成对退出(无泄漏)");
|
||||
"TC-NETSOCK-120f each first slot take enters the critical section once and leaves in pairs");
|
||||
|
||||
/* 快路径只读不写:已有槽位的任务反复读写都不该再进临界区、也不该再占槽 */
|
||||
{
|
||||
@@ -623,18 +623,18 @@ static void tc_120_errno_slot_per_task(void)
|
||||
int i_net = ns_slot_index_of((TaskHandle_t)&g_ns_task_net);
|
||||
|
||||
CHECK(i_caller >= 0 && i_net >= 0 && i_caller != i_net,
|
||||
"TC-NETSOCK-120g 两个任务落在**不同**槽位(槽位表可查,不是靠约定)");
|
||||
"TC-NETSOCK-120g two tasks land in DIFFERENT slots (table is inspectable, not convention)");
|
||||
g_ns_cur_task = (TaskHandle_t)&g_ns_task_caller;
|
||||
(void)net_set_errno(NET_ERR_BUSY);
|
||||
(void)net_get_errno();
|
||||
(void)net_set_errno(NET_ERR_CONNRESET);
|
||||
CHECK(g_ns_crit_enter == e0, "TC-NETSOCK-120h 命中已有槽位:全程零临界区(快路径只读)");
|
||||
CHECK(g_ns_crit_enter == e0, "TC-NETSOCK-120h existing slot hit: zero critical sections (fast path is read-only)");
|
||||
g_ns_cur_task = (TaskHandle_t)&g_ns_task_net;
|
||||
CHECK(net_get_errno() == NET_ERR_WOULDBLOCK &&
|
||||
ns_slot_owner_count() == owners0,
|
||||
"TC-NETSOCK-120i 别的任务反复读也不新增槽位、也读不到 caller 的码");
|
||||
"TC-NETSOCK-120i repeated reads by another task add no slot and never see the caller code");
|
||||
g_ns_cur_task = (TaskHandle_t)&g_ns_task_caller;
|
||||
CHECK(net_get_errno() == NET_ERR_CONNRESET, "TC-NETSOCK-120j caller 读到自己最新的码");
|
||||
CHECK(net_get_errno() == NET_ERR_CONNRESET, "TC-NETSOCK-120j caller reads its own latest code");
|
||||
}
|
||||
|
||||
/* 槽位用尽 → 回退 [0](刻意不重试,避免把竞态带回来) */
|
||||
@@ -648,14 +648,14 @@ static void tc_120_errno_slot_per_task(void)
|
||||
(void)net_set_errno(NET_ERR_ISCONN);
|
||||
}
|
||||
g_ns_cur_task = (TaskHandle_t)&filler[0];
|
||||
CHECK(net_get_errno() == NET_ERR_ISCONN, "TC-NETSOCK-120k 8 个槽各归各主");
|
||||
CHECK(net_get_errno() == NET_ERR_ISCONN, "TC-NETSOCK-120k 8 slots, one owner each");
|
||||
g_ns_cur_task = (TaskHandle_t)&g_ns_task_caller; /* 第 9 个任务 */
|
||||
(void)net_set_errno(NET_ERR_NOMEM);
|
||||
CHECK(net_get_errno() == NET_ERR_NOMEM,
|
||||
"TC-NETSOCK-120l 槽位用尽:新任务落 [0] 槽仍读得到自己的码");
|
||||
"TC-NETSOCK-120l slots exhausted: a new task still reads its own code from slot [0]");
|
||||
g_ns_cur_task = (TaskHandle_t)&filler[0];
|
||||
CHECK(net_get_errno() == NET_ERR_NOMEM,
|
||||
"TC-NETSOCK-120m 用尽后退化为共享 [0] 槽(只影响排障可读性,不新增共享槽位)");
|
||||
"TC-NETSOCK-120m after exhaustion it degrades to the shared slot [0] (only hurts debuggability)");
|
||||
}
|
||||
reset_all();
|
||||
}
|
||||
@@ -667,7 +667,7 @@ static void tc_121_errno_slot_isr(void)
|
||||
g_ns_cur_task = NULL; /* 中断上下文/无句柄 */
|
||||
(void)net_set_errno(NET_ERR_CONNRESET);
|
||||
CHECK(net_get_errno() == NET_ERR_CONNRESET && s_net_errno_slots[0].owner == NULL,
|
||||
"TC-NETSOCK-121 句柄为 NULL(中断上下文)→ 退 [0] 槽且不改槽位表");
|
||||
"TC-NETSOCK-121 NULL handle (ISR context) -> falls back to slot [0] and leaves the table alone");
|
||||
reset_all();
|
||||
}
|
||||
|
||||
@@ -675,9 +675,9 @@ static void tc_121_errno_slot_isr(void)
|
||||
|
||||
int main(void)
|
||||
{
|
||||
printf("=== NET Socket Tests (net_socket.c 主机单测) ===\n");
|
||||
printf("=== NET Socket Tests (net_socket.c host unit tests) ===\n");
|
||||
|
||||
printf("[shard1] 纯函数面与 fd 表\n");
|
||||
printf("[shard1] pure functions and fd table\n");
|
||||
tc_100_inet_helpers();
|
||||
tc_101_byteorder();
|
||||
tc_102_parse_ip();
|
||||
@@ -690,20 +690,20 @@ int main(void)
|
||||
tc_109_generation();
|
||||
tc_110_queue_adopt();
|
||||
|
||||
printf("[shard2] 每任务错误码槽 + 队列绑定\n");
|
||||
printf("[shard2] per-task errno slots and queue binding\n");
|
||||
tc_120_errno_slot_per_task();
|
||||
tc_121_errno_slot_isr();
|
||||
|
||||
printf("[shard3] 跨上下文消息与通知值回传\n");
|
||||
printf("[shard3] cross-context messages and notify-value return\n");
|
||||
ns_run_s3();
|
||||
|
||||
printf("[shard4] 状态机与闸门\n");
|
||||
printf("[shard4] state machine and gates\n");
|
||||
ns_run_s4();
|
||||
|
||||
printf("[shard5] 建流与读写分支\n");
|
||||
printf("[shard5] stream setup and read/write branches\n");
|
||||
ns_run_s5();
|
||||
|
||||
printf("[shard6] 边界残支与其余出口\n");
|
||||
printf("[shard6] edge branches and remaining exits\n");
|
||||
ns_run_s6();
|
||||
|
||||
printf("=== NET Socket Tests: %d/%d PASSED (failed=%d) ===\n",
|
||||
|
||||
Reference in New Issue
Block a user