Add GRPCUnaryResponseHandler

pull/20560/head
Muxi Yan 6 years ago
parent 1ecded0629
commit 48d0d6f5ad
  1. 24
      src/objective-c/ProtoRPC/ProtoRPC.h
  2. 42
      src/objective-c/ProtoRPC/ProtoRPC.m
  3. 4
      src/objective-c/tests/CronetTests/InteropTestsRemoteWithCronet.m
  4. 41
      src/objective-c/tests/InteropTests/InteropTests.m
  5. 4
      src/objective-c/tests/InteropTests/InteropTestsRemote.m
  6. 8
      src/objective-c/tests/TestBase.h
  7. 4
      src/objective-c/tests/TestBase.m

@ -70,6 +70,30 @@ NS_ASSUME_NONNULL_BEGIN
@end
/**
* A convenience class of objects that act as response handlers of calls. Issues
* response to a single handler when the response is completed.
*/
@interface GRPCUnaryResponseHandler : NSObject<GRPCProtoResponseHandler>
/**
* Creates a responsehandler object with a unary call handler.
*
* responseHandler: The unary handler to be called when the call is completed.
* responseDispatchQueue: the dispatch queue on which the response handler
* should be issued.
*/
- (nullable instancetype)initWithResponseHandler:(void (^)(GPBMessage *, NSError *))handler
responseDispatchQueue:(dispatch_queue_t)responseDispatchQueue;
/** Response headers received during the call. */
@property(readonly, nullable) NSDictionary *responseHeaders;
/** Response trailers received during the call. */
@property(readonly, nullable) NSDictionary *responseTrailers;
@end
/** A unary-request RPC call with Protobuf. */
@interface GRPCUnaryProtoCall : NSObject

@ -27,6 +27,48 @@
#import <RxLibrary/GRXWriteable.h>
#import <RxLibrary/GRXWriter+Transformations.h>
@implementation GRPCUnaryResponseHandler {
void (^_responseHandler)(GPBMessage *, NSError *);
dispatch_queue_t _responseDispatchQueue;
GPBMessage *_message;
}
- (nullable instancetype)initWithResponseHandler:(void (^)(GPBMessage *, NSError *))handler
responseDispatchQueue:(dispatch_queue_t)dispatchQueue {
if ((self = [super init])) {
_responseHandler = handler;
_responseDispatchQueue = dispatchQueue;
}
return self;
}
// Implements GRPCProtoResponseHandler
- (dispatch_queue_t)dispatchQueue {
return _responseDispatchQueue;
}
- (void)didReceiveInitialMetadata:(NSDictionary *)initialMetadata {
_responseHeaders = [initialMetadata copy];
}
- (void)didReceiveProtoMessage:(GPBMessage *)message {
_message = message;
}
- (void)didCloseWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error {
_responseTrailers = [trailingMetadata copy];
GPBMessage *message = _message;
_message = nil;
_responseHandler(message, error);
}
// Intentional no-op since flow control is N/A in a unary call
- (void)didWriteMessage {
}
@end
@implementation GRPCUnaryProtoCall {
GRPCStreamingProtoCall *_call;
GPBMessage *_message;

@ -60,4 +60,8 @@ static int32_t kRemoteInteropServerOverhead = 12;
return kRemoteInteropServerOverhead; // bytes
}
+ (BOOL)isRemoteTest {
return YES;
}
@end

@ -563,6 +563,47 @@ static dispatch_once_t initGlobalInterceptorFactory;
[self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
}
- (void)testUnaryResponseHandler {
XCTAssertNotNil([[self class] host]);
// The test does not work on a remote server since it does not echo a trailer
if ([[self class] isRemoteTest]) return;
__weak XCTestExpectation *expectComplete = [self expectationWithDescription:@"received complete"];
RMTSimpleRequest *request = [RMTSimpleRequest message];
request.responseType = RMTPayloadType_Compressable;
request.responseSize = 314159;
request.payload.body = [NSMutableData dataWithLength:271828];
GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init];
// For backwards compatibility
options.transportType = [[self class] transportType];
options.transport = [[self class] transport];
options.PEMRootCertificates = [[self class] PEMRootCertificates];
options.hostNameOverride = [[self class] hostNameOverride];
const unsigned char raw_bytes[] = {1, 2, 3, 4};
NSData *trailer_data = [NSData dataWithBytes:raw_bytes length:sizeof(raw_bytes)];
options.initialMetadata = @{
@"x-grpc-test-echo-trailing-bin" : trailer_data,
@"x-grpc-test-echo-initial" : @"test-header"
};
__block GRPCUnaryResponseHandler *handler = [[GRPCUnaryResponseHandler alloc]
initWithResponseHandler:^(GPBMessage *response, NSError *error) {
XCTAssertNil(error, @"Unexpected error: %@", error);
RMTSimpleResponse *expectedResponse = [RMTSimpleResponse message];
expectedResponse.payload.type = RMTPayloadType_Compressable;
expectedResponse.payload.body = [NSMutableData dataWithLength:314159];
XCTAssertEqualObjects(response, expectedResponse);
XCTAssertEqualObjects(handler.responseHeaders[@"x-grpc-test-echo-initial"], @"test-header");
XCTAssertEqualObjects(handler.responseTrailers[@"x-grpc-test-echo-trailing-bin"],
trailer_data);
[expectComplete fulfill];
}
responseDispatchQueue:dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL)];
[[_service unaryCallWithMessage:request responseHandler:handler callOptions:options] start];
[self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
}
- (void)testLargeUnaryRPCWithV2API {
XCTAssertNotNil([[self class] host]);
__weak XCTestExpectation *expectReceive =

@ -57,4 +57,8 @@ static int32_t kRemoteInteropServerOverhead = 12;
return GRPCTransportTypeChttp2BoringSSL;
}
+ (BOOL)isRemoteTest {
return YES;
}
@end

@ -57,9 +57,13 @@
+ (NSString *)PEMRootCertificates;
/**
* The root certificates to be used. The base implementation returns nil. Subclasses should override
* to appropriate settings.
* The host name to be used for TLS verification in the tests.
*/
+ (NSString *)hostNameOverride;
/**
* Indication of whether the test is connecting to a remote server.
*/
+ (BOOL)isRemoteTest;
@end

@ -47,4 +47,8 @@
return nil;
}
+ (BOOL)isRemoteTest {
return NO;
}
@end

Loading…
Cancel
Save