| 
														
															@@ -44,6 +44,7 @@ static GRPCProtoMethod *kFullDuplexCallMethod; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 static const int kSimpleDataLength = 100; 
														 | 
														
														 | 
														
															 static const int kSimpleDataLength = 100; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 static const NSTimeInterval kTestTimeout = 16; 
														 | 
														
														 | 
														
															 static const NSTimeInterval kTestTimeout = 16; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+static const NSTimeInterval kInvertedTimeout = 2; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 // Reveal the _class ivar for testing access 
														 | 
														
														 | 
														
															 // Reveal the _class ivar for testing access 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 @interface GRPCCall2 () { 
														 | 
														
														 | 
														
															 @interface GRPCCall2 () { 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -56,6 +57,11 @@ static const NSTimeInterval kTestTimeout = 16; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 // Convenience class to use blocks as callbacks 
														 | 
														
														 | 
														
															 // Convenience class to use blocks as callbacks 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 @interface ClientTestsBlockCallbacks : NSObject<GRPCResponseHandler> 
														 | 
														
														 | 
														
															 @interface ClientTestsBlockCallbacks : NSObject<GRPCResponseHandler> 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                messageCallback:(void (^)(id))messageCallback 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                  closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                              writeDataCallback:(void (^)(void))writeDataCallback; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 - (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback 
														 | 
														
														 | 
														
															 - (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback 
														 | 
													
												
											
												
													
														| 
														 | 
														
															                                 messageCallback:(void (^)(id))messageCallback 
														 | 
														
														 | 
														
															                                 messageCallback:(void (^)(id))messageCallback 
														 | 
													
												
											
												
													
														| 
														 | 
														
															                                   closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback; 
														 | 
														
														 | 
														
															                                   closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback; 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -66,21 +72,33 @@ static const NSTimeInterval kTestTimeout = 16; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															   void (^_initialMetadataCallback)(NSDictionary *); 
														 | 
														
														 | 
														
															   void (^_initialMetadataCallback)(NSDictionary *); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															   void (^_messageCallback)(id); 
														 | 
														
														 | 
														
															   void (^_messageCallback)(id); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															   void (^_closeCallback)(NSDictionary *, NSError *); 
														 | 
														
														 | 
														
															   void (^_closeCallback)(NSDictionary *, NSError *); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  void (^_writeDataCallback)(void); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															   dispatch_queue_t _dispatchQueue; 
														 | 
														
														 | 
														
															   dispatch_queue_t _dispatchQueue; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 } 
														 | 
														
														 | 
														
															 } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 - (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback 
														 | 
														
														 | 
														
															 - (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback 
														 | 
													
												
											
												
													
														| 
														 | 
														
															                                 messageCallback:(void (^)(id))messageCallback 
														 | 
														
														 | 
														
															                                 messageCallback:(void (^)(id))messageCallback 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-                                  closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback { 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                  closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                              writeDataCallback:(void (^)(void))writeDataCallback { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															   if ((self = [super init])) { 
														 | 
														
														 | 
														
															   if ((self = [super init])) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     _initialMetadataCallback = initialMetadataCallback; 
														 | 
														
														 | 
														
															     _initialMetadataCallback = initialMetadataCallback; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     _messageCallback = messageCallback; 
														 | 
														
														 | 
														
															     _messageCallback = messageCallback; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     _closeCallback = closeCallback; 
														 | 
														
														 | 
														
															     _closeCallback = closeCallback; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    _writeDataCallback = writeDataCallback; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     _dispatchQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL); 
														 | 
														
														 | 
														
															     _dispatchQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															   } 
														 | 
														
														 | 
														
															   } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															   return self; 
														 | 
														
														 | 
														
															   return self; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 } 
														 | 
														
														 | 
														
															 } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                messageCallback:(void (^)(id))messageCallback 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                  closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  return [self initWithInitialMetadataCallback:initialMetadataCallback 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                               messageCallback:messageCallback 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                 closeCallback:closeCallback 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                             writeDataCallback:nil]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+} 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 - (void)didReceiveInitialMetadata:(NSDictionary *)initialMetadata { 
														 | 
														
														 | 
														
															 - (void)didReceiveInitialMetadata:(NSDictionary *)initialMetadata { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															   if (self->_initialMetadataCallback) { 
														 | 
														
														 | 
														
															   if (self->_initialMetadataCallback) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     self->_initialMetadataCallback(initialMetadata); 
														 | 
														
														 | 
														
															     self->_initialMetadataCallback(initialMetadata); 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -99,6 +117,12 @@ static const NSTimeInterval kTestTimeout = 16; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															   } 
														 | 
														
														 | 
														
															   } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 } 
														 | 
														
														 | 
														
															 } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+- (void)didWriteData { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  if (self->_writeDataCallback) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    self->_writeDataCallback(); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+} 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 - (dispatch_queue_t)dispatchQueue { 
														 | 
														
														 | 
														
															 - (dispatch_queue_t)dispatchQueue { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															   return _dispatchQueue; 
														 | 
														
														 | 
														
															   return _dispatchQueue; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 } 
														 | 
														
														 | 
														
															 } 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -475,4 +499,219 @@ static const NSTimeInterval kTestTimeout = 16; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															   [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; 
														 | 
														
														 | 
														
															   [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 } 
														 | 
														
														 | 
														
															 } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+- (void)testWriteFlowControl { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  __weak XCTestExpectation *expectWriteData = 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+      [self expectationWithDescription:@"Reported write data"]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  RMTStreamingOutputCallRequest *request = [RMTStreamingOutputCallRequest message]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  RMTResponseParameters *parameters = [RMTResponseParameters message]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  parameters.size = kSimpleDataLength; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  [request.responseParametersArray addObject:parameters]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  request.payload.body = [NSMutableData dataWithLength:kSimpleDataLength]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  GRPCRequestOptions *callRequest = 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+      [[GRPCRequestOptions alloc] initWithHost:(NSString *)kHostAddress 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                          path:kUnaryCallMethod.HTTPPath 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                        safety:GRPCCallSafetyDefault]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  options.transportType = GRPCTransportTypeInsecure; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  options.enableFlowControl = YES; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  GRPCCall2 *call = 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+      [[GRPCCall2 alloc] initWithRequestOptions:callRequest 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                responseHandler:[[ClientTestsBlockCallbacks alloc] 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                                    initWithInitialMetadataCallback:nil 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                                                    messageCallback:nil 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                                                      closeCallback:nil 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                                                  writeDataCallback:^{ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                                                    [expectWriteData fulfill]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                                                  }] 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                    callOptions:options]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  [call start]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  [call receiveNextMessage]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  [call writeData:[request data]]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  // Wait for 3 seconds and make sure we do not receive the response 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  [call finish]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+} 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+- (void)testReadFlowControl { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  __weak __block XCTestExpectation *expectBlockedMessage = 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+      [self expectationWithDescription:@"Message not delivered without recvNextMessage"]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  __weak __block XCTestExpectation *expectPassedMessage = nil; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  __weak __block XCTestExpectation *expectBlockedClose = 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+      [self expectationWithDescription:@"Call not closed with pending message"]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  __weak __block XCTestExpectation *expectPassedClose = nil; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  expectBlockedMessage.inverted = YES; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  expectBlockedClose.inverted = YES; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  RMTStreamingOutputCallRequest *request = [RMTStreamingOutputCallRequest message]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  RMTResponseParameters *parameters = [RMTResponseParameters message]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  parameters.size = kSimpleDataLength; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  [request.responseParametersArray addObject:parameters]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  request.payload.body = [NSMutableData dataWithLength:kSimpleDataLength]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  GRPCRequestOptions *callRequest = 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+      [[GRPCRequestOptions alloc] initWithHost:(NSString *)kHostAddress 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                          path:kUnaryCallMethod.HTTPPath 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                        safety:GRPCCallSafetyDefault]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  options.transportType = GRPCTransportTypeInsecure; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  options.enableFlowControl = YES; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  __block int unblocked = NO; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  GRPCCall2 *call = [[GRPCCall2 alloc] 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+      initWithRequestOptions:callRequest 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+             responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                 messageCallback:^(NSData *message) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                   if (!unblocked) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                     [expectBlockedMessage fulfill]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                   } else { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                     [expectPassedMessage fulfill]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                   } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                 } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                 closeCallback:^(NSDictionary *trailers, NSError *error) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                   if (!unblocked) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                     [expectBlockedClose fulfill]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                   } else { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                     [expectPassedClose fulfill]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                   } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                 }] 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                 callOptions:options]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  [call start]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  [call writeData:[request data]]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  [call finish]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  // Wait to make sure we do not receive the response 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  [self waitForExpectationsWithTimeout:kInvertedTimeout handler:nil]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  expectPassedMessage = 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+      [self expectationWithDescription:@"Message delivered with receiveNextMessage"]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  expectPassedClose = [self expectationWithDescription:@"Close delivered after receiveNextMessage"]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  unblocked = YES; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  [call receiveNextMessage]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+} 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+- (void)testReadFlowControlReadyBeforeStart { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  __weak XCTestExpectation *expectBlockedMessage = 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+      [self expectationWithDescription:@"Message delivered with receiveNextMessage"]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  expectBlockedMessage.inverted = YES; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  RMTStreamingOutputCallRequest *request = [RMTStreamingOutputCallRequest message]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  RMTResponseParameters *parameters = [RMTResponseParameters message]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  parameters.size = kSimpleDataLength; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  [request.responseParametersArray addObject:parameters]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  request.payload.body = [NSMutableData dataWithLength:kSimpleDataLength]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  GRPCRequestOptions *callRequest = 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+      [[GRPCRequestOptions alloc] initWithHost:(NSString *)kHostAddress 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                          path:kUnaryCallMethod.HTTPPath 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                        safety:GRPCCallSafetyDefault]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  options.transportType = GRPCTransportTypeInsecure; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  options.enableFlowControl = YES; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  __block BOOL closed = NO; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  GRPCCall2 *call = [[GRPCCall2 alloc] 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+      initWithRequestOptions:callRequest 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+             responseHandler:[[ClientTestsBlockCallbacks alloc] 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                 initWithInitialMetadataCallback:nil 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                                 messageCallback:^(NSData *message) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                                   [expectBlockedMessage fulfill]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                                   XCTAssertFalse(closed); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                                 } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                                   closeCallback:nil] 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                 callOptions:options]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  [call receiveNextMessage]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  [call start]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  [call writeData:[request data]]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  [call finish]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  [self waitForExpectationsWithTimeout:kInvertedTimeout handler:nil]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+} 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+- (void)testReadFlowControlReadyAfterStart { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  __weak XCTestExpectation *expectPassedMessage = 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+      [self expectationWithDescription:@"Message delivered with receiveNextMessage"]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  __weak XCTestExpectation *expectPassedClose = 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+      [self expectationWithDescription:@"Close delivered with receiveNextMessage"]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  RMTStreamingOutputCallRequest *request = [RMTStreamingOutputCallRequest message]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  RMTResponseParameters *parameters = [RMTResponseParameters message]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  parameters.size = kSimpleDataLength; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  [request.responseParametersArray addObject:parameters]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  request.payload.body = [NSMutableData dataWithLength:kSimpleDataLength]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  GRPCRequestOptions *callRequest = 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+      [[GRPCRequestOptions alloc] initWithHost:(NSString *)kHostAddress 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                          path:kUnaryCallMethod.HTTPPath 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                        safety:GRPCCallSafetyDefault]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  options.transportType = GRPCTransportTypeInsecure; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  options.enableFlowControl = YES; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  __block BOOL closed = NO; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  GRPCCall2 *call = [[GRPCCall2 alloc] 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+      initWithRequestOptions:callRequest 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+             responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                 messageCallback:^(NSData *message) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                   [expectPassedMessage fulfill]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                   XCTAssertFalse(closed); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                 } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                 closeCallback:^(NSDictionary *trailers, NSError *error) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                   closed = YES; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                   [expectPassedClose fulfill]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                 }] 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                 callOptions:options]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  [call start]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  [call receiveNextMessage]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  [call writeData:[request data]]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  [call finish]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+} 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+- (void)testReadFlowControlNonBlockingFailure { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  __weak XCTestExpectation *completion = [self expectationWithDescription:@"RPC completed."]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  GRPCRequestOptions *requestOptions = 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+      [[GRPCRequestOptions alloc] initWithHost:kHostAddress 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                          path:kUnaryCallMethod.HTTPPath 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                        safety:GRPCCallSafetyDefault]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  options.enableFlowControl = YES; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  options.transportType = GRPCTransportTypeInsecure; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  RMTSimpleRequest *request = [RMTSimpleRequest message]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  request.payload.body = [NSMutableData dataWithLength:options.responseSizeLimit]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  RMTEchoStatus *status = [RMTEchoStatus message]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  status.code = 2; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  status.message = @"test"; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  request.responseStatus = status; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  GRPCCall2 *call = [[GRPCCall2 alloc] 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+      initWithRequestOptions:requestOptions 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+             responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                 messageCallback:^(NSData *data) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                   XCTFail(@"Received unexpected message"); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                 } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                 closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                   XCTAssertNotNil(error, @"Expecting non-nil error"); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                   XCTAssertEqual(error.code, 2); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                   [completion fulfill]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                 }] 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                 callOptions:options]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  [call writeData:[request data]]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  [call start]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  [call finish]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+} 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 @end 
														 | 
														
														 | 
														
															 @end 
														 |