阿里sdk

This commit is contained in:
Robin
2026-02-20 17:56:24 +08:00
parent 39524692e5
commit f3af234308
524 changed files with 58345 additions and 0 deletions

View File

@@ -0,0 +1,87 @@
//
// CacheKeyFunctionTest.m
// AlicloudHttpDNSTests
//
// Created by xuyecan on 2024/6/12.
// Copyright © 2024 alibaba-inc.com. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "TestBase.h"
@interface CacheKeyFunctionTest : TestBase
@end
static NSString *sdnsHost = @"sdns1.onlyforhttpdnstest.run.place";
@implementation CacheKeyFunctionTest
+ (void)setUp {
[super setUp];
}
- (void)setUp {
[super setUp];
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
self.httpdns = [[HttpDnsService alloc] initWithAccountID:100000];
});
[self.httpdns setLogEnabled:YES];
[self.httpdns setPersistentCacheIPEnabled:YES];
[self.httpdns setReuseExpiredIPEnabled:NO];
[self.httpdns setLogHandler:self];
self.currentTimeStamp = [[NSDate date] timeIntervalSince1970];
}
- (void)testSimpleSpecifyingCacheKeySituation {
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
NSString *testHost = hostNameIpPrefixMap.allKeys.firstObject;
NSString *cacheKey = [NSString stringWithFormat:@"cacheKey-%@", testHost];
__block NSString *ipPrefix = hostNameIpPrefixMap[testHost];
// 使ttl
[self.httpdns setTtlDelegate:nil];
dispatch_async(dispatch_get_global_queue(0, 0), ^{
HttpdnsResult *result = [self.httpdns resolveHostSync:testHost byIpType:HttpdnsQueryIPTypeIpv4 withSdnsParams:nil sdnsCacheKey:cacheKey];
XCTAssertNotNil(result);
XCTAssertTrue([result.host isEqualToString:testHost]);
XCTAssertGreaterThan(result.ttl, 0);
// ipip
XCTAssertLessThan([[NSDate date] timeIntervalSince1970], result.lastUpdatedTimeInterval + result.ttl);
NSString *firstIp = [result firstIpv4Address];
if (![firstIp hasPrefix:ipPrefix]) {
printf("XCTAssertWillFailed, host: %s, firstIp: %s, ipPrefix: %s\n", [testHost UTF8String], [firstIp UTF8String], [ipPrefix UTF8String]);
}
XCTAssertTrue([firstIp hasPrefix:ipPrefix]);
dispatch_semaphore_signal(semaphore);
});
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
[NSThread sleepForTimeInterval:3];
//
[self.httpdns.requestManager cleanAllHostMemoryCache];
// db
[self.httpdns.requestManager syncLoadCacheFromDbToMemory];
HttpdnsResult *result = [self.httpdns resolveHostSyncNonBlocking:testHost byIpType:HttpdnsQueryIPTypeIpv4];
// 使cacheKeynil
XCTAssertNil(result);
result = [self.httpdns resolveHostSyncNonBlocking:testHost byIpType:HttpdnsQueryIPTypeIpv4 withSdnsParams:nil sdnsCacheKey:cacheKey];
XCTAssertNotNil(result);
XCTAssertTrue([result.host isEqualToString:testHost]);
NSString *firstIp = [result firstIpv4Address];
XCTAssertTrue([firstIp hasPrefix:ipPrefix]);
}
@end

View File

@@ -0,0 +1,108 @@
//
// CustomTTLAndCleanCacheTest.m
// AlicloudHttpDNS
//
// Created by xuyecan on 2024/6/17.
// Copyright © 2024 alibaba-inc.com. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <stdatomic.h>
#import <mach/mach.h>
#import "HttpdnsService.h"
#import "HttpdnsRemoteResolver.h"
#import "TestBase.h"
static int TEST_CUSTOM_TTL_SECOND = 3;
@interface CustomTTLAndCleanCacheTest : TestBase<HttpdnsTTLDelegate>
@end
@implementation CustomTTLAndCleanCacheTest
- (void)setUp {
[super setUp];
self.httpdns = [[HttpDnsService alloc] initWithAccountID:100000];
[self.httpdns setLogEnabled:YES];
[self.httpdns setTtlDelegate:self];
[self.httpdns setLogHandler:self];
self.currentTimeStamp = [[NSDate date] timeIntervalSince1970];
}
- (void)tearDown {
[super tearDown];
}
- (int64_t)httpdnsHost:(NSString *)host ipType:(AlicloudHttpDNS_IPType)ipType ttl:(int64_t)ttl {
// ttl3
NSString *testHost = hostNameIpPrefixMap.allKeys.firstObject;
if ([host isEqual:testHost]) {
return TEST_CUSTOM_TTL_SECOND;
}
return ttl;
}
- (void)testCustomTTL {
[self presetNetworkEnvAsIpv4];
[self.httpdns cleanAllHostCache];
NSString *testHost = hostNameIpPrefixMap.allKeys.firstObject;
NSString *expectedIpPrefix = hostNameIpPrefixMap[testHost];
HttpdnsRemoteResolver *resolver = [HttpdnsRemoteResolver new];
id mockResolver = OCMPartialMock(resolver);
__block int invokeCount = 0;
OCMStub([mockResolver resolve:[OCMArg any] error:(NSError * __autoreleasing *)[OCMArg anyPointer]])
.andDo(^(NSInvocation *invocation) {
invokeCount++;
})
.andForwardToRealObject();
id mockResolverClass = OCMClassMock([HttpdnsRemoteResolver class]);
OCMStub([mockResolverClass new]).andReturn(mockResolver);
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
HttpdnsResult *result = [self.httpdns resolveHostSync:testHost byIpType:HttpdnsQueryIPTypeAuto];
XCTAssertNotNil(result);
XCTAssertEqual(result.ttl, TEST_CUSTOM_TTL_SECOND);
XCTAssertTrue([result.firstIpv4Address hasPrefix:expectedIpPrefix]);
XCTAssertEqual(invokeCount, 1);
dispatch_semaphore_signal(semaphore);
});
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
HttpdnsResult *result = [self.httpdns resolveHostSync:testHost byIpType:HttpdnsQueryIPTypeAuto];
XCTAssertNotNil(result);
XCTAssertEqual(result.ttl, TEST_CUSTOM_TTL_SECOND);
XCTAssertTrue([result.firstIpv4Address hasPrefix:expectedIpPrefix]);
XCTAssertEqual(invokeCount, 1);
dispatch_semaphore_signal(semaphore);
});
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
[NSThread sleepForTimeInterval:TEST_CUSTOM_TTL_SECOND + 1];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
HttpdnsResult *result = [self.httpdns resolveHostSync:testHost byIpType:HttpdnsQueryIPTypeAuto];
XCTAssertNotNil(result);
XCTAssertEqual(result.ttl, TEST_CUSTOM_TTL_SECOND);
XCTAssertTrue([result.firstIpv4Address hasPrefix:expectedIpPrefix]);
XCTAssertEqual(invokeCount, 2);
dispatch_semaphore_signal(semaphore);
});
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
}
@end

View File

@@ -0,0 +1,101 @@
//
// EnableReuseExpiredIpTest.m
// AlicloudHttpDNSTests
//
// Created by xuyecan on 2024/5/28.
// Copyright © 2024 alibaba-inc.com. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "TestBase.h"
@interface EnableReuseExpiredIpTest : TestBase <HttpdnsTTLDelegate>
@end
static int ttlForTest = 3;
@implementation EnableReuseExpiredIpTest
+ (void)setUp {
[super setUp];
}
- (void)setUp {
[super setUp];
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
self.httpdns = [[HttpDnsService alloc] initWithAccountID:100000];
});
[self.httpdns setLogEnabled:YES];
[self.httpdns setReuseExpiredIPEnabled:YES];
[self.httpdns setTtlDelegate:self];
[self.httpdns setLogHandler:self];
self.currentTimeStamp = [[NSDate date] timeIntervalSince1970];
}
- (int64_t)httpdnsHost:(NSString *)host ipType:(AlicloudHttpDNS_IPType)ipType ttl:(int64_t)ttl {
//
return ttlForTest;
}
- (void)testReuseExpiredIp {
NSString *host = hostNameIpPrefixMap.allKeys.firstObject;
NSString *ipPrefix = hostNameIpPrefixMap[host];
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
dispatch_async(dispatch_get_global_queue(0, 0), ^{
//
[self.httpdns.requestManager cleanAllHostMemoryCache];
//
HttpdnsResult *result = [self.httpdns resolveHostSync:host byIpType:HttpdnsQueryIPTypeIpv4];
XCTAssertNotNil(result);
XCTAssertTrue([result.host isEqualToString:host]);
XCTAssertGreaterThan(result.ttl, 0);
XCTAssertLessThanOrEqual(result.ttl, ttlForTest);
XCTAssertLessThan([[NSDate date] timeIntervalSince1970], result.lastUpdatedTimeInterval + result.ttl);
NSString *firstIp = [result firstIpv4Address];
XCTAssertTrue([firstIp hasPrefix:ipPrefix]);
//
[NSThread sleepForTimeInterval:ttlForTest + 1];
//
HttpdnsResult *result2 = [self.httpdns resolveHostSync:host byIpType:HttpdnsQueryIPTypeIpv4];
XCTAssertNotNil(result2);
XCTAssertTrue([result2.host isEqualToString:host]);
XCTAssertGreaterThan(result2.ttl, 0);
XCTAssertLessThanOrEqual(result2.ttl, ttlForTest);
//
XCTAssertGreaterThan([[NSDate date] timeIntervalSince1970], result2.lastUpdatedTimeInterval + result2.ttl);
NSString *firstIp2 = [result2 firstIpv4Address];
XCTAssertTrue([firstIp2 hasPrefix:ipPrefix]);
//
[NSThread sleepForTimeInterval:1];
// 使nonblocking
HttpdnsResult *result3 = [self.httpdns resolveHostSyncNonBlocking:host byIpType:HttpdnsQueryIPTypeIpv4];
XCTAssertNotNil(result3);
XCTAssertTrue([result3.host isEqualToString:host]);
XCTAssertGreaterThan(result3.ttl, 0);
XCTAssertLessThanOrEqual(result3.ttl, ttlForTest);
//
XCTAssertLessThan([[NSDate date] timeIntervalSince1970], result3.lastUpdatedTimeInterval + result3.ttl);
NSString *firstIp3 = [result3 firstIpv4Address];
XCTAssertTrue([firstIp3 hasPrefix:ipPrefix]);
dispatch_semaphore_signal(semaphore);
});
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
}
@end

View File

@@ -0,0 +1,165 @@
//
// HttpdnsHostObjectTest.m
// AlicloudHttpDNSTests
//
// Created by xuyecan on 2025/3/14.
// Copyright © 2025 alibaba-inc.com. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "../Testbase/TestBase.h"
#import "HttpdnsHostObject.h"
#import "HttpdnsIpObject.h"
#import <OCMock/OCMock.h>
@interface HttpdnsHostObjectTest : TestBase
@end
@implementation HttpdnsHostObjectTest
- (void)setUp {
[super setUp];
}
- (void)tearDown {
[super tearDown];
}
#pragma mark -
- (void)testHostObjectProperties {
// HttpdnsHostObject
HttpdnsHostObject *hostObject = [[HttpdnsHostObject alloc] init];
//
hostObject.host = @"example.com";
hostObject.ttl = 60;
hostObject.queryTimes = 1;
hostObject.clientIP = @"192.168.1.1";
//
XCTAssertEqualObjects(hostObject.host, @"example.com", @"host属性应该被正确设置");
XCTAssertEqual(hostObject.ttl, 60, @"ttl属性应该被正确设置");
XCTAssertEqual(hostObject.queryTimes, 1, @"queryTimes属性应该被正确设置");
XCTAssertEqualObjects(hostObject.clientIP, @"192.168.1.1", @"clientIP属性应该被正确设置");
}
#pragma mark - IP
- (void)testIpObjectProperties {
// HttpdnsIpObject
HttpdnsIpObject *ipObject = [[HttpdnsIpObject alloc] init];
//
ipObject.ip = @"1.2.3.4";
ipObject.ttl = 300;
ipObject.priority = 10;
ipObject.detectRT = 50; // detectRT
//
XCTAssertEqualObjects(ipObject.ip, @"1.2.3.4", @"ip属性应该被正确设置");
XCTAssertEqual(ipObject.ttl, 300, @"ttl属性应该被正确设置");
XCTAssertEqual(ipObject.priority, 10, @"priority属性应该被正确设置");
XCTAssertEqual(ipObject.detectRT, 50, @"detectRT属性应该被正确设置");
}
- (void)testIpObjectDetectRTMethods {
// HttpdnsIpObject
HttpdnsIpObject *ipObject = [[HttpdnsIpObject alloc] init];
//
XCTAssertEqual(ipObject.detectRT, -1, @"detectRT的默认值应该是-1");
//
[ipObject setDetectRT:100];
XCTAssertEqual(ipObject.detectRT, 100, @"detectRT应该被正确设置为100");
//
[ipObject setDetectRT:-5];
XCTAssertEqual(ipObject.detectRT, -1, @"设置负值时detectRT应该被设置为-1");
// 0
[ipObject setDetectRT:0];
XCTAssertEqual(ipObject.detectRT, 0, @"detectRT应该被正确设置为0");
}
#pragma mark - IP
- (void)testHostObjectIpManagement {
// HttpdnsHostObject
HttpdnsHostObject *hostObject = [[HttpdnsHostObject alloc] init];
hostObject.host = @"example.com";
// IP
HttpdnsIpObject *ipv4Object = [[HttpdnsIpObject alloc] init];
ipv4Object.ip = @"1.2.3.4";
ipv4Object.ttl = 300;
ipv4Object.detectRT = 50;
HttpdnsIpObject *ipv6Object = [[HttpdnsIpObject alloc] init];
ipv6Object.ip = @"2001:db8::1";
ipv6Object.ttl = 600;
ipv6Object.detectRT = 80;
// IP
[hostObject addIpv4:ipv4Object];
[hostObject addIpv6:ipv6Object];
// IP
XCTAssertEqual(hostObject.ipv4List.count, 1, @"应该有1个IPv4对象");
XCTAssertEqual(hostObject.ipv6List.count, 1, @"应该有1个IPv6对象");
// IP
HttpdnsIpObject *retrievedIpv4 = hostObject.ipv4List.firstObject;
XCTAssertEqualObjects(retrievedIpv4.ip, @"1.2.3.4", @"IPv4地址应该正确");
XCTAssertEqual(retrievedIpv4.detectRT, 50, @"IPv4的detectRT应该正确");
HttpdnsIpObject *retrievedIpv6 = hostObject.ipv6List.firstObject;
XCTAssertEqualObjects(retrievedIpv6.ip, @"2001:db8::1", @"IPv6地址应该正确");
XCTAssertEqual(retrievedIpv6.detectRT, 80, @"IPv6的detectRT应该正确");
}
#pragma mark - IP
- (void)testIpSortingByDetectRT {
// HttpdnsHostObject
HttpdnsHostObject *hostObject = [[HttpdnsHostObject alloc] init];
hostObject.host = @"example.com";
// IP
HttpdnsIpObject *ip1 = [[HttpdnsIpObject alloc] init];
ip1.ip = @"1.1.1.1";
ip1.detectRT = 100;
HttpdnsIpObject *ip2 = [[HttpdnsIpObject alloc] init];
ip2.ip = @"2.2.2.2";
ip2.detectRT = 50;
HttpdnsIpObject *ip3 = [[HttpdnsIpObject alloc] init];
ip3.ip = @"3.3.3.3";
ip3.detectRT = 200;
HttpdnsIpObject *ip4 = [[HttpdnsIpObject alloc] init];
ip4.ip = @"4.4.4.4";
ip4.detectRT = -1; //
// IP
[hostObject addIpv4:ip1];
[hostObject addIpv4:ip2];
[hostObject addIpv4:ip3];
[hostObject addIpv4:ip4];
// IP
NSArray<HttpdnsIpObject *> *sortedIps = [hostObject sortedIpv4List];
//
// ip2(50ms) -> ip1(100ms) -> ip3(200ms) -> ip4(-1ms)
XCTAssertEqual(sortedIps.count, 4, @"应该有4个IP对象");
XCTAssertEqualObjects(sortedIps[0].ip, @"2.2.2.2", @"检测时间最短的IP应该排在第一位");
XCTAssertEqualObjects(sortedIps[1].ip, @"1.1.1.1", @"检测时间第二短的IP应该排在第二位");
XCTAssertEqualObjects(sortedIps[2].ip, @"3.3.3.3", @"检测时间第三短的IP应该排在第三位");
XCTAssertEqualObjects(sortedIps[3].ip, @"4.4.4.4", @"未检测的IP应该排在最后");
}
@end

View File

@@ -0,0 +1,156 @@
//
// ManuallyCleanCacheTest.m
// AlicloudHttpDNSTests
//
// Created by xuyecan on 2024/6/17.
// Copyright © 2024 alibaba-inc.com. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <stdatomic.h>
#import <mach/mach.h>
#import "HttpdnsService.h"
#import "HttpdnsRemoteResolver.h"
#import "TestBase.h"
static int TEST_CUSTOM_TTL_SECOND = 3;
@interface ManuallyCleanCacheTest : TestBase
@end
@implementation ManuallyCleanCacheTest
- (void)setUp {
[super setUp];
self.httpdns = [[HttpDnsService alloc] initWithAccountID:100000];
[self.httpdns setLogEnabled:YES];
[self.httpdns setIPv6Enabled:YES];
[self.httpdns setLogHandler:self];
self.currentTimeStamp = [[NSDate date] timeIntervalSince1970];
}
- (void)tearDown {
[super tearDown];
}
- (void)testCleanSingleHost {
[self presetNetworkEnvAsIpv4];
[self.httpdns cleanAllHostCache];
NSString *testHost = ipv4OnlyHost;
HttpdnsHostObject *hostObject = [self constructSimpleIpv4HostObject];
[hostObject setV4TTL:60];
__block NSArray *mockResolverHostObjects = @[hostObject];
HttpdnsRemoteResolver *resolver = [HttpdnsRemoteResolver new];
id mockResolver = OCMPartialMock(resolver);
__block int invokeCount = 0;
OCMStub([mockResolver resolve:[OCMArg any] error:(NSError * __autoreleasing *)[OCMArg anyPointer]])
.andDo(^(NSInvocation *invocation) {
invokeCount++;
})
.andReturn(mockResolverHostObjects);
id mockResolverClass = OCMClassMock([HttpdnsRemoteResolver class]);
OCMStub([mockResolverClass new]).andReturn(mockResolver);
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
HttpdnsResult *result = [self.httpdns resolveHostSync:testHost byIpType:HttpdnsQueryIPTypeAuto];
XCTAssertNotNil(result);
XCTAssertEqual(result.ttl, 60);
XCTAssertEqual(invokeCount, 1);
dispatch_semaphore_signal(semaphore);
});
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
[self.httpdns cleanHostCache:@[@"invalidhostofcourse"]];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
HttpdnsResult *result = [self.httpdns resolveHostSync:testHost byIpType:HttpdnsQueryIPTypeAuto];
XCTAssertNotNil(result);
XCTAssertEqual(result.ttl, 60);
XCTAssertEqual(invokeCount, 1);
dispatch_semaphore_signal(semaphore);
});
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
[self.httpdns cleanHostCache:@[testHost]];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
HttpdnsResult *result = [self.httpdns resolveHostSync:testHost byIpType:HttpdnsQueryIPTypeAuto];
XCTAssertNotNil(result);
XCTAssertEqual(result.ttl, 60);
XCTAssertEqual(invokeCount, 2);
dispatch_semaphore_signal(semaphore);
});
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
}
- (void)testCleanAllHost {
[self presetNetworkEnvAsIpv4AndIpv6];
[self.httpdns cleanAllHostCache];
NSString *testHost = ipv4OnlyHost;
HttpdnsHostObject *hostObject = [self constructSimpleIpv4HostObject];
[hostObject setV4TTL:60];
HttpdnsRemoteResolver *resolver = [HttpdnsRemoteResolver new];
id mockResolver = OCMPartialMock(resolver);
__block int invokeCount = 0;
__block NSArray *mockResolverHostObjects = @[hostObject];
OCMStub([mockResolver resolve:[OCMArg any] error:(NSError * __autoreleasing *)[OCMArg anyPointer]])
.andDo(^(NSInvocation *invocation) {
invokeCount++;
})
.andReturn(mockResolverHostObjects);
id mockResolverClass = OCMClassMock([HttpdnsRemoteResolver class]);
OCMStub([mockResolverClass new]).andReturn(mockResolver);
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
HttpdnsResult *result = [self.httpdns resolveHostSync:testHost byIpType:HttpdnsQueryIPTypeAuto];
XCTAssertNotNil(result);
XCTAssertEqual(result.ttl, 60);
XCTAssertEqual(invokeCount, 1);
dispatch_semaphore_signal(semaphore);
});
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
[self.httpdns cleanHostCache:@[@"invalidhostofcourse"]];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
HttpdnsResult *result = [self.httpdns resolveHostSync:testHost byIpType:HttpdnsQueryIPTypeAuto];
XCTAssertNotNil(result);
XCTAssertEqual(result.ttl, 60);
XCTAssertEqual(invokeCount, 1);
dispatch_semaphore_signal(semaphore);
});
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
[self.httpdns cleanAllHostCache];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
HttpdnsResult *result = [self.httpdns resolveHostSync:testHost byIpType:HttpdnsQueryIPTypeAuto];
XCTAssertNotNil(result);
XCTAssertEqual(result.ttl, 60);
XCTAssertEqual(invokeCount, 2);
dispatch_semaphore_signal(semaphore);
});
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
}
@end

View File

@@ -0,0 +1,363 @@
//
// MultithreadCorrectnessTest.m
// AlicloudHttpDNSTests
//
// Created by xuyecan on 2024/5/26.
// Copyright © 2024 alibaba-inc.com. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <stdatomic.h>
#import <mach/mach.h>
#import "HttpdnsService.h"
#import "HttpdnsRemoteResolver.h"
#import "HttpdnsRequest_Internal.h"
#import "TestBase.h"
@interface MultithreadCorrectnessTest : TestBase
@end
@implementation MultithreadCorrectnessTest
- (void)setUp {
[super setUp];
self.httpdns = [[HttpDnsService alloc] initWithAccountID:100000];
[self.httpdns setLogEnabled:YES];
[self.httpdns setLogHandler:self];
[self.httpdns setTimeoutInterval:2];
self.currentTimeStamp = [[NSDate date] timeIntervalSince1970];
}
- (void)tearDown {
[super tearDown];
}
// 线
- (void)testNoneBlockingMethodShouldNotBlock {
HttpdnsRequestManager *requestManager = self.httpdns.requestManager;
HttpdnsRequestManager *mockedScheduler = OCMPartialMock(requestManager);
OCMStub([mockedScheduler executeRequest:[OCMArg any] retryCount:0])
.ignoringNonObjectArgs()
.andDo(^(NSInvocation *invocation) {
[NSThread sleepForTimeInterval:3];
});
[mockedScheduler cleanAllHostMemoryCache];
NSTimeInterval startTime = [[NSDate date] timeIntervalSince1970];
[self.httpdns resolveHostSyncNonBlocking:ipv4OnlyHost byIpType:HttpdnsQueryIPTypeIpv4];
NSTimeInterval elapsedTime = [[NSDate date] timeIntervalSince1970] - startTime;
XCTAssert(elapsedTime < 1, @"elapsedTime should be less than 1s, but is %f", elapsedTime);
}
// 线线
- (void)testBlockingMethodShouldNotBlockIfInMainThread {
HttpdnsRequestManager *requestManager = self.httpdns.requestManager;
HttpdnsRequestManager *mockedScheduler = OCMPartialMock(requestManager);
OCMStub([mockedScheduler executeRequest:[OCMArg any] retryCount:0])
.ignoringNonObjectArgs()
.andDo(^(NSInvocation *invocation) {
[NSThread sleepForTimeInterval:3];
});
[mockedScheduler cleanAllHostMemoryCache];
NSTimeInterval startTime = [[NSDate date] timeIntervalSince1970];
[self.httpdns resolveHostSync:ipv4OnlyHost byIpType:HttpdnsQueryIPTypeIpv4];
NSTimeInterval elapsedTime = [[NSDate date] timeIntervalSince1970] - startTime;
XCTAssert(elapsedTime < 1, @"elapsedTime should be less than 1s, but is %f", elapsedTime);
}
// 线
- (void)testBlockingMethodShouldBlockIfInBackgroundThread {
HttpdnsRequestManager *requestManager = self.httpdns.requestManager;
HttpdnsRequestManager *mockedScheduler = OCMPartialMock(requestManager);
OCMStub([mockedScheduler executeRequest:[OCMArg any] retryCount:0])
.ignoringNonObjectArgs()
.andDo(^(NSInvocation *invocation) {
[NSThread sleepForTimeInterval:2];
});
[mockedScheduler cleanAllHostMemoryCache];
NSTimeInterval startTime = [[NSDate date] timeIntervalSince1970];
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[self.httpdns resolveHostSync:ipv4OnlyHost byIpType:HttpdnsQueryIPTypeIpv4];
dispatch_semaphore_signal(semaphore);
});
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
NSTimeInterval elapsedTime = [[NSDate date] timeIntervalSince1970] - startTime;
XCTAssert(elapsedTime >= 2, @"elapsedTime should be more than 2s, but is %f", elapsedTime);
}
// 线
- (void)testBlockingMethodShouldBlockIfInBackgroundThreadWithSpecifiedMaxWaitTime {
HttpdnsRequestManager *requestManager = self.httpdns.requestManager;
HttpdnsRequestManager *mockedScheduler = OCMPartialMock(requestManager);
OCMStub([mockedScheduler executeRequest:[OCMArg any] retryCount:0])
.ignoringNonObjectArgs()
.andDo(^(NSInvocation *invocation) {
[NSThread sleepForTimeInterval:3];
});
[mockedScheduler cleanAllHostMemoryCache];
NSTimeInterval startTime = [[NSDate date] timeIntervalSince1970];
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
dispatch_async(dispatch_get_global_queue(0, 0), ^{
HttpdnsRequest *request = [HttpdnsRequest new];
request.host = ipv4OnlyHost;
request.queryIpType = HttpdnsQueryIPTypeIpv4;
request.resolveTimeoutInSecond = 3;
[self.httpdns resolveHostSync:request];
dispatch_semaphore_signal(semaphore);
});
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
NSTimeInterval elapsedTime = [[NSDate date] timeIntervalSince1970] - startTime;
XCTAssert(elapsedTime >= 3, @"elapsedTime should be more than 3s, but is %f", elapsedTime);
}
- (void)testResolveSameHostShouldWaitForTheFirstOne {
__block HttpdnsHostObject *ipv4HostObject = [self constructSimpleIpv4HostObject];
HttpdnsRemoteResolver *realResolver = [HttpdnsRemoteResolver new];
id mockResolver = OCMPartialMock(realResolver);
__block NSArray *mockResolverHostObjects = @[ipv4HostObject];
OCMStub([mockResolver resolve:[OCMArg any] error:(NSError * __autoreleasing *)[OCMArg anyPointer]])
.ignoringNonObjectArgs()
.andDo(^(NSInvocation *invocation) {
// 1.5
[NSThread sleepForTimeInterval:1.5];
[invocation setReturnValue:&mockResolverHostObjects];
});
id mockResolverClass = OCMClassMock([HttpdnsRemoteResolver class]);
OCMStub([mockResolverClass new]).andReturn(mockResolver);
[self.httpdns.requestManager cleanAllHostMemoryCache];
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[self.httpdns resolveHostSync:ipv4OnlyHost byIpType:HttpdnsQueryIPTypeIpv4];
});
//
[NSThread sleepForTimeInterval:0.5];
NSTimeInterval startTime = [[NSDate date] timeIntervalSince1970];
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
dispatch_async(dispatch_get_global_queue(0, 0), ^{
//
//
// 1
HttpdnsResult *result = [self.httpdns resolveHostSync:ipv4OnlyHost byIpType:HttpdnsQueryIPTypeIpv4];
XCTAssertNotNil(result);
XCTAssertTrue([result.host isEqualToString:ipv4OnlyHost]);
XCTAssertTrue([result.ips count] == 2);
XCTAssertTrue([result.ips[0] isEqualToString:ipv41]);
dispatch_semaphore_signal(semaphore);
});
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
NSTimeInterval elapsedTime = [[NSDate date] timeIntervalSince1970] - startTime;
XCTAssert(elapsedTime >= 1, @"elapsedTime should be more than 1s, but is %f", elapsedTime);
XCTAssert(elapsedTime <= 1.5, @"elapsedTime should not be more than 1.5s, but is %f", elapsedTime);
// TODO
// XCTAssert(elapsedTime < 4.1, @"elapsedTime should be less than 4.1s, but is %f", elapsedTime);
}
- (void)testResolveSameHostShouldRequestAgainAfterFirstFailed {
__block HttpdnsHostObject *ipv4HostObject = [self constructSimpleIpv4HostObject];
HttpdnsRemoteResolver *realResolver = [HttpdnsRemoteResolver new];
id mockResolver = OCMPartialMock(realResolver);
__block atomic_int count = 0;
__block NSArray *mockResolverHostObjects = @[ipv4HostObject];
OCMStub([mockResolver resolve:[OCMArg any] error:(NSError * __autoreleasing *)[OCMArg anyPointer]])
.ignoringNonObjectArgs()
.andDo(^(NSInvocation *invocation) {
int localCount = atomic_fetch_add(&count, 1) + 1;
if (localCount == 1) {
[NSThread sleepForTimeInterval:0.4];
//
@throw [NSException exceptionWithName:@"TestException" reason:@"TestException" userInfo:nil];
} else {
//
[NSThread sleepForTimeInterval:0.4];
[invocation setReturnValue:&mockResolverHostObjects];
}
});
id mockResolverClass = OCMClassMock([HttpdnsRemoteResolver class]);
OCMStub([mockResolverClass new]).andReturn(mockResolver);
[self.httpdns.requestManager cleanAllHostMemoryCache];
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[self.httpdns resolveHostSync:ipv4OnlyHost byIpType:HttpdnsQueryIPTypeIpv4];
});
//
[NSThread sleepForTimeInterval:0.2];
NSTimeInterval startTime = [[NSDate date] timeIntervalSince1970];
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
dispatch_async(dispatch_get_global_queue(0, 0), ^{
//
//
// 5
HttpdnsResult *result = [self.httpdns resolveHostSync:ipv4OnlyHost byIpType:HttpdnsQueryIPTypeIpv4];
XCTAssertNotNil(result);
XCTAssertTrue([result.host isEqualToString:ipv4OnlyHost]);
XCTAssertTrue([result.ips count] == 2);
XCTAssertTrue([result.ips[0] isEqualToString:ipv41]);
dispatch_semaphore_signal(semaphore);
});
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
NSTimeInterval elapsedTime = [[NSDate date] timeIntervalSince1970] - startTime;
XCTAssert(elapsedTime >= 0.6, @"elapsedTime should be more than 0.6s, but is %f", elapsedTime);
XCTAssert(elapsedTime < 0.8, @"elapsedTime should be less than 0.8s, but is %f", elapsedTime);
}
//
- (void)testSyncMethodSetBlockTimeout {
HttpdnsRequestManager *requestManager = self.httpdns.requestManager;
[self.httpdns cleanAllHostCache];
HttpdnsRequestManager *mockedScheduler = OCMPartialMock(requestManager);
OCMStub([mockedScheduler executeRequest:[OCMArg any] retryCount:0])
.ignoringNonObjectArgs()
.andDo(^(NSInvocation *invocation) {
[NSThread sleepForTimeInterval:5];
})
.andReturn([self constructSimpleIpv4HostObject]);
NSTimeInterval startTime = [[NSDate date] timeIntervalSince1970];
HttpdnsRequest *request = [HttpdnsRequest new];
request.host = ipv4OnlyHost;
request.queryIpType = HttpdnsQueryIPTypeIpv4;
request.resolveTimeoutInSecond = 2.5;
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
dispatch_async(dispatch_get_global_queue(0, 0), ^{
HttpdnsResult *result = [self.httpdns resolveHostSync:request];
NSTimeInterval elapsedTime = [[NSDate date] timeIntervalSince1970] - startTime;
XCTAssert(elapsedTime < 2.6, @"elapsedTime should be less than 2.6s, but is %f", elapsedTime);
XCTAssert(elapsedTime >= 2.5, @"elapsedTime should be greater than or equal to 2.5s, but is %f", elapsedTime);
XCTAssertNil(result);
dispatch_semaphore_signal(semaphore);
});
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
}
// 0.5 - 5
- (void)testLimitResolveTimeoutRange {
HttpdnsRequest *request = [HttpdnsRequest new];
request.host = ipv4OnlyHost;
request.queryIpType = HttpdnsQueryIPTypeAuto;
request.resolveTimeoutInSecond = 0.2;
[request ensureResolveTimeoutInReasonableRange];
XCTAssertGreaterThanOrEqual(request.resolveTimeoutInSecond, 0.5);
request.resolveTimeoutInSecond = 5.1;
[request ensureResolveTimeoutInReasonableRange];
XCTAssertLessThanOrEqual(request.resolveTimeoutInSecond, 5);
request.resolveTimeoutInSecond = 3.5;
[request ensureResolveTimeoutInReasonableRange];
XCTAssertEqual(request.resolveTimeoutInSecond, 3.5);
}
//
- (void)testAsyncMethodSetBlockTimeout {
HttpdnsRequestManager *requestManager = self.httpdns.requestManager;
[self.httpdns cleanAllHostCache];
HttpdnsRequestManager *mockedScheduler = OCMPartialMock(requestManager);
OCMStub([mockedScheduler executeRequest:[OCMArg any] retryCount:0])
.ignoringNonObjectArgs()
.andDo(^(NSInvocation *invocation) {
[NSThread sleepForTimeInterval:5];
})
.andReturn([self constructSimpleIpv4HostObject]);
NSTimeInterval startTime = [[NSDate date] timeIntervalSince1970];
HttpdnsRequest *request = [HttpdnsRequest new];
request.host = ipv4OnlyHost;
request.queryIpType = HttpdnsQueryIPTypeIpv4;
request.resolveTimeoutInSecond = 2.5;
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
[self.httpdns resolveHostAsync:request completionHandler:^(HttpdnsResult *result) {
NSTimeInterval elapsedTime = [[NSDate date] timeIntervalSince1970] - startTime;
XCTAssert(elapsedTime < 2.6, @"elapsedTime should be less than 2.6s, but is %f", elapsedTime);
XCTAssert(elapsedTime >= 2.5, @"elapsedTime should be greater than or equal to 2.5s, but is %f", elapsedTime);
XCTAssertNil(result);
dispatch_semaphore_signal(semaphore);
}];
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
}
// 线线
- (void)testMultiThreadSyncMethodMaxBlockingTime {
HttpdnsRequestManager *requestManager = self.httpdns.requestManager;
[self.httpdns cleanAllHostCache];
HttpdnsRequestManager *mockedScheduler = OCMPartialMock(requestManager);
OCMStub([mockedScheduler executeRequest:[OCMArg any] retryCount:0])
.ignoringNonObjectArgs()
.andDo(^(NSInvocation *invocation) {
[NSThread sleepForTimeInterval:5];
})
.andReturn([self constructSimpleIpv4HostObject]);
NSTimeInterval startTime = [[NSDate date] timeIntervalSince1970];
HttpdnsRequest *request = [HttpdnsRequest new];
request.host = ipv4OnlyHost;
request.queryIpType = HttpdnsQueryIPTypeIpv4;
request.resolveTimeoutInSecond = 4.5;
const int threadCount = 10;
NSMutableArray *semaArray = [NSMutableArray new];
for (int i = 0; i < threadCount; i++) {
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
[semaArray addObject:semaphore];
dispatch_async(dispatch_get_global_queue(0, 0), ^{
HttpdnsResult *result = [self.httpdns resolveHostSync:request];
NSTimeInterval elapsedTime = [[NSDate date] timeIntervalSince1970] - startTime;
XCTAssert(elapsedTime < 4.5 + 0.01, @"elapsedTime should be less than 2.6s, but is %f", elapsedTime);
XCTAssert(elapsedTime >= 4.5, @"elapsedTime should be greater than or equal to 2.5s, but is %f", elapsedTime);
XCTAssertNil(result);
dispatch_semaphore_signal(semaphore);
});
}
for (int i = 0; i < threadCount; i++) {
dispatch_semaphore_wait(semaArray[i], DISPATCH_TIME_FOREVER);
}
}
@end

View File

@@ -0,0 +1,301 @@
//
// PresetCacheAndRetrieveTest.m
// AlicloudHttpDNSTests
//
// Created by xuyecan on 2024/5/26.
// Copyright © 2024 alibaba-inc.com. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <OCMock/OCMock.h>
#import "TestBase.h"
#import "HttpdnsHostObject.h"
#import "HttpdnsService.h"
#import "HttpdnsService_Internal.h"
/**
* 使OCMockMock(使stopMocking)
* case
*/
@interface PresetCacheAndRetrieveTest : TestBase
@end
@implementation PresetCacheAndRetrieveTest
+ (void)setUp {
[super setUp];
HttpDnsService *httpdns = [[HttpDnsService alloc] initWithAccountID:100000];
[httpdns setLogEnabled:YES];
}
+ (void)tearDown {
[super tearDown];
}
- (void)setUp {
[super setUp];
self.httpdns = [HttpDnsService sharedInstance];
self.currentTimeStamp = [[NSDate date] timeIntervalSince1970];
}
- (void)tearDown {
[super tearDown];
}
// ipv4
- (void)testSimplyRetrieveCachedResultUnderIpv4Only {
[self presetNetworkEnvAsIpv4];
[self.httpdns cleanAllHostCache];
HttpdnsHostObject *hostObject = [self constructSimpleIpv4AndIpv6HostObject];
[self.httpdns.requestManager mergeLookupResultToManager:hostObject host:ipv4AndIpv6Host cacheKey:ipv4AndIpv6Host underQueryIpType:HttpdnsQueryIPTypeBoth];
// ipv4ipv4
HttpdnsResult *result = [self.httpdns resolveHostSyncNonBlocking:ipv4AndIpv6Host byIpType:HttpdnsQueryIPTypeIpv4];
XCTAssertNotNil(result);
XCTAssertTrue([result.host isEqualToString:ipv4AndIpv6Host]);
XCTAssertTrue([result.ips count] == 2);
XCTAssertTrue([result.ips[0] isEqualToString:ipv41]);
// ipv6ipv6
result = [self.httpdns resolveHostSyncNonBlocking:ipv4AndIpv6Host byIpType:HttpdnsQueryIPTypeIpv6];
XCTAssertNotNil(result);
XCTAssertTrue([result.host isEqualToString:ipv4AndIpv6Host]);
XCTAssertTrue([result.ipv6s count] == 2);
XCTAssertTrue([result.ipv6s[0] isEqualToString:ipv61]);
// both
result = [self.httpdns resolveHostSyncNonBlocking:ipv4AndIpv6Host byIpType:HttpdnsQueryIPTypeBoth];
XCTAssertNotNil(result);
XCTAssertTrue([result.host isEqualToString:ipv4AndIpv6Host]);
XCTAssertTrue([result.ips count] == 2);
XCTAssertTrue([result.ips[0] isEqualToString:ipv41]);
XCTAssertTrue([result.ipv6s count] == 2);
XCTAssertTrue([result.ipv6s[0] isEqualToString:ipv61]);
// autoipv4
result = [self.httpdns resolveHostSyncNonBlocking:ipv4AndIpv6Host byIpType:HttpdnsQueryIPTypeAuto];
XCTAssertNotNil(result);
XCTAssertTrue([result.host isEqualToString:ipv4AndIpv6Host]);
XCTAssertTrue([result.ips count] == 2);
XCTAssertTrue([result.ips[0] isEqualToString:ipv41]);
XCTAssertTrue([result.ipv6s count] == 0);
}
// ipv6
- (void)testSimplyRetrieveCachedResultUnderIpv6Only {
[self presetNetworkEnvAsIpv6];
[self.httpdns cleanAllHostCache];
HttpdnsHostObject *hostObject = [self constructSimpleIpv4AndIpv6HostObject];
[self.httpdns.requestManager mergeLookupResultToManager:hostObject host:ipv4AndIpv6Host cacheKey:ipv4AndIpv6Host underQueryIpType:HttpdnsQueryIPTypeBoth];
// ipv4ipv4
HttpdnsResult *result = [self.httpdns resolveHostSyncNonBlocking:ipv4AndIpv6Host byIpType:HttpdnsQueryIPTypeIpv4];
XCTAssertNotNil(result);
XCTAssertTrue([result.host isEqualToString:ipv4AndIpv6Host]);
XCTAssertTrue([result.ips count] == 2);
XCTAssertTrue([result.ips[0] isEqualToString:ipv41]);
// ipv6ipv6
result = [self.httpdns resolveHostSyncNonBlocking:ipv4AndIpv6Host byIpType:HttpdnsQueryIPTypeIpv6];
XCTAssertNotNil(result);
XCTAssertTrue([result.host isEqualToString:ipv4AndIpv6Host]);
XCTAssertTrue([result.ipv6s count] == 2);
XCTAssertTrue([result.ipv6s[0] isEqualToString:ipv61]);
// both
result = [self.httpdns resolveHostSyncNonBlocking:ipv4AndIpv6Host byIpType:HttpdnsQueryIPTypeBoth];
XCTAssertNotNil(result);
XCTAssertTrue([result.host isEqualToString:ipv4AndIpv6Host]);
XCTAssertTrue([result.ips count] == 2);
XCTAssertTrue([result.ips[0] isEqualToString:ipv41]);
XCTAssertTrue([result.ipv6s count] == 2);
XCTAssertTrue([result.ipv6s[0] isEqualToString:ipv61]);
// autoipv6only
// ipv4autoipv6ipv6
// ipv4+ipv6
result = [self.httpdns resolveHostSyncNonBlocking:ipv4AndIpv6Host byIpType:HttpdnsQueryIPTypeAuto];
XCTAssertNotNil(result);
XCTAssertTrue([result.host isEqualToString:ipv4AndIpv6Host]);
XCTAssertTrue([result.ips count] == 2);
XCTAssertTrue([result.ips[0] isEqualToString:ipv41]);
XCTAssertTrue([result.ipv6s count] == 2);
XCTAssertTrue([result.ipv6s[0] isEqualToString:ipv61]);
}
// ipv4ipv6
- (void)testSimplyRetrieveCachedResultUnderDualStack {
[self presetNetworkEnvAsIpv4AndIpv6];
[self.httpdns cleanAllHostCache];
// ipv4ipv6
HttpdnsHostObject *hostObject = [self constructSimpleIpv4AndIpv6HostObject];
[self.httpdns.requestManager mergeLookupResultToManager:hostObject host:ipv4AndIpv6Host cacheKey:ipv4AndIpv6Host underQueryIpType:HttpdnsQueryIPTypeBoth];
// ipv4
HttpdnsResult *result = [self.httpdns resolveHostSyncNonBlocking:ipv4AndIpv6Host byIpType:HttpdnsQueryIPTypeIpv4];
XCTAssertNotNil(result);
XCTAssertTrue([result.host isEqualToString:ipv4AndIpv6Host]);
XCTAssertTrue([result.ips count] == 2);
XCTAssertTrue([result.ips[0] isEqualToString:ipv41]);
// ipv6
result = [self.httpdns resolveHostSyncNonBlocking:ipv4AndIpv6Host byIpType:HttpdnsQueryIPTypeIpv6];
XCTAssertNotNil(result);
XCTAssertTrue([result.host isEqualToString:ipv4AndIpv6Host]);
XCTAssertTrue([result.ipv6s count] == 2);
XCTAssertTrue([result.ipv6s[0] isEqualToString:ipv61]);
// ipv4ipv6
result = [self.httpdns resolveHostSyncNonBlocking:ipv4AndIpv6Host byIpType:HttpdnsQueryIPTypeBoth];
XCTAssertNotNil(result);
XCTAssertTrue([result.host isEqualToString:ipv4AndIpv6Host]);
XCTAssertTrue([result.ips count] == 2);
XCTAssertTrue([result.ips[0] isEqualToString:ipv41]);
XCTAssertTrue([result.ipv6s count] == 2);
XCTAssertTrue([result.ipv6s[0] isEqualToString:ipv61]);
//
result = [self.httpdns resolveHostSyncNonBlocking:ipv4AndIpv6Host byIpType:HttpdnsQueryIPTypeAuto];
XCTAssertNotNil(result);
XCTAssertTrue([result.host isEqualToString:ipv4AndIpv6Host]);
XCTAssertTrue([result.ips count] == 2);
XCTAssertTrue([result.ips[0] isEqualToString:ipv41]);
XCTAssertTrue([result.ipv6s count] == 2);
XCTAssertTrue([result.ipv6s[0] isEqualToString:ipv61]);
}
// ttllastLookupTimeipv4ipv6
- (void)testTTLAndLastLookUpTime {
[self presetNetworkEnvAsIpv4AndIpv6];
[self.httpdns cleanAllHostCache];
// ipv4ipv6
HttpdnsHostObject *hostObject1 = [self constructSimpleIpv4AndIpv6HostObject];
hostObject1.v4ttl = 200;
hostObject1.v6ttl = 300;
int64_t currentTimestamp = [[NSDate new] timeIntervalSince1970];
hostObject1.lastIPv4LookupTime = currentTimestamp - 1;
hostObject1.lastIPv6LookupTime = currentTimestamp - 2;
//
[self.httpdns.requestManager mergeLookupResultToManager:hostObject1 host:ipv4AndIpv6Host cacheKey:ipv4AndIpv6Host underQueryIpType:HttpdnsQueryIPTypeBoth];
// autoipv4ipv6
HttpdnsResult *result = [self.httpdns resolveHostSyncNonBlocking:ipv4AndIpv6Host byIpType:HttpdnsQueryIPTypeAuto];
XCTAssertEqual(result.ttl, hostObject1.v4ttl);
XCTAssertEqual(result.lastUpdatedTimeInterval, hostObject1.lastIPv4LookupTime);
XCTAssertEqual(result.v6ttl, hostObject1.v6ttl);
XCTAssertEqual(result.v6LastUpdatedTimeInterval, hostObject1.lastIPv6LookupTime);
HttpdnsHostObject *hostObject2 = [self constructSimpleIpv4HostObject];
hostObject2.hostName = ipv4AndIpv6Host;
hostObject2.v4ttl = 600;
hostObject2.lastIPv4LookupTime = currentTimestamp - 10;
// ipv4
[self.httpdns.requestManager mergeLookupResultToManager:hostObject2 host:ipv4AndIpv6Host cacheKey:ipv4AndIpv6Host underQueryIpType:HttpdnsQueryIPTypeIpv4];
// v4v6
result = [self.httpdns resolveHostSyncNonBlocking:ipv4AndIpv6Host byIpType:HttpdnsQueryIPTypeAuto];
XCTAssertEqual(result.ttl, hostObject2.v4ttl);
XCTAssertEqual(result.lastUpdatedTimeInterval, hostObject2.lastIPv4LookupTime);
XCTAssertEqual(result.v6ttl, hostObject1.v6ttl);
XCTAssertEqual(result.v6LastUpdatedTimeInterval, hostObject1.lastIPv6LookupTime);
}
// ipv4ipv6
// ipv6ipv6
- (void)testMergeNoIpv6ResultAndGetBoth {
[self presetNetworkEnvAsIpv4AndIpv6];
HttpdnsHostObject *hostObject = [self constructSimpleIpv4HostObject];
// ipv4hostipv6
[self.httpdns.requestManager mergeLookupResultToManager:hostObject host:ipv4OnlyHost cacheKey:ipv4OnlyHost underQueryIpType:HttpdnsQueryIPTypeBoth];
[self shouldNotHaveCallNetworkRequestWhenResolving:^{
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
dispatch_async(dispatch_get_global_queue(0, 0), ^{
HttpdnsResult *result = [self.httpdns resolveHostSync:ipv4OnlyHost byIpType:HttpdnsQueryIPTypeBoth];
XCTAssertNotNil(result);
XCTAssertTrue([result.host isEqualToString:ipv4OnlyHost]);
XCTAssertTrue([result.ips count] == 2);
XCTAssertTrue([result.ips[0] isEqualToString:ipv41]);
result = [self.httpdns resolveHostSync:ipv4OnlyHost byIpType:HttpdnsQueryIPTypeAuto];
XCTAssertNotNil(result);
XCTAssertTrue([result.host isEqualToString:ipv4OnlyHost]);
XCTAssertTrue([result.ips count] == 2);
XCTAssertTrue([result.ips[0] isEqualToString:ipv41]);
dispatch_semaphore_signal(semaphore);
});
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
}];
}
// ipv4ipv4ipv6
// ipv6
- (void)testMergeOnlyIpv4ResultAndGetBoth {
[self presetNetworkEnvAsIpv4AndIpv6];
HttpdnsHostObject *hostObject = [self constructSimpleIpv4HostObject];
[self.httpdns.requestManager mergeLookupResultToManager:hostObject host:ipv4OnlyHost cacheKey:ipv4OnlyHost underQueryIpType:HttpdnsQueryIPTypeIpv4];
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
// 使线
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[self shouldHaveCalledRequestWhenResolving:^{
HttpdnsResult *result = [self.httpdns resolveHostSync:ipv4OnlyHost byIpType:HttpdnsQueryIPTypeBoth];
XCTAssertNil(result);
dispatch_semaphore_signal(sema);
}];
});
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
}
// ipv6ipv6ipv4
// ipv4
- (void)testMergeOnlyIpv6ResultAndGetBoth {
[self presetNetworkEnvAsIpv4AndIpv6];
HttpdnsHostObject *hostObject = [self constructSimpleIpv6HostObject];
[self.httpdns.requestManager mergeLookupResultToManager:hostObject host:ipv6OnlyHost cacheKey:ipv6OnlyHost underQueryIpType:HttpdnsQueryIPTypeIpv6];
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
// 使线
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[self shouldHaveCalledRequestWhenResolving:^{
HttpdnsResult *result = [self.httpdns resolveHostSync:ipv6OnlyHost byIpType:HttpdnsQueryIPTypeBoth];
XCTAssertNil(result);
dispatch_semaphore_signal(sema);
}];
});
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
}
@end

View File

@@ -0,0 +1,265 @@
//
// ResolvingEffectiveHostTest.m
// AlicloudHttpDNSTests
//
// Created by xuyecan on 2024/5/28.
// Copyright © 2024 alibaba-inc.com. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <stdatomic.h>
#import <mach/mach.h>
#import "HttpdnsService.h"
#import "HttpdnsRemoteResolver.h"
#import "TestBase.h"
@interface ResolvingEffectiveHostTest : TestBase<HttpdnsTTLDelegate>
@end
@implementation ResolvingEffectiveHostTest
+ (void)setUp {
[super setUp];
}
- (void)setUp {
[super setUp];
self.httpdns = [[HttpDnsService alloc] initWithAccountID:100000];
[self.httpdns setLogEnabled:YES];
[self.httpdns setReuseExpiredIPEnabled:NO];
[self.httpdns setTtlDelegate:self];
[self.httpdns setLogHandler:self];
self.currentTimeStamp = [[NSDate date] timeIntervalSince1970];
}
- (void)tearDown {
[super tearDown];
}
- (int64_t)httpdnsHost:(NSString *)host ipType:(AlicloudHttpDNS_IPType)ipType ttl:(int64_t)ttl {
// ttl1-4
return arc4random_uniform(4) + 1;
}
- (void)testNormalMultipleHostsResolve {
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
// 使ttl
[self.httpdns setTtlDelegate:nil];
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[hostNameIpPrefixMap enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull host, NSString * _Nonnull ipPrefix, BOOL * _Nonnull stop) {
HttpdnsResult *result = [self.httpdns resolveHostSync:host byIpType:HttpdnsQueryIPTypeIpv4];
XCTAssertNotNil(result);
XCTAssertTrue([result.host isEqualToString:host]);
XCTAssertGreaterThan(result.ttl, 0);
// ipip
XCTAssertLessThan([[NSDate date] timeIntervalSince1970], result.lastUpdatedTimeInterval + result.ttl);
NSString *firstIp = [result firstIpv4Address];
if (![firstIp hasPrefix:ipPrefix]) {
printf("XCTAssertWillFailed, host: %s, firstIp: %s, ipPrefix: %s\n", [host UTF8String], [firstIp UTF8String], [ipPrefix UTF8String]);
}
XCTAssertTrue([firstIp hasPrefix:ipPrefix]);
}];
dispatch_semaphore_signal(semaphore);
});
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
}
- (void)testNonblockingMethodShouldNotBlockDuringMultithreadLongRun {
NSTimeInterval startTime = [[NSDate date] timeIntervalSince1970];
NSTimeInterval testDuration = 10;
int threadCountForEachType = 5;
for (int i = 0; i < threadCountForEachType; i++) {
dispatch_async(dispatch_get_global_queue(0, 0), ^{
while ([[NSDate date] timeIntervalSince1970] - startTime < testDuration) {
NSString *host = [hostNameIpPrefixMap allKeys][arc4random_uniform((uint32_t)[hostNameIpPrefixMap count])];
NSString *ipPrefix = hostNameIpPrefixMap[host];
long long executeStartTimeInMs = [[NSDate date] timeIntervalSince1970] * 1000;
HttpdnsResult *result = [self.httpdns resolveHostSyncNonBlocking:host byIpType:HttpdnsQueryIPTypeIpv4];
long long executeEndTimeInMs = [[NSDate date] timeIntervalSince1970] * 1000;
// 30ms
if (executeEndTimeInMs - executeStartTimeInMs >= 30) {
printf("XCTAssertWillFailed, host: %s, executeTime: %lldms\n", [host UTF8String], executeEndTimeInMs - executeStartTimeInMs);
}
XCTAssertLessThan(executeEndTimeInMs - executeStartTimeInMs, 30);
if (result) {
XCTAssertNotNil(result);
XCTAssertTrue([result.host isEqualToString:host]);
NSString *firstIp = [result firstIpv4Address];
if (![firstIp hasPrefix:ipPrefix]) {
printf("XCTAssertWillFailed, host: %s, firstIp: %s, ipPrefix: %s\n", [host UTF8String], [firstIp UTF8String], [ipPrefix UTF8String]);
}
XCTAssertTrue([firstIp hasPrefix:ipPrefix]);
}
[NSThread sleepForTimeInterval:0.1];
}
});
}
[NSThread sleepForTimeInterval:testDuration + 1];
}
- (void)testMultithreadAndMultiHostResolvingForALongRun {
NSTimeInterval startTime = [[NSDate date] timeIntervalSince1970];
NSTimeInterval testDuration = 10;
int threadCountForEachType = 4;
for (int i = 0; i < threadCountForEachType; i++) {
dispatch_async(dispatch_get_global_queue(0, 0), ^{
while ([[NSDate date] timeIntervalSince1970] - startTime < testDuration) {
NSString *host = [hostNameIpPrefixMap allKeys][arc4random_uniform((uint32_t)[hostNameIpPrefixMap count])];
NSString *ipPrefix = hostNameIpPrefixMap[host];
HttpdnsResult *result = [self.httpdns resolveHostSync:host byIpType:HttpdnsQueryIPTypeIpv4];
XCTAssertNotNil(result);
XCTAssertTrue([result.host isEqualToString:host]);
NSString *firstIp = [result firstIpv4Address];
if (![firstIp hasPrefix:ipPrefix]) {
printf("XCTAssertWillFailed, host: %s, firstIp: %s, ipPrefix: %s\n", [host UTF8String], [firstIp UTF8String], [ipPrefix UTF8String]);
}
XCTAssertTrue([firstIp hasPrefix:ipPrefix]);
[NSThread sleepForTimeInterval:0.1];
}
});
}
for (int i = 0; i < threadCountForEachType; i++) {
dispatch_async(dispatch_get_global_queue(0, 0), ^{
while ([[NSDate date] timeIntervalSince1970] - startTime < testDuration) {
NSString *host = [hostNameIpPrefixMap allKeys][arc4random_uniform((uint32_t)[hostNameIpPrefixMap count])];
NSString *ipPrefix = hostNameIpPrefixMap[host];
[self.httpdns resolveHostAsync:host byIpType:HttpdnsQueryIPTypeIpv4 completionHandler:^(HttpdnsResult *result) {
XCTAssertNotNil(result);
XCTAssertTrue([result.host isEqualToString:host]);
NSString *firstIp = [result firstIpv4Address];
if (![firstIp hasPrefix:ipPrefix]) {
printf("XCTAssertWillFailed, host: %s, firstIp: %s, ipPrefix: %s\n", [host UTF8String], [firstIp UTF8String], [ipPrefix UTF8String]);
}
XCTAssertTrue([firstIp hasPrefix:ipPrefix]);
}];
[NSThread sleepForTimeInterval:0.1];
}
});
}
for (int i = 0; i < threadCountForEachType; i++) {
dispatch_async(dispatch_get_global_queue(0, 0), ^{
while ([[NSDate date] timeIntervalSince1970] - startTime < testDuration) {
NSString *host = [hostNameIpPrefixMap allKeys][arc4random_uniform((uint32_t)[hostNameIpPrefixMap count])];
NSString *ipPrefix = hostNameIpPrefixMap[host];
HttpdnsResult *result = [self.httpdns resolveHostSyncNonBlocking:host byIpType:HttpdnsQueryIPTypeIpv4];
if (result) {
XCTAssertTrue([result.host isEqualToString:host]);
NSString *firstIp = [result firstIpv4Address];
if (![firstIp hasPrefix:ipPrefix]) {
printf("XCTAssertWillFailed, host: %s, firstIp: %s, ipPrefix: %s\n", [host UTF8String], [firstIp UTF8String], [ipPrefix UTF8String]);
}
XCTAssertTrue([firstIp hasPrefix:ipPrefix]);
}
[NSThread sleepForTimeInterval:0.1];
}
});
}
sleep(testDuration + 1);
}
// bothipv4
// ipv6ipv4
- (void)testMultithreadAndMultiHostResolvingForALongRunBySpecifyBothIpv4AndIpv6 {
NSTimeInterval startTime = [[NSDate date] timeIntervalSince1970];
NSTimeInterval testDuration = 10;
int threadCountForEachType = 4;
//
__block int syncCount = 0, asyncCount = 0, syncNonBlockingCount = 0;
for (int i = 0; i < threadCountForEachType; i++) {
dispatch_async(dispatch_get_global_queue(0, 0), ^{
while ([[NSDate date] timeIntervalSince1970] - startTime < testDuration) {
NSString *host = [hostNameIpPrefixMap allKeys][arc4random_uniform((uint32_t)[hostNameIpPrefixMap count])];
NSString *ipPrefix = hostNameIpPrefixMap[host];
HttpdnsResult *result = [self.httpdns resolveHostSync:host byIpType:HttpdnsQueryIPTypeBoth];
XCTAssertNotNil(result);
XCTAssertTrue(!result.hasIpv6Address);
XCTAssertTrue([result.host isEqualToString:host]);
NSString *firstIp = [result firstIpv4Address];
if (![firstIp hasPrefix:ipPrefix]) {
printf("XCTAssertWillFailed, host: %s, firstIp: %s, ipPrefix: %s\n", [host UTF8String], [firstIp UTF8String], [ipPrefix UTF8String]);
}
XCTAssertTrue([firstIp hasPrefix:ipPrefix]);
syncCount++;
[NSThread sleepForTimeInterval:0.1];
}
});
}
for (int i = 0; i < threadCountForEachType; i++) {
dispatch_async(dispatch_get_global_queue(0, 0), ^{
while ([[NSDate date] timeIntervalSince1970] - startTime < testDuration) {
NSString *host = [hostNameIpPrefixMap allKeys][arc4random_uniform((uint32_t)[hostNameIpPrefixMap count])];
NSString *ipPrefix = hostNameIpPrefixMap[host];
[self.httpdns resolveHostAsync:host byIpType:HttpdnsQueryIPTypeBoth completionHandler:^(HttpdnsResult *result) {
XCTAssertNotNil(result);
XCTAssertTrue(!result.hasIpv6Address);
XCTAssertTrue([result.host isEqualToString:host]);
NSString *firstIp = [result firstIpv4Address];
if (![firstIp hasPrefix:ipPrefix]) {
printf("XCTAssertWillFailed, host: %s, firstIp: %s, ipPrefix: %s\n", [host UTF8String], [firstIp UTF8String], [ipPrefix UTF8String]);
}
XCTAssertTrue([firstIp hasPrefix:ipPrefix]);
asyncCount++;
}];
[NSThread sleepForTimeInterval:0.1];
}
});
}
for (int i = 0; i < threadCountForEachType; i++) {
dispatch_async(dispatch_get_global_queue(0, 0), ^{
while ([[NSDate date] timeIntervalSince1970] - startTime < testDuration) {
NSString *host = [hostNameIpPrefixMap allKeys][arc4random_uniform((uint32_t)[hostNameIpPrefixMap count])];
NSString *ipPrefix = hostNameIpPrefixMap[host];
HttpdnsResult *result = [self.httpdns resolveHostSyncNonBlocking:host byIpType:HttpdnsQueryIPTypeBoth];
if (result) {
XCTAssertTrue([result.host isEqualToString:host]);
XCTAssertTrue(!result.hasIpv6Address);
NSString *firstIp = [result firstIpv4Address];
if (![firstIp hasPrefix:ipPrefix]) {
printf("XCTAssertWillFailed, host: %s, firstIp: %s, ipPrefix: %s\n", [host UTF8String], [firstIp UTF8String], [ipPrefix UTF8String]);
}
XCTAssertTrue([firstIp hasPrefix:ipPrefix]);
}
syncNonBlockingCount++;
[NSThread sleepForTimeInterval:0.1];
}
});
}
sleep(testDuration + 1);
int theoreticalCount = threadCountForEachType * (testDuration / 0.1);
// printf all the counts
printf("syncCount: %d, asyncCount: %d, syncNonBlockingCount: %d, theoreticalCount: %d\n", syncCount, asyncCount, syncNonBlockingCount, theoreticalCount);
}
@end

View File

@@ -0,0 +1,133 @@
//
// ScheduleCenterV4Test.m
// AlicloudHttpDNSTests
//
// Created by xuyecan on 2024/6/16.
// Copyright © 2024 alibaba-inc.com. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <OCMock/OCMock.h>
#import "TestBase.h"
#import "HttpdnsHostObject.h"
#import "HttpdnsScheduleCenter.h"
#import "HttpdnsService.h"
#import "HttpdnsService_Internal.h"
#import "HttpdnsRequest_Internal.h"
#import "HttpdnsScheduleExecutor.h"
#import "HttpdnsRemoteResolver.h"
/**
* 使OCMockMock(使stopMocking)
* case
*/
@interface ScheduleCenterV4Test : TestBase
@end
@implementation ScheduleCenterV4Test
+ (void)setUp {
[super setUp];
}
+ (void)tearDown {
[super tearDown];
}
- (void)setUp {
[super setUp];
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
self.httpdns = [[HttpDnsService alloc] initWithAccountID:100000];
});
[self.httpdns setLogEnabled:YES];
[self.httpdns setReuseExpiredIPEnabled:NO];
[self.httpdns setLogHandler:self];
self.currentTimeStamp = [[NSDate date] timeIntervalSince1970];
}
- (void)tearDown {
[super tearDown];
}
- (void)testUpdateFailureWillMoveToNextUpdateServer {
[self presetNetworkEnvAsIpv4];
HttpdnsScheduleExecutor *realRequest = [HttpdnsScheduleExecutor new];
id mockRequest = OCMPartialMock(realRequest);
OCMStub([mockRequest fetchRegionConfigFromServer:[OCMArg any] error:(NSError * __autoreleasing *)[OCMArg anyPointer]])
.andReturn(nil);
id mockRequestClass = OCMClassMock([HttpdnsScheduleExecutor class]);
OCMStub([mockRequestClass new]).andReturn(mockRequest);
HttpdnsScheduleCenter *scheduleCenter = [[HttpdnsScheduleCenter alloc] initWithAccountId:100000];
NSArray<NSString *> *updateServerHostList = [scheduleCenter currentUpdateServerV4HostList];
int updateServerCount = (int)[updateServerHostList count];
XCTAssertGreaterThan(updateServerCount, 0);
int startIndex = [scheduleCenter currentActiveUpdateServerHostIndex];
// 2
[scheduleCenter asyncUpdateRegionScheduleConfigAtRetry:2];
[NSThread sleepForTimeInterval:0.1];
OCMVerify([mockRequest fetchRegionConfigFromServer:[OCMArg any] error:(NSError * __autoreleasing *)[OCMArg anyPointer]]);
int currentIndex = [scheduleCenter currentActiveUpdateServerHostIndex];
XCTAssertEqual((startIndex + 1) % updateServerCount, currentIndex);
for (int i = 0; i < updateServerCount; i++) {
[scheduleCenter asyncUpdateRegionScheduleConfigAtRetry:2];
[NSThread sleepForTimeInterval:0.1];
}
int finalIndex = [scheduleCenter currentActiveUpdateServerHostIndex];
XCTAssertEqual(currentIndex, finalIndex % updateServerCount);
[NSThread sleepForTimeInterval:3];
}
- (void)testResolveFailureWillMoveToNextServiceServer {
[self presetNetworkEnvAsIpv4];
id mockResolver = OCMPartialMock([HttpdnsRemoteResolver new]);
OCMStub([mockResolver resolve:[OCMArg any] error:(NSError * __autoreleasing *)[OCMArg anyPointer]])
.andDo(^(NSInvocation *invocation) {
NSError *mockError = [NSError errorWithDomain:@"com.example.error" code:123 userInfo:@{NSLocalizedDescriptionKey: @"Mock error"}];
NSError *__autoreleasing *errorPtr = nil;
[invocation getArgument:&errorPtr atIndex:3];
if (errorPtr) {
*errorPtr = mockError;
}
});
id mockResolverClass = OCMClassMock([HttpdnsRemoteResolver class]);
OCMStub([mockResolverClass new]).andReturn(mockResolver);
HttpdnsScheduleCenter *scheduleCenter = [[HttpdnsScheduleCenter alloc] initWithAccountId:100000];
int startIndex = [scheduleCenter currentActiveServiceServerHostIndex];
int serviceServerCount = (int)[scheduleCenter currentServiceServerV4HostList].count;
HttpdnsRequest *request = [[HttpdnsRequest alloc] initWithHost:@"mock" queryIpType:HttpdnsQueryIPTypeAuto];
[request becomeBlockingRequest];
HttpdnsRequestManager *requestManager = self.httpdns.requestManager;
[requestManager executeRequest:request retryCount:1];
int secondIndex = [scheduleCenter currentActiveServiceServerHostIndex];
XCTAssertEqual((startIndex + 1) % serviceServerCount, secondIndex);
}
@end

View File

@@ -0,0 +1,90 @@
//
// ScheduleCenterV6Test.m
// AlicloudHttpDNSTests
//
// Created by xuyecan on 2024/6/17.
// Copyright © 2024 alibaba-inc.com. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <OCMock/OCMock.h>
#import "TestBase.h"
#import "HttpdnsHostObject.h"
#import "HttpdnsScheduleExecutor.h"
#import "HttpdnsScheduleCenter.h"
#import "HttpdnsService.h"
#import "HttpdnsService_Internal.h"
#import "HttpdnsUtil.h"
/**
* 使OCMockMock(使stopMocking)
* case
*/
@interface ScheduleCenterV6Test : TestBase
@end
@implementation ScheduleCenterV6Test
+ (void)setUp {
[super setUp];
}
+ (void)tearDown {
[super tearDown];
}
- (void)setUp {
[super setUp];
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
self.httpdns = [[HttpDnsService alloc] initWithAccountID:100000];
});
[self.httpdns setLogEnabled:YES];
[self.httpdns setReuseExpiredIPEnabled:NO];
[self.httpdns setLogHandler:self];
self.currentTimeStamp = [[NSDate date] timeIntervalSince1970];
}
- (void)tearDown {
[super tearDown];
}
- (void)testUpdateFailureWillMoveToNextUpdateServer {
[self presetNetworkEnvAsIpv6];
HttpdnsScheduleExecutor *realRequest = [HttpdnsScheduleExecutor new];
id mockRequest = OCMPartialMock(realRequest);
OCMStub([mockRequest fetchRegionConfigFromServer:[OCMArg any] error:(NSError * __autoreleasing *)[OCMArg anyPointer]])
.andReturn(nil);
id mockRequestClass = OCMClassMock([HttpdnsScheduleExecutor class]);
OCMStub([mockRequestClass new]).andReturn(mockRequest);
HttpdnsScheduleCenter *scheduleCenter = [[HttpdnsScheduleCenter alloc] initWithAccountId:100000];
NSArray<NSString *> *updateServerHostList = [scheduleCenter currentUpdateServerV4HostList];
int updateServerCount = (int)[updateServerHostList count];
XCTAssertGreaterThan(updateServerCount, 0);
// 2
[scheduleCenter asyncUpdateRegionScheduleConfigAtRetry:2];
[NSThread sleepForTimeInterval:0.1];
NSString *activeUpdateHost = [scheduleCenter getActiveUpdateServerHost];
// ipv4
XCTAssertFalse([HttpdnsUtil isIPv4Address:activeUpdateHost]);
OCMVerify([mockRequest fetchRegionConfigFromServer:[OCMArg any] error:(NSError * __autoreleasing *)[OCMArg anyPointer]]);
[NSThread sleepForTimeInterval:3];
}
@end

View File

@@ -0,0 +1,108 @@
//
// SdnsScenarioTest.m
// AlicloudHttpDNSTests
//
// Created by xuyecan on 2024/5/29.
// Copyright © 2024 alibaba-inc.com. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "TestBase.h"
@interface SdnsScenarioTest : TestBase <HttpdnsTTLDelegate>
@end
static int ttlForTest = 3;
static NSString *sdnsHost = @"sdns1.onlyforhttpdnstest.run.place";
@implementation SdnsScenarioTest
+ (void)setUp {
[super setUp];
}
- (void)setUp {
[super setUp];
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
self.httpdns = [[HttpDnsService alloc] initWithAccountID:100000];
});
[self.httpdns setLogEnabled:YES];
[self.httpdns setReuseExpiredIPEnabled:NO];
[self.httpdns setTtlDelegate:self];
[self.httpdns setLogHandler:self];
self.currentTimeStamp = [[NSDate date] timeIntervalSince1970];
}
- (int64_t)httpdnsHost:(NSString *)host ipType:(AlicloudHttpDNS_IPType)ipType ttl:(int64_t)ttl {
//
return ttlForTest;
}
- (void)testSimpleSdnsScenario {
NSDictionary *extras = @{
@"testKey": @"testValue",
@"key2": @"value2",
@"key3": @"value3"
};
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
dispatch_async(dispatch_get_global_queue(0, 0), ^{
HttpdnsResult *result = [self.httpdns resolveHostSync:sdnsHost byIpType:HttpdnsQueryIPTypeIpv4 withSdnsParams:extras sdnsCacheKey:nil];
XCTAssertNotNil(result);
XCTAssertNotNil(result.ips);
// 0.0.0.0 FC
XCTAssertTrue([result.ips containsObject:@"0.0.0.0"]);
dispatch_semaphore_signal(semaphore);
});
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
}
- (void)testSdnsScenarioUsingCustomCacheKey {
[self.httpdns.requestManager cleanAllHostMemoryCache];
NSDictionary *extras = @{
@"testKey": @"testValue",
@"key2": @"value2",
@"key3": @"value3"
};
NSString *cacheKey = [NSString stringWithFormat:@"abcd_%@", sdnsHost];
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
dispatch_async(dispatch_get_global_queue(0, 0), ^{
HttpdnsResult *result = [self.httpdns resolveHostSync:sdnsHost byIpType:HttpdnsQueryIPTypeIpv4 withSdnsParams:extras sdnsCacheKey:cacheKey];
XCTAssertNotNil(result);
XCTAssertNotNil(result.ips);
// 0.0.0.0 FC
XCTAssertTrue([result.ips containsObject:@"0.0.0.0"]);
dispatch_semaphore_signal(semaphore);
});
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
// cacheKeycacheKeynil
HttpdnsResult *result1 = [self.httpdns resolveHostSyncNonBlocking:sdnsHost byIpType:HttpdnsQueryIPTypeIpv4];
XCTAssertNil(result1);
// 使cachekey
HttpdnsResult *result2 = [self.httpdns resolveHostSync:sdnsHost byIpType:HttpdnsQueryIPTypeIpv4 withSdnsParams:@{} sdnsCacheKey:cacheKey];
XCTAssertNotNil(result2);
XCTAssertNotNil(result2.ips);
// 0.0.0.0 FC
XCTAssertTrue([result2.ips containsObject:@"0.0.0.0"]);
}
@end