aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/objective-c/tests
diff options
context:
space:
mode:
authorGravatar Muxi Yan <mxyan@google.com>2018-11-18 22:47:35 -0800
committerGravatar Muxi Yan <mxyan@google.com>2018-11-18 22:47:35 -0800
commitf0cbcde73195b8e17130538c3479d4c0e3bcd2a2 (patch)
tree06483748c28dc85c4927eec35e88b6001923999e /src/objective-c/tests
parent87abab45c99ab4b40718557cbc1c25dcd7f5a418 (diff)
New channel pool design
Diffstat (limited to 'src/objective-c/tests')
-rw-r--r--src/objective-c/tests/ChannelTests/ChannelPoolTest.m222
-rw-r--r--src/objective-c/tests/ChannelTests/ChannelTests.m126
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