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 <Cronet/Cronet.h> 22#import <GRPCClient/GRPCCallOptions.h> 23#import <RxLibrary/GRXBufferedPipe.h> 24#import "src/objective-c/tests/RemoteTestClient/Messages.pbobjc.h" 25#import "src/objective-c/tests/RemoteTestClient/Test.pbobjc.h" 26#import "src/objective-c/tests/RemoteTestClient/Test.pbrpc.h" 27 28#import "../ConfigureCronet.h" 29#import "InteropTestsBlockCallbacks.h" 30 31#define NSStringize_helper(x) #x 32#define NSStringize(x) @NSStringize_helper(x) 33static NSString *const kRemoteSSLHost = NSStringize(HOST_PORT_REMOTE); 34static NSString *const kLocalSSLHost = NSStringize(HOST_PORT_LOCALSSL); 35static NSString *const kLocalCleartextHost = NSStringize(HOST_PORT_LOCAL); 36 37static const NSTimeInterval TEST_TIMEOUT = 8000; 38 39@interface RMTStreamingOutputCallRequest (Constructors) 40+ (instancetype)messageWithPayloadSize:(NSNumber *)payloadSize 41 requestedResponseSize:(NSNumber *)responseSize; 42@end 43 44@implementation RMTStreamingOutputCallRequest (Constructors) 45+ (instancetype)messageWithPayloadSize:(NSNumber *)payloadSize 46 requestedResponseSize:(NSNumber *)responseSize { 47 RMTStreamingOutputCallRequest *request = [self message]; 48 RMTResponseParameters *parameters = [RMTResponseParameters message]; 49 parameters.size = responseSize.intValue; 50 [request.responseParametersArray addObject:parameters]; 51 request.payload.body = [NSMutableData dataWithLength:payloadSize.unsignedIntegerValue]; 52 return request; 53} 54@end 55 56@interface RMTStreamingOutputCallResponse (Constructors) 57+ (instancetype)messageWithPayloadSize:(NSNumber *)payloadSize; 58@end 59 60@implementation RMTStreamingOutputCallResponse (Constructors) 61+ (instancetype)messageWithPayloadSize:(NSNumber *)payloadSize { 62 RMTStreamingOutputCallResponse *response = [self message]; 63 response.payload.type = RMTPayloadType_Compressable; 64 response.payload.body = [NSMutableData dataWithLength:payloadSize.unsignedIntegerValue]; 65 return response; 66} 67@end 68 69@interface InteropTestsMultipleChannels : XCTestCase 70 71@end 72 73dispatch_once_t initCronet; 74 75@implementation InteropTestsMultipleChannels { 76 RMTTestService *_remoteService; 77 RMTTestService *_remoteCronetService; 78 RMTTestService *_localCleartextService; 79 RMTTestService *_localSSLService; 80} 81 82- (void)setUp { 83 [super setUp]; 84 85 self.continueAfterFailure = NO; 86 87 _remoteService = [RMTTestService serviceWithHost:kRemoteSSLHost callOptions:nil]; 88 configureCronet(/*enable_netlog=*/false); 89 90 // Default stack with remote host 91 GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; 92 options.transportType = GRPCTransportTypeCronet; 93 // Cronet stack with remote host 94 _remoteCronetService = [RMTTestService serviceWithHost:kRemoteSSLHost callOptions:options]; 95 96 // Local stack with no SSL 97 options = [[GRPCMutableCallOptions alloc] init]; 98 options.transportType = GRPCTransportTypeInsecure; 99 _localCleartextService = [RMTTestService serviceWithHost:kLocalCleartextHost callOptions:options]; 100 101 // Local stack with SSL 102 NSBundle *bundle = [NSBundle bundleForClass:[self class]]; 103 NSString *certsPath = [bundle pathForResource:@"TestCertificates.bundle/test-certificates" 104 ofType:@"pem"]; 105 NSError *error = nil; 106 NSString *certs = [NSString stringWithContentsOfFile:certsPath 107 encoding:NSUTF8StringEncoding 108 error:&error]; 109 XCTAssertNil(error); 110 111 options = [[GRPCMutableCallOptions alloc] init]; 112 options.transportType = GRPCTransportTypeChttp2BoringSSL; 113 options.PEMRootCertificates = certs; 114 options.hostNameOverride = @"foo.test.google.fr"; 115 _localSSLService = [RMTTestService serviceWithHost:kLocalSSLHost callOptions:options]; 116} 117 118- (void)testEmptyUnaryRPC { 119 __weak XCTestExpectation *expectRemote = [self expectationWithDescription:@"Remote RPC finish"]; 120 __weak XCTestExpectation *expectCronetRemote = 121 [self expectationWithDescription:@"Remote RPC finish"]; 122 __weak XCTestExpectation *expectCleartext = 123 [self expectationWithDescription:@"Remote RPC finish"]; 124 __weak XCTestExpectation *expectSSL = [self expectationWithDescription:@"Remote RPC finish"]; 125 126 GPBEmpty *request = [GPBEmpty message]; 127 128 void (^messageHandler)(id message) = ^(id message) { 129 id expectedResponse = [GPBEmpty message]; 130 XCTAssertEqualObjects(message, expectedResponse); 131 }; 132 133 GRPCUnaryProtoCall *callRemote = [_remoteService 134 emptyCallWithMessage:request 135 responseHandler:[[InteropTestsBlockCallbacks alloc] 136 initWithInitialMetadataCallback:nil 137 messageCallback:messageHandler 138 closeCallback:^(NSDictionary *trailingMetadata, 139 NSError *error) { 140 XCTAssertNil(error); 141 [expectRemote fulfill]; 142 } 143 writeMessageCallback:nil] 144 callOptions:nil]; 145 GRPCUnaryProtoCall *callCronet = [_remoteCronetService 146 emptyCallWithMessage:request 147 responseHandler:[[InteropTestsBlockCallbacks alloc] 148 initWithInitialMetadataCallback:nil 149 messageCallback:messageHandler 150 closeCallback:^(NSDictionary *trailingMetadata, 151 NSError *error) { 152 XCTAssertNil(error); 153 [expectCronetRemote fulfill]; 154 } 155 writeMessageCallback:nil] 156 callOptions:nil]; 157 GRPCUnaryProtoCall *callCleartext = [_localCleartextService 158 emptyCallWithMessage:request 159 responseHandler:[[InteropTestsBlockCallbacks alloc] 160 initWithInitialMetadataCallback:nil 161 messageCallback:messageHandler 162 closeCallback:^(NSDictionary *trailingMetadata, 163 NSError *error) { 164 XCTAssertNil(error); 165 [expectCleartext fulfill]; 166 } 167 writeMessageCallback:nil] 168 callOptions:nil]; 169 GRPCUnaryProtoCall *callSSL = [_localSSLService 170 emptyCallWithMessage:request 171 responseHandler:[[InteropTestsBlockCallbacks alloc] 172 initWithInitialMetadataCallback:nil 173 messageCallback:messageHandler 174 closeCallback:^(NSDictionary *trailingMetadata, 175 NSError *error) { 176 XCTAssertNil(error); 177 [expectSSL fulfill]; 178 } 179 writeMessageCallback:nil] 180 callOptions:nil]; 181 [callRemote start]; 182 [callCronet start]; 183 [callCleartext start]; 184 [callSSL start]; 185 186 [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; 187} 188 189- (void)testFullDuplexRPC { 190 __weak XCTestExpectation *expectRemote = [self expectationWithDescription:@"Remote RPC finish"]; 191 __weak XCTestExpectation *expectCronetRemote = 192 [self expectationWithDescription:@"Remote RPC finish"]; 193 __weak XCTestExpectation *expectCleartext = 194 [self expectationWithDescription:@"Remote RPC finish"]; 195 __weak XCTestExpectation *expectSSL = [self expectationWithDescription:@"Remote RPC finish"]; 196 197 NSArray *requestSizes = @[ @100, @101, @102, @103 ]; 198 NSArray *responseSizes = @[ @104, @105, @106, @107 ]; 199 XCTAssertEqual([requestSizes count], [responseSizes count]); 200 NSUInteger kRounds = [requestSizes count]; 201 NSMutableArray<GRPCStreamingProtoCall *> *calls = [NSMutableArray arrayWithCapacity:4]; 202 203 NSMutableArray *requests = [NSMutableArray arrayWithCapacity:kRounds]; 204 NSMutableArray *responses = [NSMutableArray arrayWithCapacity:kRounds]; 205 for (int i = 0; i < kRounds; i++) { 206 requests[i] = [RMTStreamingOutputCallRequest messageWithPayloadSize:requestSizes[i] 207 requestedResponseSize:responseSizes[i]]; 208 responses[i] = [RMTStreamingOutputCallResponse messageWithPayloadSize:responseSizes[i]]; 209 } 210 211 __block NSMutableArray *steps = [NSMutableArray arrayWithCapacity:4]; 212 __block NSMutableArray *requestsBuffers = [NSMutableArray arrayWithCapacity:4]; 213 for (int i = 0; i < 4; i++) { 214 steps[i] = [NSNumber numberWithUnsignedInteger:0]; 215 requestsBuffers[i] = [[GRXBufferedPipe alloc] init]; 216 [requestsBuffers[i] writeValue:requests[0]]; 217 } 218 219 void (^handler)(NSUInteger index, id message) = ^(NSUInteger index, id message) { 220 NSUInteger step = [steps[index] unsignedIntegerValue]; 221 step++; 222 steps[index] = [NSNumber numberWithUnsignedInteger:step]; 223 if (step < kRounds) { 224 [calls[index] writeMessage:requests[step]]; 225 } else { 226 [calls[index] finish]; 227 } 228 }; 229 230 calls[0] = [_remoteService 231 fullDuplexCallWithResponseHandler:[[InteropTestsBlockCallbacks alloc] 232 initWithInitialMetadataCallback:nil 233 messageCallback:^(id message) { 234 handler(0, message); 235 } 236 closeCallback:^(NSDictionary *trailingMetadata, 237 NSError *error) { 238 XCTAssertNil(error); 239 [expectRemote fulfill]; 240 } 241 writeMessageCallback:nil] 242 callOptions:nil]; 243 calls[1] = [_remoteCronetService 244 fullDuplexCallWithResponseHandler:[[InteropTestsBlockCallbacks alloc] 245 initWithInitialMetadataCallback:nil 246 messageCallback:^(id message) { 247 handler(1, message); 248 } 249 closeCallback:^(NSDictionary *trailingMetadata, 250 NSError *error) { 251 XCTAssertNil(error); 252 [expectCronetRemote fulfill]; 253 } 254 writeMessageCallback:nil] 255 callOptions:nil]; 256 calls[2] = [_localCleartextService 257 fullDuplexCallWithResponseHandler:[[InteropTestsBlockCallbacks alloc] 258 initWithInitialMetadataCallback:nil 259 messageCallback:^(id message) { 260 handler(2, message); 261 } 262 closeCallback:^(NSDictionary *trailingMetadata, 263 NSError *error) { 264 XCTAssertNil(error); 265 [expectCleartext fulfill]; 266 } 267 writeMessageCallback:nil] 268 callOptions:nil]; 269 calls[3] = [_localSSLService 270 fullDuplexCallWithResponseHandler:[[InteropTestsBlockCallbacks alloc] 271 initWithInitialMetadataCallback:nil 272 messageCallback:^(id message) { 273 handler(3, message); 274 } 275 closeCallback:^(NSDictionary *trailingMetadata, 276 NSError *error) { 277 XCTAssertNil(error); 278 [expectSSL fulfill]; 279 } 280 writeMessageCallback:nil] 281 callOptions:nil]; 282 for (int i = 0; i < 4; i++) { 283 [calls[i] start]; 284 [calls[i] writeMessage:requests[0]]; 285 } 286 287 [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; 288} 289 290@end 291