mirror of https://github.com/grpc/grpc.git
commit
0867a350f9
45 changed files with 1677 additions and 300 deletions
@ -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 |
@ -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 |
@ -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…
Reference in new issue