xref: /aosp_15_r20/external/grpc-grpc/src/objective-c/tests/PerfTests/PerfTests.m (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
1*cc02d7e2SAndroid Build Coastguard Worker/*
2*cc02d7e2SAndroid Build Coastguard Worker *
3*cc02d7e2SAndroid Build Coastguard Worker * Copyright 2019 gRPC authors.
4*cc02d7e2SAndroid Build Coastguard Worker *
5*cc02d7e2SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
6*cc02d7e2SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
7*cc02d7e2SAndroid Build Coastguard Worker * You may obtain a copy of the License at
8*cc02d7e2SAndroid Build Coastguard Worker *
9*cc02d7e2SAndroid Build Coastguard Worker *     http://www.apache.org/licenses/LICENSE-2.0
10*cc02d7e2SAndroid Build Coastguard Worker *
11*cc02d7e2SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
12*cc02d7e2SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
13*cc02d7e2SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*cc02d7e2SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
15*cc02d7e2SAndroid Build Coastguard Worker * limitations under the License.
16*cc02d7e2SAndroid Build Coastguard Worker *
17*cc02d7e2SAndroid Build Coastguard Worker */
18*cc02d7e2SAndroid Build Coastguard Worker
19*cc02d7e2SAndroid Build Coastguard Worker#import "PerfTests.h"
20*cc02d7e2SAndroid Build Coastguard Worker
21*cc02d7e2SAndroid Build Coastguard Worker#include <grpc/status.h>
22*cc02d7e2SAndroid Build Coastguard Worker
23*cc02d7e2SAndroid Build Coastguard Worker#import <GRPCClient/GRPCCall+ChannelArg.h>
24*cc02d7e2SAndroid Build Coastguard Worker#import <GRPCClient/GRPCCall+Cronet.h>
25*cc02d7e2SAndroid Build Coastguard Worker#import <GRPCClient/GRPCCall+Interceptor.h>
26*cc02d7e2SAndroid Build Coastguard Worker#import <GRPCClient/GRPCCall+Tests.h>
27*cc02d7e2SAndroid Build Coastguard Worker#import <GRPCClient/GRPCInterceptor.h>
28*cc02d7e2SAndroid Build Coastguard Worker#import <GRPCClient/internal_testing/GRPCCall+InternalTests.h>
29*cc02d7e2SAndroid Build Coastguard Worker#import <ProtoRPC/ProtoRPC.h>
30*cc02d7e2SAndroid Build Coastguard Worker#import <RxLibrary/GRXBufferedPipe.h>
31*cc02d7e2SAndroid Build Coastguard Worker#import <RxLibrary/GRXWriter+Immediate.h>
32*cc02d7e2SAndroid Build Coastguard Worker#import <grpc/grpc.h>
33*cc02d7e2SAndroid Build Coastguard Worker#import <grpc/support/log.h>
34*cc02d7e2SAndroid Build Coastguard Worker#import "src/objective-c/tests/RemoteTestClient/Messages.pbobjc.h"
35*cc02d7e2SAndroid Build Coastguard Worker#import "src/objective-c/tests/RemoteTestClient/Test.pbobjc.h"
36*cc02d7e2SAndroid Build Coastguard Worker#import "src/objective-c/tests/RemoteTestClient/Test.pbrpc.h"
37*cc02d7e2SAndroid Build Coastguard Worker
38*cc02d7e2SAndroid Build Coastguard Worker#import "PerfTestsBlockCallbacks.h"
39*cc02d7e2SAndroid Build Coastguard Worker
40*cc02d7e2SAndroid Build Coastguard Worker#define TEST_TIMEOUT 128
41*cc02d7e2SAndroid Build Coastguard Worker
42*cc02d7e2SAndroid Build Coastguard Workerextern const char *kCFStreamVarName;
43*cc02d7e2SAndroid Build Coastguard Worker
44*cc02d7e2SAndroid Build Coastguard Worker// Convenience constructors for the generated proto messages:
45*cc02d7e2SAndroid Build Coastguard Worker
46*cc02d7e2SAndroid Build Coastguard Worker@interface RMTStreamingOutputCallRequest (Constructors)
47*cc02d7e2SAndroid Build Coastguard Worker+ (instancetype)messageWithPayloadSize:(NSNumber *)payloadSize
48*cc02d7e2SAndroid Build Coastguard Worker                 requestedResponseSize:(NSNumber *)responseSize;
49*cc02d7e2SAndroid Build Coastguard Worker@end
50*cc02d7e2SAndroid Build Coastguard Worker
51*cc02d7e2SAndroid Build Coastguard Worker@implementation RMTStreamingOutputCallRequest (Constructors)
52*cc02d7e2SAndroid Build Coastguard Worker+ (instancetype)messageWithPayloadSize:(NSNumber *)payloadSize
53*cc02d7e2SAndroid Build Coastguard Worker                 requestedResponseSize:(NSNumber *)responseSize {
54*cc02d7e2SAndroid Build Coastguard Worker  RMTStreamingOutputCallRequest *request = [self message];
55*cc02d7e2SAndroid Build Coastguard Worker  RMTResponseParameters *parameters = [RMTResponseParameters message];
56*cc02d7e2SAndroid Build Coastguard Worker  parameters.size = responseSize.intValue;
57*cc02d7e2SAndroid Build Coastguard Worker  [request.responseParametersArray addObject:parameters];
58*cc02d7e2SAndroid Build Coastguard Worker  request.payload.body = [NSMutableData dataWithLength:payloadSize.unsignedIntegerValue];
59*cc02d7e2SAndroid Build Coastguard Worker  return request;
60*cc02d7e2SAndroid Build Coastguard Worker}
61*cc02d7e2SAndroid Build Coastguard Worker@end
62*cc02d7e2SAndroid Build Coastguard Worker
63*cc02d7e2SAndroid Build Coastguard Worker@interface DefaultInterceptorFactory : NSObject <GRPCInterceptorFactory>
64*cc02d7e2SAndroid Build Coastguard Worker
65*cc02d7e2SAndroid Build Coastguard Worker- (GRPCInterceptor *)createInterceptorWithManager:(GRPCInterceptorManager *)interceptorManager;
66*cc02d7e2SAndroid Build Coastguard Worker
67*cc02d7e2SAndroid Build Coastguard Worker@end
68*cc02d7e2SAndroid Build Coastguard Worker
69*cc02d7e2SAndroid Build Coastguard Worker@implementation DefaultInterceptorFactory
70*cc02d7e2SAndroid Build Coastguard Worker
71*cc02d7e2SAndroid Build Coastguard Worker- (GRPCInterceptor *)createInterceptorWithManager:(GRPCInterceptorManager *)interceptorManager {
72*cc02d7e2SAndroid Build Coastguard Worker  dispatch_queue_t queue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL);
73*cc02d7e2SAndroid Build Coastguard Worker  return [[GRPCInterceptor alloc] initWithInterceptorManager:interceptorManager
74*cc02d7e2SAndroid Build Coastguard Worker                                               dispatchQueue:queue];
75*cc02d7e2SAndroid Build Coastguard Worker}
76*cc02d7e2SAndroid Build Coastguard Worker
77*cc02d7e2SAndroid Build Coastguard Worker@end
78*cc02d7e2SAndroid Build Coastguard Worker
79*cc02d7e2SAndroid Build Coastguard Worker#pragma mark Tests
80*cc02d7e2SAndroid Build Coastguard Worker
81*cc02d7e2SAndroid Build Coastguard Worker@implementation PerfTests {
82*cc02d7e2SAndroid Build Coastguard Worker  RMTTestService *_service;
83*cc02d7e2SAndroid Build Coastguard Worker}
84*cc02d7e2SAndroid Build Coastguard Worker
85*cc02d7e2SAndroid Build Coastguard Worker+ (XCTestSuite *)defaultTestSuite {
86*cc02d7e2SAndroid Build Coastguard Worker  if (self == [PerfTests class]) {
87*cc02d7e2SAndroid Build Coastguard Worker    return [XCTestSuite testSuiteWithName:@"PerfTestsEmptySuite"];
88*cc02d7e2SAndroid Build Coastguard Worker  } else {
89*cc02d7e2SAndroid Build Coastguard Worker    return super.defaultTestSuite;
90*cc02d7e2SAndroid Build Coastguard Worker  }
91*cc02d7e2SAndroid Build Coastguard Worker}
92*cc02d7e2SAndroid Build Coastguard Worker
93*cc02d7e2SAndroid Build Coastguard Worker+ (NSString *)host {
94*cc02d7e2SAndroid Build Coastguard Worker  return nil;
95*cc02d7e2SAndroid Build Coastguard Worker}
96*cc02d7e2SAndroid Build Coastguard Worker
97*cc02d7e2SAndroid Build Coastguard Worker// This number indicates how many bytes of overhead does Protocol Buffers encoding add onto the
98*cc02d7e2SAndroid Build Coastguard Worker// message. The number varies as different message.proto is used on different servers. The actual
99*cc02d7e2SAndroid Build Coastguard Worker// number for each interop server is overridden in corresponding derived test classes.
100*cc02d7e2SAndroid Build Coastguard Worker- (int32_t)encodingOverhead {
101*cc02d7e2SAndroid Build Coastguard Worker  return 0;
102*cc02d7e2SAndroid Build Coastguard Worker}
103*cc02d7e2SAndroid Build Coastguard Worker
104*cc02d7e2SAndroid Build Coastguard Worker+ (GRPCTransportID)transport {
105*cc02d7e2SAndroid Build Coastguard Worker  return NULL;
106*cc02d7e2SAndroid Build Coastguard Worker}
107*cc02d7e2SAndroid Build Coastguard Worker
108*cc02d7e2SAndroid Build Coastguard Worker+ (NSString *)PEMRootCertificates {
109*cc02d7e2SAndroid Build Coastguard Worker  return nil;
110*cc02d7e2SAndroid Build Coastguard Worker}
111*cc02d7e2SAndroid Build Coastguard Worker
112*cc02d7e2SAndroid Build Coastguard Worker+ (NSString *)hostNameOverride {
113*cc02d7e2SAndroid Build Coastguard Worker  return nil;
114*cc02d7e2SAndroid Build Coastguard Worker}
115*cc02d7e2SAndroid Build Coastguard Worker
116*cc02d7e2SAndroid Build Coastguard Worker- (void)setUp {
117*cc02d7e2SAndroid Build Coastguard Worker  self.continueAfterFailure = NO;
118*cc02d7e2SAndroid Build Coastguard Worker
119*cc02d7e2SAndroid Build Coastguard Worker  [GRPCCall resetHostSettings];
120*cc02d7e2SAndroid Build Coastguard Worker
121*cc02d7e2SAndroid Build Coastguard Worker#pragma clang diagnostic push
122*cc02d7e2SAndroid Build Coastguard Worker#pragma clang diagnostic ignored "-Wdeprecated-declarations"
123*cc02d7e2SAndroid Build Coastguard Worker  [GRPCCall closeOpenConnections];
124*cc02d7e2SAndroid Build Coastguard Worker#pragma clang diagnostic pop
125*cc02d7e2SAndroid Build Coastguard Worker
126*cc02d7e2SAndroid Build Coastguard Worker  _service = [[self class] host] ? [RMTTestService serviceWithHost:[[self class] host]] : nil;
127*cc02d7e2SAndroid Build Coastguard Worker}
128*cc02d7e2SAndroid Build Coastguard Worker
129*cc02d7e2SAndroid Build Coastguard Worker- (BOOL)isUsingCFStream {
130*cc02d7e2SAndroid Build Coastguard Worker  return [NSStringFromClass([self class]) isEqualToString:@"PerfTestsCFStreamSSL"];
131*cc02d7e2SAndroid Build Coastguard Worker}
132*cc02d7e2SAndroid Build Coastguard Worker
133*cc02d7e2SAndroid Build Coastguard Worker- (void)pingPongV2APIWithRequest:(RMTStreamingOutputCallRequest *)request
134*cc02d7e2SAndroid Build Coastguard Worker                     numMessages:(int)numMessages
135*cc02d7e2SAndroid Build Coastguard Worker                         options:(GRPCMutableCallOptions *)options {
136*cc02d7e2SAndroid Build Coastguard Worker  __weak XCTestExpectation *expectation = [self expectationWithDescription:@"PingPong"];
137*cc02d7e2SAndroid Build Coastguard Worker
138*cc02d7e2SAndroid Build Coastguard Worker  __block BOOL flowControlEnabled = options.flowControlEnabled;
139*cc02d7e2SAndroid Build Coastguard Worker  __block int index = 0;
140*cc02d7e2SAndroid Build Coastguard Worker  __block GRPCStreamingProtoCall *call = [self->_service
141*cc02d7e2SAndroid Build Coastguard Worker      fullDuplexCallWithResponseHandler:[[PerfTestsBlockCallbacks alloc]
142*cc02d7e2SAndroid Build Coastguard Worker                                            initWithInitialMetadataCallback:nil
143*cc02d7e2SAndroid Build Coastguard Worker                                            messageCallback:^(id message) {
144*cc02d7e2SAndroid Build Coastguard Worker                                              int indexCopy;
145*cc02d7e2SAndroid Build Coastguard Worker                                              @synchronized(self) {
146*cc02d7e2SAndroid Build Coastguard Worker                                                indexCopy = index;
147*cc02d7e2SAndroid Build Coastguard Worker                                                index += 1;
148*cc02d7e2SAndroid Build Coastguard Worker                                              }
149*cc02d7e2SAndroid Build Coastguard Worker                                              if (indexCopy < numMessages) {
150*cc02d7e2SAndroid Build Coastguard Worker                                                [call writeMessage:request];
151*cc02d7e2SAndroid Build Coastguard Worker                                                if (flowControlEnabled) {
152*cc02d7e2SAndroid Build Coastguard Worker                                                  [call receiveNextMessage];
153*cc02d7e2SAndroid Build Coastguard Worker                                                }
154*cc02d7e2SAndroid Build Coastguard Worker                                              } else {
155*cc02d7e2SAndroid Build Coastguard Worker                                                [call finish];
156*cc02d7e2SAndroid Build Coastguard Worker                                              }
157*cc02d7e2SAndroid Build Coastguard Worker                                            }
158*cc02d7e2SAndroid Build Coastguard Worker                                            closeCallback:^(NSDictionary *trailingMetadata,
159*cc02d7e2SAndroid Build Coastguard Worker                                                            NSError *error) {
160*cc02d7e2SAndroid Build Coastguard Worker                                              [expectation fulfill];
161*cc02d7e2SAndroid Build Coastguard Worker                                            }]
162*cc02d7e2SAndroid Build Coastguard Worker                            callOptions:options];
163*cc02d7e2SAndroid Build Coastguard Worker  [call start];
164*cc02d7e2SAndroid Build Coastguard Worker  if (flowControlEnabled) {
165*cc02d7e2SAndroid Build Coastguard Worker    [call receiveNextMessage];
166*cc02d7e2SAndroid Build Coastguard Worker  }
167*cc02d7e2SAndroid Build Coastguard Worker  [call writeMessage:request];
168*cc02d7e2SAndroid Build Coastguard Worker  [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
169*cc02d7e2SAndroid Build Coastguard Worker}
170*cc02d7e2SAndroid Build Coastguard Worker
171*cc02d7e2SAndroid Build Coastguard Worker- (void)testPingPongRPCWithV2API {
172*cc02d7e2SAndroid Build Coastguard Worker  GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init];
173*cc02d7e2SAndroid Build Coastguard Worker  options.transport = [[self class] transport];
174*cc02d7e2SAndroid Build Coastguard Worker  options.PEMRootCertificates = [[self class] PEMRootCertificates];
175*cc02d7e2SAndroid Build Coastguard Worker  options.hostNameOverride = [[self class] hostNameOverride];
176*cc02d7e2SAndroid Build Coastguard Worker
177*cc02d7e2SAndroid Build Coastguard Worker  id request = [RMTStreamingOutputCallRequest messageWithPayloadSize:@1 requestedResponseSize:@1];
178*cc02d7e2SAndroid Build Coastguard Worker
179*cc02d7e2SAndroid Build Coastguard Worker  // warm up
180*cc02d7e2SAndroid Build Coastguard Worker  [self pingPongV2APIWithRequest:request numMessages:1000 options:options];
181*cc02d7e2SAndroid Build Coastguard Worker
182*cc02d7e2SAndroid Build Coastguard Worker  [self measureBlock:^{
183*cc02d7e2SAndroid Build Coastguard Worker    [self pingPongV2APIWithRequest:request numMessages:1000 options:options];
184*cc02d7e2SAndroid Build Coastguard Worker  }];
185*cc02d7e2SAndroid Build Coastguard Worker}
186*cc02d7e2SAndroid Build Coastguard Worker
187*cc02d7e2SAndroid Build Coastguard Worker- (void)testPingPongRPCWithFlowControl {
188*cc02d7e2SAndroid Build Coastguard Worker  GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init];
189*cc02d7e2SAndroid Build Coastguard Worker  options.transport = [[self class] transport];
190*cc02d7e2SAndroid Build Coastguard Worker  options.PEMRootCertificates = [[self class] PEMRootCertificates];
191*cc02d7e2SAndroid Build Coastguard Worker  options.hostNameOverride = [[self class] hostNameOverride];
192*cc02d7e2SAndroid Build Coastguard Worker  options.flowControlEnabled = YES;
193*cc02d7e2SAndroid Build Coastguard Worker
194*cc02d7e2SAndroid Build Coastguard Worker  id request = [RMTStreamingOutputCallRequest messageWithPayloadSize:@1 requestedResponseSize:@1];
195*cc02d7e2SAndroid Build Coastguard Worker
196*cc02d7e2SAndroid Build Coastguard Worker  // warm up
197*cc02d7e2SAndroid Build Coastguard Worker  [self pingPongV2APIWithRequest:request numMessages:1000 options:options];
198*cc02d7e2SAndroid Build Coastguard Worker
199*cc02d7e2SAndroid Build Coastguard Worker  [self measureBlock:^{
200*cc02d7e2SAndroid Build Coastguard Worker    [self pingPongV2APIWithRequest:request numMessages:1000 options:options];
201*cc02d7e2SAndroid Build Coastguard Worker  }];
202*cc02d7e2SAndroid Build Coastguard Worker}
203*cc02d7e2SAndroid Build Coastguard Worker
204*cc02d7e2SAndroid Build Coastguard Worker- (void)testPingPongRPCWithInterceptor {
205*cc02d7e2SAndroid Build Coastguard Worker  GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init];
206*cc02d7e2SAndroid Build Coastguard Worker  options.transport = [[self class] transport];
207*cc02d7e2SAndroid Build Coastguard Worker  options.PEMRootCertificates = [[self class] PEMRootCertificates];
208*cc02d7e2SAndroid Build Coastguard Worker  options.hostNameOverride = [[self class] hostNameOverride];
209*cc02d7e2SAndroid Build Coastguard Worker  options.interceptorFactories = @[ [[DefaultInterceptorFactory alloc] init] ];
210*cc02d7e2SAndroid Build Coastguard Worker
211*cc02d7e2SAndroid Build Coastguard Worker  id request = [RMTStreamingOutputCallRequest messageWithPayloadSize:@1 requestedResponseSize:@1];
212*cc02d7e2SAndroid Build Coastguard Worker
213*cc02d7e2SAndroid Build Coastguard Worker  // warm up
214*cc02d7e2SAndroid Build Coastguard Worker  [self pingPongV2APIWithRequest:request numMessages:1000 options:options];
215*cc02d7e2SAndroid Build Coastguard Worker
216*cc02d7e2SAndroid Build Coastguard Worker  [self measureBlock:^{
217*cc02d7e2SAndroid Build Coastguard Worker    [self pingPongV2APIWithRequest:request numMessages:1000 options:options];
218*cc02d7e2SAndroid Build Coastguard Worker  }];
219*cc02d7e2SAndroid Build Coastguard Worker}
220*cc02d7e2SAndroid Build Coastguard Worker
221*cc02d7e2SAndroid Build Coastguard Worker- (void)pingPongV1APIWithRequest:(RMTStreamingOutputCallRequest *)request
222*cc02d7e2SAndroid Build Coastguard Worker                     numMessages:(int)numMessages {
223*cc02d7e2SAndroid Build Coastguard Worker  __block int index = 0;
224*cc02d7e2SAndroid Build Coastguard Worker  __weak XCTestExpectation *expectation = [self expectationWithDescription:@"PingPong"];
225*cc02d7e2SAndroid Build Coastguard Worker  GRXBufferedPipe *requestsBuffer = [[GRXBufferedPipe alloc] init];
226*cc02d7e2SAndroid Build Coastguard Worker
227*cc02d7e2SAndroid Build Coastguard Worker  [requestsBuffer writeValue:request];
228*cc02d7e2SAndroid Build Coastguard Worker
229*cc02d7e2SAndroid Build Coastguard Worker  [_service fullDuplexCallWithRequestsWriter:requestsBuffer
230*cc02d7e2SAndroid Build Coastguard Worker                                eventHandler:^(BOOL done, RMTStreamingOutputCallResponse *response,
231*cc02d7e2SAndroid Build Coastguard Worker                                               NSError *error) {
232*cc02d7e2SAndroid Build Coastguard Worker                                  if (response) {
233*cc02d7e2SAndroid Build Coastguard Worker                                    int indexCopy;
234*cc02d7e2SAndroid Build Coastguard Worker                                    @synchronized(self) {
235*cc02d7e2SAndroid Build Coastguard Worker                                      index += 1;
236*cc02d7e2SAndroid Build Coastguard Worker                                      indexCopy = index;
237*cc02d7e2SAndroid Build Coastguard Worker                                    }
238*cc02d7e2SAndroid Build Coastguard Worker                                    if (indexCopy < numMessages) {
239*cc02d7e2SAndroid Build Coastguard Worker                                      [requestsBuffer writeValue:request];
240*cc02d7e2SAndroid Build Coastguard Worker                                    } else {
241*cc02d7e2SAndroid Build Coastguard Worker                                      [requestsBuffer writesFinishedWithError:nil];
242*cc02d7e2SAndroid Build Coastguard Worker                                    }
243*cc02d7e2SAndroid Build Coastguard Worker                                  }
244*cc02d7e2SAndroid Build Coastguard Worker
245*cc02d7e2SAndroid Build Coastguard Worker                                  if (done) {
246*cc02d7e2SAndroid Build Coastguard Worker                                    [expectation fulfill];
247*cc02d7e2SAndroid Build Coastguard Worker                                  }
248*cc02d7e2SAndroid Build Coastguard Worker                                }];
249*cc02d7e2SAndroid Build Coastguard Worker  [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
250*cc02d7e2SAndroid Build Coastguard Worker}
251*cc02d7e2SAndroid Build Coastguard Worker
252*cc02d7e2SAndroid Build Coastguard Worker- (void)testPingPongRPCWithV1API {
253*cc02d7e2SAndroid Build Coastguard Worker  id request = [RMTStreamingOutputCallRequest messageWithPayloadSize:@1 requestedResponseSize:@1];
254*cc02d7e2SAndroid Build Coastguard Worker  [self pingPongV1APIWithRequest:request numMessages:1000];
255*cc02d7e2SAndroid Build Coastguard Worker  [self measureBlock:^{
256*cc02d7e2SAndroid Build Coastguard Worker    [self pingPongV1APIWithRequest:request numMessages:1000];
257*cc02d7e2SAndroid Build Coastguard Worker  }];
258*cc02d7e2SAndroid Build Coastguard Worker}
259*cc02d7e2SAndroid Build Coastguard Worker
260*cc02d7e2SAndroid Build Coastguard Worker- (void)unaryRPCsWithServices:(NSArray<RMTTestService *> *)services
261*cc02d7e2SAndroid Build Coastguard Worker                      request:(RMTSimpleRequest *)request
262*cc02d7e2SAndroid Build Coastguard Worker              callsPerService:(int)callsPerService
263*cc02d7e2SAndroid Build Coastguard Worker          maxOutstandingCalls:(int)maxOutstandingCalls
264*cc02d7e2SAndroid Build Coastguard Worker                  callOptions:(GRPCMutableCallOptions *)options {
265*cc02d7e2SAndroid Build Coastguard Worker  __weak XCTestExpectation *expectation = [self expectationWithDescription:@"unaryRPC"];
266*cc02d7e2SAndroid Build Coastguard Worker
267*cc02d7e2SAndroid Build Coastguard Worker  dispatch_semaphore_t sema = dispatch_semaphore_create(maxOutstandingCalls);
268*cc02d7e2SAndroid Build Coastguard Worker  __block int index = 0;
269*cc02d7e2SAndroid Build Coastguard Worker
270*cc02d7e2SAndroid Build Coastguard Worker  for (RMTTestService *service in services) {
271*cc02d7e2SAndroid Build Coastguard Worker    for (int i = 0; i < callsPerService; ++i) {
272*cc02d7e2SAndroid Build Coastguard Worker      GRPCUnaryProtoCall *call = [service
273*cc02d7e2SAndroid Build Coastguard Worker          unaryCallWithMessage:request
274*cc02d7e2SAndroid Build Coastguard Worker               responseHandler:[[PerfTestsBlockCallbacks alloc]
275*cc02d7e2SAndroid Build Coastguard Worker                                   initWithInitialMetadataCallback:nil
276*cc02d7e2SAndroid Build Coastguard Worker                                                   messageCallback:nil
277*cc02d7e2SAndroid Build Coastguard Worker                                                     closeCallback:^(NSDictionary *trailingMetadata,
278*cc02d7e2SAndroid Build Coastguard Worker                                                                     NSError *error) {
279*cc02d7e2SAndroid Build Coastguard Worker                                                       dispatch_semaphore_signal(sema);
280*cc02d7e2SAndroid Build Coastguard Worker                                                       @synchronized(self) {
281*cc02d7e2SAndroid Build Coastguard Worker                                                         ++index;
282*cc02d7e2SAndroid Build Coastguard Worker                                                         if (index ==
283*cc02d7e2SAndroid Build Coastguard Worker                                                             callsPerService * [services count]) {
284*cc02d7e2SAndroid Build Coastguard Worker                                                           [expectation fulfill];
285*cc02d7e2SAndroid Build Coastguard Worker                                                         }
286*cc02d7e2SAndroid Build Coastguard Worker                                                       }
287*cc02d7e2SAndroid Build Coastguard Worker                                                     }]
288*cc02d7e2SAndroid Build Coastguard Worker                   callOptions:options];
289*cc02d7e2SAndroid Build Coastguard Worker      dispatch_time_t timeout =
290*cc02d7e2SAndroid Build Coastguard Worker          dispatch_time(DISPATCH_TIME_NOW, (int64_t)(TEST_TIMEOUT * NSEC_PER_SEC));
291*cc02d7e2SAndroid Build Coastguard Worker      dispatch_semaphore_wait(sema, timeout);
292*cc02d7e2SAndroid Build Coastguard Worker      [call start];
293*cc02d7e2SAndroid Build Coastguard Worker    }
294*cc02d7e2SAndroid Build Coastguard Worker  }
295*cc02d7e2SAndroid Build Coastguard Worker
296*cc02d7e2SAndroid Build Coastguard Worker  [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
297*cc02d7e2SAndroid Build Coastguard Worker}
298*cc02d7e2SAndroid Build Coastguard Worker
299*cc02d7e2SAndroid Build Coastguard Worker- (void)test1MBUnaryRPC {
300*cc02d7e2SAndroid Build Coastguard Worker  // Workaround Apple CFStream bug
301*cc02d7e2SAndroid Build Coastguard Worker  if ([self isUsingCFStream]) {
302*cc02d7e2SAndroid Build Coastguard Worker    return;
303*cc02d7e2SAndroid Build Coastguard Worker  }
304*cc02d7e2SAndroid Build Coastguard Worker
305*cc02d7e2SAndroid Build Coastguard Worker  RMTSimpleRequest *request = [RMTSimpleRequest message];
306*cc02d7e2SAndroid Build Coastguard Worker  request.responseSize = 1048576;
307*cc02d7e2SAndroid Build Coastguard Worker  request.payload.body = [NSMutableData dataWithLength:1048576];
308*cc02d7e2SAndroid Build Coastguard Worker
309*cc02d7e2SAndroid Build Coastguard Worker  GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init];
310*cc02d7e2SAndroid Build Coastguard Worker  options.transport = [[self class] transport];
311*cc02d7e2SAndroid Build Coastguard Worker  options.PEMRootCertificates = [[self class] PEMRootCertificates];
312*cc02d7e2SAndroid Build Coastguard Worker  options.hostNameOverride = [[self class] hostNameOverride];
313*cc02d7e2SAndroid Build Coastguard Worker
314*cc02d7e2SAndroid Build Coastguard Worker  // warm up
315*cc02d7e2SAndroid Build Coastguard Worker  [self unaryRPCsWithServices:@[ self->_service ]
316*cc02d7e2SAndroid Build Coastguard Worker                      request:request
317*cc02d7e2SAndroid Build Coastguard Worker              callsPerService:50
318*cc02d7e2SAndroid Build Coastguard Worker          maxOutstandingCalls:10
319*cc02d7e2SAndroid Build Coastguard Worker                  callOptions:options];
320*cc02d7e2SAndroid Build Coastguard Worker
321*cc02d7e2SAndroid Build Coastguard Worker  [self measureBlock:^{
322*cc02d7e2SAndroid Build Coastguard Worker    [self unaryRPCsWithServices:@[ self->_service ]
323*cc02d7e2SAndroid Build Coastguard Worker                        request:request
324*cc02d7e2SAndroid Build Coastguard Worker                callsPerService:50
325*cc02d7e2SAndroid Build Coastguard Worker            maxOutstandingCalls:10
326*cc02d7e2SAndroid Build Coastguard Worker                    callOptions:options];
327*cc02d7e2SAndroid Build Coastguard Worker  }];
328*cc02d7e2SAndroid Build Coastguard Worker}
329*cc02d7e2SAndroid Build Coastguard Worker
330*cc02d7e2SAndroid Build Coastguard Worker- (void)test1KBUnaryRPC {
331*cc02d7e2SAndroid Build Coastguard Worker  RMTSimpleRequest *request = [RMTSimpleRequest message];
332*cc02d7e2SAndroid Build Coastguard Worker  request.responseSize = 1024;
333*cc02d7e2SAndroid Build Coastguard Worker  request.payload.body = [NSMutableData dataWithLength:1024];
334*cc02d7e2SAndroid Build Coastguard Worker
335*cc02d7e2SAndroid Build Coastguard Worker  GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init];
336*cc02d7e2SAndroid Build Coastguard Worker  options.transport = [[self class] transport];
337*cc02d7e2SAndroid Build Coastguard Worker  options.PEMRootCertificates = [[self class] PEMRootCertificates];
338*cc02d7e2SAndroid Build Coastguard Worker  options.hostNameOverride = [[self class] hostNameOverride];
339*cc02d7e2SAndroid Build Coastguard Worker
340*cc02d7e2SAndroid Build Coastguard Worker  // warm up
341*cc02d7e2SAndroid Build Coastguard Worker  [self unaryRPCsWithServices:@[ self->_service ]
342*cc02d7e2SAndroid Build Coastguard Worker                      request:request
343*cc02d7e2SAndroid Build Coastguard Worker              callsPerService:1000
344*cc02d7e2SAndroid Build Coastguard Worker          maxOutstandingCalls:100
345*cc02d7e2SAndroid Build Coastguard Worker                  callOptions:options];
346*cc02d7e2SAndroid Build Coastguard Worker
347*cc02d7e2SAndroid Build Coastguard Worker  [self measureBlock:^{
348*cc02d7e2SAndroid Build Coastguard Worker    [self unaryRPCsWithServices:@[ self->_service ]
349*cc02d7e2SAndroid Build Coastguard Worker                        request:request
350*cc02d7e2SAndroid Build Coastguard Worker                callsPerService:1000
351*cc02d7e2SAndroid Build Coastguard Worker            maxOutstandingCalls:100
352*cc02d7e2SAndroid Build Coastguard Worker                    callOptions:options];
353*cc02d7e2SAndroid Build Coastguard Worker  }];
354*cc02d7e2SAndroid Build Coastguard Worker}
355*cc02d7e2SAndroid Build Coastguard Worker
356*cc02d7e2SAndroid Build Coastguard Worker- (void)testMultipleChannels {
357*cc02d7e2SAndroid Build Coastguard Worker  NSString *port = [[[self class] host] componentsSeparatedByString:@":"][1];
358*cc02d7e2SAndroid Build Coastguard Worker  int kNumAddrs = 10;
359*cc02d7e2SAndroid Build Coastguard Worker  NSMutableArray<NSString *> *addrs = [NSMutableArray arrayWithCapacity:kNumAddrs];
360*cc02d7e2SAndroid Build Coastguard Worker  NSMutableArray<RMTTestService *> *services = [NSMutableArray arrayWithCapacity:kNumAddrs];
361*cc02d7e2SAndroid Build Coastguard Worker  for (int i = 0; i < kNumAddrs; ++i) {
362*cc02d7e2SAndroid Build Coastguard Worker    // http://readme.localtest.me/
363*cc02d7e2SAndroid Build Coastguard Worker    addrs[i] = [NSString stringWithFormat:@"%d.localtest.me", (i + 1)];
364*cc02d7e2SAndroid Build Coastguard Worker    NSString *hostWithPort = [NSString stringWithFormat:@"%@:%@", addrs[i], port];
365*cc02d7e2SAndroid Build Coastguard Worker    services[i] = [RMTTestService serviceWithHost:hostWithPort];
366*cc02d7e2SAndroid Build Coastguard Worker  }
367*cc02d7e2SAndroid Build Coastguard Worker
368*cc02d7e2SAndroid Build Coastguard Worker  RMTSimpleRequest *request = [RMTSimpleRequest message];
369*cc02d7e2SAndroid Build Coastguard Worker  request.responseSize = 0;
370*cc02d7e2SAndroid Build Coastguard Worker  request.payload.body = [NSMutableData dataWithLength:0];
371*cc02d7e2SAndroid Build Coastguard Worker
372*cc02d7e2SAndroid Build Coastguard Worker  GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init];
373*cc02d7e2SAndroid Build Coastguard Worker  options.transport = [[self class] transport];
374*cc02d7e2SAndroid Build Coastguard Worker  options.PEMRootCertificates = [[self class] PEMRootCertificates];
375*cc02d7e2SAndroid Build Coastguard Worker  options.hostNameOverride = [[self class] hostNameOverride];
376*cc02d7e2SAndroid Build Coastguard Worker
377*cc02d7e2SAndroid Build Coastguard Worker  // warm up
378*cc02d7e2SAndroid Build Coastguard Worker  [self unaryRPCsWithServices:services
379*cc02d7e2SAndroid Build Coastguard Worker                      request:request
380*cc02d7e2SAndroid Build Coastguard Worker              callsPerService:100
381*cc02d7e2SAndroid Build Coastguard Worker          maxOutstandingCalls:100
382*cc02d7e2SAndroid Build Coastguard Worker                  callOptions:options];
383*cc02d7e2SAndroid Build Coastguard Worker
384*cc02d7e2SAndroid Build Coastguard Worker  [self measureBlock:^{
385*cc02d7e2SAndroid Build Coastguard Worker    [self unaryRPCsWithServices:services
386*cc02d7e2SAndroid Build Coastguard Worker                        request:request
387*cc02d7e2SAndroid Build Coastguard Worker                callsPerService:100
388*cc02d7e2SAndroid Build Coastguard Worker            maxOutstandingCalls:100
389*cc02d7e2SAndroid Build Coastguard Worker                    callOptions:options];
390*cc02d7e2SAndroid Build Coastguard Worker  }];
391*cc02d7e2SAndroid Build Coastguard Worker}
392*cc02d7e2SAndroid Build Coastguard Worker
393*cc02d7e2SAndroid Build Coastguard Worker@end
394