diff options
author | Muxi Yan <mxyan@google.com> | 2018-11-18 22:47:35 -0800 |
---|---|---|
committer | Muxi Yan <mxyan@google.com> | 2018-11-18 22:47:35 -0800 |
commit | f0cbcde73195b8e17130538c3479d4c0e3bcd2a2 (patch) | |
tree | 06483748c28dc85c4927eec35e88b6001923999e /src/objective-c/tests | |
parent | 87abab45c99ab4b40718557cbc1c25dcd7f5a418 (diff) |
New channel pool design
Diffstat (limited to 'src/objective-c/tests')
-rw-r--r-- | src/objective-c/tests/ChannelTests/ChannelPoolTest.m | 222 | ||||
-rw-r--r-- | src/objective-c/tests/ChannelTests/ChannelTests.m | 126 |
2 files changed, 220 insertions, 128 deletions
diff --git a/src/objective-c/tests/ChannelTests/ChannelPoolTest.m b/src/objective-c/tests/ChannelTests/ChannelPoolTest.m index b85e62feb5..51819b12c2 100644 --- a/src/objective-c/tests/ChannelTests/ChannelPoolTest.m +++ b/src/objective-c/tests/ChannelTests/ChannelPoolTest.m @@ -25,6 +25,8 @@ #define TEST_TIMEOUT 32 NSString *kDummyHost = @"dummy.host"; +NSString *kDummyHost2 = @"dummy.host.2"; +NSString *kDummyPath = @"/dummy/path"; @interface ChannelPoolTest : XCTestCase @@ -36,94 +38,156 @@ NSString *kDummyHost = @"dummy.host"; grpc_init(); } -- (void)testChannelPooling { - NSString *kDummyHost = @"dummy.host"; - NSString *kDummyHost2 = @"dummy.host2"; +- (void)testCreateChannelAndCall { + GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; + GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; + GRPCPooledChannel *channel = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost + callOptions:options]; + XCTAssertNil(channel.wrappedChannel); + GRPCCompletionQueue *cq = [GRPCCompletionQueue completionQueue]; + grpc_call *call = [channel unmanagedCallWithPath:kDummyPath + completionQueue:cq callOptions:options]; + XCTAssert(call != NULL); + XCTAssertNotNil(channel.wrappedChannel); + [channel unrefUnmanagedCall:call]; + XCTAssertNil(channel.wrappedChannel); +} - GRPCMutableCallOptions *options1 = [[GRPCMutableCallOptions alloc] init]; +- (void)testCacheChannel { + GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; + GRPCCallOptions *options1 = [[GRPCCallOptions alloc] init]; GRPCCallOptions *options2 = [options1 copy]; - GRPCMutableCallOptions *options3 = [options2 mutableCopy]; + GRPCMutableCallOptions *options3 = [options1 mutableCopy]; options3.transportType = GRPCTransportTypeInsecure; - - GRPCChannelPool *pool = [GRPCChannelPool sharedInstance]; - - GRPCChannel *channel1 = [pool channelWithHost:kDummyHost callOptions:options1]; - GRPCChannel *channel2 = [pool channelWithHost:kDummyHost callOptions:options2]; - GRPCChannel *channel3 = [pool channelWithHost:kDummyHost2 callOptions:options1]; - GRPCChannel *channel4 = [pool channelWithHost:kDummyHost callOptions:options3]; - XCTAssertEqual(channel1, channel2); - XCTAssertNotEqual(channel1, channel3); - XCTAssertNotEqual(channel1, channel4); - XCTAssertNotEqual(channel3, channel4); -} - -- (void)testDestroyAllChannels { - NSString *kDummyHost = @"dummy.host"; - - GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; - GRPCChannelPool *pool = [GRPCChannelPool sharedInstance]; - GRPCChannel *channel = [pool channelWithHost:kDummyHost callOptions:options]; - grpc_call *call = [channel unmanagedCallWithPath:@"dummy.path" - completionQueue:[GRPCCompletionQueue completionQueue] - callOptions:options - disconnected:nil]; - [pool destroyAllChannels]; - XCTAssertTrue(channel.disconnected); - GRPCChannel *channel2 = [pool channelWithHost:kDummyHost callOptions:options]; - XCTAssertNotEqual(channel, channel2); - grpc_call_unref(call); + GRPCCompletionQueue *cq = [GRPCCompletionQueue completionQueue]; + GRPCPooledChannel *channel1 = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost + callOptions:options1]; + grpc_call *call1 = [channel1 unmanagedCallWithPath:kDummyPath + completionQueue:cq + callOptions:options1]; + GRPCPooledChannel *channel2 = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost + callOptions:options2]; + grpc_call *call2 = [channel2 unmanagedCallWithPath:kDummyPath + completionQueue:cq + callOptions:options2]; + GRPCPooledChannel *channel3 = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost + callOptions:options3]; + grpc_call *call3 = [channel3 unmanagedCallWithPath:kDummyPath + completionQueue:cq + callOptions:options3]; + GRPCPooledChannel *channel4 = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost2 + callOptions:options1]; + grpc_call *call4 = [channel4 unmanagedCallWithPath:kDummyPath + completionQueue:cq + callOptions:options1]; + XCTAssertEqual(channel1.wrappedChannel, channel2.wrappedChannel); + XCTAssertNotEqual(channel1.wrappedChannel, channel3.wrappedChannel); + XCTAssertNotEqual(channel1.wrappedChannel, channel4.wrappedChannel); + XCTAssertNotEqual(channel3.wrappedChannel, channel4.wrappedChannel); + [channel1 unrefUnmanagedCall:call1]; + [channel2 unrefUnmanagedCall:call2]; + [channel3 unrefUnmanagedCall:call3]; + [channel4 unrefUnmanagedCall:call4]; } -- (void)testGetChannelBeforeChannelTimedDisconnection { - NSString *kDummyHost = @"dummy.host"; - const NSTimeInterval kDestroyDelay = 1; - - GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; - GRPCChannelPool *pool = [GRPCChannelPool sharedInstance]; - GRPCChannel *channel = - [pool channelWithHost:kDummyHost callOptions:options destroyDelay:kDestroyDelay]; - grpc_call *call = [channel unmanagedCallWithPath:@"dummy.path" - completionQueue:[GRPCCompletionQueue completionQueue] - callOptions:options - disconnected:nil]; - grpc_call_unref(call); - [channel unref]; - - // Test that we can still get the channel at this time - GRPCChannel *channel2 = - [pool channelWithHost:kDummyHost callOptions:options destroyDelay:kDestroyDelay]; - XCTAssertEqual(channel, channel2); - call = [channel2 unmanagedCallWithPath:@"dummy.path" - completionQueue:[GRPCCompletionQueue completionQueue] - callOptions:options - disconnected:nil]; - - // Test that after the destroy delay, the channel is still alive +- (void)testTimedDestroyChannel { + const NSTimeInterval kDestroyDelay = 1.0; + + GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; + pool.destroyDelay = kDestroyDelay; + GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; + GRPCPooledChannel *channel = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost + callOptions:options]; + GRPCCompletionQueue *cq = [GRPCCompletionQueue completionQueue]; + grpc_call *call = [channel unmanagedCallWithPath:kDummyPath + completionQueue:cq callOptions:options]; + GRPCChannel *wrappedChannel = channel.wrappedChannel; + + [channel unrefUnmanagedCall:call]; + // Confirm channel is not destroyed at this time + call = [channel unmanagedCallWithPath:kDummyPath + completionQueue:cq + callOptions:options]; + XCTAssertEqual(wrappedChannel, channel.wrappedChannel); + + [channel unrefUnmanagedCall:call]; sleep(kDestroyDelay + 1); - XCTAssertFalse(channel.disconnected); + // Confirm channel is new at this time + call = [channel unmanagedCallWithPath:kDummyPath + completionQueue:cq + callOptions:options]; + XCTAssertNotEqual(wrappedChannel, channel.wrappedChannel); + + // Confirm the new channel can create call + call = [channel unmanagedCallWithPath:kDummyPath + completionQueue:cq + callOptions:options]; + XCTAssert(call != NULL); + [channel unrefUnmanagedCall:call]; } -- (void)testGetChannelAfterChannelTimedDisconnection { - NSString *kDummyHost = @"dummy.host"; - const NSTimeInterval kDestroyDelay = 1; - - GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; - GRPCChannelPool *pool = [GRPCChannelPool sharedInstance]; - GRPCChannel *channel = - [pool channelWithHost:kDummyHost callOptions:options destroyDelay:kDestroyDelay]; - grpc_call *call = [channel unmanagedCallWithPath:@"dummy.path" - completionQueue:[GRPCCompletionQueue completionQueue] - callOptions:options - disconnected:nil]; - grpc_call_unref(call); - [channel unref]; - - sleep(kDestroyDelay + 1); +- (void)testPoolDisconnection { + GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; + GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; + GRPCPooledChannel *channel = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost + callOptions:options]; + GRPCCompletionQueue *cq = [GRPCCompletionQueue completionQueue]; + grpc_call *call = [channel unmanagedCallWithPath:kDummyPath + completionQueue:cq + callOptions:options]; + XCTAssertNotNil(channel.wrappedChannel); + GRPCChannel *wrappedChannel = channel.wrappedChannel; + + // Test a new channel is created by requesting a channel from pool + [pool disconnectAllChannels]; + channel = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost + callOptions:options]; + call = [channel unmanagedCallWithPath:kDummyPath + completionQueue:cq + callOptions:options]; + XCTAssertNotNil(channel.wrappedChannel); + XCTAssertNotEqual(wrappedChannel, channel.wrappedChannel); + wrappedChannel = channel.wrappedChannel; + + // Test a new channel is created by requesting a new call from the previous proxy + [pool disconnectAllChannels]; + grpc_call *call2 = [channel unmanagedCallWithPath:kDummyPath + completionQueue:cq + callOptions:options]; + XCTAssertNotNil(channel.wrappedChannel); + XCTAssertNotEqual(channel.wrappedChannel, wrappedChannel); + [channel unrefUnmanagedCall:call]; + [channel unrefUnmanagedCall:call2]; +} - // Test that we get new channel to the same host and with the same callOptions - GRPCChannel *channel2 = - [pool channelWithHost:kDummyHost callOptions:options destroyDelay:kDestroyDelay]; - XCTAssertNotEqual(channel, channel2); +- (void)testUnrefCallFromStaleChannel { + GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; + GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; + GRPCPooledChannel *channel = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost + callOptions:options]; + GRPCCompletionQueue *cq = [GRPCCompletionQueue completionQueue]; + grpc_call *call = [channel unmanagedCallWithPath:kDummyPath + completionQueue:cq + callOptions:options]; + + [pool disconnectAllChannels]; + channel = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost + callOptions:options]; + + grpc_call *call2 = [channel unmanagedCallWithPath:kDummyPath + completionQueue:cq + callOptions:options]; + // Test unref the call of a stale channel will not cause the current channel going into timed + // destroy state + XCTAssertNotNil(channel.wrappedChannel); + GRPCChannel *wrappedChannel = channel.wrappedChannel; + [channel unrefUnmanagedCall:call]; + XCTAssertNotNil(channel.wrappedChannel); + XCTAssertEqual(wrappedChannel, channel.wrappedChannel); + // Test unref the call of the current channel will cause the channel going into timed destroy + // state + [channel unrefUnmanagedCall:call2]; + XCTAssertNil(channel.wrappedChannel); } @end diff --git a/src/objective-c/tests/ChannelTests/ChannelTests.m b/src/objective-c/tests/ChannelTests/ChannelTests.m index 5daafcdf3f..212db2f653 100644 --- a/src/objective-c/tests/ChannelTests/ChannelTests.m +++ b/src/objective-c/tests/ChannelTests/ChannelTests.m @@ -20,65 +20,93 @@ #import "../../GRPCClient/GRPCCallOptions.h" #import "../../GRPCClient/private/GRPCChannel.h" +#import "../../GRPCClient/private/GRPCChannelPool.h" #import "../../GRPCClient/private/GRPCCompletionQueue.h" -@interface ChannelTests : XCTestCase +/* +#define TEST_TIMEOUT 8 + +@interface GRPCChannelFake : NSObject + +- (instancetype)initWithCreateExpectation:(XCTestExpectation *)createExpectation + unrefExpectation:(XCTestExpectation *)unrefExpectation; + +- (nullable grpc_call *)unmanagedCallWithPath:(NSString *)path + completionQueue:(GRPCCompletionQueue *)queue + callOptions:(GRPCCallOptions *)callOptions; + +- (void)unrefUnmanagedCall:(grpc_call *)unmanagedCall; @end -@implementation ChannelTests +@implementation GRPCChannelFake { + __weak XCTestExpectation *_createExpectation; + __weak XCTestExpectation *_unrefExpectation; + long _grpcCallCounter; +} -+ (void)setUp { - grpc_init(); +- (nullable instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration *)channelConfiguration { + return nil; } -- (void)testTimedDisconnection { - NSString *const kHost = @"grpc-test.sandbox.googleapis.com"; - const NSTimeInterval kDestroyDelay = 1; - GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; - GRPCChannelConfiguration *configuration = - [[GRPCChannelConfiguration alloc] initWithHost:kHost callOptions:options]; - GRPCChannel *channel = - [[GRPCChannel alloc] initWithChannelConfiguration:configuration destroyDelay:kDestroyDelay]; - BOOL disconnected; - grpc_call *call = [channel unmanagedCallWithPath:@"dummy.path" - completionQueue:[GRPCCompletionQueue completionQueue] - callOptions:options - disconnected:&disconnected]; - XCTAssertFalse(disconnected); - grpc_call_unref(call); - [channel unref]; - XCTAssertFalse(channel.disconnected, @"Channel is pre-maturely disconnected."); - sleep(kDestroyDelay + 1); - XCTAssertTrue(channel.disconnected, @"Channel is not disconnected after delay."); - - // Check another call creation returns null and indicates disconnected. - call = [channel unmanagedCallWithPath:@"dummy.path" - completionQueue:[GRPCCompletionQueue completionQueue] - callOptions:options - disconnected:&disconnected]; - XCTAssert(call == NULL); - XCTAssertTrue(disconnected); +- (instancetype)initWithCreateExpectation:(XCTestExpectation *)createExpectation + unrefExpectation:(XCTestExpectation *)unrefExpectation { + if ((self = [super init])) { + _createExpectation = createExpectation; + _unrefExpectation = unrefExpectation; + _grpcCallCounter = 0; + } + return self; } -- (void)testForceDisconnection { - NSString *const kHost = @"grpc-test.sandbox.googleapis.com"; - const NSTimeInterval kDestroyDelay = 1; - GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; - GRPCChannelConfiguration *configuration = - [[GRPCChannelConfiguration alloc] initWithHost:kHost callOptions:options]; - GRPCChannel *channel = - [[GRPCChannel alloc] initWithChannelConfiguration:configuration destroyDelay:kDestroyDelay]; - grpc_call *call = [channel unmanagedCallWithPath:@"dummy.path" - completionQueue:[GRPCCompletionQueue completionQueue] - callOptions:options - disconnected:nil]; - grpc_call_unref(call); - [channel disconnect]; - XCTAssertTrue(channel.disconnected, @"Channel is not disconnected."); - - // Test calling another unref here will not crash - [channel unref]; +- (nullable grpc_call *)unmanagedCallWithPath:(NSString *)path + completionQueue:(GRPCCompletionQueue *)queue + callOptions:(GRPCCallOptions *)callOptions { + if (_createExpectation) [_createExpectation fulfill]; + return (grpc_call *)(++_grpcCallCounter); +} + +- (void)unrefUnmanagedCall:(grpc_call *)unmanagedCall { + if (_unrefExpectation) [_unrefExpectation fulfill]; +} + +@end + +@interface GRPCChannelPoolFake : NSObject + +- (instancetype)initWithDelayedDestroyExpectation:(XCTestExpectation *)delayedDestroyExpectation; + +- (GRPCChannel *)rawChannelWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions; + +- (void)delayedDestroyChannel; + +@end + +@implementation GRPCChannelPoolFake { + __weak XCTestExpectation *_delayedDestroyExpectation; +} + +- (instancetype)initWithDelayedDestroyExpectation:(XCTestExpectation *)delayedDestroyExpectation { + if ((self = [super init])) { + _delayedDestroyExpectation = delayedDestroyExpectation; + } + return self; +} + +- (void)delayedDestroyChannel { + if (_delayedDestroyExpectation) [_delayedDestroyExpectation fulfill]; +} + +@end */ + +@interface ChannelTests : XCTestCase + +@end + +@implementation ChannelTests + ++ (void)setUp { + grpc_init(); } @end |