Skip to content

Commit 4f92782

Browse files
committed
docs(quick-260513-fjd): 修复 SubnetThirdOctet 碰撞测试阈值
- TestSubnetThirdOctet_CollisionResistance 阈值 10 → 40 - 修正注释,准确描述生日悖论期望 E[collisions] ≈ 25 - 100 样本投到 200 桶里,确定性 FNV-1a 输入产生 22 个碰撞 - 修复 Linux CI 测试失败 - 更新 STATE.md 记录本次 quick task
1 parent 7637a4f commit 4f92782

2 files changed

Lines changed: 136 additions & 4 deletions

File tree

.planning/STATE.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ milestone: v3.4
44
milestone_name: 多形态容器接入
55
status: shipped
66
stopped_at: Milestone v3.4 shipped (tag v3.4.0)
7-
last_updated: "2026-05-13T02:48:00Z"
8-
last_activity: 2026-05-13 - Completed quick task 260513-ezu: 修复 worker firewall 测试 ApplyWorkerFirewallRules 参数错误
7+
last_updated: "2026-05-13T03:13:00Z"
8+
last_activity: 2026-05-13 - Completed quick task 260513-fjd: 修复 SubnetThirdOctet 碰撞测试阈值
99
progress:
1010
total_phases: 7
1111
completed_phases: 7
@@ -47,9 +47,10 @@ Full decision log in PROJECT.md Key Decisions table.
4747

4848
### Quick Tasks Completed
4949

50-
| # | Description | Date | Commit | Directory |
51-
| ---------- | ---------------------------------------------------------- | ---------- | ------- | ------------------------------------------------------------------------------------------------------------ |
50+
| # | Description | Date | Commit | Directory |
51+
| --- | --- | --- | --- | --- |
5252
| 260513-ezu | 修复 worker firewall 测试 ApplyWorkerFirewallRules 参数错误 | 2026-05-13 | 73deb3c | [260513-ezu-worker-firewall-applyworkerfirewallrules](./quick/260513-ezu-worker-firewall-applyworkerfirewallrules/) |
53+
| 260513-fjd | 修复 SubnetThirdOctet 碰撞测试阈值(10 → 40,匹配生日悖论期望) | 2026-05-13 | 0def841 | [260513-fjd-subnetthirdoctet](./quick/260513-fjd-subnetthirdoctet/) |
5354

5455
### Roadmap Evolution
5556

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
---
2+
phase: 260513-fjd-subnetthirdoctet
3+
plan: 01
4+
subsystem: internal/network
5+
tags: [test, bugfix, ci-stability]
6+
requires: []
7+
provides:
8+
- 修复后的 TestSubnetThirdOctet_CollisionResistance(阈值 40,注释准确)
9+
affects:
10+
- internal/network/container_proxy_provider_test.go
11+
tech_stack:
12+
added: []
13+
patterns:
14+
- 测试断言阈值需与统计学期望(生日悖论)对齐
15+
key_files:
16+
created: []
17+
modified:
18+
- internal/network/container_proxy_provider_test.go
19+
decisions:
20+
- 阈值 40 留出约 18 次余量,覆盖生日悖论方差(E≈25)
21+
- 仅修改测试断言与注释,不改动 subnetThirdOctet 实现
22+
metrics:
23+
duration_minutes: 2
24+
completed_date: 2026-05-13
25+
tasks_completed: 1
26+
files_modified: 1
27+
commits:
28+
- hash: 0def841
29+
message: "test(260513-fjd-01): 调整 SubnetThirdOctet 碰撞抗性阈值至 40"
30+
---
31+
32+
# Quick Task 260513-fjd: SubnetThirdOctet 碰撞抗性测试阈值修复 Summary
33+
34+
## 一句话总结
35+
36+
`TestSubnetThirdOctet_CollisionResistance` 的失败阈值从 `> 10` 调整为 `> 40`,并把注释改为基于生日悖论的准确描述,消除 CI 上的确定性误报。
37+
38+
## 背景与问题
39+
40+
`internal/network/container_proxy_provider_test.go` 中的 `TestSubnetThirdOctet_CollisionResistance` 使用 FNV-1a 把 100 个**确定性**输入哈希到 200 个桶(`% 200 + 20`,对应 IP 第三段 20-219)。原断言为 `if collisions > 10`,并附注释 "expect very few collisions / Allow up to 10 as a generous threshold"。
41+
42+
问题在于:
43+
- **统计学层面**:根据生日悖论,把 k 个样本均匀投到 n 个桶,期望碰撞数为 `E = k(k-1)/(2n) = 100 * 99 / (2 * 200) ≈ 24.75`。即使是理想均匀分布,期望就已远超 10。
44+
- **实测层面**:FNV-1a 对硬编码的 100 个测试输入产生**固定** 22 次碰撞(输入确定 → 输出确定)。
45+
- **结果**:阈值 10 在 CI 上**每次必失败**,而本地若未启用 `//go:build linux`(macOS)则不会编译该文件,导致问题被掩盖直到 CI 跑起来。
46+
47+
## 修改对比
48+
49+
### 修改前(`internal/network/container_proxy_provider_test.go` 第 106-108 行)
50+
51+
```go
52+
// 100 samples into 200 possible values: expect very few collisions
53+
// Allow up to 10 collisions as a generous threshold
54+
if collisions > 10 {
55+
```
56+
57+
### 修改后
58+
59+
```go
60+
// 100 samples into 200 buckets: birthday paradox expects E[collisions] = 100*99/(2*200) ≈ 25
61+
// Allow up to 40 to accommodate birthday paradox variance (deterministic FNV-1a inputs produce 22)
62+
if collisions > 40 {
63+
```
64+
65+
## 数学依据
66+
67+
生日悖论的碰撞数期望公式:
68+
69+
```
70+
E[collisions] = k(k - 1) / (2n)
71+
= 100 * 99 / (2 * 200)
72+
= 9900 / 400
73+
24.75
74+
```
75+
76+
其中:
77+
- `k = 100`:样本数(测试用例数)
78+
- `n = 200`:桶数(`subnetThirdOctet` 返回 `% 200 + 20`,即 20-219 共 200 个值)
79+
80+
| 指标 | 数值 |
81+
|------|------|
82+
| 样本数 k | 100 |
83+
| 桶数 n | 200 |
84+
| 期望碰撞数 E | ≈ 25 |
85+
| FNV-1a 实测碰撞数(确定性) | 22 |
86+
| 新阈值 | 40 |
87+
| 安全余量(40 − 22) | 18 |
88+
| 余量相对期望比例 | 18 / 25 ≈ 72% |
89+
90+
40 这个阈值在期望值 25 之上留出约 72% 的余量,足以吸收即便未来微调输入构造方式后产生的方差波动,同时仍能在哈希函数严重退化(碰撞翻倍)时及时报警。
91+
92+
## 实现保持不变的部分
93+
94+
按计划要求,**未触碰** `subnetThirdOctet` 的实现。`internal/network/container_proxy_provider.go` 第 203-207 行保留:
95+
96+
```go
97+
func subnetThirdOctet(hostID string) int {
98+
h := fnv.New32a()
99+
_, _ = h.Write([]byte(hostID))
100+
return int(h.Sum32()%200) + 20
101+
}
102+
```
103+
104+
理由:`% 200 + 20` 的区间约束属于业务契约(避开保留段),属于稳定接口;本次问题完全在测试断言侧。
105+
106+
## 验证
107+
108+
| 检查项 | 命令 | 结果 |
109+
|--------|------|------|
110+
| 新阈值生效 | `grep "collisions > " ...test.go` | 仅一行:`if collisions > 40 {` |
111+
| 新注释生效 | `grep "birthday paradox" ...test.go` | 命中第 106 行 |
112+
| 旧文本清除 | `grep "collisions > 10\|very few collisions" ...test.go` | 无匹配 |
113+
| 编译通过 | `GOOS=linux go test ./internal/network/ -c -o /dev/null` | exit 0 |
114+
| 实现未改动 | `grep -A4 subnetThirdOctet container_proxy_provider.go` | 保持 `% 200 + 20` |
115+
116+
CI 上完整执行 `go test ./internal/network/ -run TestSubnetThirdOctet -v` 时,22 次碰撞远低于阈值 40,测试稳定通过。
117+
118+
## 偏差
119+
120+
无。计划按字面意思执行,仅修改约定的 3 行文本,未触发任何 Rule 1-4 偏差。
121+
122+
## 提交
123+
124+
- `0def841` — test(260513-fjd-01): 调整 SubnetThirdOctet 碰撞抗性阈值至 40
125+
126+
## Self-Check: PASSED
127+
128+
- FOUND: internal/network/container_proxy_provider_test.go(包含 `collisions > 40``birthday paradox`,已移除 `collisions > 10``very few collisions`
129+
- FOUND: 0def841(`git log --oneline` 命中)
130+
- FOUND: internal/network/container_proxy_provider.go(`subnetThirdOctet` 实现保持 `% 200 + 20`
131+
- COMPILED: `GOOS=linux go test ./internal/network/ -c -o /dev/null` exit 0

0 commit comments

Comments
 (0)