xref: /aosp_15_r20/external/grpc-grpc/src/objective-c/tests/MacTests/StressTests.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#include "StressTests.h"
19*cc02d7e2SAndroid Build Coastguard Worker
20*cc02d7e2SAndroid Build Coastguard Worker#import <GRPCClient/GRPCCall+ChannelArg.h>
21*cc02d7e2SAndroid Build Coastguard Worker#import <GRPCClient/GRPCCall+Tests.h>
22*cc02d7e2SAndroid Build Coastguard Worker#import <GRPCClient/internal_testing/GRPCCall+InternalTests.h>
23*cc02d7e2SAndroid Build Coastguard Worker#import <ProtoRPC/ProtoRPC.h>
24*cc02d7e2SAndroid Build Coastguard Worker#import <RxLibrary/GRXBufferedPipe.h>
25*cc02d7e2SAndroid Build Coastguard Worker#import <RxLibrary/GRXWriter+Immediate.h>
26*cc02d7e2SAndroid Build Coastguard Worker#import <grpc/grpc.h>
27*cc02d7e2SAndroid Build Coastguard Worker#import <grpc/support/log.h>
28*cc02d7e2SAndroid Build Coastguard Worker#import "src/objective-c/tests/RemoteTestClient/Messages.pbobjc.h"
29*cc02d7e2SAndroid Build Coastguard Worker#import "src/objective-c/tests/RemoteTestClient/Test.pbobjc.h"
30*cc02d7e2SAndroid Build Coastguard Worker#import "src/objective-c/tests/RemoteTestClient/Test.pbrpc.h"
31*cc02d7e2SAndroid Build Coastguard Worker
32*cc02d7e2SAndroid Build Coastguard Worker#define TEST_TIMEOUT 32
33*cc02d7e2SAndroid Build Coastguard Worker
34*cc02d7e2SAndroid Build Coastguard Workerextern const char *kCFStreamVarName;
35*cc02d7e2SAndroid Build Coastguard Worker
36*cc02d7e2SAndroid Build Coastguard Worker// Convenience class to use blocks as callbacks
37*cc02d7e2SAndroid Build Coastguard Worker@interface MacTestsBlockCallbacks : NSObject <GRPCProtoResponseHandler>
38*cc02d7e2SAndroid Build Coastguard Worker
39*cc02d7e2SAndroid Build Coastguard Worker- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback
40*cc02d7e2SAndroid Build Coastguard Worker                                messageCallback:(void (^)(id))messageCallback
41*cc02d7e2SAndroid Build Coastguard Worker                                  closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback;
42*cc02d7e2SAndroid Build Coastguard Worker
43*cc02d7e2SAndroid Build Coastguard Worker@end
44*cc02d7e2SAndroid Build Coastguard Worker
45*cc02d7e2SAndroid Build Coastguard Worker@implementation MacTestsBlockCallbacks {
46*cc02d7e2SAndroid Build Coastguard Worker  void (^_initialMetadataCallback)(NSDictionary *);
47*cc02d7e2SAndroid Build Coastguard Worker  void (^_messageCallback)(id);
48*cc02d7e2SAndroid Build Coastguard Worker  void (^_closeCallback)(NSDictionary *, NSError *);
49*cc02d7e2SAndroid Build Coastguard Worker  dispatch_queue_t _dispatchQueue;
50*cc02d7e2SAndroid Build Coastguard Worker}
51*cc02d7e2SAndroid Build Coastguard Worker
52*cc02d7e2SAndroid Build Coastguard Worker- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback
53*cc02d7e2SAndroid Build Coastguard Worker                                messageCallback:(void (^)(id))messageCallback
54*cc02d7e2SAndroid Build Coastguard Worker                                  closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback {
55*cc02d7e2SAndroid Build Coastguard Worker  if ((self = [super init])) {
56*cc02d7e2SAndroid Build Coastguard Worker    _initialMetadataCallback = initialMetadataCallback;
57*cc02d7e2SAndroid Build Coastguard Worker    _messageCallback = messageCallback;
58*cc02d7e2SAndroid Build Coastguard Worker    _closeCallback = closeCallback;
59*cc02d7e2SAndroid Build Coastguard Worker    _dispatchQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL);
60*cc02d7e2SAndroid Build Coastguard Worker  }
61*cc02d7e2SAndroid Build Coastguard Worker  return self;
62*cc02d7e2SAndroid Build Coastguard Worker}
63*cc02d7e2SAndroid Build Coastguard Worker
64*cc02d7e2SAndroid Build Coastguard Worker- (void)didReceiveInitialMetadata:(NSDictionary *)initialMetadata {
65*cc02d7e2SAndroid Build Coastguard Worker  if (_initialMetadataCallback) {
66*cc02d7e2SAndroid Build Coastguard Worker    _initialMetadataCallback(initialMetadata);
67*cc02d7e2SAndroid Build Coastguard Worker  }
68*cc02d7e2SAndroid Build Coastguard Worker}
69*cc02d7e2SAndroid Build Coastguard Worker
70*cc02d7e2SAndroid Build Coastguard Worker- (void)didReceiveProtoMessage:(GPBMessage *)message {
71*cc02d7e2SAndroid Build Coastguard Worker  if (_messageCallback) {
72*cc02d7e2SAndroid Build Coastguard Worker    _messageCallback(message);
73*cc02d7e2SAndroid Build Coastguard Worker  }
74*cc02d7e2SAndroid Build Coastguard Worker}
75*cc02d7e2SAndroid Build Coastguard Worker
76*cc02d7e2SAndroid Build Coastguard Worker- (void)didCloseWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error {
77*cc02d7e2SAndroid Build Coastguard Worker  if (_closeCallback) {
78*cc02d7e2SAndroid Build Coastguard Worker    _closeCallback(trailingMetadata, error);
79*cc02d7e2SAndroid Build Coastguard Worker  }
80*cc02d7e2SAndroid Build Coastguard Worker}
81*cc02d7e2SAndroid Build Coastguard Worker
82*cc02d7e2SAndroid Build Coastguard Worker- (dispatch_queue_t)dispatchQueue {
83*cc02d7e2SAndroid Build Coastguard Worker  return _dispatchQueue;
84*cc02d7e2SAndroid Build Coastguard Worker}
85*cc02d7e2SAndroid Build Coastguard Worker
86*cc02d7e2SAndroid Build Coastguard Worker@end
87*cc02d7e2SAndroid Build Coastguard Worker
88*cc02d7e2SAndroid Build Coastguard Worker@implementation StressTests {
89*cc02d7e2SAndroid Build Coastguard Worker  RMTTestService *_service;
90*cc02d7e2SAndroid Build Coastguard Worker}
91*cc02d7e2SAndroid Build Coastguard Worker
92*cc02d7e2SAndroid Build Coastguard Worker+ (XCTestSuite *)defaultTestSuite {
93*cc02d7e2SAndroid Build Coastguard Worker  if (self == [StressTests class]) {
94*cc02d7e2SAndroid Build Coastguard Worker    return [XCTestSuite testSuiteWithName:@"StressTestsEmptySuite"];
95*cc02d7e2SAndroid Build Coastguard Worker  } else {
96*cc02d7e2SAndroid Build Coastguard Worker    return super.defaultTestSuite;
97*cc02d7e2SAndroid Build Coastguard Worker  }
98*cc02d7e2SAndroid Build Coastguard Worker}
99*cc02d7e2SAndroid Build Coastguard Worker
100*cc02d7e2SAndroid Build Coastguard Worker+ (NSString *)host {
101*cc02d7e2SAndroid Build Coastguard Worker  return nil;
102*cc02d7e2SAndroid Build Coastguard Worker}
103*cc02d7e2SAndroid Build Coastguard Worker
104*cc02d7e2SAndroid Build Coastguard Worker+ (NSString *)hostAddress {
105*cc02d7e2SAndroid Build Coastguard Worker  return nil;
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- (int32_t)encodingOverhead {
117*cc02d7e2SAndroid Build Coastguard Worker  return 0;
118*cc02d7e2SAndroid Build Coastguard Worker}
119*cc02d7e2SAndroid Build Coastguard Worker
120*cc02d7e2SAndroid Build Coastguard Worker+ (void)setUp {
121*cc02d7e2SAndroid Build Coastguard Worker  setenv(kCFStreamVarName, "1", 1);
122*cc02d7e2SAndroid Build Coastguard Worker}
123*cc02d7e2SAndroid Build Coastguard Worker
124*cc02d7e2SAndroid Build Coastguard Worker- (void)setUp {
125*cc02d7e2SAndroid Build Coastguard Worker  self.continueAfterFailure = NO;
126*cc02d7e2SAndroid Build Coastguard Worker
127*cc02d7e2SAndroid Build Coastguard Worker  [GRPCCall resetHostSettings];
128*cc02d7e2SAndroid Build Coastguard Worker
129*cc02d7e2SAndroid Build Coastguard Worker#pragma clang diagnostic push
130*cc02d7e2SAndroid Build Coastguard Worker#pragma clang diagnostic ignored "-Wdeprecated-declarations"
131*cc02d7e2SAndroid Build Coastguard Worker  [GRPCCall closeOpenConnections];
132*cc02d7e2SAndroid Build Coastguard Worker#pragma clang diagnostic pop
133*cc02d7e2SAndroid Build Coastguard Worker
134*cc02d7e2SAndroid Build Coastguard Worker  GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init];
135*cc02d7e2SAndroid Build Coastguard Worker  options.transportType = [[self class] transportType];
136*cc02d7e2SAndroid Build Coastguard Worker  options.PEMRootCertificates = [[self class] PEMRootCertificates];
137*cc02d7e2SAndroid Build Coastguard Worker  options.hostNameOverride = [[self class] hostNameOverride];
138*cc02d7e2SAndroid Build Coastguard Worker  _service = [RMTTestService serviceWithHost:[[self class] host] callOptions:options];
139*cc02d7e2SAndroid Build Coastguard Worker  system([[NSString stringWithFormat:@"sudo ifconfig lo0 alias %@", [[self class] hostAddress]]
140*cc02d7e2SAndroid Build Coastguard Worker      UTF8String]);
141*cc02d7e2SAndroid Build Coastguard Worker}
142*cc02d7e2SAndroid Build Coastguard Worker
143*cc02d7e2SAndroid Build Coastguard Worker- (void)tearDown {
144*cc02d7e2SAndroid Build Coastguard Worker  system([[NSString stringWithFormat:@"sudo ifconfig lo0 -alias %@", [[self class] hostAddress]]
145*cc02d7e2SAndroid Build Coastguard Worker      UTF8String]);
146*cc02d7e2SAndroid Build Coastguard Worker}
147*cc02d7e2SAndroid Build Coastguard Worker
148*cc02d7e2SAndroid Build Coastguard Worker+ (GRPCTransportType)transportType {
149*cc02d7e2SAndroid Build Coastguard Worker  return GRPCTransportTypeChttp2BoringSSL;
150*cc02d7e2SAndroid Build Coastguard Worker}
151*cc02d7e2SAndroid Build Coastguard Worker
152*cc02d7e2SAndroid Build Coastguard Worker- (void)testNetworkFlapWithV2API {
153*cc02d7e2SAndroid Build Coastguard Worker  NSMutableArray *completeExpectations = [NSMutableArray array];
154*cc02d7e2SAndroid Build Coastguard Worker  NSMutableArray *calls = [NSMutableArray array];
155*cc02d7e2SAndroid Build Coastguard Worker  int num_rpcs = 100;
156*cc02d7e2SAndroid Build Coastguard Worker  __block BOOL address_removed = FALSE;
157*cc02d7e2SAndroid Build Coastguard Worker  __block BOOL address_readded = FALSE;
158*cc02d7e2SAndroid Build Coastguard Worker  for (int i = 0; i < num_rpcs; ++i) {
159*cc02d7e2SAndroid Build Coastguard Worker    [completeExpectations
160*cc02d7e2SAndroid Build Coastguard Worker        addObject:[self expectationWithDescription:
161*cc02d7e2SAndroid Build Coastguard Worker                            [NSString stringWithFormat:@"Received trailer for RPC %d", i]]];
162*cc02d7e2SAndroid Build Coastguard Worker
163*cc02d7e2SAndroid Build Coastguard Worker    RMTSimpleRequest *request = [RMTSimpleRequest message];
164*cc02d7e2SAndroid Build Coastguard Worker    request.responseType = RMTPayloadType_Compressable;
165*cc02d7e2SAndroid Build Coastguard Worker    request.responseSize = 314159;
166*cc02d7e2SAndroid Build Coastguard Worker    request.payload.body = [NSMutableData dataWithLength:271828];
167*cc02d7e2SAndroid Build Coastguard Worker
168*cc02d7e2SAndroid Build Coastguard Worker    GRPCUnaryProtoCall *call = [_service
169*cc02d7e2SAndroid Build Coastguard Worker        unaryCallWithMessage:request
170*cc02d7e2SAndroid Build Coastguard Worker             responseHandler:[[MacTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil
171*cc02d7e2SAndroid Build Coastguard Worker                                 messageCallback:^(id message) {
172*cc02d7e2SAndroid Build Coastguard Worker                                   if (message) {
173*cc02d7e2SAndroid Build Coastguard Worker                                     RMTSimpleResponse *expectedResponse =
174*cc02d7e2SAndroid Build Coastguard Worker                                         [RMTSimpleResponse message];
175*cc02d7e2SAndroid Build Coastguard Worker                                     expectedResponse.payload.type = RMTPayloadType_Compressable;
176*cc02d7e2SAndroid Build Coastguard Worker                                     expectedResponse.payload.body =
177*cc02d7e2SAndroid Build Coastguard Worker                                         [NSMutableData dataWithLength:314159];
178*cc02d7e2SAndroid Build Coastguard Worker                                     XCTAssertEqualObjects(message, expectedResponse);
179*cc02d7e2SAndroid Build Coastguard Worker                                   }
180*cc02d7e2SAndroid Build Coastguard Worker                                 }
181*cc02d7e2SAndroid Build Coastguard Worker                                 closeCallback:^(NSDictionary *trailingMetadata, NSError *error) {
182*cc02d7e2SAndroid Build Coastguard Worker                                   @synchronized(self) {
183*cc02d7e2SAndroid Build Coastguard Worker                                     if (error == nil && !address_removed) {
184*cc02d7e2SAndroid Build Coastguard Worker                                       system([[NSString
185*cc02d7e2SAndroid Build Coastguard Worker                                           stringWithFormat:@"sudo ifconfig lo0 -alias %@",
186*cc02d7e2SAndroid Build Coastguard Worker                                                            [[self class] hostAddress]]
187*cc02d7e2SAndroid Build Coastguard Worker                                           UTF8String]);
188*cc02d7e2SAndroid Build Coastguard Worker                                       address_removed = YES;
189*cc02d7e2SAndroid Build Coastguard Worker                                     } else if (error != nil && !address_readded) {
190*cc02d7e2SAndroid Build Coastguard Worker                                       system([[NSString
191*cc02d7e2SAndroid Build Coastguard Worker                                           stringWithFormat:@"sudo ifconfig lo0 alias %@",
192*cc02d7e2SAndroid Build Coastguard Worker                                                            [[self class] hostAddress]]
193*cc02d7e2SAndroid Build Coastguard Worker                                           UTF8String]);
194*cc02d7e2SAndroid Build Coastguard Worker                                       address_readded = YES;
195*cc02d7e2SAndroid Build Coastguard Worker                                     }
196*cc02d7e2SAndroid Build Coastguard Worker                                   }
197*cc02d7e2SAndroid Build Coastguard Worker                                   [completeExpectations[i] fulfill];
198*cc02d7e2SAndroid Build Coastguard Worker                                 }]
199*cc02d7e2SAndroid Build Coastguard Worker                 callOptions:nil];
200*cc02d7e2SAndroid Build Coastguard Worker    [calls addObject:call];
201*cc02d7e2SAndroid Build Coastguard Worker  }
202*cc02d7e2SAndroid Build Coastguard Worker
203*cc02d7e2SAndroid Build Coastguard Worker  for (int i = 0; i < num_rpcs; ++i) {
204*cc02d7e2SAndroid Build Coastguard Worker    GRPCUnaryProtoCall *call = calls[i];
205*cc02d7e2SAndroid Build Coastguard Worker    [call start];
206*cc02d7e2SAndroid Build Coastguard Worker    [NSThread sleepForTimeInterval:0.1f];
207*cc02d7e2SAndroid Build Coastguard Worker  }
208*cc02d7e2SAndroid Build Coastguard Worker  [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
209*cc02d7e2SAndroid Build Coastguard Worker}
210*cc02d7e2SAndroid Build Coastguard Worker
211*cc02d7e2SAndroid Build Coastguard Worker- (void)testNetworkFlapWithV1API {
212*cc02d7e2SAndroid Build Coastguard Worker  NSMutableArray *completeExpectations = [NSMutableArray array];
213*cc02d7e2SAndroid Build Coastguard Worker  int num_rpcs = 100;
214*cc02d7e2SAndroid Build Coastguard Worker  __block BOOL address_removed = FALSE;
215*cc02d7e2SAndroid Build Coastguard Worker  __block BOOL address_readded = FALSE;
216*cc02d7e2SAndroid Build Coastguard Worker  for (int i = 0; i < num_rpcs; ++i) {
217*cc02d7e2SAndroid Build Coastguard Worker    [completeExpectations
218*cc02d7e2SAndroid Build Coastguard Worker        addObject:[self expectationWithDescription:
219*cc02d7e2SAndroid Build Coastguard Worker                            [NSString stringWithFormat:@"Received response for RPC %d", i]]];
220*cc02d7e2SAndroid Build Coastguard Worker
221*cc02d7e2SAndroid Build Coastguard Worker    RMTSimpleRequest *request = [RMTSimpleRequest message];
222*cc02d7e2SAndroid Build Coastguard Worker    request.responseType = RMTPayloadType_Compressable;
223*cc02d7e2SAndroid Build Coastguard Worker    request.responseSize = 314159;
224*cc02d7e2SAndroid Build Coastguard Worker    request.payload.body = [NSMutableData dataWithLength:271828];
225*cc02d7e2SAndroid Build Coastguard Worker
226*cc02d7e2SAndroid Build Coastguard Worker    [_service unaryCallWithRequest:request
227*cc02d7e2SAndroid Build Coastguard Worker                           handler:^(RMTSimpleResponse *response, NSError *error) {
228*cc02d7e2SAndroid Build Coastguard Worker                             @synchronized(self) {
229*cc02d7e2SAndroid Build Coastguard Worker                               if (error == nil && !address_removed) {
230*cc02d7e2SAndroid Build Coastguard Worker                                 system([[NSString stringWithFormat:@"sudo ifconfig lo0 -alias %@",
231*cc02d7e2SAndroid Build Coastguard Worker                                                                    [[self class] hostAddress]]
232*cc02d7e2SAndroid Build Coastguard Worker                                     UTF8String]);
233*cc02d7e2SAndroid Build Coastguard Worker                                 address_removed = YES;
234*cc02d7e2SAndroid Build Coastguard Worker                               } else if (error != nil && !address_readded) {
235*cc02d7e2SAndroid Build Coastguard Worker                                 system([[NSString stringWithFormat:@"sudo ifconfig lo0 alias %@",
236*cc02d7e2SAndroid Build Coastguard Worker                                                                    [[self class] hostAddress]]
237*cc02d7e2SAndroid Build Coastguard Worker                                     UTF8String]);
238*cc02d7e2SAndroid Build Coastguard Worker                                 address_readded = YES;
239*cc02d7e2SAndroid Build Coastguard Worker                               }
240*cc02d7e2SAndroid Build Coastguard Worker                             }
241*cc02d7e2SAndroid Build Coastguard Worker
242*cc02d7e2SAndroid Build Coastguard Worker                             [completeExpectations[i] fulfill];
243*cc02d7e2SAndroid Build Coastguard Worker                           }];
244*cc02d7e2SAndroid Build Coastguard Worker
245*cc02d7e2SAndroid Build Coastguard Worker    [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
246*cc02d7e2SAndroid Build Coastguard Worker  }
247*cc02d7e2SAndroid Build Coastguard Worker}
248*cc02d7e2SAndroid Build Coastguard Worker
249*cc02d7e2SAndroid Build Coastguard Worker@end
250