blob: f23102988bd155609b178cbae02e1f1d18bb7b74 [file] [log] [blame]
Jorge Canizalesb3be2292015-05-31 19:11:20 -07001/*
2 *
3 * Copyright 2015, Google Inc.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following disclaimer
14 * in the documentation and/or other materials provided with the
15 * distribution.
16 * * Neither the name of Google Inc. nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
33
34#import <UIKit/UIKit.h>
35#import <XCTest/XCTest.h>
36
Jorge Canizalesc42a38e2015-06-21 14:44:25 -070037#import <GRPCClient/GRPCCall.h>
Jorge Canizales631dc002015-08-06 23:08:41 -070038#import <GRPCClient/GRPCCall+OAuth2.h>
Jorge Canizalesb2bd0672015-08-01 23:19:11 -070039#import <GRPCClient/GRPCCall+Tests.h>
Jorge Canizalesbe808e32015-07-04 14:37:58 -070040#import <ProtoRPC/ProtoMethod.h>
Jorge Canizalesb3be2292015-05-31 19:11:20 -070041#import <RemoteTest/Messages.pbobjc.h>
Jorge Canizalesc42a38e2015-06-21 14:44:25 -070042#import <RxLibrary/GRXWriteable.h>
43#import <RxLibrary/GRXWriter+Immediate.h>
Jorge Canizalesb3be2292015-05-31 19:11:20 -070044
45// These are a few tests similar to InteropTests, but which use the generic gRPC client (GRPCCall)
46// rather than a generated proto library on top of it.
47
Jorge Canizalesb2bd0672015-08-01 23:19:11 -070048static NSString * const kHostAddress = @"localhost:5050";
Jorge Canizalesd666fd02015-06-12 18:59:11 -070049static NSString * const kPackage = @"grpc.testing";
50static NSString * const kService = @"TestService";
51
Jorge Canizales469d4b62015-07-03 12:02:38 -070052static ProtoMethod *kInexistentMethod;
53static ProtoMethod *kEmptyCallMethod;
54static ProtoMethod *kUnaryCallMethod;
Jorge Canizalesd666fd02015-06-12 18:59:11 -070055
Jorge Canizalesb3be2292015-05-31 19:11:20 -070056@interface GRPCClientTests : XCTestCase
57@end
58
59@implementation GRPCClientTests
60
Jorge Canizalesd666fd02015-06-12 18:59:11 -070061- (void)setUp {
Jorge Canizalesb2bd0672015-08-01 23:19:11 -070062 // Register test server as non-SSL.
63 [GRPCCall useInsecureConnectionsForHost:kHostAddress];
64
Jorge Canizalesd666fd02015-06-12 18:59:11 -070065 // This method isn't implemented by the remote server.
Jorge Canizales469d4b62015-07-03 12:02:38 -070066 kInexistentMethod = [[ProtoMethod alloc] initWithPackage:kPackage
Jorge Canizalesbe808e32015-07-04 14:37:58 -070067 service:kService
68 method:@"Inexistent"];
Jorge Canizales469d4b62015-07-03 12:02:38 -070069 kEmptyCallMethod = [[ProtoMethod alloc] initWithPackage:kPackage
Jorge Canizalesbe808e32015-07-04 14:37:58 -070070 service:kService
71 method:@"EmptyCall"];
Jorge Canizales469d4b62015-07-03 12:02:38 -070072 kUnaryCallMethod = [[ProtoMethod alloc] initWithPackage:kPackage
Jorge Canizalesbe808e32015-07-04 14:37:58 -070073 service:kService
74 method:@"UnaryCall"];
Jorge Canizalesd666fd02015-06-12 18:59:11 -070075}
76
Jorge Canizalesb3be2292015-05-31 19:11:20 -070077- (void)testConnectionToRemoteServer {
78 __weak XCTestExpectation *expectation = [self expectationWithDescription:@"Server reachable."];
79
Jorge Canizalesd666fd02015-06-12 18:59:11 -070080 GRPCCall *call = [[GRPCCall alloc] initWithHost:kHostAddress
Jorge Canizales5260f532015-07-04 14:47:41 -070081 path:kInexistentMethod.HTTPPath
Jorge Canizalesd666fd02015-06-12 18:59:11 -070082 requestsWriter:[GRXWriter writerWithValue:[NSData data]]];
Jorge Canizalesb3be2292015-05-31 19:11:20 -070083
84 id<GRXWriteable> responsesWriteable = [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
85 XCTFail(@"Received unexpected response: %@", value);
86 } completionHandler:^(NSError *errorOrNil) {
87 XCTAssertNotNil(errorOrNil, @"Finished without error!");
88 // TODO(jcanizales): The server should return code 12 UNIMPLEMENTED, not 5 NOT FOUND.
89 XCTAssertEqual(errorOrNil.code, 5, @"Finished with unexpected error: %@", errorOrNil);
90 [expectation fulfill];
91 }];
92
93 [call startWithWriteable:responsesWriteable];
94
Jorge Canizales5580e5d2015-07-15 23:35:48 -070095 [self waitForExpectationsWithTimeout:4 handler:nil];
Jorge Canizalesb3be2292015-05-31 19:11:20 -070096}
97
98- (void)testEmptyRPC {
99 __weak XCTestExpectation *response = [self expectationWithDescription:@"Empty response received."];
100 __weak XCTestExpectation *completion = [self expectationWithDescription:@"Empty RPC completed."];
101
Jorge Canizalesd666fd02015-06-12 18:59:11 -0700102 GRPCCall *call = [[GRPCCall alloc] initWithHost:kHostAddress
Jorge Canizales5260f532015-07-04 14:47:41 -0700103 path:kEmptyCallMethod.HTTPPath
Jorge Canizalesd666fd02015-06-12 18:59:11 -0700104 requestsWriter:[GRXWriter writerWithValue:[NSData data]]];
Jorge Canizalesb3be2292015-05-31 19:11:20 -0700105
106 id<GRXWriteable> responsesWriteable = [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
107 XCTAssertNotNil(value, @"nil value received as response.");
108 XCTAssertEqual([value length], 0, @"Non-empty response received: %@", value);
109 [response fulfill];
110 } completionHandler:^(NSError *errorOrNil) {
111 XCTAssertNil(errorOrNil, @"Finished with unexpected error: %@", errorOrNil);
112 [completion fulfill];
113 }];
114
115 [call startWithWriteable:responsesWriteable];
116
Jorge Canizales83c57cb2015-08-09 16:36:49 -0700117 [self waitForExpectationsWithTimeout:8 handler:nil];
Jorge Canizalesb3be2292015-05-31 19:11:20 -0700118}
119
120- (void)testSimpleProtoRPC {
Jorge Canizalesd666fd02015-06-12 18:59:11 -0700121 __weak XCTestExpectation *response = [self expectationWithDescription:@"Expected response."];
Jorge Canizalesb3be2292015-05-31 19:11:20 -0700122 __weak XCTestExpectation *completion = [self expectationWithDescription:@"RPC completed."];
123
Jorge Canizalesd666fd02015-06-12 18:59:11 -0700124 RMTSimpleRequest *request = [RMTSimpleRequest message];
Jorge Canizalesb3be2292015-05-31 19:11:20 -0700125 request.responseSize = 100;
126 request.fillUsername = YES;
127 request.fillOauthScope = YES;
Jorge Canizalesa8c5d962015-07-16 18:55:31 -0700128 GRXWriter *requestsWriter = [GRXWriter writerWithValue:[request data]];
Jorge Canizalesb3be2292015-05-31 19:11:20 -0700129
Jorge Canizalesd666fd02015-06-12 18:59:11 -0700130 GRPCCall *call = [[GRPCCall alloc] initWithHost:kHostAddress
Jorge Canizales5260f532015-07-04 14:47:41 -0700131 path:kUnaryCallMethod.HTTPPath
Jorge Canizalesb3be2292015-05-31 19:11:20 -0700132 requestsWriter:requestsWriter];
133
134 id<GRXWriteable> responsesWriteable = [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
135 XCTAssertNotNil(value, @"nil value received as response.");
Jorge Canizalesb3be2292015-05-31 19:11:20 -0700136 XCTAssertGreaterThan(value.length, 0, @"Empty response received.");
Jorge Canizalesd666fd02015-06-12 18:59:11 -0700137 RMTSimpleResponse *responseProto = [RMTSimpleResponse parseFromData:value error:NULL];
Jorge Canizalesb3be2292015-05-31 19:11:20 -0700138 // We expect empty strings, not nil:
Jorge Canizalesd666fd02015-06-12 18:59:11 -0700139 XCTAssertNotNil(responseProto.username, @"Response's username is nil.");
140 XCTAssertNotNil(responseProto.oauthScope, @"Response's OAuth scope is nil.");
141 [response fulfill];
Jorge Canizalesb3be2292015-05-31 19:11:20 -0700142 } completionHandler:^(NSError *errorOrNil) {
143 XCTAssertNil(errorOrNil, @"Finished with unexpected error: %@", errorOrNil);
144 [completion fulfill];
145 }];
146
147 [call startWithWriteable:responsesWriteable];
148
Jorge Canizales83c57cb2015-08-09 16:36:49 -0700149 [self waitForExpectationsWithTimeout:8 handler:nil];
Jorge Canizalesb3be2292015-05-31 19:11:20 -0700150}
151
Jorge Canizalesd7981252015-06-12 19:15:18 -0700152- (void)testMetadata {
153 __weak XCTestExpectation *expectation = [self expectationWithDescription:@"RPC unauthorized."];
154
155 RMTSimpleRequest *request = [RMTSimpleRequest message];
156 request.fillUsername = YES;
157 request.fillOauthScope = YES;
Jorge Canizalesa8c5d962015-07-16 18:55:31 -0700158 GRXWriter *requestsWriter = [GRXWriter writerWithValue:[request data]];
Jorge Canizalesd7981252015-06-12 19:15:18 -0700159
160 GRPCCall *call = [[GRPCCall alloc] initWithHost:kHostAddress
Jorge Canizales5260f532015-07-04 14:47:41 -0700161 path:kUnaryCallMethod.HTTPPath
Jorge Canizalesd7981252015-06-12 19:15:18 -0700162 requestsWriter:requestsWriter];
163
Jorge Canizales721b7a32015-08-07 10:11:16 -0700164 call.oauth2AccessToken = @"bogusToken";
Jorge Canizalesd7981252015-06-12 19:15:18 -0700165
166 id<GRXWriteable> responsesWriteable = [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
167 XCTFail(@"Received unexpected response: %@", value);
168 } completionHandler:^(NSError *errorOrNil) {
169 XCTAssertNotNil(errorOrNil, @"Finished without error!");
170 XCTAssertEqual(errorOrNil.code, 16, @"Finished with unexpected error: %@", errorOrNil);
Jorge Canizales8c6bc6e2015-06-12 22:19:23 -0700171 XCTAssertEqualObjects(call.responseMetadata, errorOrNil.userInfo[kGRPCStatusMetadataKey],
172 @"Metadata in the NSError object and call object differ.");
Jorge Canizales721b7a32015-08-07 10:11:16 -0700173 NSString *challengeHeader = call.oauth2ChallengeHeader;
Jorge Canizalesd7981252015-06-12 19:15:18 -0700174 XCTAssertGreaterThan(challengeHeader.length, 0,
175 @"No challenge in response headers %@", call.responseMetadata);
176 [expectation fulfill];
177 }];
178
179 [call startWithWriteable:responsesWriteable];
180
Jorge Canizales5580e5d2015-07-15 23:35:48 -0700181 [self waitForExpectationsWithTimeout:4 handler:nil];
Jorge Canizalesd7981252015-06-12 19:15:18 -0700182}
183
Jorge Canizalesb3be2292015-05-31 19:11:20 -0700184@end