| /* |
| * |
| * Copyright 2018 gRPC authors. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| */ |
| |
| #import <XCTest/XCTest.h> |
| |
| #import <Cronet/Cronet.h> |
| #import <GRPCClient/GRPCCallOptions.h> |
| #import <RxLibrary/GRXBufferedPipe.h> |
| #import "src/objective-c/tests/RemoteTestClient/Messages.pbobjc.h" |
| #import "src/objective-c/tests/RemoteTestClient/Test.pbobjc.h" |
| #import "src/objective-c/tests/RemoteTestClient/Test.pbrpc.h" |
| |
| #import "../ConfigureCronet.h" |
| #import "InteropTestsBlockCallbacks.h" |
| |
| #define NSStringize_helper(x) #x |
| #define NSStringize(x) @NSStringize_helper(x) |
| static NSString *const kRemoteSSLHost = NSStringize(HOST_PORT_REMOTE); |
| static NSString *const kLocalSSLHost = NSStringize(HOST_PORT_LOCALSSL); |
| static NSString *const kLocalCleartextHost = NSStringize(HOST_PORT_LOCAL); |
| |
| static const NSTimeInterval TEST_TIMEOUT = 8000; |
| |
| @interface RMTStreamingOutputCallRequest (Constructors) |
| + (instancetype)messageWithPayloadSize:(NSNumber *)payloadSize |
| requestedResponseSize:(NSNumber *)responseSize; |
| @end |
| |
| @implementation RMTStreamingOutputCallRequest (Constructors) |
| + (instancetype)messageWithPayloadSize:(NSNumber *)payloadSize |
| requestedResponseSize:(NSNumber *)responseSize { |
| RMTStreamingOutputCallRequest *request = [self message]; |
| RMTResponseParameters *parameters = [RMTResponseParameters message]; |
| parameters.size = responseSize.intValue; |
| [request.responseParametersArray addObject:parameters]; |
| request.payload.body = [NSMutableData dataWithLength:payloadSize.unsignedIntegerValue]; |
| return request; |
| } |
| @end |
| |
| @interface RMTStreamingOutputCallResponse (Constructors) |
| + (instancetype)messageWithPayloadSize:(NSNumber *)payloadSize; |
| @end |
| |
| @implementation RMTStreamingOutputCallResponse (Constructors) |
| + (instancetype)messageWithPayloadSize:(NSNumber *)payloadSize { |
| RMTStreamingOutputCallResponse *response = [self message]; |
| response.payload.type = RMTPayloadType_Compressable; |
| response.payload.body = [NSMutableData dataWithLength:payloadSize.unsignedIntegerValue]; |
| return response; |
| } |
| @end |
| |
| @interface InteropTestsMultipleChannels : XCTestCase |
| |
| @end |
| |
| dispatch_once_t initCronet; |
| |
| @implementation InteropTestsMultipleChannels { |
| RMTTestService *_remoteService; |
| RMTTestService *_remoteCronetService; |
| RMTTestService *_localCleartextService; |
| RMTTestService *_localSSLService; |
| } |
| |
| - (void)setUp { |
| [super setUp]; |
| |
| self.continueAfterFailure = NO; |
| |
| _remoteService = [RMTTestService serviceWithHost:kRemoteSSLHost callOptions:nil]; |
| configureCronet(/*enable_netlog=*/false); |
| |
| // Default stack with remote host |
| GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; |
| options.transportType = GRPCTransportTypeCronet; |
| // Cronet stack with remote host |
| _remoteCronetService = [RMTTestService serviceWithHost:kRemoteSSLHost callOptions:options]; |
| |
| // Local stack with no SSL |
| options = [[GRPCMutableCallOptions alloc] init]; |
| options.transportType = GRPCTransportTypeInsecure; |
| _localCleartextService = [RMTTestService serviceWithHost:kLocalCleartextHost callOptions:options]; |
| |
| // Local stack with SSL |
| NSBundle *bundle = [NSBundle bundleForClass:[self class]]; |
| NSString *certsPath = |
| [bundle pathForResource:@"TestCertificates.bundle/test-certificates" ofType:@"pem"]; |
| NSError *error = nil; |
| NSString *certs = |
| [NSString stringWithContentsOfFile:certsPath encoding:NSUTF8StringEncoding error:&error]; |
| XCTAssertNil(error); |
| |
| options = [[GRPCMutableCallOptions alloc] init]; |
| options.transportType = GRPCTransportTypeChttp2BoringSSL; |
| options.PEMRootCertificates = certs; |
| options.hostNameOverride = @"foo.test.google.fr"; |
| _localSSLService = [RMTTestService serviceWithHost:kLocalSSLHost callOptions:options]; |
| } |
| |
| - (void)testEmptyUnaryRPC { |
| __weak XCTestExpectation *expectRemote = [self expectationWithDescription:@"Remote RPC finish"]; |
| __weak XCTestExpectation *expectCronetRemote = |
| [self expectationWithDescription:@"Remote RPC finish"]; |
| __weak XCTestExpectation *expectCleartext = |
| [self expectationWithDescription:@"Remote RPC finish"]; |
| __weak XCTestExpectation *expectSSL = [self expectationWithDescription:@"Remote RPC finish"]; |
| |
| GPBEmpty *request = [GPBEmpty message]; |
| |
| void (^messageHandler)(id message) = ^(id message) { |
| id expectedResponse = [GPBEmpty message]; |
| XCTAssertEqualObjects(message, expectedResponse); |
| }; |
| |
| GRPCUnaryProtoCall *callRemote = [_remoteService |
| emptyCallWithMessage:request |
| responseHandler:[[InteropTestsBlockCallbacks alloc] |
| initWithInitialMetadataCallback:nil |
| messageCallback:messageHandler |
| closeCallback:^(NSDictionary *trailingMetadata, |
| NSError *error) { |
| XCTAssertNil(error); |
| [expectRemote fulfill]; |
| } |
| writeMessageCallback:nil] |
| callOptions:nil]; |
| GRPCUnaryProtoCall *callCronet = [_remoteCronetService |
| emptyCallWithMessage:request |
| responseHandler:[[InteropTestsBlockCallbacks alloc] |
| initWithInitialMetadataCallback:nil |
| messageCallback:messageHandler |
| closeCallback:^(NSDictionary *trailingMetadata, |
| NSError *error) { |
| XCTAssertNil(error); |
| [expectCronetRemote fulfill]; |
| } |
| writeMessageCallback:nil] |
| callOptions:nil]; |
| GRPCUnaryProtoCall *callCleartext = [_localCleartextService |
| emptyCallWithMessage:request |
| responseHandler:[[InteropTestsBlockCallbacks alloc] |
| initWithInitialMetadataCallback:nil |
| messageCallback:messageHandler |
| closeCallback:^(NSDictionary *trailingMetadata, |
| NSError *error) { |
| XCTAssertNil(error); |
| [expectCleartext fulfill]; |
| } |
| writeMessageCallback:nil] |
| callOptions:nil]; |
| GRPCUnaryProtoCall *callSSL = [_localSSLService |
| emptyCallWithMessage:request |
| responseHandler:[[InteropTestsBlockCallbacks alloc] |
| initWithInitialMetadataCallback:nil |
| messageCallback:messageHandler |
| closeCallback:^(NSDictionary *trailingMetadata, |
| NSError *error) { |
| XCTAssertNil(error); |
| [expectSSL fulfill]; |
| } |
| writeMessageCallback:nil] |
| callOptions:nil]; |
| [callRemote start]; |
| [callCronet start]; |
| [callCleartext start]; |
| [callSSL start]; |
| |
| [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; |
| } |
| |
| - (void)testFullDuplexRPC { |
| __weak XCTestExpectation *expectRemote = [self expectationWithDescription:@"Remote RPC finish"]; |
| __weak XCTestExpectation *expectCronetRemote = |
| [self expectationWithDescription:@"Remote RPC finish"]; |
| __weak XCTestExpectation *expectCleartext = |
| [self expectationWithDescription:@"Remote RPC finish"]; |
| __weak XCTestExpectation *expectSSL = [self expectationWithDescription:@"Remote RPC finish"]; |
| |
| NSArray *requestSizes = @[ @100, @101, @102, @103 ]; |
| NSArray *responseSizes = @[ @104, @105, @106, @107 ]; |
| XCTAssertEqual([requestSizes count], [responseSizes count]); |
| NSUInteger kRounds = [requestSizes count]; |
| NSMutableArray<GRPCStreamingProtoCall *> *calls = [NSMutableArray arrayWithCapacity:4]; |
| |
| NSMutableArray *requests = [NSMutableArray arrayWithCapacity:kRounds]; |
| NSMutableArray *responses = [NSMutableArray arrayWithCapacity:kRounds]; |
| for (int i = 0; i < kRounds; i++) { |
| requests[i] = [RMTStreamingOutputCallRequest messageWithPayloadSize:requestSizes[i] |
| requestedResponseSize:responseSizes[i]]; |
| responses[i] = [RMTStreamingOutputCallResponse messageWithPayloadSize:responseSizes[i]]; |
| } |
| |
| __block NSMutableArray *steps = [NSMutableArray arrayWithCapacity:4]; |
| __block NSMutableArray *requestsBuffers = [NSMutableArray arrayWithCapacity:4]; |
| for (int i = 0; i < 4; i++) { |
| steps[i] = [NSNumber numberWithUnsignedInteger:0]; |
| requestsBuffers[i] = [[GRXBufferedPipe alloc] init]; |
| [requestsBuffers[i] writeValue:requests[0]]; |
| } |
| |
| void (^handler)(NSUInteger index, id message) = ^(NSUInteger index, id message) { |
| NSUInteger step = [steps[index] unsignedIntegerValue]; |
| step++; |
| steps[index] = [NSNumber numberWithUnsignedInteger:step]; |
| if (step < kRounds) { |
| [calls[index] writeMessage:requests[step]]; |
| } else { |
| [calls[index] finish]; |
| } |
| }; |
| |
| calls[0] = [_remoteService |
| fullDuplexCallWithResponseHandler:[[InteropTestsBlockCallbacks alloc] |
| initWithInitialMetadataCallback:nil |
| messageCallback:^(id message) { |
| handler(0, message); |
| } |
| closeCallback:^(NSDictionary *trailingMetadata, |
| NSError *error) { |
| XCTAssertNil(error); |
| [expectRemote fulfill]; |
| } |
| writeMessageCallback:nil] |
| callOptions:nil]; |
| calls[1] = [_remoteCronetService |
| fullDuplexCallWithResponseHandler:[[InteropTestsBlockCallbacks alloc] |
| initWithInitialMetadataCallback:nil |
| messageCallback:^(id message) { |
| handler(1, message); |
| } |
| closeCallback:^(NSDictionary *trailingMetadata, |
| NSError *error) { |
| XCTAssertNil(error); |
| [expectCronetRemote fulfill]; |
| } |
| writeMessageCallback:nil] |
| callOptions:nil]; |
| calls[2] = [_localCleartextService |
| fullDuplexCallWithResponseHandler:[[InteropTestsBlockCallbacks alloc] |
| initWithInitialMetadataCallback:nil |
| messageCallback:^(id message) { |
| handler(2, message); |
| } |
| closeCallback:^(NSDictionary *trailingMetadata, |
| NSError *error) { |
| XCTAssertNil(error); |
| [expectCleartext fulfill]; |
| } |
| writeMessageCallback:nil] |
| callOptions:nil]; |
| calls[3] = [_localSSLService |
| fullDuplexCallWithResponseHandler:[[InteropTestsBlockCallbacks alloc] |
| initWithInitialMetadataCallback:nil |
| messageCallback:^(id message) { |
| handler(3, message); |
| } |
| closeCallback:^(NSDictionary *trailingMetadata, |
| NSError *error) { |
| XCTAssertNil(error); |
| [expectSSL fulfill]; |
| } |
| writeMessageCallback:nil] |
| callOptions:nil]; |
| for (int i = 0; i < 4; i++) { |
| [calls[i] start]; |
| [calls[i] writeMessage:requests[0]]; |
| } |
| |
| [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; |
| } |
| |
| @end |