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