Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(962)

Side by Side Diff: third_party/grpc/src/objective-c/tests/GRPCClientTests.m

Issue 1932353002: Initial checkin of gRPC to third_party/ Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 *
3 * Copyright 2015-2016, 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
37 #import <GRPCClient/GRPCCall.h>
38 #import <GRPCClient/GRPCCall+ChannelArg.h>
39 #import <GRPCClient/GRPCCall+OAuth2.h>
40 #import <GRPCClient/GRPCCall+Tests.h>
41 #import <ProtoRPC/ProtoMethod.h>
42 #import <RemoteTest/Messages.pbobjc.h>
43 #import <RxLibrary/GRXWriteable.h>
44 #import <RxLibrary/GRXWriter+Immediate.h>
45
46 static NSString * const kHostAddress = @"localhost:5050";
47 static NSString * const kPackage = @"grpc.testing";
48 static NSString * const kService = @"TestService";
49 static NSString * const kRemoteSSLHost = @"grpc-test.sandbox.googleapis.com";
50
51 static ProtoMethod *kInexistentMethod;
52 static ProtoMethod *kEmptyCallMethod;
53 static ProtoMethod *kUnaryCallMethod;
54
55 /** Observer class for testing that responseMetadata is KVO-compliant */
56 @interface PassthroughObserver : NSObject
57 - (instancetype) initWithCallback:(void (^)(NSString*, id, NSDictionary*))callba ck
58 NS_DESIGNATED_INITIALIZER;
59
60 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(N SDictionary *)change
61 context:(void *)context;
62 @end
63
64 @implementation PassthroughObserver {
65 void (^_callback)(NSString*, id, NSDictionary*);
66 }
67
68 - (instancetype)init {
69 return [self initWithCallback:nil];
70 }
71
72 - (instancetype)initWithCallback:(void (^)(NSString *, id, NSDictionary *))callb ack {
73 if (!callback) {
74 return nil;
75 }
76 if ((self = [super init])) {
77 _callback = callback;
78 }
79 return self;
80 }
81
82 - (void)observeValueForKeyPath:(NSString *)keyPath
83 ofObject:(id)object
84 change:(NSDictionary *)change
85 context:(void *)context {
86 _callback(keyPath, object, change);
87 [object removeObserver:self forKeyPath:keyPath];
88 }
89
90 @end
91
92 # pragma mark Tests
93
94 /**
95 * A few tests similar to InteropTests, but which use the generic gRPC client (G RPCCall) rather than
96 * a generated proto library on top of it. Its RPCs are sent to a local cleartex t server.
97 *
98 * TODO(jcanizales): Run them also against a local SSL server and against a remo te server.
99 */
100 @interface GRPCClientTests : XCTestCase
101 @end
102
103 @implementation GRPCClientTests
104
105 - (void)setUp {
106 // Add a custom user agent prefix that will be used in test
107 [GRPCCall setUserAgentPrefix:@"Foo" forHost:kHostAddress];
108 // Register test server as non-SSL.
109 [GRPCCall useInsecureConnectionsForHost:kHostAddress];
110
111 // This method isn't implemented by the remote server.
112 kInexistentMethod = [[ProtoMethod alloc] initWithPackage:kPackage
113 service:kService
114 method:@"Inexistent"];
115 kEmptyCallMethod = [[ProtoMethod alloc] initWithPackage:kPackage
116 service:kService
117 method:@"EmptyCall"];
118 kUnaryCallMethod = [[ProtoMethod alloc] initWithPackage:kPackage
119 service:kService
120 method:@"UnaryCall"];
121 }
122
123 - (void)testConnectionToRemoteServer {
124 __weak XCTestExpectation *expectation = [self expectationWithDescription:@"Ser ver reachable."];
125
126 GRPCCall *call = [[GRPCCall alloc] initWithHost:kHostAddress
127 path:kInexistentMethod.HTTPPath
128 requestsWriter:[GRXWriter writerWithValue:[NS Data data]]];
129
130 id<GRXWriteable> responsesWriteable = [[GRXWriteable alloc] initWithValueHandl er:^(NSData *value) {
131 XCTFail(@"Received unexpected response: %@", value);
132 } completionHandler:^(NSError *errorOrNil) {
133 XCTAssertNotNil(errorOrNil, @"Finished without error!");
134 XCTAssertEqual(errorOrNil.code, 12, @"Finished with unexpected error: %@", e rrorOrNil);
135 [expectation fulfill];
136 }];
137
138 [call startWithWriteable:responsesWriteable];
139
140 [self waitForExpectationsWithTimeout:4 handler:nil];
141 }
142
143 - (void)testEmptyRPC {
144 __weak XCTestExpectation *response = [self expectationWithDescription:@"Empty response received."];
145 __weak XCTestExpectation *completion = [self expectationWithDescription:@"Empt y RPC completed."];
146
147 GRPCCall *call = [[GRPCCall alloc] initWithHost:kHostAddress
148 path:kEmptyCallMethod.HTTPPath
149 requestsWriter:[GRXWriter writerWithValue:[NS Data data]]];
150
151 id<GRXWriteable> responsesWriteable = [[GRXWriteable alloc] initWithValueHandl er:^(NSData *value) {
152 XCTAssertNotNil(value, @"nil value received as response.");
153 XCTAssertEqual([value length], 0, @"Non-empty response received: %@", value) ;
154 [response fulfill];
155 } completionHandler:^(NSError *errorOrNil) {
156 XCTAssertNil(errorOrNil, @"Finished with unexpected error: %@", errorOrNil);
157 [completion fulfill];
158 }];
159
160 [call startWithWriteable:responsesWriteable];
161
162 [self waitForExpectationsWithTimeout:8 handler:nil];
163 }
164
165 - (void)testSimpleProtoRPC {
166 __weak XCTestExpectation *response = [self expectationWithDescription:@"Expect ed response."];
167 __weak XCTestExpectation *completion = [self expectationWithDescription:@"RPC completed."];
168
169 RMTSimpleRequest *request = [RMTSimpleRequest message];
170 request.responseSize = 100;
171 request.fillUsername = YES;
172 request.fillOauthScope = YES;
173 GRXWriter *requestsWriter = [GRXWriter writerWithValue:[request data]];
174
175 GRPCCall *call = [[GRPCCall alloc] initWithHost:kHostAddress
176 path:kUnaryCallMethod.HTTPPath
177 requestsWriter:requestsWriter];
178
179 id<GRXWriteable> responsesWriteable = [[GRXWriteable alloc] initWithValueHandl er:^(NSData *value) {
180 XCTAssertNotNil(value, @"nil value received as response.");
181 XCTAssertGreaterThan(value.length, 0, @"Empty response received.");
182 RMTSimpleResponse *responseProto = [RMTSimpleResponse parseFromData:value er ror:NULL];
183 // We expect empty strings, not nil:
184 XCTAssertNotNil(responseProto.username, @"Response's username is nil.");
185 XCTAssertNotNil(responseProto.oauthScope, @"Response's OAuth scope is nil.") ;
186 [response fulfill];
187 } completionHandler:^(NSError *errorOrNil) {
188 XCTAssertNil(errorOrNil, @"Finished with unexpected error: %@", errorOrNil);
189 [completion fulfill];
190 }];
191
192 [call startWithWriteable:responsesWriteable];
193
194 [self waitForExpectationsWithTimeout:8 handler:nil];
195 }
196
197 - (void)testMetadata {
198 __weak XCTestExpectation *expectation = [self expectationWithDescription:@"RPC unauthorized."];
199
200 RMTSimpleRequest *request = [RMTSimpleRequest message];
201 request.fillUsername = YES;
202 request.fillOauthScope = YES;
203 GRXWriter *requestsWriter = [GRXWriter writerWithValue:[request data]];
204
205 GRPCCall *call = [[GRPCCall alloc] initWithHost:kRemoteSSLHost
206 path:kUnaryCallMethod.HTTPPath
207 requestsWriter:requestsWriter];
208
209 call.oauth2AccessToken = @"bogusToken";
210
211 id<GRXWriteable> responsesWriteable = [[GRXWriteable alloc] initWithValueHandl er:^(NSData *value) {
212 XCTFail(@"Received unexpected response: %@", value);
213 } completionHandler:^(NSError *errorOrNil) {
214 XCTAssertNotNil(errorOrNil, @"Finished without error!");
215 XCTAssertEqual(errorOrNil.code, 16, @"Finished with unexpected error: %@", e rrorOrNil);
216 XCTAssertEqualObjects(call.responseHeaders, errorOrNil.userInfo[kGRPCHeaders Key],
217 @"Headers in the NSError object and call object differ .");
218 XCTAssertEqualObjects(call.responseTrailers, errorOrNil.userInfo[kGRPCTraile rsKey],
219 @"Trailers in the NSError object and call object diffe r.");
220 NSString *challengeHeader = call.oauth2ChallengeHeader;
221 XCTAssertGreaterThan(challengeHeader.length, 0,
222 @"No challenge in response headers %@", call.responseHe aders);
223 [expectation fulfill];
224 }];
225
226 [call startWithWriteable:responsesWriteable];
227
228 [self waitForExpectationsWithTimeout:4 handler:nil];
229 }
230
231 - (void)testResponseMetadataKVO {
232 __weak XCTestExpectation *response = [self expectationWithDescription:@"Empty response received."];
233 __weak XCTestExpectation *completion = [self expectationWithDescription:@"Empt y RPC completed."];
234 __weak XCTestExpectation *metadata = [self expectationWithDescription:@"Metada ta changed."];
235
236 GRPCCall *call = [[GRPCCall alloc] initWithHost:kHostAddress
237 path:kEmptyCallMethod.HTTPPath
238 requestsWriter:[GRXWriter writerWithValue:[NS Data data]]];
239
240 PassthroughObserver *observer = [[PassthroughObserver alloc] initWithCallback: ^(NSString *keypath, id object, NSDictionary * change) {
241 if ([keypath isEqual: @"responseHeaders"]) {
242 [metadata fulfill];
243 }
244 }];
245
246 [call addObserver:observer forKeyPath:@"responseHeaders" options:0 context:NUL L];
247
248 id<GRXWriteable> responsesWriteable = [[GRXWriteable alloc] initWithValueHandl er:^(NSData *value) {
249 XCTAssertNotNil(value, @"nil value received as response.");
250 XCTAssertEqual([value length], 0, @"Non-empty response received: %@", value) ;
251 [response fulfill];
252 } completionHandler:^(NSError *errorOrNil) {
253 XCTAssertNil(errorOrNil, @"Finished with unexpected error: %@", errorOrNil);
254 [completion fulfill];
255 }];
256
257 [call startWithWriteable:responsesWriteable];
258
259 [self waitForExpectationsWithTimeout:8 handler:nil];
260 }
261
262 - (void)testUserAgentPrefix {
263 __weak XCTestExpectation *response = [self expectationWithDescription:@"Empty response received."];
264 __weak XCTestExpectation *completion = [self expectationWithDescription:@"Empt y RPC completed."];
265
266 GRPCCall *call = [[GRPCCall alloc] initWithHost:kHostAddress
267 path:kEmptyCallMethod.HTTPPath
268 requestsWriter:[GRXWriter writerWithValue:[NS Data data]]];
269 // Setting this special key in the header will cause the interop server to ech o back the
270 // user-agent value, which we confirm.
271 call.requestHeaders[@"x-grpc-test-echo-useragent"] = @"";
272
273 id<GRXWriteable> responsesWriteable = [[GRXWriteable alloc] initWithValueHandl er:^(NSData *value) {
274 XCTAssertNotNil(value, @"nil value received as response.");
275 XCTAssertEqual([value length], 0, @"Non-empty response received: %@", value) ;
276 /* This test needs to be more clever in regards to changing the version of t he core.
277 XCTAssertEqualObjects(call.responseHeaders[@"x-grpc-test-echo-useragent"],
278 @"Foo grpc-objc/0.13.0 grpc-c/0.14.0-dev (ios)",
279 @"Did not receive expected user agent %@",
280 call.responseHeaders[@"x-grpc-test-echo-useragent"]);
281 */
282 [response fulfill];
283 } completionHandler:^(NSError *errorOrNil) {
284 XCTAssertNil(errorOrNil, @"Finished with unexpected error: %@", errorOrNil);
285 [completion fulfill];
286 }];
287
288 [call startWithWriteable:responsesWriteable];
289
290 [self waitForExpectationsWithTimeout:8 handler:nil];
291 }
292
293 // TODO(makarandd): Move to a different file that contains only unit tests
294 - (void)testExceptions {
295 // Try to set userAgentPrefix for host that is nil. This should cause
296 // an exception.
297 @try {
298 [GRPCCall setUserAgentPrefix:@"Foo" forHost:nil];
299 XCTFail(@"Did not receive an exception when host is nil");
300 } @catch(NSException *theException) {
301 NSLog(@"Received exception as expected: %@", theException.name);
302 }
303
304 // Try to set parameters to nil for GRPCCall. This should cause an exception
305 @try {
306 GRPCCall *call = [[GRPCCall alloc] initWithHost:nil
307 path:nil
308 requestsWriter:nil];
309 XCTFail(@"Did not receive an exception when parameters are nil");
310 } @catch(NSException *theException) {
311 NSLog(@"Received exception as expected: %@", theException.name);
312 }
313
314
315 // Set state to Finished by force
316 GRXWriter *requestsWriter = [GRXWriter emptyWriter];
317 [requestsWriter finishWithError:nil];
318 @try {
319 GRPCCall *call = [[GRPCCall alloc] initWithHost:kHostAddress
320 path:kUnaryCallMethod.HTTPPath
321 requestsWriter:requestsWriter];
322 XCTFail(@"Did not receive an exception when GRXWriter has incorrect state.") ;
323 } @catch(NSException *theException) {
324 NSLog(@"Received exception as expected: %@", theException.name);
325 }
326
327 }
328
329 @end
OLDNEW
« no previous file with comments | « third_party/grpc/src/objective-c/format-all-comments.sh ('k') | third_party/grpc/src/objective-c/tests/Info.plist » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698