带阿里标识的版本

This commit is contained in:
robin
2026-02-28 18:55:33 +08:00
parent 150799f41d
commit 5d0b7c7e91
477 changed files with 10813 additions and 4044 deletions

View File

@@ -1,12 +1,12 @@
//
// HttpdnsNWHTTPClient_EdgeCasesAndTimeoutTests.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.
//
// - (M) (P) Connection (R)
// 15 M:4 + P:6 + R:5
// <EFBFBD><EFBFBD>?- (M)<EFBFBD><EFBFBD>?(P) <EFBFBD><EFBFBD>?Connection (R) <EFBFBD><EFBFBD>?
// <EFBFBD><EFBFBD>?5 M:4 + P:6 + R:5<EFBFBD><EFBFBD>?
//
#import "HttpdnsNWHTTPClientTestBase.h"
@@ -17,14 +17,14 @@
@implementation HttpdnsNWHTTPClient_EdgeCasesAndTimeoutTests
#pragma mark - M.
#pragma mark - M. <EFBFBD><EFBFBD>?
// M.1
- (void)testEdgeCase_ConnectionReuseWithinPortOnly_NotAcross {
XCTestExpectation *expectation = [self expectationWithDescription:@"Reuse boundaries"];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// A 11443
// A <EFBFBD><EFBFBD>?11443
CFAbsoluteTime timeA = CFAbsoluteTimeGetCurrent();
NSError *errorA = nil;
HttpdnsNWHTTPClientResponse *responseA = [self.client performRequestWithURLString:@"https://127.0.0.1:11443/get"
@@ -34,7 +34,7 @@
CFAbsoluteTime elapsedA = CFAbsoluteTimeGetCurrent() - timeA;
XCTAssertNotNil(responseA);
// B 11443
// B <EFBFBD><EFBFBD>?11443<EFBFBD><EFBFBD>?
CFAbsoluteTime timeB = CFAbsoluteTimeGetCurrent();
NSError *errorB = nil;
HttpdnsNWHTTPClientResponse *responseB = [self.client performRequestWithURLString:@"https://127.0.0.1:11443/get"
@@ -44,7 +44,7 @@
CFAbsoluteTime elapsedB = CFAbsoluteTimeGetCurrent() - timeB;
XCTAssertNotNil(responseB);
// C 11444
// C <EFBFBD><EFBFBD>?11444<EFBFBD><EFBFBD>?
CFAbsoluteTime timeC = CFAbsoluteTimeGetCurrent();
NSError *errorC = nil;
HttpdnsNWHTTPClientResponse *responseC = [self.client performRequestWithURLString:@"https://127.0.0.1:11444/get"
@@ -54,7 +54,7 @@
CFAbsoluteTime elapsedC = CFAbsoluteTimeGetCurrent() - timeC;
XCTAssertNotNil(responseC);
// D 11444 11444
// D <EFBFBD><EFBFBD>?11444<EFBFBD><EFBFBD>?11444
CFAbsoluteTime timeD = CFAbsoluteTimeGetCurrent();
NSError *errorD = nil;
HttpdnsNWHTTPClientResponse *responseD = [self.client performRequestWithURLString:@"https://127.0.0.1:11444/get"
@@ -76,14 +76,14 @@
[self waitForExpectations:@[expectation] timeout:70.0];
}
// M.2
// M.2 <EFBFBD><EFBFBD>?
- (void)testEdgeCase_HighPortCount_AllPortsManaged {
XCTestExpectation *expectation = [self expectationWithDescription:@"High port count"];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSArray<NSNumber *> *ports = @[@11443, @11444, @11445, @11446];
//
// <EFBFBD><EFBFBD>?
for (NSNumber *port in ports) {
NSString *urlString = [NSString stringWithFormat:@"https://127.0.0.1:%@/get", port];
NSError *error = nil;
@@ -94,7 +94,7 @@
XCTAssertNotNil(response, @"First round request to port %@ should succeed", port);
}
//
// <EFBFBD><EFBFBD>?
for (NSNumber *port in ports) {
NSString *urlString = [NSString stringWithFormat:@"https://127.0.0.1:%@/get", port];
NSError *error = nil;
@@ -111,7 +111,7 @@
[self waitForExpectations:@[expectation] timeout:120.0];
}
// M.3 访
// M.3 访<EFBFBD><EFBFBD>?
- (void)testEdgeCase_ConcurrentPoolAccess_NoDataRace {
NSMutableArray<XCTestExpectation *> *expectations = [NSMutableArray array];
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
@@ -119,7 +119,7 @@
NSArray<NSNumber *> *ports = @[@11443, @11444, @11445];
NSInteger requestsPerPort = 5;
//
// <EFBFBD><EFBFBD>?
for (NSNumber *port in ports) {
for (NSInteger i = 0; i < requestsPerPort; i++) {
XCTestExpectation *expectation = [self expectationWithDescription:[NSString stringWithFormat:@"Port %@ Req %ld", port, (long)i]];
@@ -132,7 +132,7 @@
userAgent:@"ConcurrentAccess"
timeout:15.0
error:&error];
// 访
// 访<EFBFBD><EFBFBD>?
XCTAssertTrue(response != nil || error != nil);
[expectation fulfill];
});
@@ -160,7 +160,7 @@
error:&error];
}
// 2 11444
// 2 11444<EFBFBD><EFBFBD>?
for (NSInteger i = 0; i < 5; i++) {
NSError *error = nil;
[self.client performRequestWithURLString:@"https://127.0.0.1:11444/get"
@@ -169,10 +169,10 @@
error:&error];
}
// 30 11443
// 30 <EFBFBD><EFBFBD>?11443 <EFBFBD><EFBFBD>?
[NSThread sleepForTimeInterval:31.0];
// 3 11444
// 3<EFBFBD><EFBFBD>?11444
NSError *error1 = nil;
HttpdnsNWHTTPClientResponse *response1 = [self.client performRequestWithURLString:@"https://127.0.0.1:11444/get"
userAgent:@"Port11444After"
@@ -180,7 +180,7 @@
error:&error1];
XCTAssertNotNil(response1, @"Port 11444 should still work after 11443 expired");
// 4 11443
// 4<EFBFBD><EFBFBD>?11443 <EFBFBD><EFBFBD>?
NSError *error2 = nil;
HttpdnsNWHTTPClientResponse *response2 = [self.client performRequestWithURLString:@"https://127.0.0.1:11443/get"
userAgent:@"Port11443New"
@@ -201,11 +201,11 @@
[self.client resetPoolStatistics];
NSString *poolKey = @"127.0.0.1:11080:tcp";
//
// <EFBFBD><EFBFBD>?
XCTAssertEqual([self.client connectionPoolCountForKey:poolKey], 0,
@"Pool should be empty initially");
// delay 10s, timeout 1s
// delay 10s, timeout 1s<EFBFBD><EFBFBD>?
NSError *error = nil;
HttpdnsNWHTTPClientResponse *response = [self.client performRequestWithURLString:@"http://127.0.0.1:11080/delay/10"
userAgent:@"TimeoutTest"
@@ -219,7 +219,7 @@
// returnConnection
[NSThread sleepForTimeInterval:0.5];
//
// <EFBFBD><EFBFBD>?
XCTAssertEqual([self.client connectionPoolCountForKey:poolKey], 0,
@"Timed-out connection should be removed from pool");
XCTAssertEqual([self.client totalConnectionCount], 0,
@@ -261,7 +261,7 @@
// returnConnection
[NSThread sleepForTimeInterval:0.5];
// 1
// <EFBFBD><EFBFBD>?1
XCTAssertEqual([self.client connectionPoolCountForKey:poolKey], 1,
@"Pool should have 1 connection from second request");
@@ -274,14 +274,14 @@
XCTAssertNotNil(response3);
XCTAssertEqual(response3.statusCode, 200);
// 1 + 1 + 1
// <EFBFBD><EFBFBD>? + 1 <EFBFBD><EFBFBD>? 1 <EFBFBD><EFBFBD>?
XCTAssertEqual(self.client.connectionCreationCount, 2,
@"Should have created 2 connections (1 timed out, 1 succeeded)");
XCTAssertEqual(self.client.connectionReuseCount, 1,
@"Third request should reuse second's connection");
}
// P.3
// P.3 <EFBFBD><EFBFBD>?
- (void)testTimeout_ConcurrentPartialTimeout_SuccessfulRequestsReuse {
[self.client resetPoolStatistics];
NSString *poolKey = @"127.0.0.1:11080:tcp";
@@ -294,7 +294,7 @@
__block NSInteger successCount = 0;
__block NSInteger timeoutCount = 0;
// 10 5 5
// 10 5 5 <EFBFBD><EFBFBD>?
for (NSInteger i = 0; i < 10; i++) {
XCTestExpectation *expectation = [self expectationWithDescription:[NSString stringWithFormat:@"Request %ld", (long)i]];
[expectations addObject:expectation];
@@ -305,11 +305,11 @@
NSTimeInterval timeout;
if (i % 2 == 0) {
//
// <EFBFBD><EFBFBD>?
urlString = @"http://127.0.0.1:11080/get";
timeout = 15.0;
} else {
//
// <EFBFBD><EFBFBD>?
urlString = @"http://127.0.0.1:11080/delay/10";
timeout = 0.5;
}
@@ -339,7 +339,7 @@
XCTAssertEqual(successCount, 5, @"5 requests should succeed");
XCTAssertEqual(timeoutCount, 5, @"5 requests should timeout");
// 5 + 5 = 10
// 5<EFBFBD><EFBFBD>?+ 5<EFBFBD><EFBFBD>?= <EFBFBD><EFBFBD>?0
XCTAssertGreaterThan(self.client.connectionCreationCount, 0,
@"Should have created connections for concurrent requests");
XCTAssertLessThanOrEqual(self.client.connectionCreationCount, 10,
@@ -348,8 +348,8 @@
//
[NSThread sleepForTimeInterval:2.0];
// -
// remote close
// <EFBFBD><EFBFBD>? <EFBFBD><EFBFBD>?
// remote close<EFBFBD><EFBFBD>?
XCTAssertLessThanOrEqual([self.client totalConnectionCount], 4,
@"Total connections should not exceed pool limit (no leak)");
@@ -363,12 +363,12 @@
XCTAssertEqual(recoveryResponse.statusCode, 200, @"Recovery request should succeed");
}
// P.4
// P.4 <EFBFBD><EFBFBD>?
- (void)testTimeout_ConsecutiveTimeouts_NoConnectionLeak {
[self.client resetPoolStatistics];
NSString *poolKey = @"127.0.0.1:11080:tcp";
// 10
// 10 <EFBFBD><EFBFBD>?
for (NSInteger i = 0; i < 10; i++) {
NSError *error = nil;
HttpdnsNWHTTPClientResponse *response = [self.client performRequestWithURLString:@"http://127.0.0.1:11080/delay/10"
@@ -381,13 +381,13 @@
[NSThread sleepForTimeInterval:0.2];
}
//
// <EFBFBD><EFBFBD>?
XCTAssertEqual([self.client connectionPoolCountForKey:poolKey], 0,
@"Pool should be empty after consecutive timeouts");
XCTAssertEqual([self.client totalConnectionCount], 0,
@"No connections should leak");
//
// <EFBFBD><EFBFBD>?
XCTAssertEqual(self.client.connectionCreationCount, 10,
@"Should have created 10 connections (all timed out and removed)");
XCTAssertEqual(self.client.connectionReuseCount, 0,
@@ -403,7 +403,7 @@
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// Adelay 10s, timeout 2s
// Adelay 10s, timeout 2s<EFBFBD><EFBFBD>?
dispatch_async(queue, ^{
NSError *error = nil;
HttpdnsNWHTTPClientResponse *response = [self.client performRequestWithURLString:@"http://127.0.0.1:11080/delay/10"
@@ -414,9 +414,9 @@
[timeoutExpectation fulfill];
});
// B A
// B A <EFBFBD><EFBFBD>?
dispatch_async(queue, ^{
// A
// <EFBFBD><EFBFBD>?A <EFBFBD><EFBFBD>?
[NSThread sleepForTimeInterval:0.1];
CFAbsoluteTime startTime = CFAbsoluteTimeGetCurrent();
@@ -430,7 +430,7 @@
XCTAssertNotNil(response, @"Request B should succeed despite A timing out");
XCTAssertEqual(response.statusCode, 200);
// B A
// B <EFBFBD><EFBFBD>?A
XCTAssertLessThan(elapsed, 5.0,
@"Request B should complete quickly, not blocked by A's timeout");
@@ -442,20 +442,20 @@
//
[NSThread sleepForTimeInterval:0.5];
// B
// B <EFBFBD><EFBFBD>?
NSString *poolKey = @"127.0.0.1:11080:tcp";
XCTAssertEqual([self.client connectionPoolCountForKey:poolKey], 1,
@"Pool should have 1 connection from successful request B");
}
// P.6
// P.6 <EFBFBD><EFBFBD>?
- (void)testTimeout_MultiPort_IsolatedPoolCleaning {
[self.client resetPoolStatistics];
NSString *poolKey11443 = @"127.0.0.1:11443:tls";
NSString *poolKey11444 = @"127.0.0.1:11444:tls";
// 11443
// 11443<EFBFBD><EFBFBD>?
NSError *error1 = nil;
HttpdnsNWHTTPClientResponse *response1 = [self.client performRequestWithURLString:@"https://127.0.0.1:11443/delay/10"
userAgent:@"Port11443Timeout"
@@ -463,7 +463,7 @@
error:&error1];
XCTAssertNil(response1, @"Port 11443 request should timeout");
// 11444
// 11444<EFBFBD><EFBFBD>?
NSError *error2 = nil;
HttpdnsNWHTTPClientResponse *response2 = [self.client performRequestWithURLString:@"https://127.0.0.1:11444/get"
userAgent:@"Port11444Success"
@@ -475,7 +475,7 @@
//
[NSThread sleepForTimeInterval:0.5];
// 11443 11444 1
// <EFBFBD><EFBFBD>?11443 11444 <EFBFBD><EFBFBD>?1 <EFBFBD><EFBFBD>?
XCTAssertEqual([self.client connectionPoolCountForKey:poolKey11443], 0,
@"Port 11443 pool should be empty (timed out)");
XCTAssertEqual([self.client connectionPoolCountForKey:poolKey11444], 1,
@@ -485,7 +485,7 @@
XCTAssertEqual([self.client totalConnectionCount], 1,
@"Total should be 1 (only from port 11444)");
// 11444
// 11444<EFBFBD><EFBFBD>?
NSError *error3 = nil;
HttpdnsNWHTTPClientResponse *response3 = [self.client performRequestWithURLString:@"https://127.0.0.1:11444/get"
userAgent:@"Port11444Reuse"
@@ -501,7 +501,7 @@
#pragma mark - R. Connection
// R.1 Connection: close
// R.1 Connection: close <EFBFBD><EFBFBD>?
- (void)testConnectionHeader_Close_ConnectionInvalidated {
[self.client resetPoolStatistics];
NSString *poolKey = @"127.0.0.1:11080:tcp";
@@ -522,7 +522,7 @@
XCTAssertEqual([self.client connectionPoolCountForKey:poolKey], 0,
@"Connection with 'Connection: close' header should be invalidated and not returned to pool");
// 2
// 2<EFBFBD><EFBFBD>?
NSError *error2 = nil;
HttpdnsNWHTTPClientResponse *response2 = [self.client performRequestWithURLString:@"http://127.0.0.1:11080/connection-test?mode=keep-alive"
userAgent:@"KeepAliveTest"
@@ -531,7 +531,7 @@
XCTAssertNotNil(response2);
XCTAssertEqual(response2.statusCode, 200);
// 2 close
// 2 close<EFBFBD><EFBFBD>?
XCTAssertEqual(self.client.connectionCreationCount, 2,
@"Should have created 2 connections (first closed by server)");
XCTAssertEqual(self.client.connectionReuseCount, 0,
@@ -559,7 +559,7 @@
XCTAssertEqual([self.client connectionPoolCountForKey:poolKey], 1,
@"Connection with 'Connection: keep-alive' should be returned to pool");
// 2
// 2<EFBFBD><EFBFBD>?
NSError *error2 = nil;
HttpdnsNWHTTPClientResponse *response2 = [self.client performRequestWithURLString:@"http://127.0.0.1:11080/connection-test?mode=keep-alive"
userAgent:@"KeepAlive2"
@@ -568,7 +568,7 @@
XCTAssertNotNil(response2);
XCTAssertEqual(response2.statusCode, 200);
// 1
// <EFBFBD><EFBFBD>?1 <EFBFBD><EFBFBD>?
XCTAssertEqual(self.client.connectionCreationCount, 1,
@"Should have created only 1 connection");
XCTAssertEqual(self.client.connectionReuseCount, 1,
@@ -592,7 +592,7 @@
// returnConnection
[NSThread sleepForTimeInterval:0.5];
// Proxy-Connection: close
// Proxy-Connection: close <EFBFBD><EFBFBD>?
XCTAssertEqual([self.client connectionPoolCountForKey:poolKey], 0,
@"Connection with 'Proxy-Connection: close' header should be invalidated");
@@ -605,7 +605,7 @@
XCTAssertNotNil(response2);
XCTAssertEqual(response2.statusCode, 200);
// 2
// 2 <EFBFBD><EFBFBD>?
XCTAssertEqual(self.client.connectionCreationCount, 2,
@"Should have created 2 connections (first closed by proxy header)");
XCTAssertEqual(self.client.connectionReuseCount, 0,
@@ -617,7 +617,7 @@
[self.client resetPoolStatistics];
NSString *poolKey = @"127.0.0.1:11080:tcp";
// 1CONNECTION: CLOSE ()
// 1CONNECTION: CLOSE (<EFBFBD><EFBFBD>?
NSError *error1 = nil;
HttpdnsNWHTTPClientResponse *response1 = [self.client performRequestWithURLString:@"http://127.0.0.1:11080/connection-test?mode=close-uppercase"
userAgent:@"UppercaseTest"
@@ -628,11 +628,11 @@
[NSThread sleepForTimeInterval:0.5];
// CLOSE
// CLOSE <EFBFBD><EFBFBD>?
XCTAssertEqual([self.client connectionPoolCountForKey:poolKey], 0,
@"'CONNECTION: CLOSE' (uppercase) should also close connection");
// 2Connection: Close ()
// 2Connection: Close (<EFBFBD><EFBFBD>?
NSError *error2 = nil;
HttpdnsNWHTTPClientResponse *response2 = [self.client performRequestWithURLString:@"http://127.0.0.1:11080/connection-test?mode=close-mixed"
userAgent:@"MixedCaseTest"
@@ -654,7 +654,7 @@
@"No reuse for any closed connections");
}
// R.5 close keep-alive
// R.5 <EFBFBD><EFBFBD>?close <EFBFBD><EFBFBD>?keep-alive
- (void)testConnectionHeader_ConcurrentMixed_CloseAndKeepAliveIsolated {
[self.client resetPoolStatistics];
NSString *poolKey = @"127.0.0.1:11080:tcp";
@@ -667,7 +667,7 @@
__block NSInteger closeCount = 0;
__block NSInteger keepAliveCount = 0;
// 10 5 close5 keep-alive
// 10 5 <EFBFBD><EFBFBD>?close<EFBFBD><EFBFBD>? <EFBFBD><EFBFBD>?keep-alive
for (NSInteger i = 0; i < 10; i++) {
XCTestExpectation *expectation = [self expectationWithDescription:[NSString stringWithFormat:@"Request %ld", (long)i]];
[expectations addObject:expectation];
@@ -711,23 +711,23 @@
XCTAssertEqual(closeCount, 5, @"5 close requests should succeed");
XCTAssertEqual(keepAliveCount, 5, @"5 keep-alive requests should succeed");
//
// <EFBFBD><EFBFBD>?
[NSThread sleepForTimeInterval:1.0];
//
// - close
// - keep-alive remote close
// - 4
// - close <EFBFBD><EFBFBD>?
// - keep-alive remote close<EFBFBD><EFBFBD>?
// - <EFBFBD><EFBFBD>?4<EFBFBD><EFBFBD>?
NSInteger poolSize = [self.client connectionPoolCountForKey:poolKey];
XCTAssertLessThanOrEqual(poolSize, 4,
@"Pool size should not exceed limit (no leak from close connections)");
// close
// >= 6 ( 5 close + 1 keep-alive close )
// <EFBFBD><EFBFBD>?>= 6 ( 5 <EFBFBD><EFBFBD>?close + 1 <EFBFBD><EFBFBD>?keep-alive<EFBFBD><EFBFBD>?close )
XCTAssertGreaterThanOrEqual(self.client.connectionCreationCount, 6,
@"Should have created at least 6 connections (5 close + at least 1 keep-alive)");
//
// <EFBFBD><EFBFBD>?
NSError *recoveryError = nil;
HttpdnsNWHTTPClientResponse *recoveryResponse = [self.client performRequestWithURLString:@"http://127.0.0.1:11080/get"
userAgent:@"RecoveryTest"