1/* 2 * 3 * Copyright 2018 gRPC authors. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19#import <XCTest/XCTest.h> 20 21#import "../../GRPCClient/GRPCCallOptions.h" 22#import "../../GRPCClient/private/GRPCCore/GRPCChannel.h" 23#import "../../GRPCClient/private/GRPCCore/GRPCChannelPool+Test.h" 24#import "../../GRPCClient/private/GRPCCore/GRPCChannelPool.h" 25#import "../../GRPCClient/private/GRPCCore/GRPCCompletionQueue.h" 26#import "../../GRPCClient/private/GRPCCore/GRPCWrappedCall.h" 27 28static NSString *kDummyHost = @"dummy.host"; 29static NSString *kDummyPath = @"/dummy/path"; 30 31@interface ChannelTests : XCTestCase 32 33@end 34 35@implementation ChannelTests 36 37+ (void)setUp { 38 grpc_init(); 39} 40 41- (void)testPooledChannelCreatingChannel { 42 GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; 43 GRPCChannelConfiguration *config = [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost 44 callOptions:options]; 45 GRPCPooledChannel *channel = [[GRPCPooledChannel alloc] initWithChannelConfiguration:config]; 46 GRPCCompletionQueue *cq = [GRPCCompletionQueue completionQueue]; 47 GRPCWrappedCall *wrappedCall = [channel wrappedCallWithPath:kDummyPath 48 completionQueue:cq 49 callOptions:options]; 50 XCTAssertNotNil(channel.wrappedChannel); 51 (void)wrappedCall; 52} 53 54- (void)testTimedDestroyChannel { 55 const NSTimeInterval kDestroyDelay = 1.0; 56 GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; 57 GRPCChannelConfiguration *config = [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost 58 callOptions:options]; 59 GRPCPooledChannel *channel = 60 [[GRPCPooledChannel alloc] initWithChannelConfiguration:config destroyDelay:kDestroyDelay]; 61 GRPCCompletionQueue *cq = [GRPCCompletionQueue completionQueue]; 62 GRPCWrappedCall *wrappedCall; 63 GRPCChannel *wrappedChannel; 64 @autoreleasepool { 65 wrappedCall = [channel wrappedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; 66 XCTAssertNotNil(channel.wrappedChannel); 67 68 // Unref and ref channel immediately; expect using the same raw channel. 69 wrappedChannel = channel.wrappedChannel; 70 71 wrappedCall = nil; 72 wrappedCall = [channel wrappedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; 73 XCTAssertEqual(channel.wrappedChannel, wrappedChannel); 74 75 // Unref and ref channel after destroy delay; expect a new raw channel. 76 wrappedCall = nil; 77 } 78 sleep(kDestroyDelay + 1); 79 XCTAssertNil(channel.wrappedChannel); 80 wrappedCall = [channel wrappedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; 81 XCTAssertNotEqual(channel.wrappedChannel, wrappedChannel); 82} 83 84- (void)testDisconnect { 85 const NSTimeInterval kDestroyDelay = 1.0; 86 GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; 87 GRPCChannelConfiguration *config = [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost 88 callOptions:options]; 89 GRPCPooledChannel *channel = 90 [[GRPCPooledChannel alloc] initWithChannelConfiguration:config destroyDelay:kDestroyDelay]; 91 GRPCCompletionQueue *cq = [GRPCCompletionQueue completionQueue]; 92 GRPCWrappedCall *wrappedCall = [channel wrappedCallWithPath:kDummyPath 93 completionQueue:cq 94 callOptions:options]; 95 XCTAssertNotNil(channel.wrappedChannel); 96 97 // Disconnect; expect wrapped channel to be dropped 98 [channel disconnect]; 99 XCTAssertNil(channel.wrappedChannel); 100 101 // Create a new call and unref the old call; confirm that destroy of the old call does not make 102 // the channel disconnect, even after the destroy delay. 103 GRPCWrappedCall *wrappedCall2 = [channel wrappedCallWithPath:kDummyPath 104 completionQueue:cq 105 callOptions:options]; 106 XCTAssertNotNil(channel.wrappedChannel); 107 GRPCChannel *wrappedChannel = channel.wrappedChannel; 108 wrappedCall = nil; 109 sleep(kDestroyDelay + 1); 110 XCTAssertNotNil(channel.wrappedChannel); 111 XCTAssertEqual(wrappedChannel, channel.wrappedChannel); 112 (void)wrappedCall2; 113} 114 115@end 116