mirror of https://github.com/grpc/grpc.git
parent
dc42ee624d
commit
7307684b2b
2 changed files with 309 additions and 0 deletions
@ -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 |
Loading…
Reference in new issue