带阿里标识的版本
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
//
|
||||
// HttpdnsNWHTTPClient_PoolManagementTests.m
|
||||
// AlicloudHttpDNSTests
|
||||
// TrustHttpDNSTests
|
||||
//
|
||||
// @author Created by Claude Code on 2025-11-01
|
||||
// Copyright © 2025 alibaba-inc.com. All rights reserved.
|
||||
// Copyright © 2025 trustapp.com. All rights reserved.
|
||||
//
|
||||
// 连接池管理测试 - 包含多端口隔离 (K)、端口池耗尽 (L)、池验证 (O)、空闲超时 (S) 测试组
|
||||
// 测试总数:16 个(K:5 + L:3 + O:3 + S:5)
|
||||
// 连接池管理测<EFBFBD><EFBFBD>?- 包含多端口隔<EFBFBD><EFBFBD>?(K)、端口池耗尽 (L)、池验证 (O)、空闲超<EFBFBD><EFBFBD>?(S) 测试<EFBFBD><EFBFBD>?
|
||||
// 测试总数<EFBFBD><EFBFBD>?6 个(K:5 + L:3 + O:3 + S:5<EFBFBD><EFBFBD>?
|
||||
//
|
||||
|
||||
#import "HttpdnsNWHTTPClientTestBase.h"
|
||||
@@ -17,9 +17,9 @@
|
||||
|
||||
@implementation HttpdnsNWHTTPClient_PoolManagementTests
|
||||
|
||||
#pragma mark - K. 多端口连接隔离测试
|
||||
#pragma mark - K. 多端口连接隔离测<EFBFBD><EFBFBD>?
|
||||
|
||||
// K.1 不同 HTTPS 端口使用不同连接池
|
||||
// K.1 不同 HTTPS 端口使用不同连接<EFBFBD><EFBFBD>?
|
||||
- (void)testMultiPort_DifferentHTTPSPorts_SeparatePoolKeys {
|
||||
XCTestExpectation *expectation = [self expectationWithDescription:@"Different ports use different pools"];
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
XCTAssertNotNil(response2, @"First request to port 11444 should succeed");
|
||||
XCTAssertEqual(response2.statusCode, 200);
|
||||
|
||||
// 再次请求端口 11443(应该复用之前的连接)
|
||||
// 再次请求端口 11443(应该复用之前的连接<EFBFBD><EFBFBD>?
|
||||
NSError *error3 = nil;
|
||||
HttpdnsNWHTTPClientResponse *response3 = [self.client performRequestWithURLString:@"https://127.0.0.1:11443/get"
|
||||
userAgent:@"Port11443Again"
|
||||
@@ -57,7 +57,7 @@
|
||||
[self waitForExpectations:@[expectation] timeout:50.0];
|
||||
}
|
||||
|
||||
// K.2 三个不同 HTTPS 端口的并发请求
|
||||
// K.2 三个不同 HTTPS 端口的并发请<EFBFBD><EFBFBD>?
|
||||
- (void)testMultiPort_ConcurrentThreePorts_AllSucceed {
|
||||
NSInteger requestsPerPort = 10;
|
||||
NSArray<NSNumber *> *ports = @[@11443, @11444, @11445];
|
||||
@@ -97,17 +97,17 @@
|
||||
XCTAssertEqual(successCount, ports.count * requestsPerPort, @"All 30 requests should succeed");
|
||||
}
|
||||
|
||||
// K.3 快速切换端口模式
|
||||
// K.3 快速切换端口模<EFBFBD><EFBFBD>?
|
||||
- (void)testMultiPort_SequentialPortSwitching_ConnectionReusePerPort {
|
||||
XCTestExpectation *expectation = [self expectationWithDescription:@"Sequential port switching"];
|
||||
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
NSArray<NSString *> *urls = @[
|
||||
@"https://127.0.0.1:11443/get", // 第一次访问 11443
|
||||
@"https://127.0.0.1:11444/get", // 第一次访问 11444
|
||||
@"https://127.0.0.1:11445/get", // 第一次访问 11445
|
||||
@"https://127.0.0.1:11443/get", // 第二次访问 11443(应复用)
|
||||
@"https://127.0.0.1:11444/get", // 第二次访问 11444(应复用)
|
||||
@"https://127.0.0.1:11443/get", // 第一次访<EFBFBD><EFBFBD>?11443
|
||||
@"https://127.0.0.1:11444/get", // 第一次访<EFBFBD><EFBFBD>?11444
|
||||
@"https://127.0.0.1:11445/get", // 第一次访<EFBFBD><EFBFBD>?11445
|
||||
@"https://127.0.0.1:11443/get", // 第二次访<EFBFBD><EFBFBD>?11443(应复用<EFBFBD><EFBFBD>?
|
||||
@"https://127.0.0.1:11444/get", // 第二次访<EFBFBD><EFBFBD>?11444(应复用<EFBFBD><EFBFBD>?
|
||||
];
|
||||
|
||||
NSMutableArray<NSNumber *> *responseTimes = [NSMutableArray array];
|
||||
@@ -140,7 +140,7 @@
|
||||
XCTestExpectation *expectation = [self expectationWithDescription:@"Per-port pool limits"];
|
||||
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
// 向端口 11443 发送 10 个请求
|
||||
// 向端<EFBFBD><EFBFBD>?11443 发<EFBFBD><EFBFBD>?10 个请<EFBFBD><EFBFBD>?
|
||||
for (NSInteger i = 0; i < 10; i++) {
|
||||
NSError *error = nil;
|
||||
HttpdnsNWHTTPClientResponse *response = [self.client performRequestWithURLString:@"https://127.0.0.1:11443/get"
|
||||
@@ -150,7 +150,7 @@
|
||||
XCTAssertTrue(response != nil || error != nil);
|
||||
}
|
||||
|
||||
// 向端口 11444 发送 10 个请求(应该有独立的池)
|
||||
// 向端<EFBFBD><EFBFBD>?11444 发<EFBFBD><EFBFBD>?10 个请求(应该有独立的池)
|
||||
for (NSInteger i = 0; i < 10; i++) {
|
||||
NSError *error = nil;
|
||||
HttpdnsNWHTTPClientResponse *response = [self.client performRequestWithURLString:@"https://127.0.0.1:11444/get"
|
||||
@@ -163,7 +163,7 @@
|
||||
// 等待连接归还
|
||||
[NSThread sleepForTimeInterval:1.0];
|
||||
|
||||
// 验证两个端口都仍然可用
|
||||
// 验证两个端口都仍然可<EFBFBD><EFBFBD>?
|
||||
NSError *error1 = nil;
|
||||
HttpdnsNWHTTPClientResponse *response1 = [self.client performRequestWithURLString:@"https://127.0.0.1:11443/get"
|
||||
userAgent:@"Verify11443"
|
||||
@@ -193,7 +193,7 @@
|
||||
NSInteger totalRequests = 20;
|
||||
NSInteger successCount = 0;
|
||||
|
||||
// 交错请求:依次循环访问所有端口
|
||||
// 交错请求:依次循环访问所有端<EFBFBD><EFBFBD>?
|
||||
for (NSInteger i = 0; i < totalRequests; i++) {
|
||||
NSNumber *port = ports[i % ports.count];
|
||||
NSString *urlString = [NSString stringWithFormat:@"https://127.0.0.1:%@/get", port];
|
||||
@@ -219,7 +219,7 @@
|
||||
|
||||
#pragma mark - L. 基于端口的池耗尽测试
|
||||
|
||||
// L.1 四个端口同时承载高负载
|
||||
// L.1 四个端口同时承载高负<EFBFBD><EFBFBD>?
|
||||
- (void)testPoolExhaustion_FourPortsSimultaneous_AllSucceed {
|
||||
NSInteger requestsPerPort = 10;
|
||||
NSArray<NSNumber *> *ports = @[@11443, @11444, @11445, @11446];
|
||||
@@ -229,7 +229,7 @@
|
||||
NSLock *successCountLock = [[NSLock alloc] init];
|
||||
__block NSInteger successCount = 0;
|
||||
|
||||
// 向 4 个端口各发起 10 个并发请求(共 40 个)
|
||||
// <EFBFBD><EFBFBD>?4 个端口各发起 10 个并发请求(<EFBFBD><EFBFBD>?40 个)
|
||||
for (NSNumber *port in ports) {
|
||||
for (NSInteger i = 0; i < requestsPerPort; i++) {
|
||||
XCTestExpectation *expectation = [self expectationWithDescription:[NSString stringWithFormat:@"Port %@ Request %ld", port, (long)i]];
|
||||
@@ -256,11 +256,11 @@
|
||||
|
||||
[self waitForExpectations:expectations timeout:80.0];
|
||||
|
||||
// 验证成功率 > 95%(允许少量因并发导致的失败)
|
||||
// 验证成功<EFBFBD><EFBFBD>?> 95%(允许少量因并发导致的失败)
|
||||
XCTAssertGreaterThan(successCount, 38, @"At least 95%% of 40 requests should succeed");
|
||||
}
|
||||
|
||||
// L.2 单个端口耗尽时其他端口不受影响
|
||||
// L.2 单个端口耗尽时其他端口不受影<EFBFBD><EFBFBD>?
|
||||
- (void)testPoolExhaustion_SinglePortExhausted_OthersUnaffected {
|
||||
NSMutableArray<XCTestExpectation *> *expectations = [NSMutableArray array];
|
||||
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
|
||||
@@ -268,7 +268,7 @@
|
||||
__block NSInteger port11444SuccessCount = 0;
|
||||
NSLock *countLock = [[NSLock alloc] init];
|
||||
|
||||
// 向端口 11443 发起 20 个并发请求(可能导致池耗尽)
|
||||
// 向端<EFBFBD><EFBFBD>?11443 发起 20 个并发请求(可能导致池耗尽<EFBFBD><EFBFBD>?
|
||||
for (NSInteger i = 0; i < 20; i++) {
|
||||
XCTestExpectation *expectation = [self expectationWithDescription:[NSString stringWithFormat:@"Exhaust11443 %ld", (long)i]];
|
||||
[expectations addObject:expectation];
|
||||
@@ -283,7 +283,7 @@
|
||||
});
|
||||
}
|
||||
|
||||
// 同时向端口 11444 发起 5 个请求(应该不受 11443 影响)
|
||||
// 同时向端<EFBFBD><EFBFBD>?11444 发起 5 个请求(应该不受 11443 影响<EFBFBD><EFBFBD>?
|
||||
for (NSInteger i = 0; i < 5; i++) {
|
||||
XCTestExpectation *expectation = [self expectationWithDescription:[NSString stringWithFormat:@"Port11444 %ld", (long)i]];
|
||||
[expectations addObject:expectation];
|
||||
@@ -316,7 +316,7 @@
|
||||
XCTAssertEqual(port11444SuccessCount, 5, @"All port 11444 requests should succeed despite 11443 load");
|
||||
}
|
||||
|
||||
// L.3 多端口使用后的连接清理
|
||||
// L.3 多端口使用后的连接清<EFBFBD><EFBFBD>?
|
||||
- (void)testPoolExhaustion_MultiPortCleanup_ExpiredConnectionsPruned {
|
||||
if (getenv("SKIP_SLOW_TESTS")) {
|
||||
return;
|
||||
@@ -327,7 +327,7 @@
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
NSArray<NSNumber *> *ports = @[@11443, @11444, @11445];
|
||||
|
||||
// 向三个端口各发起一个请求
|
||||
// 向三个端口各发起一个请<EFBFBD><EFBFBD>?
|
||||
for (NSNumber *port in ports) {
|
||||
NSString *urlString = [NSString stringWithFormat:@"https://127.0.0.1:%@/get", port];
|
||||
NSError *error = nil;
|
||||
@@ -338,7 +338,7 @@
|
||||
XCTAssertTrue(response != nil || error != nil);
|
||||
}
|
||||
|
||||
// 等待超过 30 秒,让所有连接过期
|
||||
// 等待超过 30 秒,让所有连接过<EFBFBD><EFBFBD>?
|
||||
[NSThread sleepForTimeInterval:31.0];
|
||||
|
||||
// 再次向三个端口发起请求(应该创建新连接)
|
||||
@@ -358,14 +358,14 @@
|
||||
[self waitForExpectations:@[expectation] timeout:80.0];
|
||||
}
|
||||
|
||||
#pragma mark - O. 连接池验证测试(使用新增的检查 API)
|
||||
#pragma mark - O. 连接池验证测试(使用新增的检<EFBFBD><EFBFBD>?API<EFBFBD><EFBFBD>?
|
||||
|
||||
// O.1 综合连接池验证 - 演示所有检查能力
|
||||
// O.1 综合连接池验<EFBFBD><EFBFBD>?- 演示所有检查能<EFBFBD><EFBFBD>?
|
||||
- (void)testPoolVerification_ComprehensiveCheck_AllAspectsVerified {
|
||||
[self.client resetPoolStatistics];
|
||||
NSString *poolKey = @"127.0.0.1:11080:tcp";
|
||||
|
||||
// 初始状态:无连接
|
||||
// 初始状态:无连<EFBFBD><EFBFBD>?
|
||||
XCTAssertEqual([self.client connectionPoolCountForKey:poolKey], 0,
|
||||
@"Pool should be empty initially");
|
||||
XCTAssertEqual([self.client totalConnectionCount], 0,
|
||||
@@ -375,7 +375,7 @@
|
||||
XCTAssertEqual(self.client.connectionReuseCount, 0,
|
||||
@"Reuse count should be 0 initially");
|
||||
|
||||
// 发送 5 个请求到同一端点
|
||||
// 发<EFBFBD><EFBFBD>?5 个请求到同一端点
|
||||
for (NSInteger i = 0; i < 5; i++) {
|
||||
NSError *error = nil;
|
||||
HttpdnsNWHTTPClientResponse *response = [self.client performRequestWithURLString:@"http://127.0.0.1:11080/get"
|
||||
@@ -386,7 +386,7 @@
|
||||
XCTAssertEqual(response.statusCode, 200, @"Request %ld should return 200", (long)i);
|
||||
}
|
||||
|
||||
// 验证连接池状态
|
||||
// 验证连接池状<EFBFBD><EFBFBD>?
|
||||
XCTAssertEqual([self.client connectionPoolCountForKey:poolKey], 1,
|
||||
@"Should have exactly 1 connection in pool for key: %@", poolKey);
|
||||
XCTAssertEqual([self.client totalConnectionCount], 1,
|
||||
@@ -398,7 +398,7 @@
|
||||
XCTAssertEqual(self.client.connectionReuseCount, 4,
|
||||
@"Should reuse connection 4 times");
|
||||
|
||||
// 验证连接复用率
|
||||
// 验证连接复用<EFBFBD><EFBFBD>?
|
||||
CGFloat reuseRate = (CGFloat)self.client.connectionReuseCount /
|
||||
(self.client.connectionCreationCount + self.client.connectionReuseCount);
|
||||
XCTAssertGreaterThanOrEqual(reuseRate, 0.8,
|
||||
@@ -417,11 +417,11 @@
|
||||
NSString *key11443 = @"127.0.0.1:11443:tls";
|
||||
NSString *key11444 = @"127.0.0.1:11444:tls";
|
||||
|
||||
// 初始:两个池都为空
|
||||
// 初始:两个池都为<EFBFBD><EFBFBD>?
|
||||
XCTAssertEqual([self.client connectionPoolCountForKey:key11443], 0);
|
||||
XCTAssertEqual([self.client connectionPoolCountForKey:key11444], 0);
|
||||
|
||||
// 向端口 11443 发送 3 个请求
|
||||
// 向端<EFBFBD><EFBFBD>?11443 发<EFBFBD><EFBFBD>?3 个请<EFBFBD><EFBFBD>?
|
||||
for (NSInteger i = 0; i < 3; i++) {
|
||||
NSError *error = nil;
|
||||
HttpdnsNWHTTPClientResponse *response = [self.client performRequestWithURLString:@"https://127.0.0.1:11443/get"
|
||||
@@ -431,13 +431,13 @@
|
||||
XCTAssertNotNil(response);
|
||||
}
|
||||
|
||||
// 验证端口 11443 的池状态
|
||||
// 验证端口 11443 的池状<EFBFBD><EFBFBD>?
|
||||
XCTAssertEqual([self.client connectionPoolCountForKey:key11443], 1,
|
||||
@"Port 11443 should have 1 connection");
|
||||
XCTAssertEqual([self.client connectionPoolCountForKey:key11444], 0,
|
||||
@"Port 11444 should still be empty");
|
||||
|
||||
// 向端口 11444 发送 3 个请求
|
||||
// 向端<EFBFBD><EFBFBD>?11444 发<EFBFBD><EFBFBD>?3 个请<EFBFBD><EFBFBD>?
|
||||
for (NSInteger i = 0; i < 3; i++) {
|
||||
NSError *error = nil;
|
||||
HttpdnsNWHTTPClientResponse *response = [self.client performRequestWithURLString:@"https://127.0.0.1:11444/get"
|
||||
@@ -455,7 +455,7 @@
|
||||
XCTAssertEqual([self.client totalConnectionCount], 2,
|
||||
@"Total should be 2 connections (one per port)");
|
||||
|
||||
// 验证统计:应该创建了 2 个连接,复用了 4 次
|
||||
// 验证统计:应该创建了 2 个连接,复用<EFBFBD><EFBFBD>?4 <EFBFBD><EFBFBD>?
|
||||
XCTAssertEqual(self.client.connectionCreationCount, 2,
|
||||
@"Should create 2 connections (one per port)");
|
||||
XCTAssertEqual(self.client.connectionReuseCount, 4,
|
||||
@@ -468,12 +468,12 @@
|
||||
XCTAssertTrue([allKeys containsObject:key11444], @"Should contain key for port 11444");
|
||||
}
|
||||
|
||||
// O.3 连接池容量限制验证
|
||||
// O.3 连接池容量限制验<EFBFBD><EFBFBD>?
|
||||
- (void)testPoolVerification_PoolCapacity_MaxFourConnections {
|
||||
[self.client resetPoolStatistics];
|
||||
NSString *poolKey = @"127.0.0.1:11080:tcp";
|
||||
|
||||
// 发送 10 个连续请求(每个请求都会归还连接到池)
|
||||
// 发<EFBFBD><EFBFBD>?10 个连续请求(每个请求都会归还连接到池<EFBFBD><EFBFBD>?
|
||||
for (NSInteger i = 0; i < 10; i++) {
|
||||
NSError *error = nil;
|
||||
HttpdnsNWHTTPClientResponse *response = [self.client performRequestWithURLString:@"http://127.0.0.1:11080/get"
|
||||
@@ -486,12 +486,12 @@
|
||||
// 等待连接归还
|
||||
[NSThread sleepForTimeInterval:1.0];
|
||||
|
||||
// 验证池大小不超过 4(kHttpdnsNWHTTPClientMaxIdleConnectionsPerKey)
|
||||
// 验证池大小不超过 4(kHttpdnsNWHTTPClientMaxIdleConnectionsPerKey<EFBFBD><EFBFBD>?
|
||||
NSUInteger poolSize = [self.client connectionPoolCountForKey:poolKey];
|
||||
XCTAssertLessThanOrEqual(poolSize, 4,
|
||||
@"Pool size should not exceed 4 (actual: %lu)", (unsigned long)poolSize);
|
||||
|
||||
// 验证统计:应该只创建了 1 个连接(因为串行请求,每次都复用)
|
||||
// 验证统计:应该只创建<EFBFBD><EFBFBD>?1 个连接(因为串行请求,每次都复用<EFBFBD><EFBFBD>?
|
||||
XCTAssertEqual(self.client.connectionCreationCount, 1,
|
||||
@"Should create only 1 connection for sequential requests");
|
||||
XCTAssertEqual(self.client.connectionReuseCount, 9,
|
||||
@@ -500,12 +500,12 @@
|
||||
|
||||
#pragma mark - S. 空闲超时详细测试
|
||||
|
||||
// S.1 混合过期和有效连接 - 选择性清理
|
||||
// S.1 混合过期和有效连<EFBFBD><EFBFBD>?- 选择性清<EFBFBD><EFBFBD>?
|
||||
- (void)testIdleTimeout_MixedExpiredValid_SelectivePruning {
|
||||
[self.client resetPoolStatistics];
|
||||
NSString *poolKey = @"127.0.0.1:11080:tcp";
|
||||
|
||||
// 创建第一个连接
|
||||
// 创建第一个连<EFBFBD><EFBFBD>?
|
||||
NSError *error1 = nil;
|
||||
HttpdnsNWHTTPClientResponse *response1 = [self.client performRequestWithURLString:@"http://127.0.0.1:11080/get"
|
||||
userAgent:@"ConnectionA"
|
||||
@@ -517,7 +517,7 @@
|
||||
// 等待连接归还
|
||||
[NSThread sleepForTimeInterval:0.5];
|
||||
|
||||
// 使用 DEBUG API 获取连接 A 并设置为过期(35 秒前)
|
||||
// 使用 DEBUG API 获取连接 A 并设置为过期<EFBFBD><EFBFBD>?5 秒前<EFBFBD><EFBFBD>?
|
||||
NSArray<HttpdnsNWReusableConnection *> *connections = [self.client connectionsInPoolForKey:poolKey];
|
||||
XCTAssertEqual(connections.count, 1, @"Should have 1 connection in pool");
|
||||
|
||||
@@ -525,7 +525,7 @@
|
||||
NSDate *expiredDate = [NSDate dateWithTimeIntervalSinceNow:-35.0];
|
||||
[connectionA debugSetLastUsedDate:expiredDate];
|
||||
|
||||
// 创建第二个连接(通过并发请求)
|
||||
// 创建第二个连接(通过并发请求<EFBFBD><EFBFBD>?
|
||||
NSError *error2 = nil;
|
||||
HttpdnsNWHTTPClientResponse *response2 = [self.client performRequestWithURLString:@"http://127.0.0.1:11080/get"
|
||||
userAgent:@"ConnectionB"
|
||||
@@ -536,12 +536,12 @@
|
||||
// 等待归还
|
||||
[NSThread sleepForTimeInterval:0.5];
|
||||
|
||||
// 验证:应该有 1 个连接(connectionA 过期被移除,connectionB 留下)
|
||||
// 验证:应该有 1 个连接(connectionA 过期被移除,connectionB 留下<EFBFBD><EFBFBD>?
|
||||
connections = [self.client connectionsInPoolForKey:poolKey];
|
||||
XCTAssertEqual(connections.count, 1,
|
||||
@"Should have only 1 connection (expired A removed, valid B kept)");
|
||||
|
||||
// 第三个请求应该复用 connectionB
|
||||
// 第三个请求应该复<EFBFBD><EFBFBD>?connectionB
|
||||
[self.client resetPoolStatistics];
|
||||
NSError *error3 = nil;
|
||||
HttpdnsNWHTTPClientResponse *response3 = [self.client performRequestWithURLString:@"http://127.0.0.1:11080/get"
|
||||
@@ -550,7 +550,7 @@
|
||||
error:&error3];
|
||||
XCTAssertNotNil(response3);
|
||||
|
||||
// 验证:复用了 connectionB(没有创建新连接)
|
||||
// 验证:复用了 connectionB(没有创建新连接<EFBFBD><EFBFBD>?
|
||||
XCTAssertEqual(self.client.connectionCreationCount, 0,
|
||||
@"Should not create new connection (reuse existing valid connection)");
|
||||
XCTAssertEqual(self.client.connectionReuseCount, 1,
|
||||
@@ -562,7 +562,7 @@
|
||||
[self.client resetPoolStatistics];
|
||||
NSString *poolKey = @"127.0.0.1:11080:tcp";
|
||||
|
||||
// 创建第一个连接
|
||||
// 创建第一个连<EFBFBD><EFBFBD>?
|
||||
NSError *error1 = nil;
|
||||
HttpdnsNWHTTPClientResponse *response1 = [self.client performRequestWithURLString:@"http://127.0.0.1:11080/get"
|
||||
userAgent:@"Initial"
|
||||
@@ -572,17 +572,17 @@
|
||||
|
||||
[NSThread sleepForTimeInterval:0.5];
|
||||
|
||||
// 借出连接并保持 inUse=YES
|
||||
// 借出连接并保<EFBFBD><EFBFBD>?inUse=YES
|
||||
NSArray<HttpdnsNWReusableConnection *> *connections = [self.client connectionsInPoolForKey:poolKey];
|
||||
XCTAssertEqual(connections.count, 1);
|
||||
|
||||
HttpdnsNWReusableConnection *conn = connections.firstObject;
|
||||
|
||||
// 手动设置为 60 秒前(远超 30 秒超时)
|
||||
// 手动设置<EFBFBD><EFBFBD>?60 秒前(远<EFBFBD><EFBFBD>?30 秒超时)
|
||||
NSDate *veryOldDate = [NSDate dateWithTimeIntervalSinceNow:-60.0];
|
||||
[conn debugSetLastUsedDate:veryOldDate];
|
||||
|
||||
// 将连接标记为使用中
|
||||
// 将连接标记为使用<EFBFBD><EFBFBD>?
|
||||
[conn debugSetInUse:YES];
|
||||
|
||||
// 触发清理(通过发起另一个并发请求)
|
||||
@@ -593,7 +593,7 @@
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
connectionsBefore = [self.client totalConnectionCount];
|
||||
|
||||
// 发起请求(会触发 pruneConnectionPool)
|
||||
// 发起请求(会触发 pruneConnectionPool<EFBFBD><EFBFBD>?
|
||||
NSError *error2 = nil;
|
||||
[self.client performRequestWithURLString:@"http://127.0.0.1:11080/get"
|
||||
userAgent:@"TriggerPrune"
|
||||
@@ -608,18 +608,18 @@
|
||||
|
||||
dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW, 20 * NSEC_PER_SEC));
|
||||
|
||||
// 清理:重置 inUse 状态
|
||||
// 清理:重<EFBFBD><EFBFBD>?inUse 状<EFBFBD><EFBFBD>?
|
||||
[conn debugSetInUse:NO];
|
||||
|
||||
// 验证:inUse=YES 的连接不应该被清理
|
||||
// connectionsBefore = 1 (旧连接), connectionsAfter = 2 (旧连接 + 新连接)
|
||||
// 验证:inUse=YES 的连接不应该被清<EFBFBD><EFBFBD>?
|
||||
// connectionsBefore = 1 (旧连<EFBFBD><EFBFBD>?, connectionsAfter = 2 (旧连<EFBFBD><EFBFBD>?+ 新连<EFBFBD><EFBFBD>?
|
||||
XCTAssertEqual(connectionsBefore, 1,
|
||||
@"Should have 1 connection before (in-use protected)");
|
||||
XCTAssertEqual(connectionsAfter, 2,
|
||||
@"Should have 2 connections after (in-use connection NOT pruned, new connection added)");
|
||||
}
|
||||
|
||||
// S.3 所有连接过期 - 批量清理
|
||||
// S.3 所有连接过<EFBFBD><EFBFBD>?- 批量清理
|
||||
- (void)testIdleTimeout_AllExpired_BulkPruning {
|
||||
[self.client resetPoolStatistics];
|
||||
NSString *poolKey = @"127.0.0.1:11080:tcp";
|
||||
@@ -645,21 +645,21 @@
|
||||
|
||||
[self waitForExpectations:expectations timeout:30.0];
|
||||
|
||||
// 等待所有连接归还
|
||||
// 等待所有连接归<EFBFBD><EFBFBD>?
|
||||
[NSThread sleepForTimeInterval:1.0];
|
||||
|
||||
// 验证池已满
|
||||
// 验证池已<EFBFBD><EFBFBD>?
|
||||
NSUInteger poolSizeBefore = [self.client connectionPoolCountForKey:poolKey];
|
||||
XCTAssertGreaterThan(poolSizeBefore, 0, @"Pool should have connections");
|
||||
|
||||
// 将所有连接设置为过期(31 秒前)
|
||||
// 将所有连接设置为过期<EFBFBD><EFBFBD>?1 秒前<EFBFBD><EFBFBD>?
|
||||
NSArray<HttpdnsNWReusableConnection *> *connections = [self.client connectionsInPoolForKey:poolKey];
|
||||
NSDate *expiredDate = [NSDate dateWithTimeIntervalSinceNow:-31.0];
|
||||
for (HttpdnsNWReusableConnection *conn in connections) {
|
||||
[conn debugSetLastUsedDate:expiredDate];
|
||||
}
|
||||
|
||||
// 发起新请求(触发批量清理)
|
||||
// 发起新请求(触发批量清理<EFBFBD><EFBFBD>?
|
||||
NSError *errorNew = nil;
|
||||
HttpdnsNWHTTPClientResponse *responseNew = [self.client performRequestWithURLString:@"http://127.0.0.1:11080/get"
|
||||
userAgent:@"AfterBulkExpiry"
|
||||
@@ -677,7 +677,7 @@
|
||||
@"Pool should have only 1 connection (new one after bulk pruning)");
|
||||
}
|
||||
|
||||
// S.4 过期后池状态验证
|
||||
// S.4 过期后池状态验<EFBFBD><EFBFBD>?
|
||||
- (void)testIdleTimeout_PoolStateAfterExpiry_DirectVerification {
|
||||
[self.client resetPoolStatistics];
|
||||
NSString *poolKey = @"127.0.0.1:11080:tcp";
|
||||
@@ -692,11 +692,11 @@
|
||||
|
||||
[NSThread sleepForTimeInterval:0.5];
|
||||
|
||||
// 验证连接在池中
|
||||
// 验证连接在池<EFBFBD><EFBFBD>?
|
||||
XCTAssertEqual([self.client connectionPoolCountForKey:poolKey], 1,
|
||||
@"Pool should have 1 connection");
|
||||
|
||||
// 设置连接为过期
|
||||
// 设置连接为过<EFBFBD><EFBFBD>?
|
||||
NSArray<HttpdnsNWReusableConnection *> *connections = [self.client connectionsInPoolForKey:poolKey];
|
||||
HttpdnsNWReusableConnection *conn = connections.firstObject;
|
||||
[conn debugSetLastUsedDate:[NSDate dateWithTimeIntervalSinceNow:-31.0]];
|
||||
@@ -711,7 +711,7 @@
|
||||
|
||||
[NSThread sleepForTimeInterval:0.5];
|
||||
|
||||
// 直接验证池状态:过期连接已被移除,新连接已加入
|
||||
// 直接验证池状态:过期连接已被移除,新连接已加<EFBFBD><EFBFBD>?
|
||||
NSUInteger poolSizeAfter = [self.client connectionPoolCountForKey:poolKey];
|
||||
XCTAssertEqual(poolSizeAfter, 1,
|
||||
@"Pool should have 1 connection (expired removed, new added)");
|
||||
@@ -721,7 +721,7 @@
|
||||
@"Should have created at least 1 new connection");
|
||||
}
|
||||
|
||||
// S.5 快速过期测试(无需等待)- 演示最佳实践
|
||||
// S.5 快速过期测试(无需等待<EFBFBD><EFBFBD>? 演示最佳实<EFBFBD><EFBFBD>?
|
||||
- (void)testIdleTimeout_FastExpiry_NoWaiting {
|
||||
[self.client resetPoolStatistics];
|
||||
NSString *poolKey = @"127.0.0.1:11080:tcp";
|
||||
@@ -740,7 +740,7 @@
|
||||
|
||||
[NSThread sleepForTimeInterval:0.5];
|
||||
|
||||
// 使用 DEBUG 辅助函数模拟 31 秒过期(无需实际等待)
|
||||
// 使用 DEBUG 辅助函数模拟 31 秒过期(无需实际等待<EFBFBD><EFBFBD>?
|
||||
NSArray<HttpdnsNWReusableConnection *> *connections = [self.client connectionsInPoolForKey:poolKey];
|
||||
XCTAssertEqual(connections.count, 1);
|
||||
|
||||
@@ -766,7 +766,7 @@
|
||||
|
||||
CFAbsoluteTime elapsed = CFAbsoluteTimeGetCurrent() - startTime;
|
||||
|
||||
// 关键验证:测试应该很快完成(< 5 秒),而非等待 30+ 秒
|
||||
// 关键验证:测试应该很快完成(< 5 秒),而非等待 30+ <EFBFBD><EFBFBD>?
|
||||
XCTAssertLessThan(elapsed, 5.0,
|
||||
@"Fast expiry test should complete quickly (%.1fs) without 30s wait", elapsed);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user