aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Jorge Canizales <jcanizales@google.com>2015-05-30 12:04:43 -0700
committerGravatar Jorge Canizales <jcanizales@google.com>2015-05-30 23:08:23 -0700
commit7307684b2ba07e25e7858080c667a98f5b1171ee (patch)
treeae472270148b3d0b3d8ecc04ed141237e6dce0cc
parentdc42ee624db264a6d76c3a890d0ddcdc86d887d7 (diff)
Add RemoteProtoTests as InteropTests to tests project
-rw-r--r--src/objective-c/tests/InteropTests.m305
-rw-r--r--src/objective-c/tests/Tests.xcodeproj/project.pbxproj4
2 files changed, 309 insertions, 0 deletions
diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m
new file mode 100644
index 0000000000..0a512c17dc
--- /dev/null
+++ b/src/objective-c/tests/InteropTests.m
@@ -0,0 +1,305 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <grpc/status.h>
+
+#import <UIKit/UIKit.h>
+#import <XCTest/XCTest.h>
+
+#import <gRPC/GRXWriter+Immediate.h>
+#import <gRPC/GRXBufferedPipe.h>
+#import <gRPC/ProtoRPC.h>
+#import <RemoteTest/Empty.pbobjc.h>
+#import <RemoteTest/Messages.pbobjc.h>
+#import <RemoteTest/Test.pbobjc.h>
+#import <RemoteTest/Test.pbrpc.h>
+
+// Convenience constructors for the generated proto messages:
+
+@interface RMTStreamingOutputCallRequest (Constructors)
++ (instancetype)messageWithPayloadSize:(NSNumber *)payloadSize
+ requestedResponseSize:(NSNumber *)responseSize;
+@end
+
+@implementation RMTStreamingOutputCallRequest (Constructors)
++ (instancetype)messageWithPayloadSize:(NSNumber *)payloadSize
+ requestedResponseSize:(NSNumber *)responseSize {
+ RMTStreamingOutputCallRequest *request = [self message];
+ RMTResponseParameters *parameters = [RMTResponseParameters message];
+ parameters.size = responseSize.integerValue;
+ [request.responseParametersArray addObject:parameters];
+ request.payload.body = [NSMutableData dataWithLength:payloadSize.unsignedIntegerValue];
+ return request;
+}
+@end
+
+@interface RMTStreamingOutputCallResponse (Constructors)
++ (instancetype)messageWithPayloadSize:(NSNumber *)payloadSize;
+@end
+
+@implementation RMTStreamingOutputCallResponse (Constructors)
++ (instancetype)messageWithPayloadSize:(NSNumber *)payloadSize {
+ RMTStreamingOutputCallResponse * response = [self message];
+ response.payload.type = RMTPayloadType_Compressable;
+ response.payload.body = [NSMutableData dataWithLength:payloadSize.unsignedIntegerValue];
+ return response;
+}
+@end
+
+@interface InteropTests : XCTestCase
+@end
+
+@implementation InteropTests {
+ RMTTestService *_service;
+}
+
+- (void)setUp {
+ _service = [[RMTTestService alloc] initWithHost:@"grpc-test.sandbox.google.com"];
+}
+
+// Tests as described here: https://github.com/grpc/grpc/blob/master/doc/interop-test-descriptions.md
+
+- (void)testEmptyUnaryRPC {
+ __weak XCTestExpectation *expectation = [self expectationWithDescription:@"EmptyUnary"];
+
+ RMTEmpty *request = [RMTEmpty message];
+
+ [_service emptyCallWithRequest:request handler:^(RMTEmpty *response, NSError *error) {
+ XCTAssertNil(error, @"Finished with unexpected error: %@", error);
+
+ id expectedResponse = [RMTEmpty message];
+ XCTAssertEqualObjects(response, expectedResponse);
+
+ [expectation fulfill];
+ }];
+
+ [self waitForExpectationsWithTimeout:2 handler:nil];
+}
+
+- (void)testLargeUnaryRPC {
+ __weak XCTestExpectation *expectation = [self expectationWithDescription:@"LargeUnary"];
+
+ RMTSimpleRequest *request = [RMTSimpleRequest message];
+ request.responseType = RMTPayloadType_Compressable;
+ request.responseSize = 314159;
+ request.payload.body = [NSMutableData dataWithLength:271828];
+
+ [_service unaryCallWithRequest:request handler:^(RMTSimpleResponse *response, NSError *error) {
+ XCTAssertNil(error, @"Finished with unexpected error: %@", error);
+
+ RMTSimpleResponse *expectedResponse = [RMTSimpleResponse message];
+ expectedResponse.payload.type = RMTPayloadType_Compressable;
+ expectedResponse.payload.body = [NSMutableData dataWithLength:314159];
+ XCTAssertEqualObjects(response, expectedResponse);
+
+ [expectation fulfill];
+ }];
+
+ [self waitForExpectationsWithTimeout:4 handler:nil];
+}
+
+- (void)testClientStreamingRPC {
+ __weak XCTestExpectation *expectation = [self expectationWithDescription:@"ClientStreaming"];
+
+ RMTStreamingInputCallRequest *request1 = [RMTStreamingInputCallRequest message];
+ request1.payload.body = [NSMutableData dataWithLength:27182];
+
+ RMTStreamingInputCallRequest *request2 = [RMTStreamingInputCallRequest message];
+ request2.payload.body = [NSMutableData dataWithLength:8];
+
+ RMTStreamingInputCallRequest *request3 = [RMTStreamingInputCallRequest message];
+ request3.payload.body = [NSMutableData dataWithLength:1828];
+
+ RMTStreamingInputCallRequest *request4 = [RMTStreamingInputCallRequest message];
+ request4.payload.body = [NSMutableData dataWithLength:45904];
+
+ id<GRXWriter> writer = [GRXWriter writerWithContainer:@[request1, request2, request3, request4]];
+
+ [_service streamingInputCallWithRequestsWriter:writer
+ handler:^(RMTStreamingInputCallResponse *response,
+ NSError *error) {
+ XCTAssertNil(error, @"Finished with unexpected error: %@", error);
+
+ RMTStreamingInputCallResponse *expectedResponse = [RMTStreamingInputCallResponse message];
+ expectedResponse.aggregatedPayloadSize = 74922;
+ XCTAssertEqualObjects(response, expectedResponse);
+
+ [expectation fulfill];
+ }];
+
+ [self waitForExpectationsWithTimeout:4 handler:nil];
+}
+
+- (void)testServerStreamingRPC {
+ __weak XCTestExpectation *expectation = [self expectationWithDescription:@"ServerStreaming"];
+
+ NSArray *expectedSizes = @[@31415, @9, @2653, @58979];
+
+ RMTStreamingOutputCallRequest *request = [RMTStreamingOutputCallRequest message];
+ for (NSNumber *size in expectedSizes) {
+ RMTResponseParameters *parameters = [RMTResponseParameters message];
+ parameters.size = [size integerValue];
+ [request.responseParametersArray addObject:parameters];
+ }
+
+ __block int index = 0;
+ [_service streamingOutputCallWithRequest:request
+ handler:^(BOOL done,
+ RMTStreamingOutputCallResponse *response,
+ NSError *error){
+ XCTAssertNil(error, @"Finished with unexpected error: %@", error);
+ XCTAssertTrue(done || response, @"Event handler called without an event.");
+
+ if (response) {
+ XCTAssertLessThan(index, 4, @"More than 4 responses received.");
+ id expected = [RMTStreamingOutputCallResponse messageWithPayloadSize:expectedSizes[index]];
+ XCTAssertEqualObjects(response, expected);
+ index += 1;
+ }
+
+ if (done) {
+ XCTAssertEqual(index, 4, @"Received %i responses instead of 4.", index);
+ [expectation fulfill];
+ }
+ }];
+
+ [self waitForExpectationsWithTimeout:4 handler:nil];
+}
+
+- (void)testPingPongRPC {
+ __weak XCTestExpectation *expectation = [self expectationWithDescription:@"PingPong"];
+
+ NSArray *requests = @[@27182, @8, @1828, @45904];
+ NSArray *responses = @[@31415, @9, @2653, @58979];
+
+ GRXBufferedPipe *requestsBuffer = [[GRXBufferedPipe alloc] init];
+
+ __block int index = 0;
+
+ id request = [RMTStreamingOutputCallRequest messageWithPayloadSize:requests[index]
+ requestedResponseSize:responses[index]];
+ [requestsBuffer writeValue:request];
+
+ [_service fullDuplexCallWithRequestsWriter:requestsBuffer
+ handler:^(BOOL done,
+ RMTStreamingOutputCallResponse *response,
+ NSError *error) {
+ XCTAssertNil(error, @"Finished with unexpected error: %@", error);
+ XCTAssertTrue(done || response, @"Event handler called without an event.");
+
+ if (response) {
+ XCTAssertLessThan(index, 4, @"More than 4 responses received.");
+ id expected = [RMTStreamingOutputCallResponse messageWithPayloadSize:responses[index]];
+ XCTAssertEqualObjects(response, expected);
+ index += 1;
+ if (index < 4) {
+ id request = [RMTStreamingOutputCallRequest messageWithPayloadSize:requests[index]
+ requestedResponseSize:responses[index]];
+ [requestsBuffer writeValue:request];
+ } else {
+ [requestsBuffer writesFinishedWithError:nil];
+ }
+ }
+
+ if (done) {
+ XCTAssertEqual(index, 4, @"Received %i responses instead of 4.", index);
+ [expectation fulfill];
+ }
+ }];
+ [self waitForExpectationsWithTimeout:2 handler:nil];
+}
+
+- (void)testEmptyStreamRPC {
+ __weak XCTestExpectation *expectation = [self expectationWithDescription:@"EmptyStream"];
+ [_service fullDuplexCallWithRequestsWriter:[GRXWriter emptyWriter]
+ handler:^(BOOL done,
+ RMTStreamingOutputCallResponse *response,
+ NSError *error) {
+ XCTAssertNil(error, @"Finished with unexpected error: %@", error);
+ XCTAssert(done, @"Unexpected response: %@", response);
+ [expectation fulfill];
+ }];
+ [self waitForExpectationsWithTimeout:2 handler:nil];
+}
+
+- (void)testCancelAfterBeginRPC {
+ __weak XCTestExpectation *expectation = [self expectationWithDescription:@"CancelAfterBegin"];
+
+ // A buffered pipe to which we never write any value acts as a writer that just hangs.
+ GRXBufferedPipe *requestsBuffer = [[GRXBufferedPipe alloc] init];
+
+ ProtoRPC *call = [_service RPCToStreamingInputCallWithRequestsWriter:requestsBuffer
+ handler:^(RMTStreamingInputCallResponse *response,
+ NSError *error) {
+ XCTAssertEqual(error.code, GRPC_STATUS_CANCELLED);
+ [expectation fulfill];
+ }];
+ [call start];
+ [call cancel];
+ [self waitForExpectationsWithTimeout:1 handler:nil];
+}
+
+- (void)testCancelAfterFirstResponseRPC {
+ __weak XCTestExpectation *expectation = [self expectationWithDescription:@"CancelAfterFirstResponse"];
+
+ // A buffered pipe to which we write a single value but never close
+ GRXBufferedPipe *requestsBuffer = [[GRXBufferedPipe alloc] init];
+
+ __block BOOL receivedResponse = NO;
+
+ id request = [RMTStreamingOutputCallRequest messageWithPayloadSize:@21782
+ requestedResponseSize:@31415];
+
+ [requestsBuffer writeValue:request];
+
+ __block ProtoRPC *call = [_service RPCToFullDuplexCallWithRequestsWriter:requestsBuffer
+ handler:^(BOOL done,
+ RMTStreamingOutputCallResponse *response,
+ NSError *error) {
+ if (receivedResponse) {
+ XCTAssert(done, @"Unexpected extra response %@", response);
+ XCTAssertEqual(error.code, GRPC_STATUS_CANCELLED);
+ [expectation fulfill];
+ } else {
+ XCTAssertNil(error, @"Finished with unexpected error: %@", error);
+ XCTAssertFalse(done, @"Finished without response");
+ XCTAssertNotNil(response);
+ receivedResponse = YES;
+ [call cancel];
+ }
+ }];
+ [call start];
+ [self waitForExpectationsWithTimeout:4 handler:nil];
+}
+
+@end
diff --git a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj
index 80059b7cbe..3a98fec11a 100644
--- a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj
+++ b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj
@@ -10,6 +10,7 @@
63423F4A1B150A5F006CF63C /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; };
63423F511B151B77006CF63C /* RxLibraryUnitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 63423F501B151B77006CF63C /* RxLibraryUnitTests.m */; };
635697CD1B14FC11007A7283 /* Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = 635697CC1B14FC11007A7283 /* Tests.m */; };
+ 635ED2EC1B1A3BC400FDE5C3 /* InteropTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 635ED2EB1B1A3BC400FDE5C3 /* InteropTests.m */; };
7D8A186224D39101F90230F6 /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 35F2B6BF3BAE8F0DC4AFD76E /* libPods.a */; };
/* End PBXBuildFile section */
@@ -43,6 +44,7 @@
635697C71B14FC11007A7283 /* libTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libTests.a; sourceTree = BUILT_PRODUCTS_DIR; };
635697CC1B14FC11007A7283 /* Tests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Tests.m; sourceTree = "<group>"; };
635697D81B14FC11007A7283 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+ 635ED2EB1B1A3BC400FDE5C3 /* InteropTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = InteropTests.m; sourceTree = "<group>"; };
FF7B5489BCFE40111D768DD0 /* Pods.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.debug.xcconfig; path = "Pods/Target Support Files/Pods/Pods.debug.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */
@@ -105,6 +107,7 @@
635697C91B14FC11007A7283 /* Tests */ = {
isa = PBXGroup;
children = (
+ 635ED2EB1B1A3BC400FDE5C3 /* InteropTests.m */,
63423F501B151B77006CF63C /* RxLibraryUnitTests.m */,
635697CC1B14FC11007A7283 /* Tests.m */,
635697D71B14FC11007A7283 /* Supporting Files */,
@@ -244,6 +247,7 @@
buildActionMask = 2147483647;
files = (
63423F511B151B77006CF63C /* RxLibraryUnitTests.m in Sources */,
+ 635ED2EC1B1A3BC400FDE5C3 /* InteropTests.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};