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