带阿里标识的版本
This commit is contained in:
@@ -2,10 +2,10 @@
|
||||
|
||||
## 问题描述
|
||||
|
||||
当前测试套件没有充分验证**超时与连接池交互**的"无形结果"(intangible outcomes),可能存在以下风险:
|
||||
当前测试套件没有充分验证**超时与连接池交互**<EFBFBD><EFBFBD>?无形结果"(intangible outcomes),可能存在以下风险<EFBFBD><EFBFBD>?
|
||||
- 超时后的连接泄漏
|
||||
- 连接池被超时连接污染
|
||||
- 连接池无法从超时中恢复
|
||||
- 连接池无法从超时中恢<EFBFBD><EFBFBD>?
|
||||
- 并发场景下部分超时影响整体池健康
|
||||
|
||||
---
|
||||
@@ -26,11 +26,11 @@ if (!rawResponse) {
|
||||
```objc
|
||||
if (shouldClose || connection.isInvalidated) {
|
||||
[connection invalidate]; // 取消底层 nw_connection
|
||||
[pool removeObject:connection]; // 从池中移除
|
||||
[pool removeObject:connection]; // 从池中移<EFBFBD><EFBFBD>?
|
||||
}
|
||||
```
|
||||
|
||||
**结论**:代码逻辑正确,超时连接**会被移除**而非留在池中。
|
||||
**结论**:代码逻辑正确,超时连<EFBFBD><EFBFBD>?*会被移除**而非留在池中<EFBFBD><EFBFBD>?
|
||||
|
||||
---
|
||||
|
||||
@@ -38,33 +38,33 @@ if (shouldClose || connection.isInvalidated) {
|
||||
|
||||
### 已有测试:`testIntegration_RequestTimeout_ReturnsError`
|
||||
|
||||
**验证内容:**
|
||||
- ✅ 超时返回 `nil` response
|
||||
- ✅ 超时设置 `error`
|
||||
**验证内容<EFBFBD><EFBFBD>?*
|
||||
- <EFBFBD><EFBFBD>?超时返回 `nil` response
|
||||
- <EFBFBD><EFBFBD>?超时设置 `error`
|
||||
|
||||
**未验证内容(缺失):**
|
||||
- ❌ 连接是否从池中移除
|
||||
- ❌ 池计数是否正确
|
||||
- ❌ 后续请求是否正常工作
|
||||
- ❌ 是否存在连接泄漏
|
||||
- ❌ 并发场景下部分超时的影响
|
||||
- <EFBFBD><EFBFBD>?连接是否从池中移<EFBFBD><EFBFBD>?
|
||||
- <EFBFBD><EFBFBD>?池计数是否正<EFBFBD><EFBFBD>?
|
||||
- <EFBFBD><EFBFBD>?后续请求是否正常工作
|
||||
- <EFBFBD><EFBFBD>?是否存在连接泄漏
|
||||
- <EFBFBD><EFBFBD>?并发场景下部分超时的影响
|
||||
|
||||
---
|
||||
|
||||
## 需要验证的"无形结果"
|
||||
|
||||
### 1. 单次超时后的池清理
|
||||
### 1. 单次超时后的池清<EFBFBD><EFBFBD>?
|
||||
|
||||
**场景**:
|
||||
1. 请求 A 超时(timeout=1s, endpoint=/delay/10)
|
||||
2. 验证池状态
|
||||
**场景**<EFBFBD><EFBFBD>?
|
||||
1. 请求 A 超时(timeout=1s, endpoint=/delay/10<EFBFBD><EFBFBD>?
|
||||
2. 验证池状<EFBFBD><EFBFBD>?
|
||||
|
||||
**应验证:**
|
||||
- Pool count = 0(连接已移除)
|
||||
- Pool count = 0(连接已移除<EFBFBD><EFBFBD>?
|
||||
- Total connection count 没有异常增长
|
||||
- 无连接泄漏
|
||||
- 无连接泄<EFBFBD><EFBFBD>?
|
||||
|
||||
**测试方法**:
|
||||
**测试方法**<EFBFBD><EFBFBD>?
|
||||
```objc
|
||||
[client resetPoolStatistics];
|
||||
|
||||
@@ -78,7 +78,7 @@ HttpdnsNWHTTPClientResponse *response = [client performRequestWithURLString:@"ht
|
||||
XCTAssertNil(response);
|
||||
XCTAssertNotNil(error);
|
||||
|
||||
// 验证池状态
|
||||
// 验证池状<EFBFBD><EFBFBD>?
|
||||
NSString *poolKey = @"127.0.0.1:11080:tcp";
|
||||
XCTAssertEqual([client connectionPoolCountForKey:poolKey], 0, @"Timed-out connection should be removed");
|
||||
XCTAssertEqual([client totalConnectionCount], 0, @"No connections should remain");
|
||||
@@ -88,72 +88,72 @@ XCTAssertEqual(client.connectionReuseCount, 0, @"No reuse for timed-out connecti
|
||||
|
||||
---
|
||||
|
||||
### 2. 超时后的池恢复能力
|
||||
### 2. 超时后的池恢复能<EFBFBD><EFBFBD>?
|
||||
|
||||
**场景**:
|
||||
**场景**<EFBFBD><EFBFBD>?
|
||||
1. 请求 A 超时
|
||||
2. 请求 B 正常(验证池恢复)
|
||||
3. 请求 C 复用 B 的连接
|
||||
2. 请求 B 正常(验证池恢复<EFBFBD><EFBFBD>?
|
||||
3. 请求 C 复用 B 的连<EFBFBD><EFBFBD>?
|
||||
|
||||
**应验证:**
|
||||
- 请求 B 成功(池已恢复)
|
||||
- 请求 C 复用连接(connectionReuseCount = 1)
|
||||
- Pool count = 1(只有 B/C 的连接)
|
||||
- 请求 C 复用连接(connectionReuseCount = 1<EFBFBD><EFBFBD>?
|
||||
- Pool count = 1(只<EFBFBD><EFBFBD>?B/C 的连接)
|
||||
|
||||
---
|
||||
|
||||
### 3. 并发场景:部分超时不影响成功请求
|
||||
|
||||
**场景**:
|
||||
1. 并发发起 10 个请求
|
||||
2. 5 个正常(timeout=15s)
|
||||
3. 5 个超时(timeout=0.5s, endpoint=/delay/10)
|
||||
**场景**<EFBFBD><EFBFBD>?
|
||||
1. 并发发起 10 个请<EFBFBD><EFBFBD>?
|
||||
2. 5 个正常(timeout=15s<EFBFBD><EFBFBD>?
|
||||
3. 5 个超时(timeout=0.5s, endpoint=/delay/10<EFBFBD><EFBFBD>?
|
||||
|
||||
**应验证:**
|
||||
- 5 个正常请求成功
|
||||
- 5 个超时请求失败
|
||||
- Pool count ≤ 5(只保留成功的连接)
|
||||
- Total connection count ≤ 5(无泄漏)
|
||||
- connectionCreationCount ≤ 10(合理范围)
|
||||
- 成功的请求可以复用连接
|
||||
- 5 个正常请求成<EFBFBD><EFBFBD>?
|
||||
- 5 个超时请求失<EFBFBD><EFBFBD>?
|
||||
- Pool count <EFBFBD><EFBFBD>?5(只保留成功的连接)
|
||||
- Total connection count <EFBFBD><EFBFBD>?5(无泄漏<EFBFBD><EFBFBD>?
|
||||
- connectionCreationCount <EFBFBD><EFBFBD>?10(合理范围)
|
||||
- 成功的请求可以复用连<EFBFBD><EFBFBD>?
|
||||
|
||||
---
|
||||
|
||||
### 4. 连续超时不导致资源泄漏
|
||||
### 4. 连续超时不导致资源泄<EFBFBD><EFBFBD>?
|
||||
|
||||
**场景**:
|
||||
1. 连续 20 次超时请求
|
||||
2. 验证连接池没有累积"僵尸连接"
|
||||
**场景**<EFBFBD><EFBFBD>?
|
||||
1. 连续 20 次超时请<EFBFBD><EFBFBD>?
|
||||
2. 验证连接池没有累<EFBFBD><EFBFBD>?僵尸连接"
|
||||
|
||||
**应验证:**
|
||||
- Pool count = 0
|
||||
- Total connection count = 0
|
||||
- connectionCreationCount = 20(每次都创建新连接,因为超时的被移除)
|
||||
- connectionCreationCount = 20(每次都创建新连接,因为超时的被移除<EFBFBD><EFBFBD>?
|
||||
- connectionReuseCount = 0(超时连接不可复用)
|
||||
- 无内存泄漏(虽然代码层面无法直接测试)
|
||||
- 无内存泄漏(虽然代码层面无法直接测试<EFBFBD><EFBFBD>?
|
||||
|
||||
---
|
||||
|
||||
### 5. 超时不阻塞连接池
|
||||
|
||||
**场景**:
|
||||
1. 请求 A 超时(endpoint=/delay/10, timeout=1s)
|
||||
2. 同时请求 B 正常(endpoint=/get, timeout=15s)
|
||||
**场景**<EFBFBD><EFBFBD>?
|
||||
1. 请求 A 超时(endpoint=/delay/10, timeout=1s<EFBFBD><EFBFBD>?
|
||||
2. 同时请求 B 正常(endpoint=/get, timeout=15s<EFBFBD><EFBFBD>?
|
||||
|
||||
**应验证:**
|
||||
- 请求 A 和 B 并发执行(不互相阻塞)
|
||||
- 请求 B 成功(不受 A 超时影响)
|
||||
- 请求 A <EFBFBD><EFBFBD>?B 并发执行(不互相阻塞<EFBFBD><EFBFBD>?
|
||||
- 请求 B 成功(不<EFBFBD><EFBFBD>?A 超时影响<EFBFBD><EFBFBD>?
|
||||
- 请求 A 的超时连接被正确移除
|
||||
- Pool 中只有请求 B 的连接
|
||||
- Pool 中只有请<EFBFBD><EFBFBD>?B 的连<EFBFBD><EFBFBD>?
|
||||
|
||||
---
|
||||
|
||||
### 6. 多端口场景下的超时隔离
|
||||
### 6. 多端口场景下的超时隔<EFBFBD><EFBFBD>?
|
||||
|
||||
**场景**:
|
||||
**场景**<EFBFBD><EFBFBD>?
|
||||
1. 端口 11443 请求超时
|
||||
2. 端口 11444 请求正常
|
||||
3. 验证端口间隔离
|
||||
3. 验证端口间隔<EFBFBD><EFBFBD>?
|
||||
|
||||
**应验证:**
|
||||
- 端口 11443 pool count = 0
|
||||
@@ -175,52 +175,52 @@ XCTAssertEqual(client.connectionReuseCount, 0, @"No reuse for timed-out connecti
|
||||
**P.3 并发部分超时**
|
||||
- `testTimeout_ConcurrentPartialTimeout_SuccessfulRequestsReuse`
|
||||
|
||||
**P.4 连续超时无泄漏**
|
||||
**P.4 连续超时无泄<EFBFBD><EFBFBD>?*
|
||||
- `testTimeout_ConsecutiveTimeouts_NoConnectionLeak`
|
||||
|
||||
**P.5 超时不阻塞池**
|
||||
- `testTimeout_NonBlocking_ConcurrentNormalRequestSucceeds`
|
||||
|
||||
**P.6 多端口超时隔离**
|
||||
**P.6 多端口超时隔<EFBFBD><EFBFBD>?*
|
||||
- `testTimeout_MultiPort_IsolatedPoolCleaning`
|
||||
|
||||
---
|
||||
|
||||
## Mock Server 支持
|
||||
|
||||
需要添加可配置延迟的 endpoint:
|
||||
- `/delay/10` - 延迟 10 秒(已有)
|
||||
- 测试时设置短 timeout(如 0.5s-2s)触发超时
|
||||
需要添加可配置延迟<EFBFBD><EFBFBD>?endpoint<EFBFBD><EFBFBD>?
|
||||
- `/delay/10` - 延迟 10 秒(已有<EFBFBD><EFBFBD>?
|
||||
- 测试时设置短 timeout(如 0.5s-2s)触发超<EFBFBD><EFBFBD>?
|
||||
|
||||
---
|
||||
|
||||
## 预期测试结果
|
||||
|
||||
| 验证项 | 当前状态 | 目标状态 |
|
||||
| 验证<EFBFBD><EFBFBD>?| 当前状<EFBFBD><EFBFBD>?| 目标状<EFBFBD><EFBFBD>?|
|
||||
|--------|---------|---------|
|
||||
| 超时连接移除 | 未验证 | ✅ 验证池计数=0 |
|
||||
| 池恢复能力 | 未验证 | ✅ 后续请求成功 |
|
||||
| 并发超时隔离 | 未验证 | ✅ 成功请求不受影响 |
|
||||
| 无连接泄漏 | 未验证 | ✅ 总连接数稳定 |
|
||||
| 超时不阻塞 | 未验证 | ✅ 并发执行不阻塞 |
|
||||
| 多端口隔离 | 未验证 | ✅ 端口间独立清理 |
|
||||
| 超时连接移除 | 未验<EFBFBD><EFBFBD>?| <20><>?验证池计<EFBFBD><EFBFBD>?0 |
|
||||
| 池恢复能<EFBFBD><EFBFBD>?| 未验<EFBFBD><EFBFBD>?| <20><>?后续请求成功 |
|
||||
| 并发超时隔离 | 未验<EFBFBD><EFBFBD>?| <20><>?成功请求不受影响 |
|
||||
| 无连接泄<EFBFBD><EFBFBD>?| 未验<EFBFBD><EFBFBD>?| <20><>?总连接数稳定 |
|
||||
| 超时不阻<EFBFBD><EFBFBD>?| 未验<EFBFBD><EFBFBD>?| <20><>?并发执行不阻<EFBFBD><EFBFBD>?|
|
||||
| 多端口隔<EFBFBD><EFBFBD>?| 未验<EFBFBD><EFBFBD>?| <20><>?端口间独立清<EFBFBD><EFBFBD>?|
|
||||
|
||||
---
|
||||
|
||||
## 风险评估
|
||||
|
||||
**如果不测试这些场景的风险:**
|
||||
1. **连接泄漏**:超时连接可能未正确清理,导致内存泄漏
|
||||
2. **池污染**:超时连接留在池中,被后续请求复用导致失败
|
||||
**如果不测试这些场景的风险<EFBFBD><EFBFBD>?*
|
||||
1. **连接泄漏**:超时连接可能未正确清理,导致内存泄<EFBFBD><EFBFBD>?
|
||||
2. **池污<EFBFBD><EFBFBD>?*:超时连接留在池中,被后续请求复用导致失<EFBFBD><EFBFBD>?
|
||||
3. **级联故障**:部分超时影响整体连接池健康
|
||||
4. **资源耗尽**:连续超时累积连接,最终耗尽系统资源
|
||||
|
||||
**当前代码逻辑正确性:** ✅ 高(代码分析显示正确处理)
|
||||
**测试验证覆盖率:** ❌ 低(缺少池交互验证)
|
||||
**当前代码逻辑正确性:** <EFBFBD><EFBFBD>?高(代码分析显示正确处理<EFBFBD><EFBFBD>?
|
||||
**测试验证覆盖率:** <EFBFBD><EFBFBD>?低(缺少池交互验证)
|
||||
|
||||
**建议:** 添加 P 组测试以提供**可观测的证据**证明超时处理正确。
|
||||
**建议<EFBFBD><EFBFBD>?* 添加 P 组测试以提供**可观测的证据**证明超时处理正确<EFBFBD><EFBFBD>?
|
||||
|
||||
---
|
||||
|
||||
**创建时间**: 2025-11-01
|
||||
**维护者**: Claude Code
|
||||
**维护<EFBFBD><EFBFBD>?*: Claude Code
|
||||
|
||||
Reference in New Issue
Block a user