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