From e98c18ff225db91dd59395afbcd85f76551fb7a8 Mon Sep 17 00:00:00 2001 From: liujl Date: Wed, 3 Aug 2016 19:14:36 +0800 Subject: [PATCH] ADD: concurrency and performance tests Change-Id: I2c9532de20727306c8ac595905382da96f949ff0 --- .gitignore | 1 + YTKNetwork.xcodeproj/project.pbxproj | 8 ++++ YTKNetworkTests/YTKConcurrencyTests.m | 58 +++++++++++++++++++++++++++ YTKNetworkTests/YTKPerformanceTests.m | 41 +++++++++++++++++++ YTKNetworkTests/YTKTestCase.m | 3 +- 5 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 YTKNetworkTests/YTKConcurrencyTests.m create mode 100644 YTKNetworkTests/YTKPerformanceTests.m diff --git a/.gitignore b/.gitignore index b50be58..aec599c 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,7 @@ DerivedData *.perspectivev3 !default.perspectivev3 xcuserdata +xcbaselines ## Other *.xccheckout diff --git a/YTKNetwork.xcodeproj/project.pbxproj b/YTKNetwork.xcodeproj/project.pbxproj index 64da502..d809c94 100644 --- a/YTKNetwork.xcodeproj/project.pbxproj +++ b/YTKNetwork.xcodeproj/project.pbxproj @@ -39,7 +39,9 @@ 2D244E631D4EDC7E0031202D /* AFNetworking.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2D244E621D4EDC7E0031202D /* AFNetworking.framework */; }; 2D244E641D4EDCCA0031202D /* AFNetworking.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2D244E621D4EDC7E0031202D /* AFNetworking.framework */; }; 2D513AAB1D5080F400E475EA /* YTKRequestFilterTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D513AAA1D5080F400E475EA /* YTKRequestFilterTests.m */; }; + 2D9714A61D51DA55001EE8CD /* YTKConcurrencyTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D9714A51D51DA55001EE8CD /* YTKConcurrencyTests.m */; }; 2DA9B00C1D5082C200D4A1EC /* YTKTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DA9B00B1D5082C200D4A1EC /* YTKTestCase.m */; }; + 2DB52D691D520856006B779C /* YTKPerformanceTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DB52D681D520856006B779C /* YTKPerformanceTests.m */; }; 2DCFCBF71D4EE10D002CAC24 /* AFNetworking.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 2D244E621D4EDC7E0031202D /* AFNetworking.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; /* End PBXBuildFile section */ @@ -108,8 +110,10 @@ 2D244E571D4ED7CB0031202D /* YTKTimeoutRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YTKTimeoutRequest.m; sourceTree = ""; }; 2D244E621D4EDC7E0031202D /* AFNetworking.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AFNetworking.framework; path = Carthage/Build/iOS/AFNetworking.framework; sourceTree = ""; }; 2D513AAA1D5080F400E475EA /* YTKRequestFilterTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YTKRequestFilterTests.m; sourceTree = ""; }; + 2D9714A51D51DA55001EE8CD /* YTKConcurrencyTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YTKConcurrencyTests.m; sourceTree = ""; }; 2DA9B00A1D5082C200D4A1EC /* YTKTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YTKTestCase.h; sourceTree = ""; }; 2DA9B00B1D5082C200D4A1EC /* YTKTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YTKTestCase.m; sourceTree = ""; }; + 2DB52D681D520856006B779C /* YTKPerformanceTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YTKPerformanceTests.m; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -222,6 +226,8 @@ 2D513AAA1D5080F400E475EA /* YTKRequestFilterTests.m */, 2D244E521D4ED7CB0031202D /* YTKJSONValidatorTests.m */, 2D244E531D4ED7CB0031202D /* YTKNetworkRequestTests.m */, + 2D9714A51D51DA55001EE8CD /* YTKConcurrencyTests.m */, + 2DB52D681D520856006B779C /* YTKPerformanceTests.m */, 2DA9B00A1D5082C200D4A1EC /* YTKTestCase.h */, 2DA9B00B1D5082C200D4A1EC /* YTKTestCase.m */, ); @@ -384,6 +390,8 @@ 2D244E5F1D4ED7CB0031202D /* YTKStatusCodeValidatorRequest.m in Sources */, 2D244E5C1D4ED7CB0031202D /* YTKJSONValidatorRequest.m in Sources */, 2D244E5D1D4ED7CB0031202D /* YTKJSONValidatorTests.m in Sources */, + 2D9714A61D51DA55001EE8CD /* YTKConcurrencyTests.m in Sources */, + 2DB52D691D520856006B779C /* YTKPerformanceTests.m in Sources */, 2D244E5A1D4ED7CB0031202D /* YTKBasicUrlFilter.m in Sources */, 2D244E5B1D4ED7CB0031202D /* YTKCustomHeaderFieldRequest.m in Sources */, 2D244E581D4ED7CB0031202D /* YTKBasicAuthRequest.m in Sources */, diff --git a/YTKNetworkTests/YTKConcurrencyTests.m b/YTKNetworkTests/YTKConcurrencyTests.m new file mode 100644 index 0000000..e624c54 --- /dev/null +++ b/YTKNetworkTests/YTKConcurrencyTests.m @@ -0,0 +1,58 @@ +// +// YTKRequestConcurrencyTest.m +// YTKNetwork +// +// Created by skyline on 16/8/3. +// Copyright © 2016年 skyline. All rights reserved. +// + +#import "YTKTestCase.h" +#import "YTKBasicHTTPRequest.h" +#import "YTKNetworkPrivate.h" + +@interface YTKConcurrencyTest : YTKTestCase + +@end + +@implementation YTKConcurrencyTest + +- (void)setUp { + [super setUp]; +} + +- (void)tearDown { + [super tearDown]; +} + +- (void)testBasicConcurrentRequestCreation { + dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul); + + NSInteger dispatchTarget = 1000; + __block NSInteger completionCount = 0; + for (NSUInteger i = 0; i < dispatchTarget; i++) { + dispatch_async(queue, ^{ + YTKBasicHTTPRequest *req = [[YTKBasicHTTPRequest alloc] init]; + [req startWithCompletionBlockWithSuccess:^(__kindof YTKBaseRequest * _Nonnull request) { + NSNumber *result = request.responseObject; + XCTAssertTrue([result isEqualToNumber:@(i)]); + } failure:nil]; + // We just need to simulate concurrent request creation here. + [req.requestTask cancel]; + + YTKBaseRequest *mockedSuccessResult = [[YTKBaseRequest alloc] init]; + mockedSuccessResult.responseObject = @(i); + req.successCompletionBlock(mockedSuccessResult); + + NSLog(@"Current req number: %zd", i); + dispatch_sync(dispatch_get_main_queue(), ^{ + completionCount++; + }); + }); + } + + while (completionCount < dispatchTarget) { + [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; + } +} + +@end diff --git a/YTKNetworkTests/YTKPerformanceTests.m b/YTKNetworkTests/YTKPerformanceTests.m new file mode 100644 index 0000000..9880d35 --- /dev/null +++ b/YTKNetworkTests/YTKPerformanceTests.m @@ -0,0 +1,41 @@ +// +// YTKPerformanceTests.m +// YTKNetwork +// +// Created by skyline on 16/8/3. +// Copyright © 2016年 skyline. All rights reserved. +// + +#import "YTKTestCase.h" +#import "YTKBasicHTTPRequest.h" + +@interface YTKPerformanceTests : YTKTestCase + +@end + +@implementation YTKPerformanceTests + +- (void)setUp { + [super setUp]; +} + +- (void)tearDown { + [super tearDown]; +} + +- (void)testBaseRequestCreationPerformance { + NSInteger targetCount = 1000; + // The measure block will be called several times. + [self measureBlock:^{ + for (NSUInteger i = 0; i < targetCount; i++) { + YTKBasicHTTPRequest *req = [[YTKBasicHTTPRequest alloc] init]; + [req startWithCompletionBlockWithSuccess:^(__kindof YTKBaseRequest * _Nonnull request) { + NSNumber *result = request.responseObject; + XCTAssertTrue([result isEqualToNumber:@(i)]); + } failure:nil]; + [req.requestTask cancel]; + } + }]; +} + +@end diff --git a/YTKNetworkTests/YTKTestCase.m b/YTKNetworkTests/YTKTestCase.m index 01e0b28..e9fafc8 100644 --- a/YTKNetworkTests/YTKTestCase.m +++ b/YTKNetworkTests/YTKTestCase.m @@ -8,6 +8,7 @@ #import "YTKTestCase.h" #import "YTKNetworkConfig.h" +#import "YTKNetworkAgent.h" #import "YTKRequest.h" NSString * const YTKNetworkingTestsBaseURLString = @"https://httpbin.org/"; @@ -17,12 +18,12 @@ @implementation YTKTestCase - (void)setUp { [super setUp]; self.networkTimeout = 20.0; - [YTKNetworkConfig sharedInstance].baseUrl = YTKNetworkingTestsBaseURLString; } - (void)tearDown { [super tearDown]; + [[YTKNetworkAgent sharedInstance] cancelAllRequests]; [YTKNetworkConfig sharedInstance].baseUrl = @""; [YTKNetworkConfig sharedInstance].cdnUrl = @""; [[YTKNetworkConfig sharedInstance] clearUrlFilter];