From 17a67fdb0fb01fe34c75d2c6bf34e24214222a89 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 2 Nov 2018 14:48:56 -0700 Subject: [PATCH] Aggregate v2 api tests --- src/objective-c/GRPCClient/GRPCCall.m | 2 +- src/objective-c/GRPCClient/GRPCCallOptions.h | 2 +- src/objective-c/tests/APIv2Tests/APIv2Tests.m | 482 ++++++++++++++++++ src/objective-c/tests/APIv2Tests/Info.plist | 22 + src/objective-c/tests/GRPCClientTests.m | 291 ----------- src/objective-c/tests/Podfile | 1 + .../tests/Tests.xcodeproj/project.pbxproj | 263 ++++++++++ .../xcschemes/APIv2Tests.xcscheme | 90 ++++ src/objective-c/tests/run_tests.sh | 10 + 9 files changed, 870 insertions(+), 293 deletions(-) create mode 100644 src/objective-c/tests/APIv2Tests/APIv2Tests.m create mode 100644 src/objective-c/tests/APIv2Tests/Info.plist create mode 100644 src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/APIv2Tests.xcscheme diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 8e7d5a5f94b..2abc0fe8f3b 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -780,7 +780,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; @synchronized(self) { self.isWaitingForToken = YES; } - [self.tokenProvider getTokenWithHandler:^(NSString *token) { + [_callOptions.authTokenProvider getTokenWithHandler:^(NSString *token) { @synchronized(self) { if (self.isWaitingForToken) { if (token) { diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index 9683bd3c638..77fde371bc0 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -64,7 +64,7 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { * This method is called when gRPC is about to start the call. When OAuth token is acquired, * \a handler is expected to be called with \a token being the new token to be used for this call. */ -- (void)getTokenWithHandler:(void (^)(NSString *token))hander; +- (void)getTokenWithHandler:(void (^)(NSString *token))handler; @end @interface GRPCCallOptions : NSObject diff --git a/src/objective-c/tests/APIv2Tests/APIv2Tests.m b/src/objective-c/tests/APIv2Tests/APIv2Tests.m new file mode 100644 index 00000000000..7fc353391f3 --- /dev/null +++ b/src/objective-c/tests/APIv2Tests/APIv2Tests.m @@ -0,0 +1,482 @@ +/* + * + * 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 +#import +#import +#import + +#include + +#import "../version.h" + +// The server address is derived from preprocessor macro, which is +// in turn derived from environment variable of the same name. +#define NSStringize_helper(x) #x +#define NSStringize(x) @NSStringize_helper(x) +static NSString *const kHostAddress = NSStringize(HOST_PORT_LOCAL); +static NSString *const kRemoteSSLHost = NSStringize(HOST_PORT_REMOTE); + +// Package and service name of test server +static NSString *const kPackage = @"grpc.testing"; +static NSString *const kService = @"TestService"; + +static GRPCProtoMethod *kInexistentMethod; +static GRPCProtoMethod *kEmptyCallMethod; +static GRPCProtoMethod *kUnaryCallMethod; +static GRPCProtoMethod *kFullDuplexCallMethod; + +static const int kSimpleDataLength = 100; + +static const NSTimeInterval kTestTimeout = 16; + +// Reveal the _class ivar for testing access +@interface GRPCCall2 () { + @public + GRPCCall *_call; +} + +@end + +// Convenience class to use blocks as callbacks +@interface ClientTestsBlockCallbacks : NSObject + +- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback + messageCallback:(void (^)(id))messageCallback + closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback; + +@end + +@implementation ClientTestsBlockCallbacks { + void (^_initialMetadataCallback)(NSDictionary *); + void (^_messageCallback)(id); + void (^_closeCallback)(NSDictionary *, NSError *); + dispatch_queue_t _dispatchQueue; +} + +- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback + messageCallback:(void (^)(id))messageCallback + closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback { + if ((self = [super init])) { + _initialMetadataCallback = initialMetadataCallback; + _messageCallback = messageCallback; + _closeCallback = closeCallback; + _dispatchQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL); + } + return self; +} + +- (void)receivedInitialMetadata:(NSDictionary *_Nullable)initialMetadata { + dispatch_async(_dispatchQueue, ^{ + if (self->_initialMetadataCallback) { + self->_initialMetadataCallback(initialMetadata); + } + }); +} + +- (void)receivedRawMessage:(GPBMessage *_Nullable)message { + dispatch_async(_dispatchQueue, ^{ + if (self->_messageCallback) { + self->_messageCallback(message); + } + }); +} + +- (void)closedWithTrailingMetadata:(NSDictionary *_Nullable)trailingMetadata + error:(NSError *_Nullable)error { + dispatch_async(_dispatchQueue, ^{ + if (self->_closeCallback) { + self->_closeCallback(trailingMetadata, error); + } + }); +} + +- (dispatch_queue_t)dispatchQueue { + return _dispatchQueue; +} + +@end + +@interface CallAPIv2Tests : XCTestCase + +@end + +@implementation CallAPIv2Tests + +- (void)setUp { + // This method isn't implemented by the remote server. + kInexistentMethod = + [[GRPCProtoMethod alloc] initWithPackage:kPackage service:kService method:@"Inexistent"]; + kEmptyCallMethod = + [[GRPCProtoMethod alloc] initWithPackage:kPackage service:kService method:@"EmptyCall"]; + kUnaryCallMethod = + [[GRPCProtoMethod alloc] initWithPackage:kPackage service:kService method:@"UnaryCall"]; + kFullDuplexCallMethod = + [[GRPCProtoMethod alloc] initWithPackage:kPackage service:kService method:@"FullDuplexCall"]; +} + +- (void)testMetadata { + __weak XCTestExpectation *expectation = [self expectationWithDescription:@"RPC unauthorized."]; + + RMTSimpleRequest *request = [RMTSimpleRequest message]; + request.fillUsername = YES; + request.fillOauthScope = YES; + + GRPCRequestOptions *callRequest = + [[GRPCRequestOptions alloc] initWithHost:(NSString *)kRemoteSSLHost + path:kUnaryCallMethod.HTTPPath + safety:GRPCCallSafetyDefault]; + __block NSDictionary *init_md; + __block NSDictionary *trailing_md; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.oauth2AccessToken = @"bogusToken"; + GRPCCall2 *call = [[GRPCCall2 alloc] + initWithRequestOptions:callRequest + responseHandler:[[ClientTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:^(NSDictionary *initialMetadata) { + init_md = initialMetadata; + } + messageCallback:^(id message) { + XCTFail(@"Received unexpected response."); + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + trailing_md = trailingMetadata; + if (error) { + XCTAssertEqual(error.code, 16, + @"Finished with unexpected error: %@", error); + XCTAssertEqualObjects(init_md, + error.userInfo[kGRPCHeadersKey]); + XCTAssertEqualObjects(trailing_md, + error.userInfo[kGRPCTrailersKey]); + NSString *challengeHeader = init_md[@"www-authenticate"]; + XCTAssertGreaterThan(challengeHeader.length, 0, + @"No challenge in response headers %@", + init_md); + [expectation fulfill]; + } + }] + callOptions:options]; + + [call start]; + [call writeData:[request data]]; + [call finish]; + + [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; +} + +- (void)testUserAgentPrefix { + __weak XCTestExpectation *completion = [self expectationWithDescription:@"Empty RPC completed."]; + __weak XCTestExpectation *recvInitialMd = + [self expectationWithDescription:@"Did not receive initial md."]; + + GRPCRequestOptions *request = [[GRPCRequestOptions alloc] initWithHost:kHostAddress + path:kEmptyCallMethod.HTTPPath + safety:GRPCCallSafetyDefault]; + NSDictionary *headers = + [NSDictionary dictionaryWithObjectsAndKeys:@"", @"x-grpc-test-echo-useragent", nil]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = GRPCTransportTypeInsecure; + options.userAgentPrefix = @"Foo"; + options.initialMetadata = headers; + GRPCCall2 *call = [[GRPCCall2 alloc] + initWithRequestOptions:request + responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:^( + NSDictionary *initialMetadata) { + NSString *userAgent = initialMetadata[@"x-grpc-test-echo-useragent"]; + // Test the regex is correct + NSString *expectedUserAgent = @"Foo grpc-objc/"; + expectedUserAgent = + [expectedUserAgent stringByAppendingString:GRPC_OBJC_VERSION_STRING]; + expectedUserAgent = [expectedUserAgent stringByAppendingString:@" grpc-c/"]; + expectedUserAgent = + [expectedUserAgent stringByAppendingString:GRPC_C_VERSION_STRING]; + expectedUserAgent = [expectedUserAgent stringByAppendingString:@" (ios; chttp2; "]; + expectedUserAgent = [expectedUserAgent + stringByAppendingString:[NSString stringWithUTF8String:grpc_g_stands_for()]]; + expectedUserAgent = [expectedUserAgent stringByAppendingString:@")"]; + XCTAssertEqualObjects(userAgent, expectedUserAgent); + + NSError *error = nil; + // Change in format of user-agent field in a direction that does not match + // the regex will likely cause problem for certain gRPC users. For details, + // refer to internal doc https://goo.gl/c2diBc + NSRegularExpression *regex = [NSRegularExpression + regularExpressionWithPattern: + @" grpc-[a-zA-Z0-9]+(-[a-zA-Z0-9]+)?/[^ ,]+( \\([^)]*\\))?" + options:0 + error:&error]; + + NSString *customUserAgent = + [regex stringByReplacingMatchesInString:userAgent + options:0 + range:NSMakeRange(0, [userAgent length]) + withTemplate:@""]; + XCTAssertEqualObjects(customUserAgent, @"Foo"); + [recvInitialMd fulfill]; + } + messageCallback:^(id message) { + XCTAssertNotNil(message); + XCTAssertEqual([message length], 0, + @"Non-empty response received: %@", message); + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + if (error) { + XCTFail(@"Finished with unexpected error: %@", error); + } else { + [completion fulfill]; + } + }] + callOptions:options]; + [call writeData:[NSData data]]; + [call start]; + + [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; +} + +- (void)getTokenWithHandler:(void (^)(NSString *token))handler { + dispatch_queue_t queue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); + dispatch_sync(queue, ^{ + handler(@"test-access-token"); + }); +} + +- (void)testOAuthToken { + __weak XCTestExpectation *completion = [self expectationWithDescription:@"RPC completed."]; + + GRPCRequestOptions *requestOptions = + [[GRPCRequestOptions alloc] initWithHost:kHostAddress + path:kEmptyCallMethod.HTTPPath + safety:GRPCCallSafetyDefault]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = GRPCTransportTypeInsecure; + options.authTokenProvider = self; + __block GRPCCall2 *call = [[GRPCCall2 alloc] + initWithRequestOptions:requestOptions + responseHandler:[[ClientTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:nil + messageCallback:nil + closeCallback:^(NSDictionary *trailingMetadata, + NSError *error) { + [completion fulfill]; + }] + callOptions:options]; + [call writeData:[NSData data]]; + [call start]; + + [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; +} + +- (void)testResponseSizeLimitExceeded { + __weak XCTestExpectation *completion = [self expectationWithDescription:@"RPC completed."]; + + GRPCRequestOptions *requestOptions = + [[GRPCRequestOptions alloc] initWithHost:kHostAddress + path:kUnaryCallMethod.HTTPPath + safety:GRPCCallSafetyDefault]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.responseSizeLimit = kSimpleDataLength; + options.transportType = GRPCTransportTypeInsecure; + + RMTSimpleRequest *request = [RMTSimpleRequest message]; + request.payload.body = [NSMutableData dataWithLength:options.responseSizeLimit]; + request.responseSize = (int32_t)(options.responseSizeLimit * 2); + + GRPCCall2 *call = [[GRPCCall2 alloc] + initWithRequestOptions:requestOptions + responseHandler:[[ClientTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:nil + messageCallback:nil + closeCallback:^(NSDictionary *trailingMetadata, + NSError *error) { + XCTAssertNotNil(error, + @"Expecting non-nil error"); + XCTAssertEqual(error.code, + GRPCErrorCodeResourceExhausted); + [completion fulfill]; + }] + callOptions:options]; + [call writeData:[request data]]; + [call start]; + + [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; +} + +- (void)testIdempotentProtoRPC { + __weak XCTestExpectation *response = [self expectationWithDescription:@"Expected response."]; + __weak XCTestExpectation *completion = [self expectationWithDescription:@"RPC completed."]; + + RMTSimpleRequest *request = [RMTSimpleRequest message]; + request.responseSize = kSimpleDataLength; + request.fillUsername = YES; + request.fillOauthScope = YES; + GRPCRequestOptions *requestOptions = + [[GRPCRequestOptions alloc] initWithHost:kHostAddress + path:kUnaryCallMethod.HTTPPath + safety:GRPCCallSafetyIdempotentRequest]; + + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = GRPCTransportTypeInsecure; + GRPCCall2 *call = [[GRPCCall2 alloc] + initWithRequestOptions:requestOptions + responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(id message) { + NSData *data = (NSData *)message; + XCTAssertNotNil(data, @"nil value received as response."); + XCTAssertGreaterThan(data.length, 0, + @"Empty response received."); + RMTSimpleResponse *responseProto = + [RMTSimpleResponse parseFromData:data error:NULL]; + // We expect empty strings, not nil: + XCTAssertNotNil(responseProto.username, + @"Response's username is nil."); + XCTAssertNotNil(responseProto.oauthScope, + @"Response's OAuth scope is nil."); + [response fulfill]; + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + XCTAssertNil(error, @"Finished with unexpected error: %@", + error); + [completion fulfill]; + }] + callOptions:options]; + + [call start]; + [call writeData:[request data]]; + [call finish]; + + [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; +} + +- (void)testTimeout { + __weak XCTestExpectation *completion = [self expectationWithDescription:@"RPC completed."]; + + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.timeout = 0.001; + GRPCRequestOptions *requestOptions = + [[GRPCRequestOptions alloc] initWithHost:kHostAddress + path:kFullDuplexCallMethod.HTTPPath + safety:GRPCCallSafetyDefault]; + + GRPCCall2 *call = [[GRPCCall2 alloc] + initWithRequestOptions:requestOptions + responseHandler: + [[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(NSData *data) { + XCTFail(@"Failure: response received; Expect: no response received."); + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + XCTAssertNotNil(error, + @"Failure: no error received; Expect: receive " + @"deadline exceeded."); + XCTAssertEqual(error.code, GRPCErrorCodeDeadlineExceeded); + [completion fulfill]; + }] + callOptions:options]; + + [call start]; + + [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; +} + +- (void)testTimeoutBackoffWithTimeout:(double)timeout Backoff:(double)backoff { + const double maxConnectTime = timeout > backoff ? timeout : backoff; + const double kMargin = 0.1; + + __weak XCTestExpectation *completion = [self expectationWithDescription:@"Timeout in a second."]; + NSString *const kDummyAddress = [NSString stringWithFormat:@"127.0.0.1:10000"]; + GRPCRequestOptions *requestOptions = + [[GRPCRequestOptions alloc] initWithHost:kDummyAddress + path:@"/dummy/path" + safety:GRPCCallSafetyDefault]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.connectMinTimeout = timeout; + options.connectInitialBackoff = backoff; + options.connectMaxBackoff = 0; + + NSDate *startTime = [NSDate date]; + GRPCCall2 *call = [[GRPCCall2 alloc] + initWithRequestOptions:requestOptions + responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(NSData *data) { + XCTFail(@"Received message. Should not reach here."); + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + XCTAssertNotNil(error, + @"Finished with no error; expecting error"); + XCTAssertLessThan( + [[NSDate date] timeIntervalSinceDate:startTime], + maxConnectTime + kMargin); + [completion fulfill]; + }] + callOptions:options]; + + [call start]; + + [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; +} + +- (void)testTimeoutBackoff1 { + [self testTimeoutBackoffWithTimeout:0.7 Backoff:0.4]; +} + +- (void)testTimeoutBackoff2 { + [self testTimeoutBackoffWithTimeout:0.3 Backoff:0.8]; +} + +- (void)testCompression { + __weak XCTestExpectation *completion = [self expectationWithDescription:@"RPC completed."]; + + RMTSimpleRequest *request = [RMTSimpleRequest message]; + request.expectCompressed = [RMTBoolValue message]; + request.expectCompressed.value = YES; + request.responseCompressed = [RMTBoolValue message]; + request.expectCompressed.value = YES; + request.responseSize = kSimpleDataLength; + request.payload.body = [NSMutableData dataWithLength:kSimpleDataLength]; + GRPCRequestOptions *requestOptions = + [[GRPCRequestOptions alloc] initWithHost:kHostAddress + path:kUnaryCallMethod.HTTPPath + safety:GRPCCallSafetyDefault]; + + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = GRPCTransportTypeInsecure; + options.compressionAlgorithm = GRPCCompressGzip; + GRPCCall2 *call = [[GRPCCall2 alloc] + initWithRequestOptions:requestOptions + responseHandler: [[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(NSData *data) { + NSError *error; + RMTSimpleResponse *response = [RMTSimpleResponse parseFromData:data error:&error]; + XCTAssertNil(error, @"Error when parsing response: %@", error); + XCTAssertEqual(response.payload.body.length, kSimpleDataLength); + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + XCTAssertNil(error, @"Received failure: %@", error); + [completion fulfill]; + }] + + callOptions:options]; + + [call start]; + [call writeData:[request data]]; + [call finish]; + + [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; +} + +@end diff --git a/src/objective-c/tests/APIv2Tests/Info.plist b/src/objective-c/tests/APIv2Tests/Info.plist new file mode 100644 index 00000000000..6c40a6cd0c4 --- /dev/null +++ b/src/objective-c/tests/APIv2Tests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/src/objective-c/tests/GRPCClientTests.m b/src/objective-c/tests/GRPCClientTests.m index bbe81502dcf..727dc59ca11 100644 --- a/src/objective-c/tests/GRPCClientTests.m +++ b/src/objective-c/tests/GRPCClientTests.m @@ -86,65 +86,6 @@ static GRPCProtoMethod *kFullDuplexCallMethod; @end -// Convenience class to use blocks as callbacks -@interface ClientTestsBlockCallbacks : NSObject - -- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback - messageCallback:(void (^)(id))messageCallback - closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback; - -@end - -@implementation ClientTestsBlockCallbacks { - void (^_initialMetadataCallback)(NSDictionary *); - void (^_messageCallback)(id); - void (^_closeCallback)(NSDictionary *, NSError *); - dispatch_queue_t _dispatchQueue; -} - -- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback - messageCallback:(void (^)(id))messageCallback - closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback { - if ((self = [super init])) { - _initialMetadataCallback = initialMetadataCallback; - _messageCallback = messageCallback; - _closeCallback = closeCallback; - _dispatchQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL); - } - return self; -} - -- (void)receivedInitialMetadata:(NSDictionary *_Nullable)initialMetadata { - dispatch_async(_dispatchQueue, ^{ - if (_initialMetadataCallback) { - _initialMetadataCallback(initialMetadata); - } - }); -} - -- (void)receivedRawMessage:(GPBMessage *_Nullable)message { - dispatch_async(_dispatchQueue, ^{ - if (_messageCallback) { - _messageCallback(message); - } - }); -} - -- (void)closedWithTrailingMetadata:(NSDictionary *_Nullable)trailingMetadata - error:(NSError *_Nullable)error { - dispatch_async(_dispatchQueue, ^{ - if (_closeCallback) { - _closeCallback(trailingMetadata, error); - } - }); -} - -- (dispatch_queue_t)dispatchQueue { - return _dispatchQueue; -} - -@end - #pragma mark Tests /** @@ -296,55 +237,6 @@ static GRPCProtoMethod *kFullDuplexCallMethod; [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } -- (void)testMetadataWithV2API { - __weak XCTestExpectation *expectation = [self expectationWithDescription:@"RPC unauthorized."]; - - RMTSimpleRequest *request = [RMTSimpleRequest message]; - request.fillUsername = YES; - request.fillOauthScope = YES; - - GRPCRequestOptions *callRequest = - [[GRPCRequestOptions alloc] initWithHost:(NSString *)kRemoteSSLHost - path:kUnaryCallMethod.HTTPPath - safety:GRPCCallSafetyDefault]; - __block NSDictionary *init_md; - __block NSDictionary *trailing_md; - GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; - options.oauth2AccessToken = @"bogusToken"; - GRPCCall2 *call = [[GRPCCall2 alloc] - initWithRequestOptions:callRequest - responseHandler:[[ClientTestsBlockCallbacks alloc] - initWithInitialMetadataCallback:^(NSDictionary *initialMetadata) { - init_md = initialMetadata; - } - messageCallback:^(id message) { - XCTFail(@"Received unexpected response."); - } - closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { - trailing_md = trailingMetadata; - if (error) { - XCTAssertEqual(error.code, 16, - @"Finished with unexpected error: %@", error); - XCTAssertEqualObjects(init_md, - error.userInfo[kGRPCHeadersKey]); - XCTAssertEqualObjects(trailing_md, - error.userInfo[kGRPCTrailersKey]); - NSString *challengeHeader = init_md[@"www-authenticate"]; - XCTAssertGreaterThan(challengeHeader.length, 0, - @"No challenge in response headers %@", - init_md); - [expectation fulfill]; - } - }] - callOptions:options]; - - [call start]; - [call writeData:[request data]]; - [call finish]; - - [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; -} - - (void)testResponseMetadataKVO { __weak XCTestExpectation *response = [self expectationWithDescription:@"Empty response received."]; @@ -437,75 +329,6 @@ static GRPCProtoMethod *kFullDuplexCallMethod; [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } -- (void)testUserAgentPrefixWithV2API { - __weak XCTestExpectation *completion = [self expectationWithDescription:@"Empty RPC completed."]; - __weak XCTestExpectation *recvInitialMd = - [self expectationWithDescription:@"Did not receive initial md."]; - - GRPCRequestOptions *request = [[GRPCRequestOptions alloc] initWithHost:kHostAddress - path:kEmptyCallMethod.HTTPPath - safety:GRPCCallSafetyDefault]; - NSDictionary *headers = - [NSDictionary dictionaryWithObjectsAndKeys:@"", @"x-grpc-test-echo-useragent", nil]; - GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; - options.transportType = GRPCTransportTypeInsecure; - options.userAgentPrefix = @"Foo"; - options.initialMetadata = headers; - GRPCCall2 *call = [[GRPCCall2 alloc] - initWithRequestOptions:request - responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:^( - NSDictionary *initialMetadata) { - NSString *userAgent = initialMetadata[@"x-grpc-test-echo-useragent"]; - // Test the regex is correct - NSString *expectedUserAgent = @"Foo grpc-objc/"; - expectedUserAgent = - [expectedUserAgent stringByAppendingString:GRPC_OBJC_VERSION_STRING]; - expectedUserAgent = [expectedUserAgent stringByAppendingString:@" grpc-c/"]; - expectedUserAgent = - [expectedUserAgent stringByAppendingString:GRPC_C_VERSION_STRING]; - expectedUserAgent = [expectedUserAgent stringByAppendingString:@" (ios; chttp2; "]; - expectedUserAgent = [expectedUserAgent - stringByAppendingString:[NSString stringWithUTF8String:grpc_g_stands_for()]]; - expectedUserAgent = [expectedUserAgent stringByAppendingString:@")"]; - XCTAssertEqualObjects(userAgent, expectedUserAgent); - - NSError *error = nil; - // Change in format of user-agent field in a direction that does not match - // the regex will likely cause problem for certain gRPC users. For details, - // refer to internal doc https://goo.gl/c2diBc - NSRegularExpression *regex = [NSRegularExpression - regularExpressionWithPattern: - @" grpc-[a-zA-Z0-9]+(-[a-zA-Z0-9]+)?/[^ ,]+( \\([^)]*\\))?" - options:0 - error:&error]; - - NSString *customUserAgent = - [regex stringByReplacingMatchesInString:userAgent - options:0 - range:NSMakeRange(0, [userAgent length]) - withTemplate:@""]; - XCTAssertEqualObjects(customUserAgent, @"Foo"); - [recvInitialMd fulfill]; - } - messageCallback:^(id message) { - XCTAssertNotNil(message); - XCTAssertEqual([message length], 0, - @"Non-empty response received: %@", message); - } - closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { - if (error) { - XCTFail(@"Finished with unexpected error: %@", error); - } else { - [completion fulfill]; - } - }] - callOptions:options]; - [call writeData:[NSData data]]; - [call start]; - - [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; -} - - (void)testTrailers { __weak XCTestExpectation *response = [self expectationWithDescription:@"Empty response received."]; @@ -597,52 +420,6 @@ static GRPCProtoMethod *kFullDuplexCallMethod; [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } -- (void)testIdempotentProtoRPCWithV2API { - __weak XCTestExpectation *response = [self expectationWithDescription:@"Expected response."]; - __weak XCTestExpectation *completion = [self expectationWithDescription:@"RPC completed."]; - - RMTSimpleRequest *request = [RMTSimpleRequest message]; - request.responseSize = 100; - request.fillUsername = YES; - request.fillOauthScope = YES; - GRPCRequestOptions *requestOptions = - [[GRPCRequestOptions alloc] initWithHost:kHostAddress - path:kUnaryCallMethod.HTTPPath - safety:GRPCCallSafetyIdempotentRequest]; - - GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; - options.transportType = GRPCTransportTypeInsecure; - GRPCCall2 *call = [[GRPCCall2 alloc] - initWithRequestOptions:requestOptions - responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil - messageCallback:^(id message) { - NSData *data = (NSData *)message; - XCTAssertNotNil(data, @"nil value received as response."); - XCTAssertGreaterThan(data.length, 0, - @"Empty response received."); - RMTSimpleResponse *responseProto = - [RMTSimpleResponse parseFromData:data error:NULL]; - // We expect empty strings, not nil: - XCTAssertNotNil(responseProto.username, - @"Response's username is nil."); - XCTAssertNotNil(responseProto.oauthScope, - @"Response's OAuth scope is nil."); - [response fulfill]; - } - closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { - XCTAssertNil(error, @"Finished with unexpected error: %@", - error); - [completion fulfill]; - }] - callOptions:options]; - - [call start]; - [call writeData:[request data]]; - [call finish]; - - [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; -} - - (void)testAlternateDispatchQueue { const int32_t kPayloadSize = 100; RMTSimpleRequest *request = [RMTSimpleRequest message]; @@ -732,37 +509,6 @@ static GRPCProtoMethod *kFullDuplexCallMethod; [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } -- (void)testTimeoutWithV2API { - __weak XCTestExpectation *completion = [self expectationWithDescription:@"RPC completed."]; - - GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; - options.timeout = 0.001; - GRPCRequestOptions *requestOptions = - [[GRPCRequestOptions alloc] initWithHost:kHostAddress - path:kFullDuplexCallMethod.HTTPPath - safety:GRPCCallSafetyDefault]; - - GRPCCall2 *call = [[GRPCCall2 alloc] - initWithRequestOptions:requestOptions - responseHandler: - [[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil - messageCallback:^(id data) { - XCTFail(@"Failure: response received; Expect: no response received."); - } - closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { - XCTAssertNotNil(error, - @"Failure: no error received; Expect: receive " - @"deadline exceeded."); - XCTAssertEqual(error.code, GRPCErrorCodeDeadlineExceeded); - [completion fulfill]; - }] - callOptions:options]; - - [call start]; - - [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; -} - - (int)findFreePort { struct sockaddr_in addr; unsigned int addr_len = sizeof(addr); @@ -834,43 +580,6 @@ static GRPCProtoMethod *kFullDuplexCallMethod; [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } -- (void)testTimeoutBackoffWithOptionsWithTimeout:(double)timeout Backoff:(double)backoff { - const double maxConnectTime = timeout > backoff ? timeout : backoff; - const double kMargin = 0.1; - - __weak XCTestExpectation *completion = [self expectationWithDescription:@"Timeout in a second."]; - NSString *const kDummyAddress = [NSString stringWithFormat:@"127.0.0.1:10000"]; - GRPCRequestOptions *requestOptions = - [[GRPCRequestOptions alloc] initWithHost:kDummyAddress - path:@"/dummy/path" - safety:GRPCCallSafetyDefault]; - GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; - options.connectMinTimeout = timeout; - options.connectInitialBackoff = backoff; - options.connectMaxBackoff = 0; - - NSDate *startTime = [NSDate date]; - GRPCCall2 *call = [[GRPCCall2 alloc] - initWithRequestOptions:requestOptions - responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil - messageCallback:^(id data) { - XCTFail(@"Received message. Should not reach here."); - } - closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { - XCTAssertNotNil(error, - @"Finished with no error; expecting error"); - XCTAssertLessThan( - [[NSDate date] timeIntervalSinceDate:startTime], - maxConnectTime + kMargin); - [completion fulfill]; - }] - callOptions:options]; - - [call start]; - - [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; -} - // The numbers of the following three tests are selected to be smaller than the default values of // initial backoff (1s) and min_connect_timeout (20s), so that if they fail we know the default // values fail to be overridden by the channel args. diff --git a/src/objective-c/tests/Podfile b/src/objective-c/tests/Podfile index e87aba235ad..5df9d4e85bd 100644 --- a/src/objective-c/tests/Podfile +++ b/src/objective-c/tests/Podfile @@ -17,6 +17,7 @@ GRPC_LOCAL_SRC = '../../..' InteropTestsMultipleChannels InteropTestsCallOptions UnitTests + APIv2Tests ).each do |target_name| target target_name do pod 'Protobuf', :path => "#{GRPC_LOCAL_SRC}/third_party/protobuf", :inhibit_warnings => true diff --git a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj index 104fd0a4ea0..6d1932b0215 100644 --- a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj +++ b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj @@ -16,6 +16,7 @@ 333E8FC01C8285B7C547D799 /* libPods-InteropTestsLocalCleartext.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FD346DB2C23F676C4842F3FF /* libPods-InteropTestsLocalCleartext.a */; }; 5E0282E9215AA697007AC99D /* UnitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E0282E8215AA697007AC99D /* UnitTests.m */; }; 5E0282EB215AA697007AC99D /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; }; + 5E10F5AA218CB0D2008BAB68 /* APIv2Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E10F5A9218CB0D2008BAB68 /* APIv2Tests.m */; }; 5E7D71AD210954A8001EA6BA /* TestCertificates.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 63E240CF1B6C63DC005F3B0E /* TestCertificates.bundle */; }; 5E7D71B5210B9EC9001EA6BA /* InteropTestsCallOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E7D71B4210B9EC9001EA6BA /* InteropTestsCallOptions.m */; }; 5E7D71B7210B9EC9001EA6BA /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; }; @@ -68,6 +69,7 @@ BC111C80CBF7068B62869352 /* libPods-InteropTestsRemoteCFStream.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F44AC3F44E3491A8C0D890FE /* libPods-InteropTestsRemoteCFStream.a */; }; C3D6F4270A2FFF634D8849ED /* libPods-InteropTestsLocalCleartextCFStream.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 0BDA4BA011779D5D25B5618C /* libPods-InteropTestsLocalCleartextCFStream.a */; }; CCF5C0719EF608276AE16374 /* libPods-UnitTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 22A3EBB488699C8CEA19707B /* libPods-UnitTests.a */; }; + E7F4C80FC8FC667B7447BFE7 /* libPods-APIv2Tests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B6AD69CACF67505B0F028E92 /* libPods-APIv2Tests.a */; }; F15EF7852DC70770EFDB1D2C /* libPods-AllTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = CAE086D5B470DA367D415AB0 /* libPods-AllTests.a */; }; /* End PBXBuildFile section */ @@ -176,7 +178,9 @@ 0A4F89D9C90E9C30990218F0 /* Pods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.release.xcconfig; path = "Pods/Target Support Files/Pods/Pods.release.xcconfig"; sourceTree = ""; }; 0BDA4BA011779D5D25B5618C /* libPods-InteropTestsLocalCleartextCFStream.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsLocalCleartextCFStream.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 0D2284C3DF7E57F0ED504E39 /* Pods-CoreCronetEnd2EndTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CoreCronetEnd2EndTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests.debug.xcconfig"; sourceTree = ""; }; + 1286B30AD74CB64CD91FB17D /* Pods-APIv2Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-APIv2Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-APIv2Tests/Pods-APIv2Tests.debug.xcconfig"; sourceTree = ""; }; 1295CCBD1082B4A7CFCED95F /* Pods-InteropTestsMultipleChannels.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsMultipleChannels.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsMultipleChannels/Pods-InteropTestsMultipleChannels.cronet.xcconfig"; sourceTree = ""; }; + 12B238CD1702393C2BA5DE80 /* Pods-APIv2Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-APIv2Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-APIv2Tests/Pods-APIv2Tests.release.xcconfig"; sourceTree = ""; }; 14B09A58FEE53A7A6B838920 /* Pods-InteropTestsLocalSSL.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSL.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL.cronet.xcconfig"; sourceTree = ""; }; 1588C85DEAF7FC0ACDEA4C02 /* Pods-InteropTestsLocalCleartext.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartext.test.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartext/Pods-InteropTestsLocalCleartext.test.xcconfig"; sourceTree = ""; }; 17F60BF2871F6AF85FB3FA12 /* Pods-InteropTestsRemoteWithCronet.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemoteWithCronet.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemoteWithCronet/Pods-InteropTestsRemoteWithCronet.debug.xcconfig"; sourceTree = ""; }; @@ -200,6 +204,7 @@ 4AD97096D13D7416DC91A72A /* Pods-CoreCronetEnd2EndTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CoreCronetEnd2EndTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests.release.xcconfig"; sourceTree = ""; }; 4ADEA1C8BBE10D90940AC68E /* Pods-InteropTestsRemote.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemote.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemote/Pods-InteropTestsRemote.cronet.xcconfig"; sourceTree = ""; }; 51A275E86C141416ED63FF76 /* Pods-InteropTestsLocalCleartext.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartext.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartext/Pods-InteropTestsLocalCleartext.release.xcconfig"; sourceTree = ""; }; + 51F2A64B7AADBA1B225B132E /* Pods-APIv2Tests.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-APIv2Tests.test.xcconfig"; path = "Pods/Target Support Files/Pods-APIv2Tests/Pods-APIv2Tests.test.xcconfig"; sourceTree = ""; }; 553BBBED24E4162D1F769D65 /* Pods-InteropTestsLocalSSL.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSL.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL.debug.xcconfig"; sourceTree = ""; }; 55B630C1FF8C36D1EFC4E0A4 /* Pods-InteropTestsLocalSSLCFStream.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSLCFStream.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSLCFStream/Pods-InteropTestsLocalSSLCFStream.cronet.xcconfig"; sourceTree = ""; }; 573450F334B331D0BED8B961 /* Pods-CoreCronetEnd2EndTests.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CoreCronetEnd2EndTests.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests.cronet.xcconfig"; sourceTree = ""; }; @@ -207,6 +212,9 @@ 5E0282E6215AA697007AC99D /* UnitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = UnitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 5E0282E8215AA697007AC99D /* UnitTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UnitTests.m; sourceTree = ""; }; 5E0282EA215AA697007AC99D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 5E10F5A7218CB0D1008BAB68 /* APIv2Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = APIv2Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 5E10F5A9218CB0D2008BAB68 /* APIv2Tests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = APIv2Tests.m; sourceTree = ""; }; + 5E10F5AB218CB0D2008BAB68 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 5E7D71B2210B9EC8001EA6BA /* InteropTestsCallOptions.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = InteropTestsCallOptions.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 5E7D71B4210B9EC9001EA6BA /* InteropTestsCallOptions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = InteropTestsCallOptions.m; sourceTree = ""; }; 5E7D71B6210B9EC9001EA6BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -254,6 +262,7 @@ 7A2E97E3F469CC2A758D77DE /* Pods-InteropTestsLocalSSL.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSL.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL.release.xcconfig"; sourceTree = ""; }; 7BA53C6D224288D5870FE6F3 /* Pods-InteropTestsLocalCleartextCFStream.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartextCFStream.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartextCFStream/Pods-InteropTestsLocalCleartextCFStream.release.xcconfig"; sourceTree = ""; }; 8B498B05C6DA0818B2FA91D4 /* Pods-InteropTestsLocalCleartextCFStream.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartextCFStream.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartextCFStream/Pods-InteropTestsLocalCleartextCFStream.cronet.xcconfig"; sourceTree = ""; }; + 8C233E85C3EB45B3CAE52EDF /* Pods-APIv2Tests.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-APIv2Tests.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-APIv2Tests/Pods-APIv2Tests.cronet.xcconfig"; sourceTree = ""; }; 90E63AD3C4A1E3E6BC745096 /* Pods-ChannelTests.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ChannelTests.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-ChannelTests/Pods-ChannelTests.cronet.xcconfig"; sourceTree = ""; }; 943138072A9605B5B8DC1FC0 /* Pods-InteropTestsLocalCleartextCFStream.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartextCFStream.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartextCFStream/Pods-InteropTestsLocalCleartextCFStream.debug.xcconfig"; sourceTree = ""; }; 94D7A5FAA13480E9A5166D7A /* Pods-UnitTests.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-UnitTests.test.xcconfig"; path = "Pods/Target Support Files/Pods-UnitTests/Pods-UnitTests.test.xcconfig"; sourceTree = ""; }; @@ -266,6 +275,7 @@ AC414EF7A6BF76ED02B6E480 /* Pods-InteropTestsRemoteWithCronet.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemoteWithCronet.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemoteWithCronet/Pods-InteropTestsRemoteWithCronet.release.xcconfig"; sourceTree = ""; }; AF3FC2CFFE7B0961823BC740 /* libPods-InteropTestsCallOptions.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsCallOptions.a"; sourceTree = BUILT_PRODUCTS_DIR; }; B226619DC4E709E0FFFF94B8 /* Pods-CronetUnitTests.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CronetUnitTests.test.xcconfig"; path = "Pods/Target Support Files/Pods-CronetUnitTests/Pods-CronetUnitTests.test.xcconfig"; sourceTree = ""; }; + B6AD69CACF67505B0F028E92 /* libPods-APIv2Tests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-APIv2Tests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; B94C27C06733CF98CE1B2757 /* Pods-AllTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AllTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-AllTests/Pods-AllTests.debug.xcconfig"; sourceTree = ""; }; BED74BC8ABF9917C66175879 /* Pods-ChannelTests.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ChannelTests.test.xcconfig"; path = "Pods/Target Support Files/Pods-ChannelTests/Pods-ChannelTests.test.xcconfig"; sourceTree = ""; }; C17F57E5BCB989AB1C2F1F25 /* Pods-InteropTestsRemoteCFStream.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemoteCFStream.test.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemoteCFStream/Pods-InteropTestsRemoteCFStream.test.xcconfig"; sourceTree = ""; }; @@ -303,6 +313,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 5E10F5A4218CB0D1008BAB68 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + E7F4C80FC8FC667B7447BFE7 /* libPods-APIv2Tests.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5E7D71AF210B9EC8001EA6BA /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -456,6 +474,7 @@ 355D0E30AD224763BC9519F4 /* libPods-InteropTestsMultipleChannels.a */, AF3FC2CFFE7B0961823BC740 /* libPods-InteropTestsCallOptions.a */, 22A3EBB488699C8CEA19707B /* libPods-UnitTests.a */, + B6AD69CACF67505B0F028E92 /* libPods-APIv2Tests.a */, ); name = Frameworks; sourceTree = ""; @@ -525,6 +544,10 @@ 94D7A5FAA13480E9A5166D7A /* Pods-UnitTests.test.xcconfig */, E1E7660656D902104F728892 /* Pods-UnitTests.cronet.xcconfig */, EBFFEC04B514CB0D4922DC40 /* Pods-UnitTests.release.xcconfig */, + 1286B30AD74CB64CD91FB17D /* Pods-APIv2Tests.debug.xcconfig */, + 51F2A64B7AADBA1B225B132E /* Pods-APIv2Tests.test.xcconfig */, + 8C233E85C3EB45B3CAE52EDF /* Pods-APIv2Tests.cronet.xcconfig */, + 12B238CD1702393C2BA5DE80 /* Pods-APIv2Tests.release.xcconfig */, ); name = Pods; sourceTree = ""; @@ -538,6 +561,15 @@ path = UnitTests; sourceTree = ""; }; + 5E10F5A8218CB0D1008BAB68 /* APIv2Tests */ = { + isa = PBXGroup; + children = ( + 5E10F5A9218CB0D2008BAB68 /* APIv2Tests.m */, + 5E10F5AB218CB0D2008BAB68 /* Info.plist */, + ); + path = APIv2Tests; + sourceTree = ""; + }; 5E7D71B3210B9EC9001EA6BA /* InteropTestsCallOptions */ = { isa = PBXGroup; children = ( @@ -604,6 +636,7 @@ 5EB2A2F62109284500EB4B69 /* InteropTestsMultipleChannels */, 5E7D71B3210B9EC9001EA6BA /* InteropTestsCallOptions */, 5E0282E7215AA697007AC99D /* UnitTests */, + 5E10F5A8218CB0D1008BAB68 /* APIv2Tests */, 635697C81B14FC11007A7283 /* Products */, 51E4650F34F854F41FF053B3 /* Pods */, 136D535E19727099B941D7B1 /* Frameworks */, @@ -629,6 +662,7 @@ 5EB2A2F52109284500EB4B69 /* InteropTestsMultipleChannels.xctest */, 5E7D71B2210B9EC8001EA6BA /* InteropTestsCallOptions.xctest */, 5E0282E6215AA697007AC99D /* UnitTests.xctest */, + 5E10F5A7218CB0D1008BAB68 /* APIv2Tests.xctest */, ); name = Products; sourceTree = ""; @@ -681,6 +715,25 @@ productReference = 5E0282E6215AA697007AC99D /* UnitTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; + 5E10F5A6218CB0D1008BAB68 /* APIv2Tests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5E10F5B0218CB0D2008BAB68 /* Build configuration list for PBXNativeTarget "APIv2Tests" */; + buildPhases = ( + 031ADD72298D6C6979CB06DB /* [CP] Check Pods Manifest.lock */, + 5E10F5A3218CB0D1008BAB68 /* Sources */, + 5E10F5A4218CB0D1008BAB68 /* Frameworks */, + 5E10F5A5218CB0D1008BAB68 /* Resources */, + FBB92A8B11C52512E67791E8 /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = APIv2Tests; + productName = APIv2Tests; + productReference = 5E10F5A7218CB0D1008BAB68 /* APIv2Tests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; 5E7D71B1210B9EC8001EA6BA /* InteropTestsCallOptions */ = { isa = PBXNativeTarget; buildConfigurationList = 5E7D71BA210B9EC9001EA6BA /* Build configuration list for PBXNativeTarget "InteropTestsCallOptions" */; @@ -990,6 +1043,10 @@ CreatedOnToolsVersion = 9.2; ProvisioningStyle = Automatic; }; + 5E10F5A6218CB0D1008BAB68 = { + CreatedOnToolsVersion = 10.0; + ProvisioningStyle = Automatic; + }; 5E7D71B1210B9EC8001EA6BA = { CreatedOnToolsVersion = 9.3; ProvisioningStyle = Automatic; @@ -1071,6 +1128,7 @@ 5EB2A2F42109284500EB4B69 /* InteropTestsMultipleChannels */, 5E7D71B1210B9EC8001EA6BA /* InteropTestsCallOptions */, 5E0282E5215AA697007AC99D /* UnitTests */, + 5E10F5A6218CB0D1008BAB68 /* APIv2Tests */, ); }; /* End PBXProject section */ @@ -1083,6 +1141,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 5E10F5A5218CB0D1008BAB68 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5E7D71B0210B9EC8001EA6BA /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -1206,6 +1271,28 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; + 031ADD72298D6C6979CB06DB /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-APIv2Tests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; 0617B5294978A95BEBBFF733 /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -1764,6 +1851,28 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; + FBB92A8B11C52512E67791E8 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-APIv2Tests/Pods-APIv2Tests-resources.sh", + "${PODS_CONFIGURATION_BUILD_DIR}/gRPC/gRPCCertificates.bundle", + ); + name = "[CP] Copy Pods Resources"; + outputFileListPaths = ( + ); + outputPaths = ( + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gRPCCertificates.bundle", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-APIv2Tests/Pods-APIv2Tests-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -1775,6 +1884,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 5E10F5A3218CB0D1008BAB68 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5E10F5AA218CB0D2008BAB68 /* APIv2Tests.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5E7D71AE210B9EC8001EA6BA /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -2098,6 +2215,141 @@ }; name = Release; }; + 5E10F5AC218CB0D2008BAB68 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 1286B30AD74CB64CD91FB17D /* Pods-APIv2Tests.debug.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = APIv2Tests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.APIv2Tests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 5E10F5AD218CB0D2008BAB68 /* Test */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 51F2A64B7AADBA1B225B132E /* Pods-APIv2Tests.test.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = APIv2Tests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.APIv2Tests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Test; + }; + 5E10F5AE218CB0D2008BAB68 /* Cronet */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 8C233E85C3EB45B3CAE52EDF /* Pods-APIv2Tests.cronet.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = APIv2Tests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.APIv2Tests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Cronet; + }; + 5E10F5AF218CB0D2008BAB68 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 12B238CD1702393C2BA5DE80 /* Pods-APIv2Tests.release.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = APIv2Tests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.APIv2Tests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; 5E1228981E4D400F00E8504F /* Test */ = { isa = XCBuildConfiguration; buildSettings = { @@ -3648,6 +3900,17 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 5E10F5B0218CB0D2008BAB68 /* Build configuration list for PBXNativeTarget "APIv2Tests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5E10F5AC218CB0D2008BAB68 /* Debug */, + 5E10F5AD218CB0D2008BAB68 /* Test */, + 5E10F5AE218CB0D2008BAB68 /* Cronet */, + 5E10F5AF218CB0D2008BAB68 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 5E7D71BA210B9EC9001EA6BA /* Build configuration list for PBXNativeTarget "InteropTestsCallOptions" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/APIv2Tests.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/APIv2Tests.xcscheme new file mode 100644 index 00000000000..b444ddc2b67 --- /dev/null +++ b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/APIv2Tests.xcscheme @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/objective-c/tests/run_tests.sh b/src/objective-c/tests/run_tests.sh index 118220ce4b1..e8c3e6ec2a4 100755 --- a/src/objective-c/tests/run_tests.sh +++ b/src/objective-c/tests/run_tests.sh @@ -183,4 +183,14 @@ xcodebuild \ | egrep -v '^$' \ | egrep -v "(GPBDictionary|GPBArray)" - +echo "TIME: $(date)" +xcodebuild \ + -workspace Tests.xcworkspace \ + -scheme APIv2Tests \ + -destination name="iPhone 8" \ + test \ + | egrep -v "$XCODEBUILD_FILTER" \ + | egrep -v '^$' \ + | egrep -v "(GPBDictionary|GPBArray)" - + exit 0