1*cc02d7e2SAndroid Build Coastguard Worker/* 2*cc02d7e2SAndroid Build Coastguard Worker * 3*cc02d7e2SAndroid Build Coastguard Worker * Copyright 2015 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 <GRPCClient/GRPCCall+Tests.h> 20*cc02d7e2SAndroid Build Coastguard Worker#import <GRPCClient/GRPCCall.h> 21*cc02d7e2SAndroid Build Coastguard Worker#import <GRPCClient/internal_testing/GRPCCall+InternalTests.h> 22*cc02d7e2SAndroid Build Coastguard Worker#import <RxLibrary/GRXWriter+Immediate.h> 23*cc02d7e2SAndroid Build Coastguard Worker 24*cc02d7e2SAndroid Build Coastguard Worker#import "../Common/GRPCBlockCallbackResponseHandler.h" 25*cc02d7e2SAndroid Build Coastguard Worker 26*cc02d7e2SAndroid Build Coastguard Worker#import "src/objective-c/tests/RemoteTestClient/Messages.pbobjc.h" 27*cc02d7e2SAndroid Build Coastguard Worker#import "src/objective-c/tests/RemoteTestClient/Test.pbobjc.h" 28*cc02d7e2SAndroid Build Coastguard Worker#import "src/objective-c/tests/RemoteTestClient/Test.pbrpc.h" 29*cc02d7e2SAndroid Build Coastguard Worker 30*cc02d7e2SAndroid Build Coastguard Worker#import "../Common/TestUtils.h" 31*cc02d7e2SAndroid Build Coastguard Worker#import "InteropTests.h" 32*cc02d7e2SAndroid Build Coastguard Worker 33*cc02d7e2SAndroid Build Coastguard Worker// Package and service name of test server 34*cc02d7e2SAndroid Build Coastguard Workerstatic NSString *const kPackage = @"grpc.testing"; 35*cc02d7e2SAndroid Build Coastguard Workerstatic NSString *const kService = @"TestService"; 36*cc02d7e2SAndroid Build Coastguard Worker 37*cc02d7e2SAndroid Build Coastguard Worker// The Protocol Buffers encoding overhead of remote interop server. Acquired 38*cc02d7e2SAndroid Build Coastguard Worker// by experiment. Adjust this when server's proto file changes. 39*cc02d7e2SAndroid Build Coastguard Workerstatic int32_t kRemoteInteropServerOverhead = 12; 40*cc02d7e2SAndroid Build Coastguard Worker 41*cc02d7e2SAndroid Build Coastguard Workerstatic GRPCProtoMethod *kUnaryCallMethod; 42*cc02d7e2SAndroid Build Coastguard Worker 43*cc02d7e2SAndroid Build Coastguard Worker/** Tests in InteropTests.m, sending the RPCs to a remote SSL server. */ 44*cc02d7e2SAndroid Build Coastguard Worker@interface InteropTestsRemote : InteropTests 45*cc02d7e2SAndroid Build Coastguard Worker@end 46*cc02d7e2SAndroid Build Coastguard Worker 47*cc02d7e2SAndroid Build Coastguard Worker@implementation InteropTestsRemote 48*cc02d7e2SAndroid Build Coastguard Worker 49*cc02d7e2SAndroid Build Coastguard Worker#pragma mark - InteropTests 50*cc02d7e2SAndroid Build Coastguard Worker 51*cc02d7e2SAndroid Build Coastguard Worker+ (NSString *)host { 52*cc02d7e2SAndroid Build Coastguard Worker return GRPCGetRemoteInteropTestServerAddress(); 53*cc02d7e2SAndroid Build Coastguard Worker} 54*cc02d7e2SAndroid Build Coastguard Worker 55*cc02d7e2SAndroid Build Coastguard Worker+ (NSString *)PEMRootCertificates { 56*cc02d7e2SAndroid Build Coastguard Worker return nil; 57*cc02d7e2SAndroid Build Coastguard Worker} 58*cc02d7e2SAndroid Build Coastguard Worker 59*cc02d7e2SAndroid Build Coastguard Worker+ (NSString *)hostNameOverride { 60*cc02d7e2SAndroid Build Coastguard Worker return nil; 61*cc02d7e2SAndroid Build Coastguard Worker} 62*cc02d7e2SAndroid Build Coastguard Worker 63*cc02d7e2SAndroid Build Coastguard Worker- (int32_t)encodingOverhead { 64*cc02d7e2SAndroid Build Coastguard Worker return kRemoteInteropServerOverhead; // bytes 65*cc02d7e2SAndroid Build Coastguard Worker} 66*cc02d7e2SAndroid Build Coastguard Worker 67*cc02d7e2SAndroid Build Coastguard Worker+ (GRPCTransportType)transportType { 68*cc02d7e2SAndroid Build Coastguard Worker return GRPCTransportTypeChttp2BoringSSL; 69*cc02d7e2SAndroid Build Coastguard Worker} 70*cc02d7e2SAndroid Build Coastguard Worker 71*cc02d7e2SAndroid Build Coastguard Worker+ (BOOL)isRemoteTest { 72*cc02d7e2SAndroid Build Coastguard Worker return YES; 73*cc02d7e2SAndroid Build Coastguard Worker} 74*cc02d7e2SAndroid Build Coastguard Worker 75*cc02d7e2SAndroid Build Coastguard Worker#pragma mark - InteropTestsRemote tests 76*cc02d7e2SAndroid Build Coastguard Worker 77*cc02d7e2SAndroid Build Coastguard Worker- (void)setUp { 78*cc02d7e2SAndroid Build Coastguard Worker [super setUp]; 79*cc02d7e2SAndroid Build Coastguard Worker 80*cc02d7e2SAndroid Build Coastguard Worker kUnaryCallMethod = [[GRPCProtoMethod alloc] initWithPackage:kPackage 81*cc02d7e2SAndroid Build Coastguard Worker service:kService 82*cc02d7e2SAndroid Build Coastguard Worker method:@"UnaryCall"]; 83*cc02d7e2SAndroid Build Coastguard Worker} 84*cc02d7e2SAndroid Build Coastguard Worker 85*cc02d7e2SAndroid Build Coastguard Worker- (void)testMetadataForV2Call { 86*cc02d7e2SAndroid Build Coastguard Worker GRPCTestRunWithFlakeRepeats(self, ^(GRPCTestWaiter waiterBlock, GRPCTestAssert assertBlock) { 87*cc02d7e2SAndroid Build Coastguard Worker XCTestExpectation *expectation = [self expectationWithDescription:@"RPC unauthorized."]; 88*cc02d7e2SAndroid Build Coastguard Worker 89*cc02d7e2SAndroid Build Coastguard Worker RMTSimpleRequest *request = [RMTSimpleRequest message]; 90*cc02d7e2SAndroid Build Coastguard Worker request.fillUsername = YES; 91*cc02d7e2SAndroid Build Coastguard Worker request.fillOauthScope = YES; 92*cc02d7e2SAndroid Build Coastguard Worker 93*cc02d7e2SAndroid Build Coastguard Worker GRPCRequestOptions *callRequest = 94*cc02d7e2SAndroid Build Coastguard Worker [[GRPCRequestOptions alloc] initWithHost:[[self class] host] 95*cc02d7e2SAndroid Build Coastguard Worker path:kUnaryCallMethod.HTTPPath 96*cc02d7e2SAndroid Build Coastguard Worker safety:GRPCCallSafetyDefault]; 97*cc02d7e2SAndroid Build Coastguard Worker __block NSDictionary *init_md; 98*cc02d7e2SAndroid Build Coastguard Worker __block NSDictionary *trailing_md; 99*cc02d7e2SAndroid Build Coastguard Worker GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; 100*cc02d7e2SAndroid Build Coastguard Worker options.oauth2AccessToken = @"bogusToken"; 101*cc02d7e2SAndroid Build Coastguard Worker 102*cc02d7e2SAndroid Build Coastguard Worker GRPCCall2 *call = [[GRPCCall2 alloc] 103*cc02d7e2SAndroid Build Coastguard Worker initWithRequestOptions:callRequest 104*cc02d7e2SAndroid Build Coastguard Worker responseHandler:[[GRPCBlockCallbackResponseHandler alloc] 105*cc02d7e2SAndroid Build Coastguard Worker initWithInitialMetadataCallback:^( 106*cc02d7e2SAndroid Build Coastguard Worker NSDictionary *initialMetadata) { 107*cc02d7e2SAndroid Build Coastguard Worker init_md = initialMetadata; 108*cc02d7e2SAndroid Build Coastguard Worker } 109*cc02d7e2SAndroid Build Coastguard Worker messageCallback:^(id message) { 110*cc02d7e2SAndroid Build Coastguard Worker XCTFail(@"Received unexpected response."); 111*cc02d7e2SAndroid Build Coastguard Worker } 112*cc02d7e2SAndroid Build Coastguard Worker closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { 113*cc02d7e2SAndroid Build Coastguard Worker trailing_md = trailingMetadata; 114*cc02d7e2SAndroid Build Coastguard Worker if (error) { 115*cc02d7e2SAndroid Build Coastguard Worker XCTAssertEqual(error.code, 16, 116*cc02d7e2SAndroid Build Coastguard Worker @"Finished with unexpected error: %@", error); 117*cc02d7e2SAndroid Build Coastguard Worker XCTAssertEqualObjects(init_md, 118*cc02d7e2SAndroid Build Coastguard Worker error.userInfo[kGRPCHeadersKey]); 119*cc02d7e2SAndroid Build Coastguard Worker XCTAssertEqualObjects(trailing_md, 120*cc02d7e2SAndroid Build Coastguard Worker error.userInfo[kGRPCTrailersKey]); 121*cc02d7e2SAndroid Build Coastguard Worker NSString *challengeHeader = init_md[@"www-authenticate"]; 122*cc02d7e2SAndroid Build Coastguard Worker XCTAssertGreaterThan(challengeHeader.length, 0, 123*cc02d7e2SAndroid Build Coastguard Worker @"No challenge in response headers %@", 124*cc02d7e2SAndroid Build Coastguard Worker init_md); 125*cc02d7e2SAndroid Build Coastguard Worker [expectation fulfill]; 126*cc02d7e2SAndroid Build Coastguard Worker } 127*cc02d7e2SAndroid Build Coastguard Worker }] 128*cc02d7e2SAndroid Build Coastguard Worker callOptions:options]; 129*cc02d7e2SAndroid Build Coastguard Worker 130*cc02d7e2SAndroid Build Coastguard Worker [call start]; 131*cc02d7e2SAndroid Build Coastguard Worker [call writeData:[request data]]; 132*cc02d7e2SAndroid Build Coastguard Worker [call finish]; 133*cc02d7e2SAndroid Build Coastguard Worker 134*cc02d7e2SAndroid Build Coastguard Worker waiterBlock(@[ expectation ], GRPCInteropTestTimeoutDefault); 135*cc02d7e2SAndroid Build Coastguard Worker }); 136*cc02d7e2SAndroid Build Coastguard Worker} 137*cc02d7e2SAndroid Build Coastguard Worker 138*cc02d7e2SAndroid Build Coastguard Worker- (void)testMetadataForV1Call { 139*cc02d7e2SAndroid Build Coastguard Worker GRPCTestRunWithFlakeRepeats(self, ^(GRPCTestWaiter waiterBlock, GRPCTestAssert assertBlock) { 140*cc02d7e2SAndroid Build Coastguard Worker XCTestExpectation *expectation = [self expectationWithDescription:@"RPC unauthorized."]; 141*cc02d7e2SAndroid Build Coastguard Worker 142*cc02d7e2SAndroid Build Coastguard Worker RMTSimpleRequest *request = [RMTSimpleRequest message]; 143*cc02d7e2SAndroid Build Coastguard Worker request.fillUsername = YES; 144*cc02d7e2SAndroid Build Coastguard Worker request.fillOauthScope = YES; 145*cc02d7e2SAndroid Build Coastguard Worker GRXWriter *requestsWriter = [GRXWriter writerWithValue:[request data]]; 146*cc02d7e2SAndroid Build Coastguard Worker 147*cc02d7e2SAndroid Build Coastguard Worker GRPCCall *call = [[GRPCCall alloc] initWithHost:GRPCGetRemoteInteropTestServerAddress() 148*cc02d7e2SAndroid Build Coastguard Worker path:kUnaryCallMethod.HTTPPath 149*cc02d7e2SAndroid Build Coastguard Worker requestsWriter:requestsWriter]; 150*cc02d7e2SAndroid Build Coastguard Worker GRPCCall *weakCall = call; 151*cc02d7e2SAndroid Build Coastguard Worker 152*cc02d7e2SAndroid Build Coastguard Worker call.oauth2AccessToken = @"bogusToken"; 153*cc02d7e2SAndroid Build Coastguard Worker 154*cc02d7e2SAndroid Build Coastguard Worker id<GRXWriteable> responsesWriteable = [[GRXWriteable alloc] 155*cc02d7e2SAndroid Build Coastguard Worker initWithValueHandler:^(NSData *value) { 156*cc02d7e2SAndroid Build Coastguard Worker if (weakCall == nil) { 157*cc02d7e2SAndroid Build Coastguard Worker return; 158*cc02d7e2SAndroid Build Coastguard Worker } 159*cc02d7e2SAndroid Build Coastguard Worker XCTFail(@"Received unexpected response: %@", value); 160*cc02d7e2SAndroid Build Coastguard Worker } 161*cc02d7e2SAndroid Build Coastguard Worker completionHandler:^(NSError *errorOrNil) { 162*cc02d7e2SAndroid Build Coastguard Worker GRPCCall *localCall = weakCall; 163*cc02d7e2SAndroid Build Coastguard Worker if (localCall == nil) { 164*cc02d7e2SAndroid Build Coastguard Worker return; 165*cc02d7e2SAndroid Build Coastguard Worker } 166*cc02d7e2SAndroid Build Coastguard Worker 167*cc02d7e2SAndroid Build Coastguard Worker XCTAssertNotNil(errorOrNil, @"Finished without error!"); 168*cc02d7e2SAndroid Build Coastguard Worker XCTAssertEqual(errorOrNil.code, 16, @"Finished with unexpected error: %@", errorOrNil); 169*cc02d7e2SAndroid Build Coastguard Worker XCTAssertEqualObjects(localCall.responseHeaders, errorOrNil.userInfo[kGRPCHeadersKey], 170*cc02d7e2SAndroid Build Coastguard Worker @"Headers in the NSError object and call object differ."); 171*cc02d7e2SAndroid Build Coastguard Worker XCTAssertEqualObjects(localCall.responseTrailers, errorOrNil.userInfo[kGRPCTrailersKey], 172*cc02d7e2SAndroid Build Coastguard Worker @"Trailers in the NSError object and call object differ."); 173*cc02d7e2SAndroid Build Coastguard Worker NSString *challengeHeader = localCall.oauth2ChallengeHeader; 174*cc02d7e2SAndroid Build Coastguard Worker XCTAssertGreaterThan(challengeHeader.length, 0, @"No challenge in response headers %@", 175*cc02d7e2SAndroid Build Coastguard Worker localCall.responseHeaders); 176*cc02d7e2SAndroid Build Coastguard Worker [expectation fulfill]; 177*cc02d7e2SAndroid Build Coastguard Worker }]; 178*cc02d7e2SAndroid Build Coastguard Worker 179*cc02d7e2SAndroid Build Coastguard Worker [call startWithWriteable:responsesWriteable]; 180*cc02d7e2SAndroid Build Coastguard Worker 181*cc02d7e2SAndroid Build Coastguard Worker waiterBlock(@[ expectation ], GRPCInteropTestTimeoutDefault); 182*cc02d7e2SAndroid Build Coastguard Worker }); 183*cc02d7e2SAndroid Build Coastguard Worker} 184*cc02d7e2SAndroid Build Coastguard Worker 185*cc02d7e2SAndroid Build Coastguard Worker- (void)testErrorDebugInformation { 186*cc02d7e2SAndroid Build Coastguard Worker GRPCTestRunWithFlakeRepeats(self, ^(GRPCTestWaiter waiterBlock, GRPCTestAssert assertBlock) { 187*cc02d7e2SAndroid Build Coastguard Worker XCTestExpectation *expectation = [self expectationWithDescription:@"RPC unauthorized."]; 188*cc02d7e2SAndroid Build Coastguard Worker 189*cc02d7e2SAndroid Build Coastguard Worker RMTSimpleRequest *request = [RMTSimpleRequest message]; 190*cc02d7e2SAndroid Build Coastguard Worker request.fillUsername = YES; 191*cc02d7e2SAndroid Build Coastguard Worker request.fillOauthScope = YES; 192*cc02d7e2SAndroid Build Coastguard Worker GRXWriter *requestsWriter = [GRXWriter writerWithValue:[request data]]; 193*cc02d7e2SAndroid Build Coastguard Worker 194*cc02d7e2SAndroid Build Coastguard Worker GRPCCall *call = [[GRPCCall alloc] initWithHost:GRPCGetRemoteInteropTestServerAddress() 195*cc02d7e2SAndroid Build Coastguard Worker path:kUnaryCallMethod.HTTPPath 196*cc02d7e2SAndroid Build Coastguard Worker requestsWriter:requestsWriter]; 197*cc02d7e2SAndroid Build Coastguard Worker GRPCCall *weakCall = call; 198*cc02d7e2SAndroid Build Coastguard Worker 199*cc02d7e2SAndroid Build Coastguard Worker call.oauth2AccessToken = @"bogusToken"; 200*cc02d7e2SAndroid Build Coastguard Worker 201*cc02d7e2SAndroid Build Coastguard Worker id<GRXWriteable> responsesWriteable = [[GRXWriteable alloc] 202*cc02d7e2SAndroid Build Coastguard Worker initWithValueHandler:^(NSData *value) { 203*cc02d7e2SAndroid Build Coastguard Worker if (weakCall == nil) { 204*cc02d7e2SAndroid Build Coastguard Worker return; 205*cc02d7e2SAndroid Build Coastguard Worker } 206*cc02d7e2SAndroid Build Coastguard Worker XCTFail(@"Received unexpected response: %@", value); 207*cc02d7e2SAndroid Build Coastguard Worker } 208*cc02d7e2SAndroid Build Coastguard Worker completionHandler:^(NSError *errorOrNil) { 209*cc02d7e2SAndroid Build Coastguard Worker GRPCCall *localCall = weakCall; 210*cc02d7e2SAndroid Build Coastguard Worker if (localCall == nil) { 211*cc02d7e2SAndroid Build Coastguard Worker return; 212*cc02d7e2SAndroid Build Coastguard Worker } 213*cc02d7e2SAndroid Build Coastguard Worker XCTAssertNotNil(errorOrNil, @"Finished without error!"); 214*cc02d7e2SAndroid Build Coastguard Worker NSDictionary *userInfo = errorOrNil.userInfo; 215*cc02d7e2SAndroid Build Coastguard Worker NSString *debugInformation = userInfo[NSDebugDescriptionErrorKey]; 216*cc02d7e2SAndroid Build Coastguard Worker XCTAssertNotNil(debugInformation); 217*cc02d7e2SAndroid Build Coastguard Worker XCTAssertNotEqual([debugInformation length], 0); 218*cc02d7e2SAndroid Build Coastguard Worker NSString *challengeHeader = localCall.oauth2ChallengeHeader; 219*cc02d7e2SAndroid Build Coastguard Worker XCTAssertGreaterThan(challengeHeader.length, 0, @"No challenge in response headers %@", 220*cc02d7e2SAndroid Build Coastguard Worker localCall.responseHeaders); 221*cc02d7e2SAndroid Build Coastguard Worker [expectation fulfill]; 222*cc02d7e2SAndroid Build Coastguard Worker }]; 223*cc02d7e2SAndroid Build Coastguard Worker 224*cc02d7e2SAndroid Build Coastguard Worker [call startWithWriteable:responsesWriteable]; 225*cc02d7e2SAndroid Build Coastguard Worker 226*cc02d7e2SAndroid Build Coastguard Worker waiterBlock(@[ expectation ], GRPCInteropTestTimeoutDefault); 227*cc02d7e2SAndroid Build Coastguard Worker }); 228*cc02d7e2SAndroid Build Coastguard Worker} 229*cc02d7e2SAndroid Build Coastguard Worker 230*cc02d7e2SAndroid Build Coastguard Worker@end 231