Added Objective-C performance tests

pull/20238/head
Prashant Jaikumar 6 years ago
parent 1bfdbc1f6c
commit d0c65e45e8
  1. 49
      src/objective-c/tests/InteropTests/InteropTests.h
  2. 41
      src/objective-c/tests/MacTests/StressTests.h
  3. 27
      src/objective-c/tests/PerfTests/PerfTests.h
  4. 327
      src/objective-c/tests/PerfTests/PerfTests.m
  5. 33
      src/objective-c/tests/PerfTests/PerfTestsBlockCallbacks.h
  6. 80
      src/objective-c/tests/PerfTests/PerfTestsBlockCallbacks.m
  7. 74
      src/objective-c/tests/PerfTests/PerfTestsCFStreamCleartext.m
  8. 80
      src/objective-c/tests/PerfTests/PerfTestsCFStreamSSL.m
  9. 63
      src/objective-c/tests/PerfTests/PerfTestsCronet.m
  10. 74
      src/objective-c/tests/PerfTests/PerfTestsNoCFStreamCleartext.m
  11. 80
      src/objective-c/tests/PerfTests/PerfTestsNoCFStreamSSL.m
  12. 8
      src/objective-c/tests/Podfile
  13. 65
      src/objective-c/tests/TestBase.h
  14. 50
      src/objective-c/tests/TestBase.m
  15. 245
      src/objective-c/tests/Tests.xcodeproj/project.pbxproj
  16. 95
      src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/PerfTests.xcscheme

@ -18,7 +18,7 @@
#import <XCTest/XCTest.h>
#import <GRPCClient/GRPCCallOptions.h>
#import "../TestBase.h"
/**
* Implements tests as described here:
@ -26,51 +26,6 @@
*
* This is an abstract class that needs to be subclassed. See |+host|.
*/
@interface InteropTests : XCTestCase
/**
* The test suite to run, checking if the current XCTestCase instance is the base class.
* If so, run no tests (disabled). Otherwise, proceed to normal execution.
*/
@property(class, readonly) XCTestSuite *defaultTestSuite;
/**
* Host to send the RPCs to. The base implementation returns nil, which would make all tests to
* fail.
* Override in a subclass to perform these tests against a specific address.
*/
+ (NSString *)host;
/**
* Bytes of overhead of test proto responses due to encoding. This is used to excercise the behavior
* when responses are just above or below the max response size. For some reason, the local and
* remote servers enconde responses with different overhead (?), so this is defined per-subclass.
*/
- (int32_t)encodingOverhead;
/**
* DEPRECATED: \a transportType is a deprecated option. Please use \a transport instead.
*
* The type of transport to be used. The base implementation returns default. Subclasses should
* override to appropriate settings.
*/
+ (GRPCTransportType)transportType;
/*
* The transport to be used. The base implementation returns NULL. Subclasses should override to
* appropriate settings.
*/
+ (GRPCTransportID)transport;
/**
* The root certificates to be used. The base implementation returns nil. Subclasses should override
* to appropriate settings.
*/
+ (NSString *)PEMRootCertificates;
/**
* The root certificates to be used. The base implementation returns nil. Subclasses should override
* to appropriate settings.
*/
+ (NSString *)hostNameOverride;
@interface InteropTests : TestBase
@end

@ -18,45 +18,8 @@
#import <XCTest/XCTest.h>
#import <GRPCClient/GRPCCallOptions.h>
#import "../TestBase.h"
@interface StressTests : XCTestCase
/**
* The test suite to run, checking if the current XCTestCase instance is the base class.
* If so, run no tests (disabled). Otherwise, proceed to normal execution.
*/
@property(class, readonly) XCTestSuite *defaultTestSuite;
/**
* Host to send the RPCs to. The base implementation returns nil, which would make all tests to
* fail.
* Override in a subclass to perform these tests against a specific address.
*/
+ (NSString *)host;
/**
* Bytes of overhead of test proto responses due to encoding. This is used to excercise the behavior
* when responses are just above or below the max response size. For some reason, the local and
* remote servers enconde responses with different overhead (?), so this is defined per-subclass.
*/
- (int32_t)encodingOverhead;
/**
* The type of transport to be used. The base implementation returns default. Subclasses should
* override to appropriate settings.
*/
+ (GRPCTransportType)transportType;
/**
* The root certificates to be used. The base implementation returns nil. Subclasses should override
* to appropriate settings.
*/
+ (NSString *)PEMRootCertificates;
/**
* The root certificates to be used. The base implementation returns nil. Subclasses should override
* to appropriate settings.
*/
+ (NSString *)hostNameOverride;
@interface StressTests : TestBase
@end

@ -0,0 +1,27 @@
/*
*
* Copyright 2019 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 "../TestBase.h"
/**
* This is an abstract class that needs to be subclassed. See |+host|.
*/
@interface PerfTests : TestBase
@end

@ -0,0 +1,327 @@
/*
*
* Copyright 2019 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 "PerfTests.h"
#include <grpc/status.h>
#import <GRPCClient/GRPCCall+ChannelArg.h>
#import <GRPCClient/GRPCCall+Cronet.h>
#import <GRPCClient/GRPCCall+Interceptor.h>
#import <GRPCClient/GRPCCall+Tests.h>
#import <GRPCClient/GRPCInterceptor.h>
#import <GRPCClient/internal_testing/GRPCCall+InternalTests.h>
#import <ProtoRPC/ProtoRPC.h>
#import <RxLibrary/GRXBufferedPipe.h>
#import <RxLibrary/GRXWriter+Immediate.h>
#import <grpc/grpc.h>
#import <grpc/support/log.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 "PerfTestsBlockCallbacks.h"
#define TEST_TIMEOUT 128
extern const char *kCFStreamVarName;
// Convenience constructors for the generated proto messages:
@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 DefaultInterceptorFactory : NSObject<GRPCInterceptorFactory>
- (GRPCInterceptor *)createInterceptorWithManager:(GRPCInterceptorManager *)interceptorManager;
@end
@implementation DefaultInterceptorFactory
- (GRPCInterceptor *)createInterceptorWithManager:(GRPCInterceptorManager *)interceptorManager {
dispatch_queue_t queue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL);
return
[[GRPCInterceptor alloc] initWithInterceptorManager:interceptorManager dispatchQueue:queue];
}
@end
BOOL isUsingCFStream() {
NSString *enabled = @(getenv(kCFStreamVarName));
return [enabled isEqualToString:@"1"];
}
#pragma mark Tests
@implementation PerfTests {
RMTTestService *_service;
}
+ (XCTestSuite *)defaultTestSuite {
if (self == [PerfTests class]) {
return [XCTestSuite testSuiteWithName:@"PerfTestsEmptySuite"];
} else {
return super.defaultTestSuite;
}
}
+ (NSString *)host {
return nil;
}
// This number indicates how many bytes of overhead does Protocol Buffers encoding add onto the
// message. The number varies as different message.proto is used on different servers. The actual
// number for each interop server is overridden in corresponding derived test classes.
- (int32_t)encodingOverhead {
return 0;
}
+ (GRPCTransportID)transport {
return NULL;
}
+ (NSString *)PEMRootCertificates {
return nil;
}
+ (NSString *)hostNameOverride {
return nil;
}
+ (void)setUp {
setenv("GRPC_TRACE", "tcp", 1);
setenv("GRPC_VERBOSITY", "DEBUG", 1);
NSLog(@"In setUp");
}
- (void)setUp {
self.continueAfterFailure = NO;
[GRPCCall resetHostSettings];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
[GRPCCall closeOpenConnections];
#pragma clang diagnostic pop
_service = [[self class] host] ? [RMTTestService serviceWithHost:[[self class] host]] : nil;
}
- (void)pingPongV2APIWithRequest:(RMTStreamingOutputCallRequest *)request
numMessages:(int)numMessages
options:(GRPCMutableCallOptions *)options {
__weak XCTestExpectation *expectation = [self expectationWithDescription:@"PingPong"];
__block BOOL flowControlEnabled = options.flowControlEnabled;
__block int index = 0;
__block GRPCStreamingProtoCall *call = [self->_service
fullDuplexCallWithResponseHandler:[[PerfTestsBlockCallbacks alloc]
initWithInitialMetadataCallback:nil
messageCallback:^(id message) {
int indexCopy;
@synchronized(self) {
index += 1;
indexCopy = index;
}
if (indexCopy < numMessages) {
[call writeMessage:request];
if (flowControlEnabled) {
[call receiveNextMessage];
}
} else {
[call finish];
}
}
closeCallback:^(NSDictionary *trailingMetadata,
NSError *error) {
[expectation fulfill];
}]
callOptions:options];
[call start];
if (flowControlEnabled) {
[call receiveNextMessage];
}
[call writeMessage:request];
[self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
}
- (void)testPingPongRPCWithV2API {
GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init];
options.transport = [[self class] transport];
options.PEMRootCertificates = [[self class] PEMRootCertificates];
options.hostNameOverride = [[self class] hostNameOverride];
id request = [RMTStreamingOutputCallRequest messageWithPayloadSize:@1 requestedResponseSize:@1];
// warm up
[self pingPongV2APIWithRequest:request numMessages:1000 options:options];
[self measureBlock:^{
[self pingPongV2APIWithRequest:request numMessages:10000 options:options];
}];
}
- (void)testPingPongRPCWithFlowControl {
GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init];
options.transport = [[self class] transport];
options.PEMRootCertificates = [[self class] PEMRootCertificates];
options.hostNameOverride = [[self class] hostNameOverride];
options.flowControlEnabled = YES;
id request = [RMTStreamingOutputCallRequest messageWithPayloadSize:@1 requestedResponseSize:@1];
// warm up
[self pingPongV2APIWithRequest:request numMessages:1000 options:options];
[self measureBlock:^{
[self pingPongV2APIWithRequest:request numMessages:10000 options:options];
}];
}
- (void)testPingPongRPCWithInterceptor {
GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init];
options.transport = [[self class] transport];
options.PEMRootCertificates = [[self class] PEMRootCertificates];
options.hostNameOverride = [[self class] hostNameOverride];
options.interceptorFactories = @[ [[DefaultInterceptorFactory alloc] init] ];
id request = [RMTStreamingOutputCallRequest messageWithPayloadSize:@1 requestedResponseSize:@1];
// warm up
[self pingPongV2APIWithRequest:request numMessages:1000 options:options];
[self measureBlock:^{
[self pingPongV2APIWithRequest:request numMessages:10000 options:options];
}];
}
- (void)pingPongV1APIWithRequest:(RMTStreamingOutputCallRequest *)request
numMessages:(int)numMessages {
__block int index = 0;
__weak XCTestExpectation *expectation = [self expectationWithDescription:@"PingPong"];
GRXBufferedPipe *requestsBuffer = [[GRXBufferedPipe alloc] init];
[requestsBuffer writeValue:request];
[_service fullDuplexCallWithRequestsWriter:requestsBuffer
eventHandler:^(BOOL done, RMTStreamingOutputCallResponse *response,
NSError *error) {
if (response) {
int indexCopy;
@synchronized(self) {
index += 1;
indexCopy = index;
}
if (indexCopy < numMessages) {
[requestsBuffer writeValue:request];
} else {
[requestsBuffer writesFinishedWithError:nil];
}
}
if (done) {
[expectation fulfill];
}
}];
[self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
}
- (void)testPingPongRPCWithV1API {
id request = [RMTStreamingOutputCallRequest messageWithPayloadSize:@1 requestedResponseSize:@1];
[self pingPongV1APIWithRequest:request numMessages:1000];
[self measureBlock:^{
[self pingPongV1APIWithRequest:request numMessages:10000];
}];
}
- (void)unaryRPCWithRequest:(RMTSimpleRequest *)request
numMessages:(int)numMessages
callOptions:(GRPCMutableCallOptions *)options {
const int kOutstandingRPCs = 10;
NSAssert(numMessages > kOutstandingRPCs, @"Number of RPCs must be > %d", kOutstandingRPCs);
__weak XCTestExpectation *expectation = [self expectationWithDescription:@"unaryRPC"];
dispatch_semaphore_t sema = dispatch_semaphore_create(kOutstandingRPCs);
__block int index = 0;
for (int i = 0; i < numMessages; ++i) {
GRPCUnaryProtoCall *call = [_service
unaryCallWithMessage:request
responseHandler:[[PerfTestsBlockCallbacks alloc]
initWithInitialMetadataCallback:nil
messageCallback:nil
closeCallback:^(NSDictionary *trailingMetadata,
NSError *error) {
dispatch_semaphore_signal(sema);
@synchronized(self) {
++index;
if (index == numMessages) {
[expectation fulfill];
}
}
}]
callOptions:options];
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
[call start];
}
[self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
}
- (void)testUnaryRPC {
// Workaround Apple CFStream bug
if (isUsingCFStream()) {
return;
}
RMTSimpleRequest *request = [RMTSimpleRequest message];
request.responseSize = 1048576;
request.payload.body = [NSMutableData dataWithLength:1048576];
GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init];
options.transport = [[self class] transport];
options.PEMRootCertificates = [[self class] PEMRootCertificates];
options.hostNameOverride = [[self class] hostNameOverride];
// warm up
[self unaryRPCWithRequest:request numMessages:50 callOptions:options];
[self measureBlock:^{
[self unaryRPCWithRequest:request numMessages:50 callOptions:options];
}];
}
@end

@ -0,0 +1,33 @@
/*
*
* Copyright 2019 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 <ProtoRPC/ProtoRPC.h>
// Convenience class to use blocks as callbacks
@interface PerfTestsBlockCallbacks : NSObject<GRPCProtoResponseHandler>
- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback
messageCallback:(void (^)(id))messageCallback
closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback
writeMessageCallback:(void (^)(void))writeMessageCallback;
- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback
messageCallback:(void (^)(id))messageCallback
closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback;
@end

@ -0,0 +1,80 @@
/*
*
* Copyright 2019 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 "PerfTestsBlockCallbacks.h"
@implementation PerfTestsBlockCallbacks {
void (^_initialMetadataCallback)(NSDictionary *);
void (^_messageCallback)(id);
void (^_closeCallback)(NSDictionary *, NSError *);
void (^_writeMessageCallback)(void);
dispatch_queue_t _dispatchQueue;
}
- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback
messageCallback:(void (^)(id))messageCallback
closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback
writeMessageCallback:(void (^)(void))writeMessageCallback {
if ((self = [super init])) {
_initialMetadataCallback = initialMetadataCallback;
_messageCallback = messageCallback;
_closeCallback = closeCallback;
_writeMessageCallback = writeMessageCallback;
_dispatchQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL);
}
return self;
}
- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback
messageCallback:(void (^)(id))messageCallback
closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback {
return [self initWithInitialMetadataCallback:initialMetadataCallback
messageCallback:messageCallback
closeCallback:closeCallback
writeMessageCallback:nil];
}
- (void)didReceiveInitialMetadata:(NSDictionary *)initialMetadata {
if (_initialMetadataCallback) {
_initialMetadataCallback(initialMetadata);
}
}
- (void)didReceiveProtoMessage:(GPBMessage *)message {
if (_messageCallback) {
_messageCallback(message);
}
}
- (void)didCloseWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error {
if (_closeCallback) {
_closeCallback(trailingMetadata, error);
}
}
- (void)didWriteMessage {
if (_writeMessageCallback) {
_writeMessageCallback();
}
}
- (dispatch_queue_t)dispatchQueue {
return _dispatchQueue;
}
@end

@ -0,0 +1,74 @@
/*
*
* Copyright 2019 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 <GRPCClient/GRPCCall+Tests.h>
#import <GRPCClient/GRPCTransport.h>
#import <GRPCClient/internal_testing/GRPCCall+InternalTests.h>
#import "PerfTests.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 kLocalCleartextHost = NSStringize(HOST_PORT_LOCAL);
extern const char *kCFStreamVarName;
// The Protocol Buffers encoding overhead of local interop server. Acquired
// by experiment. Adjust this when server's proto file changes.
static int32_t kLocalInteropServerOverhead = 10;
/** Tests in PerfTests.m, sending the RPCs to a local cleartext server. */
@interface PerfTestsCFStreamCleartext : PerfTests
@end
@implementation PerfTestsCFStreamCleartext
+ (NSString *)host {
return kLocalCleartextHost;
}
+ (NSString *)PEMRootCertificates {
return nil;
}
+ (NSString *)hostNameOverride {
return nil;
}
- (int32_t)encodingOverhead {
return kLocalInteropServerOverhead; // bytes
}
+ (void)setUp {
setenv(kCFStreamVarName, "1", 1);
}
- (void)setUp {
[super setUp];
// Register test server as non-SSL.
[GRPCCall useInsecureConnectionsForHost:kLocalCleartextHost];
}
+ (GRPCTransportID)transport {
return GRPCDefaultTransportImplList.core_insecure;
}
@end

@ -0,0 +1,80 @@
/*
*
* Copyright 2019 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 <GRPCClient/GRPCCall+Tests.h>
#import <GRPCClient/GRPCTransport.h>
#import <GRPCClient/internal_testing/GRPCCall+InternalTests.h>
#import "PerfTests.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 kLocalSSLHost = NSStringize(HOST_PORT_LOCALSSL);
extern const char *kCFStreamVarName;
// The Protocol Buffers encoding overhead of local interop server. Acquired
// by experiment. Adjust this when server's proto file changes.
static int32_t kLocalInteropServerOverhead = 10;
/** Tests in PerfTests.m, sending the RPCs to a local SSL server. */
@interface PerfTestsCFStreamSSL : PerfTests
@end
@implementation PerfTestsCFStreamSSL
+ (NSString *)host {
return kLocalSSLHost;
}
+ (NSString *)PEMRootCertificates {
NSBundle *bundle = [NSBundle bundleForClass:[self class]];
NSString *certsPath =
[bundle pathForResource:@"TestCertificates.bundle/test-certificates" ofType:@"pem"];
NSError *error;
return [NSString stringWithContentsOfFile:certsPath encoding:NSUTF8StringEncoding error:&error];
}
+ (NSString *)hostNameOverride {
return @"foo.test.google.fr";
}
- (int32_t)encodingOverhead {
return kLocalInteropServerOverhead; // bytes
}
+ (GRPCTransportID)transport {
return GRPCDefaultTransportImplList.core_secure;
}
+ (void)setUp {
setenv(kCFStreamVarName, "1", 1);
}
- (void)setUp {
[super setUp];
// Register test server certificates and name.
NSBundle *bundle = [NSBundle bundleForClass:[self class]];
NSString *certsPath =
[bundle pathForResource:@"TestCertificates.bundle/test-certificates" ofType:@"pem"];
[GRPCCall useTestCertsPath:certsPath testName:@"foo.test.google.fr" forHost:kLocalSSLHost];
}
@end

@ -0,0 +1,63 @@
/*
*
* Copyright 2019 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 <GRPCClient/GRPCCall+Tests.h>
#import <GRPCClient/internal_testing/GRPCCall+InternalTests.h>
#import <Cronet/Cronet.h>
#import <GRPCClient/GRPCCall+Cronet.h>
#import "../ConfigureCronet.h"
#import "PerfTests.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 kLocalSSLHost = NSStringize(HOST_PORT_LOCALSSL);
// The Protocol Buffers encoding overhead of remote interop server. Acquired
// by experiment. Adjust this when server's proto file changes.
static int32_t kRemoteInteropServerOverhead = 12;
/** Tests in PerfTests.m, sending the RPCs to a remote SSL server. */
@interface PerfTestsCronet : PerfTests
@end
@implementation PerfTestsCronet
+ (void)setUp {
configureCronet();
[GRPCCall useCronetWithEngine:[Cronet getGlobalEngine]];
[super setUp];
}
+ (NSString *)host {
return kLocalSSLHost;
}
+ (GRPCTransportID)transport {
return gGRPCCoreCronetID;
}
- (int32_t)encodingOverhead {
return kRemoteInteropServerOverhead; // bytes
}
@end

@ -0,0 +1,74 @@
/*
*
* Copyright 2019 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 <GRPCClient/GRPCCall+Tests.h>
#import <GRPCClient/GRPCTransport.h>
#import <GRPCClient/internal_testing/GRPCCall+InternalTests.h>
#import "PerfTests.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 kLocalCleartextHost = NSStringize(HOST_PORT_LOCAL);
extern const char *kCFStreamVarName;
// The Protocol Buffers encoding overhead of local interop server. Acquired
// by experiment. Adjust this when server's proto file changes.
static int32_t kLocalInteropServerOverhead = 10;
/** Tests in PerfTests.m, sending the RPCs to a local cleartext server. */
@interface PerfTestsNoCFStreamCleartext : PerfTests
@end
@implementation PerfTestsNoCFStreamCleartext
+ (NSString *)host {
return kLocalCleartextHost;
}
+ (NSString *)PEMRootCertificates {
return nil;
}
+ (NSString *)hostNameOverride {
return nil;
}
- (int32_t)encodingOverhead {
return kLocalInteropServerOverhead; // bytes
}
+ (void)setUp {
setenv(kCFStreamVarName, "0", 1);
}
- (void)setUp {
[super setUp];
// Register test server as non-SSL.
[GRPCCall useInsecureConnectionsForHost:kLocalCleartextHost];
}
+ (GRPCTransportID)transport {
return GRPCDefaultTransportImplList.core_insecure;
}
@end

@ -0,0 +1,80 @@
/*
*
* Copyright 2019 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 <GRPCClient/GRPCCall+Tests.h>
#import <GRPCClient/GRPCTransport.h>
#import <GRPCClient/internal_testing/GRPCCall+InternalTests.h>
#import "PerfTests.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 kLocalSSLHost = NSStringize(HOST_PORT_LOCALSSL);
extern const char *kCFStreamVarName;
// The Protocol Buffers encoding overhead of local interop server. Acquired
// by experiment. Adjust this when server's proto file changes.
static int32_t kLocalInteropServerOverhead = 10;
/** Tests in PerfTests.m, sending the RPCs to a local SSL server. */
@interface PerfTestsNoCFStreamSSL : PerfTests
@end
@implementation PerfTestsNoCFStreamSSL
+ (NSString *)host {
return kLocalSSLHost;
}
+ (NSString *)PEMRootCertificates {
NSBundle *bundle = [NSBundle bundleForClass:[self class]];
NSString *certsPath =
[bundle pathForResource:@"TestCertificates.bundle/test-certificates" ofType:@"pem"];
NSError *error;
return [NSString stringWithContentsOfFile:certsPath encoding:NSUTF8StringEncoding error:&error];
}
+ (NSString *)hostNameOverride {
return @"foo.test.google.fr";
}
- (int32_t)encodingOverhead {
return kLocalInteropServerOverhead; // bytes
}
+ (GRPCTransportID)transport {
return GRPCDefaultTransportImplList.core_secure;
}
+ (void)setUp {
setenv(kCFStreamVarName, "0", 1);
}
- (void)setUp {
[super setUp];
// Register test server certificates and name.
NSBundle *bundle = [NSBundle bundleForClass:[self class]];
NSString *certsPath =
[bundle pathForResource:@"TestCertificates.bundle/test-certificates" ofType:@"pem"];
[GRPCCall useTestCertsPath:certsPath testName:@"foo.test.google.fr" forHost:kLocalSSLHost];
}
@end

@ -49,6 +49,14 @@ target 'CronetTests' do
pod 'gRPC-Core/Tests', :path => GRPC_LOCAL_SRC, :inhibit_warnings => true
end
target 'PerfTests' do
platform :ios, '8.0'
grpc_deps
pod 'gRPC/GRPCCoreCronet', :path => GRPC_LOCAL_SRC
pod 'CronetFramework', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c"
end
# gRPC-Core.podspec needs to be modified to be successfully used for local development. A Podfile's
# pre_install hook lets us do that. The block passed to it runs after the podspecs are downloaded
# and before they are installed in the user project.

@ -0,0 +1,65 @@
/*
*
* Copyright 2019 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 <GRPCClient/GRPCTypes.h>
/**
* This is an abstract class that needs to be subclassed. See |+host|.
*/
@interface TestBase : XCTestCase
/**
* The test suite to run, checking if the current XCTestCase instance is the base class.
* If so, run no tests (disabled). Otherwise, proceed to normal execution.
*/
@property(class, readonly) XCTestSuite *defaultTestSuite;
/**
* Host to send the RPCs to. The base implementation returns nil, which would make all tests to
* fail.
* Override in a subclass to perform these tests against a specific address.
*/
+ (NSString *)host;
/**
* Bytes of overhead of test proto responses due to encoding. This is used to excercise the behavior
* when responses are just above or below the max response size. For some reason, the local and
* remote servers enconde responses with different overhead (?), so this is defined per-subclass.
*/
- (int32_t)encodingOverhead;
/*
* The transport to be used. The base implementation returns NULL. Subclasses should override to
* appropriate settings.
*/
+ (GRPCTransportID)transport;
/**
* The root certificates to be used. The base implementation returns nil. Subclasses should override
* to appropriate settings.
*/
+ (NSString *)PEMRootCertificates;
/**
* The root certificates to be used. The base implementation returns nil. Subclasses should override
* to appropriate settings.
*/
+ (NSString *)hostNameOverride;
@end

@ -0,0 +1,50 @@
/*
*
* Copyright 2019 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 "TestBase.h"
@implementation TestBase : XCTestCase
+ (XCTestSuite *)defaultTestSuite {
return super.defaultTestSuite;
}
+ (NSString *)host {
return nil;
}
// This number indicates how many bytes of overhead does Protocol Buffers encoding add onto the
// message. The number varies as different message.proto is used on different servers. The actual
// number for each interop server is overridden in corresponding derived test classes.
- (int32_t)encodingOverhead {
return 0;
}
+ (GRPCTransportID)transport {
return NULL;
}
+ (NSString *)PEMRootCertificates {
return nil;
}
+ (NSString *)hostNameOverride {
return nil;
}
@end

@ -49,10 +49,26 @@
ABCB3EEA22F23BF500F0FECE /* APIv2Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E7F487F227782C1006656AD /* APIv2Tests.m */; };
ABCB3EEB22F23BF500F0FECE /* NSErrorUnitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E0282E8215AA697007AC99D /* NSErrorUnitTests.m */; };
B071230B22669EED004B64A1 /* StressTests.m in Sources */ = {isa = PBXBuildFile; fileRef = B071230A22669EED004B64A1 /* StressTests.m */; };
B098FC622331B7EA00029C0E /* TestBase.m in Sources */ = {isa = PBXBuildFile; fileRef = B0C461E02331AC5C004E17DA /* TestBase.m */; };
B098FC632331B7FA00029C0E /* TestBase.m in Sources */ = {isa = PBXBuildFile; fileRef = B0C461E02331AC5C004E17DA /* TestBase.m */; };
B098FC642331B80500029C0E /* TestBase.m in Sources */ = {isa = PBXBuildFile; fileRef = B0C461E02331AC5C004E17DA /* TestBase.m */; };
B098FC652331B82000029C0E /* TestBase.m in Sources */ = {isa = PBXBuildFile; fileRef = B0C461E02331AC5C004E17DA /* TestBase.m */; };
B098FC662331B83900029C0E /* TestBase.m in Sources */ = {isa = PBXBuildFile; fileRef = B0C461E02331AC5C004E17DA /* TestBase.m */; };
B0A420C523299D2200D95F2A /* TestCertificates.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 63E240CF1B6C63DC005F3B0E /* TestCertificates.bundle */; };
B0A420C623299D2D00D95F2A /* ConfigureCronet.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E3F1487227918AA007C6D90 /* ConfigureCronet.m */; };
B0BB3F08225E7ABA008DA580 /* NSErrorUnitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E0282E8215AA697007AC99D /* NSErrorUnitTests.m */; };
B0BB3F0A225EA511008DA580 /* TestCertificates.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 63E240CF1B6C63DC005F3B0E /* TestCertificates.bundle */; };
B0D39B9A2266F3CB00A4078D /* StressTestsSSL.m in Sources */ = {isa = PBXBuildFile; fileRef = B0D39B992266F3CB00A4078D /* StressTestsSSL.m */; };
B0D39B9C2266FF9800A4078D /* StressTestsCleartext.m in Sources */ = {isa = PBXBuildFile; fileRef = B0D39B9B2266FF9800A4078D /* StressTestsCleartext.m */; };
B0F2D0C4232991CC008C2575 /* PerfTestsBlockCallbacks.h in Sources */ = {isa = PBXBuildFile; fileRef = B0F2D08E23297BC6008C2575 /* PerfTestsBlockCallbacks.h */; };
B0F2D0C5232991CC008C2575 /* PerfTestsBlockCallbacks.m in Sources */ = {isa = PBXBuildFile; fileRef = B0F2D08F23297BDD008C2575 /* PerfTestsBlockCallbacks.m */; };
B0F2D0C6232991CC008C2575 /* PerfTests.m in Sources */ = {isa = PBXBuildFile; fileRef = B0F2D09123297C1A008C2575 /* PerfTests.m */; };
B0F2D0C7232991CC008C2575 /* PerfTests.h in Sources */ = {isa = PBXBuildFile; fileRef = B0F2D09323297C28008C2575 /* PerfTests.h */; };
B0F2D0C8232991CC008C2575 /* PerfTestsCronet.m in Sources */ = {isa = PBXBuildFile; fileRef = B0F2D09423297C47008C2575 /* PerfTestsCronet.m */; };
B0F2D0C9232991CC008C2575 /* PerfTestsCFStreamSSL.m in Sources */ = {isa = PBXBuildFile; fileRef = B0F2D09623297CA6008C2575 /* PerfTestsCFStreamSSL.m */; };
B0F2D0CA232991CC008C2575 /* PerfTestsCFStreamCleartext.m in Sources */ = {isa = PBXBuildFile; fileRef = B0F2D09823297CBF008C2575 /* PerfTestsCFStreamCleartext.m */; };
B0F2D0CB232991CC008C2575 /* PerfTestsNoCFStreamSSL.m in Sources */ = {isa = PBXBuildFile; fileRef = B0F2D09A23297CF2008C2575 /* PerfTestsNoCFStreamSSL.m */; };
B0F2D0CC232991CC008C2575 /* PerfTestsNoCFStreamCleartext.m in Sources */ = {isa = PBXBuildFile; fileRef = B0F2D09C23297D02008C2575 /* PerfTestsNoCFStreamCleartext.m */; };
CCF5C0719EF608276AE16374 /* libPods-UnitTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 22A3EBB488699C8CEA19707B /* libPods-UnitTests.a */; };
F4E21D69D650D61FE8F02696 /* libPods-TvTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2A0A5455106001F60357A4B6 /* libPods-TvTests.a */; };
/* End PBXBuildFile section */
@ -163,9 +179,21 @@
B071230A22669EED004B64A1 /* StressTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = StressTests.m; sourceTree = "<group>"; };
B0BB3EF7225E795F008DA580 /* MacTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MacTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
B0BB3EFB225E795F008DA580 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
B0C461DF2331AC3F004E17DA /* TestBase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TestBase.h; sourceTree = "<group>"; };
B0C461E02331AC5C004E17DA /* TestBase.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TestBase.m; sourceTree = "<group>"; };
B0C5FC172267C77200F192BE /* StressTests.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = StressTests.h; sourceTree = "<group>"; };
B0D39B992266F3CB00A4078D /* StressTestsSSL.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = StressTestsSSL.m; sourceTree = "<group>"; };
B0D39B9B2266FF9800A4078D /* StressTestsCleartext.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = StressTestsCleartext.m; sourceTree = "<group>"; };
B0F2D08E23297BC6008C2575 /* PerfTestsBlockCallbacks.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PerfTestsBlockCallbacks.h; sourceTree = "<group>"; };
B0F2D08F23297BDD008C2575 /* PerfTestsBlockCallbacks.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PerfTestsBlockCallbacks.m; sourceTree = "<group>"; };
B0F2D09123297C1A008C2575 /* PerfTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PerfTests.m; sourceTree = "<group>"; };
B0F2D09323297C28008C2575 /* PerfTests.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PerfTests.h; sourceTree = "<group>"; };
B0F2D09423297C47008C2575 /* PerfTestsCronet.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PerfTestsCronet.m; sourceTree = "<group>"; };
B0F2D09623297CA6008C2575 /* PerfTestsCFStreamSSL.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PerfTestsCFStreamSSL.m; sourceTree = "<group>"; };
B0F2D09823297CBF008C2575 /* PerfTestsCFStreamCleartext.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PerfTestsCFStreamCleartext.m; sourceTree = "<group>"; };
B0F2D09A23297CF2008C2575 /* PerfTestsNoCFStreamSSL.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PerfTestsNoCFStreamSSL.m; sourceTree = "<group>"; };
B0F2D09C23297D02008C2575 /* PerfTestsNoCFStreamCleartext.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PerfTestsNoCFStreamCleartext.m; sourceTree = "<group>"; };
B0F2D0BA232991BA008C2575 /* PerfTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PerfTests.xctest; 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 = "<group>"; };
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 = "<group>"; };
@ -241,6 +269,13 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
B0F2D0B7232991BA008C2575 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
@ -406,6 +441,7 @@
635697BE1B14FC11007A7283 = {
isa = PBXGroup;
children = (
B0F2D08D23297B9E008C2575 /* PerfTests */,
5E7F48762277820F006656AD /* InteropTests */,
635697C91B14FC11007A7283 /* Tests */,
63E240CF1B6C63DC005F3B0E /* TestCertificates.bundle */,
@ -427,6 +463,7 @@
5EA476F42272816A000F72FC /* InteropTests.xctest */,
5E7F485922775B15006656AD /* CronetTests.xctest */,
ABCB3EDA22F23B9700F0FECE /* TvTests.xctest */,
B0F2D0BA232991BA008C2575 /* PerfTests.xctest */,
);
name = Products;
sourceTree = "<group>";
@ -437,6 +474,8 @@
5E3F148A227918C4007C6D90 /* ConfigureCronet.h */,
5E3F1487227918AA007C6D90 /* ConfigureCronet.m */,
5EAFE8271F8EFB87007F2189 /* version.h */,
B0C461E02331AC5C004E17DA /* TestBase.m */,
B0C461DF2331AC3F004E17DA /* TestBase.h */,
635697D71B14FC11007A7283 /* Supporting Files */,
);
name = Tests;
@ -470,6 +509,22 @@
path = MacTests;
sourceTree = "<group>";
};
B0F2D08D23297B9E008C2575 /* PerfTests */ = {
isa = PBXGroup;
children = (
B0F2D08E23297BC6008C2575 /* PerfTestsBlockCallbacks.h */,
B0F2D08F23297BDD008C2575 /* PerfTestsBlockCallbacks.m */,
B0F2D09123297C1A008C2575 /* PerfTests.m */,
B0F2D09323297C28008C2575 /* PerfTests.h */,
B0F2D09423297C47008C2575 /* PerfTestsCronet.m */,
B0F2D09623297CA6008C2575 /* PerfTestsCFStreamSSL.m */,
B0F2D09823297CBF008C2575 /* PerfTestsCFStreamCleartext.m */,
B0F2D09A23297CF2008C2575 /* PerfTestsNoCFStreamSSL.m */,
B0F2D09C23297D02008C2575 /* PerfTestsNoCFStreamCleartext.m */,
);
path = PerfTests;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@ -569,6 +624,23 @@
productReference = B0BB3EF7225E795F008DA580 /* MacTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
B0F2D0B9232991BA008C2575 /* PerfTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = B0F2D0BF232991BA008C2575 /* Build configuration list for PBXNativeTarget "PerfTests" */;
buildPhases = (
B0F2D0B6232991BA008C2575 /* Sources */,
B0F2D0B7232991BA008C2575 /* Frameworks */,
B0F2D0B8232991BA008C2575 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = PerfTests;
productName = PerfTests;
productReference = B0F2D0BA232991BA008C2575 /* PerfTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
@ -599,6 +671,10 @@
CreatedOnToolsVersion = 10.1;
ProvisioningStyle = Automatic;
};
B0F2D0B9232991BA008C2575 = {
CreatedOnToolsVersion = 10.1;
ProvisioningStyle = Automatic;
};
};
};
buildConfigurationList = 635697C21B14FC11007A7283 /* Build configuration list for PBXProject "Tests" */;
@ -619,6 +695,7 @@
5EA476F32272816A000F72FC /* InteropTests */,
5E7F485822775B15006656AD /* CronetTests */,
ABCB3ED922F23B9700F0FECE /* TvTests */,
B0F2D0B9232991BA008C2575 /* PerfTests */,
);
};
/* End PBXProject section */
@ -663,6 +740,14 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
B0F2D0B8232991BA008C2575 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
B0A420C523299D2200D95F2A /* TestCertificates.bundle in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
@ -885,6 +970,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
B098FC652331B82000029C0E /* TestBase.m in Sources */,
5E3F14852278BF5D007C6D90 /* InteropTestsBlockCallbacks.m in Sources */,
5E3F148D22792856007C6D90 /* ConfigureCronet.m in Sources */,
5E08D07023021E3B006D76EA /* InteropTestsMultipleChannels.m in Sources */,
@ -900,6 +986,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
B098FC642331B80500029C0E /* TestBase.m in Sources */,
5E3F14842278B461007C6D90 /* InteropTestsBlockCallbacks.m in Sources */,
5E7F488922778B04006656AD /* InteropTestsRemote.m in Sources */,
5EA477042273617B000F72FC /* InteropTestsLocalCleartext.m in Sources */,
@ -912,6 +999,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
B098FC662331B83900029C0E /* TestBase.m in Sources */,
ABCB3EEA22F23BF500F0FECE /* APIv2Tests.m in Sources */,
ABCB3EE822F23BEF00F0FECE /* InteropTestsBlockCallbacks.m in Sources */,
ABCB3EE422F23BEF00F0FECE /* InteropTestsRemote.m in Sources */,
@ -927,6 +1015,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
B098FC632331B7FA00029C0E /* TestBase.m in Sources */,
B0BB3F08225E7ABA008DA580 /* NSErrorUnitTests.m in Sources */,
5E7F488D22778C85006656AD /* InteropTestsLocalSSL.m in Sources */,
5E7F488E22778C87006656AD /* InteropTestsLocalCleartext.m in Sources */,
@ -941,6 +1030,24 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
B0F2D0B6232991BA008C2575 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
B098FC622331B7EA00029C0E /* TestBase.m in Sources */,
B0A420C623299D2D00D95F2A /* ConfigureCronet.m in Sources */,
B0F2D0C4232991CC008C2575 /* PerfTestsBlockCallbacks.h in Sources */,
B0F2D0C5232991CC008C2575 /* PerfTestsBlockCallbacks.m in Sources */,
B0F2D0C6232991CC008C2575 /* PerfTests.m in Sources */,
B0F2D0C7232991CC008C2575 /* PerfTests.h in Sources */,
B0F2D0C8232991CC008C2575 /* PerfTestsCronet.m in Sources */,
B0F2D0C9232991CC008C2575 /* PerfTestsCFStreamSSL.m in Sources */,
B0F2D0CA232991CC008C2575 /* PerfTestsCFStreamCleartext.m in Sources */,
B0F2D0CB232991CC008C2575 /* PerfTestsNoCFStreamSSL.m in Sources */,
B0F2D0CC232991CC008C2575 /* PerfTestsNoCFStreamCleartext.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
@ -1790,6 +1897,133 @@
};
name = Release;
};
B0F2D0C0232991BA008C2575 /* Debug */ = {
isa = XCBuildConfiguration;
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;
IPHONEOS_DEPLOYMENT_TARGET = 12.1;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = org.grpc.PerfTests;
PRODUCT_NAME = "$(TARGET_NAME)";
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
B0F2D0C1232991BA008C2575 /* Test */ = {
isa = XCBuildConfiguration;
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;
IPHONEOS_DEPLOYMENT_TARGET = 12.1;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = org.grpc.PerfTests;
PRODUCT_NAME = "$(TARGET_NAME)";
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Test;
};
B0F2D0C2232991BA008C2575 /* Cronet */ = {
isa = XCBuildConfiguration;
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;
IPHONEOS_DEPLOYMENT_TARGET = 12.1;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = org.grpc.PerfTests;
PRODUCT_NAME = "$(TARGET_NAME)";
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Cronet;
};
B0F2D0C3232991BA008C2575 /* Release */ = {
isa = XCBuildConfiguration;
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;
IPHONEOS_DEPLOYMENT_TARGET = 12.1;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = org.grpc.PerfTests;
PRODUCT_NAME = "$(TARGET_NAME)";
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
@ -1859,6 +2093,17 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
B0F2D0BF232991BA008C2575 /* Build configuration list for PBXNativeTarget "PerfTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
B0F2D0C0232991BA008C2575 /* Debug */,
B0F2D0C1232991BA008C2575 /* Test */,
B0F2D0C2232991BA008C2575 /* Cronet */,
B0F2D0C3232991BA008C2575 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 635697BF1B14FC11007A7283 /* Project object */;

@ -0,0 +1,95 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1010"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "NO"
buildForArchiving = "NO"
buildForAnalyzing = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "B0F2D0B9232991BA008C2575"
BuildableName = "PerfTests.xctest"
BlueprintName = "PerfTests"
ReferencedContainer = "container:Tests.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Test"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "B0F2D0B9232991BA008C2575"
BuildableName = "PerfTests.xctest"
BlueprintName = "PerfTests"
ReferencedContainer = "container:Tests.xcodeproj">
</BuildableReference>
<SkippedTests>
<Test
Identifier = "PerfTests">
</Test>
</SkippedTests>
</TestableReference>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "B0F2D0B9232991BA008C2575"
BuildableName = "PerfTests.xctest"
BlueprintName = "PerfTests"
ReferencedContainer = "container:Tests.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "B0F2D0B9232991BA008C2575"
BuildableName = "PerfTests.xctest"
BlueprintName = "PerfTests"
ReferencedContainer = "container:Tests.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
Loading…
Cancel
Save