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

Side by Side Diff: third_party/grpc/src/node/test/surface_test.js

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 'use strict';
35
36 var assert = require('assert');
37
38 var surface_client = require('../src/client.js');
39
40 var ProtoBuf = require('protobufjs');
41
42 var grpc = require('..');
43
44 var math_proto = ProtoBuf.loadProtoFile(__dirname +
45 '/../../proto/math/math.proto');
46
47 var mathService = math_proto.lookup('math.Math');
48
49 var _ = require('lodash');
50
51 /**
52 * This is used for testing functions with multiple asynchronous calls that
53 * can happen in different orders. This should be passed the number of async
54 * function invocations that can occur last, and each of those should call this
55 * function's return value
56 * @param {function()} done The function that should be called when a test is
57 * complete.
58 * @param {number} count The number of calls to the resulting function if the
59 * test passes.
60 * @return {function()} The function that should be called at the end of each
61 * sequence of asynchronous functions.
62 */
63 function multiDone(done, count) {
64 return function() {
65 count -= 1;
66 if (count <= 0) {
67 done();
68 }
69 };
70 }
71
72 var server_insecure_creds = grpc.ServerCredentials.createInsecure();
73
74 describe('File loader', function() {
75 it('Should load a proto file by default', function() {
76 assert.doesNotThrow(function() {
77 grpc.load(__dirname + '/test_service.proto');
78 });
79 });
80 it('Should load a proto file with the proto format', function() {
81 assert.doesNotThrow(function() {
82 grpc.load(__dirname + '/test_service.proto', 'proto');
83 });
84 });
85 it('Should load a json file with the json format', function() {
86 assert.doesNotThrow(function() {
87 grpc.load(__dirname + '/test_service.json', 'json');
88 });
89 });
90 it('Should fail to load a file with an unknown format', function() {
91 assert.throws(function() {
92 grpc.load(__dirname + '/test_service.proto', 'fake_format');
93 });
94 });
95 });
96 describe('surface Server', function() {
97 var server;
98 beforeEach(function() {
99 server = new grpc.Server();
100 });
101 afterEach(function() {
102 server.forceShutdown();
103 });
104 it('should error if started twice', function() {
105 server.start();
106 assert.throws(function() {
107 server.start();
108 });
109 });
110 it('should error if a port is bound after the server starts', function() {
111 server.start();
112 assert.throws(function() {
113 server.bind('localhost:0', grpc.ServerCredentials.createInsecure());
114 });
115 });
116 it('should successfully shutdown if tryShutdown is called', function(done) {
117 server.start();
118 server.tryShutdown(done);
119 });
120 });
121 describe('Server.prototype.addProtoService', function() {
122 var server;
123 var dummyImpls = {
124 'div': function() {},
125 'divMany': function() {},
126 'fib': function() {},
127 'sum': function() {}
128 };
129 beforeEach(function() {
130 server = new grpc.Server();
131 });
132 afterEach(function() {
133 server.forceShutdown();
134 });
135 it('Should succeed with a single service', function() {
136 assert.doesNotThrow(function() {
137 server.addProtoService(mathService, dummyImpls);
138 });
139 });
140 it('Should fail with conflicting method names', function() {
141 server.addProtoService(mathService, dummyImpls);
142 assert.throws(function() {
143 server.addProtoService(mathService, dummyImpls);
144 });
145 });
146 it('Should fail with missing handlers', function() {
147 assert.throws(function() {
148 server.addProtoService(mathService, {
149 'div': function() {},
150 'divMany': function() {},
151 'fib': function() {}
152 });
153 }, /math.Math.Sum/);
154 });
155 it('Should fail if the server has been started', function() {
156 server.start();
157 assert.throws(function() {
158 server.addProtoService(mathService, dummyImpls);
159 });
160 });
161 });
162 describe('Client constructor building', function() {
163 var illegal_service_attrs = {
164 $method : {
165 path: '/illegal/$method',
166 requestStream: false,
167 responseStream: false,
168 requestSerialize: _.identity,
169 requestDeserialize: _.identity,
170 responseSerialize: _.identity,
171 responseDeserialize: _.identity
172 }
173 };
174 it('Should reject method names starting with $', function() {
175 assert.throws(function() {
176 grpc.makeGenericClientConstructor(illegal_service_attrs);
177 }, /\$/);
178 });
179 });
180 describe('waitForClientReady', function() {
181 var server;
182 var port;
183 var Client;
184 var client;
185 before(function() {
186 server = new grpc.Server();
187 port = server.bind('localhost:0', grpc.ServerCredentials.createInsecure());
188 server.start();
189 Client = surface_client.makeProtobufClientConstructor(mathService);
190 });
191 beforeEach(function() {
192 client = new Client('localhost:' + port, grpc.credentials.createInsecure());
193 });
194 after(function() {
195 server.forceShutdown();
196 });
197 it('should complete when called alone', function(done) {
198 grpc.waitForClientReady(client, Infinity, function(error) {
199 assert.ifError(error);
200 done();
201 });
202 });
203 it('should complete when a call is initiated', function(done) {
204 grpc.waitForClientReady(client, Infinity, function(error) {
205 assert.ifError(error);
206 done();
207 });
208 var call = client.div({}, function(err, response) {});
209 call.cancel();
210 });
211 it('should complete if called more than once', function(done) {
212 done = multiDone(done, 2);
213 grpc.waitForClientReady(client, Infinity, function(error) {
214 assert.ifError(error);
215 done();
216 });
217 grpc.waitForClientReady(client, Infinity, function(error) {
218 assert.ifError(error);
219 done();
220 });
221 });
222 it('should complete if called when already ready', function(done) {
223 grpc.waitForClientReady(client, Infinity, function(error) {
224 assert.ifError(error);
225 grpc.waitForClientReady(client, Infinity, function(error) {
226 assert.ifError(error);
227 done();
228 });
229 });
230 });
231 it('should time out if the server does not exist', function(done) {
232 var bad_client = new Client('nonexistent_hostname',
233 grpc.credentials.createInsecure());
234 var deadline = new Date();
235 deadline.setSeconds(deadline.getSeconds() + 1);
236 grpc.waitForClientReady(bad_client, deadline, function(error) {
237 assert(error);
238 done();
239 });
240 });
241 });
242 describe('Echo service', function() {
243 var server;
244 var client;
245 before(function() {
246 var test_proto = ProtoBuf.loadProtoFile(__dirname + '/echo_service.proto');
247 var echo_service = test_proto.lookup('EchoService');
248 server = new grpc.Server();
249 server.addProtoService(echo_service, {
250 echo: function(call, callback) {
251 callback(null, call.request);
252 }
253 });
254 var port = server.bind('localhost:0', server_insecure_creds);
255 var Client = surface_client.makeProtobufClientConstructor(echo_service);
256 client = new Client('localhost:' + port, grpc.credentials.createInsecure());
257 server.start();
258 });
259 after(function() {
260 server.forceShutdown();
261 });
262 it('should echo the recieved message directly', function(done) {
263 client.echo({value: 'test value', value2: 3}, function(error, response) {
264 assert.ifError(error);
265 assert.deepEqual(response, {value: 'test value', value2: 3});
266 done();
267 });
268 });
269 });
270 describe('Generic client and server', function() {
271 function toString(val) {
272 return val.toString();
273 }
274 function toBuffer(str) {
275 return new Buffer(str);
276 }
277 var string_service_attrs = {
278 'capitalize' : {
279 path: '/string/capitalize',
280 requestStream: false,
281 responseStream: false,
282 requestSerialize: toBuffer,
283 requestDeserialize: toString,
284 responseSerialize: toBuffer,
285 responseDeserialize: toString
286 }
287 };
288 describe('String client and server', function() {
289 var client;
290 var server;
291 before(function() {
292 server = new grpc.Server();
293 server.addService(string_service_attrs, {
294 capitalize: function(call, callback) {
295 callback(null, _.capitalize(call.request));
296 }
297 });
298 var port = server.bind('localhost:0', server_insecure_creds);
299 server.start();
300 var Client = grpc.makeGenericClientConstructor(string_service_attrs);
301 client = new Client('localhost:' + port,
302 grpc.credentials.createInsecure());
303 });
304 after(function() {
305 server.forceShutdown();
306 });
307 it('Should respond with a capitalized string', function(done) {
308 client.capitalize('abc', function(err, response) {
309 assert.ifError(err);
310 assert.strictEqual(response, 'Abc');
311 done();
312 });
313 });
314 });
315 });
316 describe('Server-side getPeer', function() {
317 function toString(val) {
318 return val.toString();
319 }
320 function toBuffer(str) {
321 return new Buffer(str);
322 }
323 var string_service_attrs = {
324 'getPeer' : {
325 path: '/string/getPeer',
326 requestStream: false,
327 responseStream: false,
328 requestSerialize: toBuffer,
329 requestDeserialize: toString,
330 responseSerialize: toBuffer,
331 responseDeserialize: toString
332 }
333 };
334 var client;
335 var server;
336 before(function() {
337 server = new grpc.Server();
338 server.addService(string_service_attrs, {
339 getPeer: function(call, callback) {
340 try {
341 callback(null, call.getPeer());
342 } catch (e) {
343 call.emit('error', e);
344 }
345 }
346 });
347 var port = server.bind('localhost:0', server_insecure_creds);
348 server.start();
349 var Client = grpc.makeGenericClientConstructor(string_service_attrs);
350 client = new Client('localhost:' + port,
351 grpc.credentials.createInsecure());
352 });
353 after(function() {
354 server.forceShutdown();
355 });
356 it('should respond with a string representing the client', function(done) {
357 client.getPeer('', function(err, response) {
358 assert.ifError(err);
359 // We don't expect a specific value, just that it worked without error
360 done();
361 });
362 });
363 });
364 describe('Echo metadata', function() {
365 var client;
366 var server;
367 var metadata;
368 before(function() {
369 var test_proto = ProtoBuf.loadProtoFile(__dirname + '/test_service.proto');
370 var test_service = test_proto.lookup('TestService');
371 server = new grpc.Server();
372 server.addProtoService(test_service, {
373 unary: function(call, cb) {
374 call.sendMetadata(call.metadata);
375 cb(null, {});
376 },
377 clientStream: function(stream, cb){
378 stream.on('data', function(data) {});
379 stream.on('end', function() {
380 stream.sendMetadata(stream.metadata);
381 cb(null, {});
382 });
383 },
384 serverStream: function(stream) {
385 stream.sendMetadata(stream.metadata);
386 stream.end();
387 },
388 bidiStream: function(stream) {
389 stream.on('data', function(data) {});
390 stream.on('end', function() {
391 stream.sendMetadata(stream.metadata);
392 stream.end();
393 });
394 }
395 });
396 var port = server.bind('localhost:0', server_insecure_creds);
397 var Client = surface_client.makeProtobufClientConstructor(test_service);
398 client = new Client('localhost:' + port, grpc.credentials.createInsecure());
399 server.start();
400 metadata = new grpc.Metadata();
401 metadata.set('key', 'value');
402 });
403 after(function() {
404 server.forceShutdown();
405 });
406 it('with unary call', function(done) {
407 var call = client.unary({}, function(err, data) {
408 assert.ifError(err);
409 }, metadata);
410 call.on('metadata', function(metadata) {
411 assert.deepEqual(metadata.get('key'), ['value']);
412 done();
413 });
414 });
415 it('with client stream call', function(done) {
416 var call = client.clientStream(function(err, data) {
417 assert.ifError(err);
418 }, metadata);
419 call.on('metadata', function(metadata) {
420 assert.deepEqual(metadata.get('key'), ['value']);
421 done();
422 });
423 call.end();
424 });
425 it('with server stream call', function(done) {
426 var call = client.serverStream({}, metadata);
427 call.on('data', function() {});
428 call.on('metadata', function(metadata) {
429 assert.deepEqual(metadata.get('key'), ['value']);
430 done();
431 });
432 });
433 it('with bidi stream call', function(done) {
434 var call = client.bidiStream(metadata);
435 call.on('data', function() {});
436 call.on('metadata', function(metadata) {
437 assert.deepEqual(metadata.get('key'), ['value']);
438 done();
439 });
440 call.end();
441 });
442 it('shows the correct user-agent string', function(done) {
443 var version = require('../../../package.json').version;
444 var call = client.unary({}, function(err, data) { assert.ifError(err); },
445 metadata);
446 call.on('metadata', function(metadata) {
447 assert(_.startsWith(metadata.get('user-agent')[0],
448 'grpc-node/' + version));
449 done();
450 });
451 });
452 it('properly handles duplicate values', function(done) {
453 var dup_metadata = metadata.clone();
454 dup_metadata.add('key', 'value2');
455 var call = client.unary({}, function(err, data) {assert.ifError(err); },
456 dup_metadata);
457 call.on('metadata', function(resp_metadata) {
458 // Two arrays are equal iff their symmetric difference is empty
459 assert.deepEqual(_.xor(dup_metadata.get('key'), resp_metadata.get('key')),
460 []);
461 done();
462 });
463 });
464 });
465 describe('Client malformed response handling', function() {
466 var server;
467 var client;
468 var badArg = new Buffer([0xFF]);
469 before(function() {
470 var test_proto = ProtoBuf.loadProtoFile(__dirname + '/test_service.proto');
471 var test_service = test_proto.lookup('TestService');
472 var malformed_test_service = {
473 unary: {
474 path: '/TestService/Unary',
475 requestStream: false,
476 responseStream: false,
477 requestDeserialize: _.identity,
478 responseSerialize: _.identity
479 },
480 clientStream: {
481 path: '/TestService/ClientStream',
482 requestStream: true,
483 responseStream: false,
484 requestDeserialize: _.identity,
485 responseSerialize: _.identity
486 },
487 serverStream: {
488 path: '/TestService/ServerStream',
489 requestStream: false,
490 responseStream: true,
491 requestDeserialize: _.identity,
492 responseSerialize: _.identity
493 },
494 bidiStream: {
495 path: '/TestService/BidiStream',
496 requestStream: true,
497 responseStream: true,
498 requestDeserialize: _.identity,
499 responseSerialize: _.identity
500 }
501 };
502 server = new grpc.Server();
503 server.addService(malformed_test_service, {
504 unary: function(call, cb) {
505 cb(null, badArg);
506 },
507 clientStream: function(stream, cb) {
508 stream.on('data', function() {/* Ignore requests */});
509 stream.on('end', function() {
510 cb(null, badArg);
511 });
512 },
513 serverStream: function(stream) {
514 stream.write(badArg);
515 stream.end();
516 },
517 bidiStream: function(stream) {
518 stream.on('data', function() {
519 // Ignore requests
520 stream.write(badArg);
521 });
522 stream.on('end', function() {
523 stream.end();
524 });
525 }
526 });
527 var port = server.bind('localhost:0', server_insecure_creds);
528 var Client = surface_client.makeProtobufClientConstructor(test_service);
529 client = new Client('localhost:' + port, grpc.credentials.createInsecure());
530 server.start();
531 });
532 after(function() {
533 server.forceShutdown();
534 });
535 it('should get an INTERNAL status with a unary call', function(done) {
536 client.unary({}, function(err, data) {
537 assert(err);
538 assert.strictEqual(err.code, grpc.status.INTERNAL);
539 done();
540 });
541 });
542 it('should get an INTERNAL status with a client stream call', function(done) {
543 var call = client.clientStream(function(err, data) {
544 assert(err);
545 assert.strictEqual(err.code, grpc.status.INTERNAL);
546 done();
547 });
548 call.write({});
549 call.end();
550 });
551 it('should get an INTERNAL status with a server stream call', function(done) {
552 var call = client.serverStream({});
553 call.on('data', function(){});
554 call.on('error', function(err) {
555 assert.strictEqual(err.code, grpc.status.INTERNAL);
556 done();
557 });
558 });
559 it('should get an INTERNAL status with a bidi stream call', function(done) {
560 var call = client.bidiStream();
561 call.on('data', function(){});
562 call.on('error', function(err) {
563 assert.strictEqual(err.code, grpc.status.INTERNAL);
564 done();
565 });
566 call.write({});
567 call.end();
568 });
569 });
570 describe('Other conditions', function() {
571 var test_service;
572 var Client;
573 var client;
574 var server;
575 var port;
576 before(function() {
577 var test_proto = ProtoBuf.loadProtoFile(__dirname + '/test_service.proto');
578 test_service = test_proto.lookup('TestService');
579 server = new grpc.Server();
580 var trailer_metadata = new grpc.Metadata();
581 trailer_metadata.add('trailer-present', 'yes');
582 server.addProtoService(test_service, {
583 unary: function(call, cb) {
584 var req = call.request;
585 if (req.error) {
586 cb({code: grpc.status.UNKNOWN,
587 details: 'Requested error'}, null, trailer_metadata);
588 } else {
589 cb(null, {count: 1}, trailer_metadata);
590 }
591 },
592 clientStream: function(stream, cb){
593 var count = 0;
594 var errored;
595 stream.on('data', function(data) {
596 if (data.error) {
597 errored = true;
598 cb(new Error('Requested error'), null, trailer_metadata);
599 } else {
600 count += 1;
601 }
602 });
603 stream.on('end', function() {
604 if (!errored) {
605 cb(null, {count: count}, trailer_metadata);
606 }
607 });
608 },
609 serverStream: function(stream) {
610 var req = stream.request;
611 if (req.error) {
612 var err = {code: grpc.status.UNKNOWN,
613 details: 'Requested error'};
614 err.metadata = trailer_metadata;
615 stream.emit('error', err);
616 } else {
617 for (var i = 0; i < 5; i++) {
618 stream.write({count: i});
619 }
620 stream.end(trailer_metadata);
621 }
622 },
623 bidiStream: function(stream) {
624 var count = 0;
625 stream.on('data', function(data) {
626 if (data.error) {
627 var err = new Error('Requested error');
628 err.metadata = trailer_metadata.clone();
629 err.metadata.add('count', '' + count);
630 stream.emit('error', err);
631 } else {
632 stream.write({count: count});
633 count += 1;
634 }
635 });
636 stream.on('end', function() {
637 stream.end(trailer_metadata);
638 });
639 }
640 });
641 port = server.bind('localhost:0', server_insecure_creds);
642 Client = surface_client.makeProtobufClientConstructor(test_service);
643 client = new Client('localhost:' + port, grpc.credentials.createInsecure());
644 server.start();
645 });
646 after(function() {
647 server.forceShutdown();
648 });
649 it('channel.getTarget should be available', function() {
650 assert.strictEqual(typeof grpc.getClientChannel(client).getTarget(),
651 'string');
652 });
653 it('client should be able to pause and resume a stream', function(done) {
654 var call = client.bidiStream();
655 call.on('data', function(data) {
656 assert(data.count < 3);
657 call.pause();
658 setTimeout(function() {
659 call.resume();
660 }, 10);
661 });
662 call.on('end', function() {
663 done();
664 });
665 call.write({});
666 call.write({});
667 call.write({});
668 call.end();
669 });
670 describe('Server recieving bad input', function() {
671 var misbehavingClient;
672 var badArg = new Buffer([0xFF]);
673 before(function() {
674 var test_service_attrs = {
675 unary: {
676 path: '/TestService/Unary',
677 requestStream: false,
678 responseStream: false,
679 requestSerialize: _.identity,
680 responseDeserialize: _.identity
681 },
682 clientStream: {
683 path: '/TestService/ClientStream',
684 requestStream: true,
685 responseStream: false,
686 requestSerialize: _.identity,
687 responseDeserialize: _.identity
688 },
689 serverStream: {
690 path: '/TestService/ServerStream',
691 requestStream: false,
692 responseStream: true,
693 requestSerialize: _.identity,
694 responseDeserialize: _.identity
695 },
696 bidiStream: {
697 path: '/TestService/BidiStream',
698 requestStream: true,
699 responseStream: true,
700 requestSerialize: _.identity,
701 responseDeserialize: _.identity
702 }
703 };
704 var Client = surface_client.makeClientConstructor(test_service_attrs,
705 'TestService');
706 misbehavingClient = new Client('localhost:' + port,
707 grpc.credentials.createInsecure());
708 });
709 it('should respond correctly to a unary call', function(done) {
710 misbehavingClient.unary(badArg, function(err, data) {
711 assert(err);
712 assert.strictEqual(err.code, grpc.status.INVALID_ARGUMENT);
713 done();
714 });
715 });
716 it('should respond correctly to a client stream', function(done) {
717 var call = misbehavingClient.clientStream(function(err, data) {
718 assert(err);
719 assert.strictEqual(err.code, grpc.status.INVALID_ARGUMENT);
720 done();
721 });
722 call.write(badArg);
723 // TODO(mlumish): Remove call.end()
724 call.end();
725 });
726 it('should respond correctly to a server stream', function(done) {
727 var call = misbehavingClient.serverStream(badArg);
728 call.on('data', function(data) {
729 assert.fail(data, null, 'Unexpected data', '===');
730 });
731 call.on('error', function(err) {
732 assert.strictEqual(err.code, grpc.status.INVALID_ARGUMENT);
733 done();
734 });
735 });
736 it('should respond correctly to a bidi stream', function(done) {
737 var call = misbehavingClient.bidiStream();
738 call.on('data', function(data) {
739 assert.fail(data, null, 'Unexpected data', '===');
740 });
741 call.on('error', function(err) {
742 assert.strictEqual(err.code, grpc.status.INVALID_ARGUMENT);
743 done();
744 });
745 call.write(badArg);
746 // TODO(mlumish): Remove call.end()
747 call.end();
748 });
749 });
750 describe('Trailing metadata', function() {
751 it('should be present when a unary call succeeds', function(done) {
752 var call = client.unary({error: false}, function(err, data) {
753 assert.ifError(err);
754 });
755 call.on('status', function(status) {
756 assert.deepEqual(status.metadata.get('trailer-present'), ['yes']);
757 done();
758 });
759 });
760 it('should be present when a unary call fails', function(done) {
761 var call = client.unary({error: true}, function(err, data) {
762 assert(err);
763 });
764 call.on('status', function(status) {
765 assert.deepEqual(status.metadata.get('trailer-present'), ['yes']);
766 done();
767 });
768 });
769 it('should be present when a client stream call succeeds', function(done) {
770 var call = client.clientStream(function(err, data) {
771 assert.ifError(err);
772 });
773 call.write({error: false});
774 call.write({error: false});
775 call.end();
776 call.on('status', function(status) {
777 assert.deepEqual(status.metadata.get('trailer-present'), ['yes']);
778 done();
779 });
780 });
781 it('should be present when a client stream call fails', function(done) {
782 var call = client.clientStream(function(err, data) {
783 assert(err);
784 });
785 call.write({error: false});
786 call.write({error: true});
787 call.end();
788 call.on('status', function(status) {
789 assert.deepEqual(status.metadata.get('trailer-present'), ['yes']);
790 done();
791 });
792 });
793 it('should be present when a server stream call succeeds', function(done) {
794 var call = client.serverStream({error: false});
795 call.on('data', function(){});
796 call.on('status', function(status) {
797 assert.strictEqual(status.code, grpc.status.OK);
798 assert.deepEqual(status.metadata.get('trailer-present'), ['yes']);
799 done();
800 });
801 });
802 it('should be present when a server stream call fails', function(done) {
803 var call = client.serverStream({error: true});
804 call.on('data', function(){});
805 call.on('error', function(error) {
806 assert.deepEqual(error.metadata.get('trailer-present'), ['yes']);
807 done();
808 });
809 });
810 it('should be present when a bidi stream succeeds', function(done) {
811 var call = client.bidiStream();
812 call.write({error: false});
813 call.write({error: false});
814 call.end();
815 call.on('data', function(){});
816 call.on('status', function(status) {
817 assert.strictEqual(status.code, grpc.status.OK);
818 assert.deepEqual(status.metadata.get('trailer-present'), ['yes']);
819 done();
820 });
821 });
822 it('should be present when a bidi stream fails', function(done) {
823 var call = client.bidiStream();
824 call.write({error: false});
825 call.write({error: true});
826 call.end();
827 call.on('data', function(){});
828 call.on('error', function(error) {
829 assert.deepEqual(error.metadata.get('trailer-present'), ['yes']);
830 done();
831 });
832 });
833 });
834 describe('Error object should contain the status', function() {
835 it('for a unary call', function(done) {
836 client.unary({error: true}, function(err, data) {
837 assert(err);
838 assert.strictEqual(err.code, grpc.status.UNKNOWN);
839 assert.strictEqual(err.message, 'Requested error');
840 done();
841 });
842 });
843 it('for a client stream call', function(done) {
844 var call = client.clientStream(function(err, data) {
845 assert(err);
846 assert.strictEqual(err.code, grpc.status.UNKNOWN);
847 assert.strictEqual(err.message, 'Requested error');
848 done();
849 });
850 call.write({error: false});
851 call.write({error: true});
852 call.end();
853 });
854 it('for a server stream call', function(done) {
855 var call = client.serverStream({error: true});
856 call.on('data', function(){});
857 call.on('error', function(error) {
858 assert.strictEqual(error.code, grpc.status.UNKNOWN);
859 assert.strictEqual(error.message, 'Requested error');
860 done();
861 });
862 });
863 it('for a bidi stream call', function(done) {
864 var call = client.bidiStream();
865 call.write({error: false});
866 call.write({error: true});
867 call.end();
868 call.on('data', function(){});
869 call.on('error', function(error) {
870 assert.strictEqual(error.code, grpc.status.UNKNOWN);
871 assert.strictEqual(error.message, 'Requested error');
872 done();
873 });
874 });
875 });
876 describe('call.getPeer should return the peer', function() {
877 it('for a unary call', function(done) {
878 var call = client.unary({error: false}, function(err, data) {
879 assert.ifError(err);
880 done();
881 });
882 assert.strictEqual(typeof call.getPeer(), 'string');
883 });
884 it('for a client stream call', function(done) {
885 var call = client.clientStream(function(err, data) {
886 assert.ifError(err);
887 done();
888 });
889 assert.strictEqual(typeof call.getPeer(), 'string');
890 call.write({error: false});
891 call.end();
892 });
893 it('for a server stream call', function(done) {
894 var call = client.serverStream({error: false});
895 assert.strictEqual(typeof call.getPeer(), 'string');
896 call.on('data', function(){});
897 call.on('status', function(status) {
898 assert.strictEqual(status.code, grpc.status.OK);
899 done();
900 });
901 });
902 it('for a bidi stream call', function(done) {
903 var call = client.bidiStream();
904 assert.strictEqual(typeof call.getPeer(), 'string');
905 call.write({error: false});
906 call.end();
907 call.on('data', function(){});
908 call.on('status', function(status) {
909 done();
910 });
911 });
912 });
913 });
914 describe('Call propagation', function() {
915 var proxy;
916 var proxy_impl;
917
918 var test_service;
919 var Client;
920 var client;
921 var server;
922 before(function() {
923 var test_proto = ProtoBuf.loadProtoFile(__dirname + '/test_service.proto');
924 test_service = test_proto.lookup('TestService');
925 server = new grpc.Server();
926 server.addProtoService(test_service, {
927 unary: function(call) {},
928 clientStream: function(stream) {},
929 serverStream: function(stream) {},
930 bidiStream: function(stream) {}
931 });
932 var port = server.bind('localhost:0', server_insecure_creds);
933 Client = surface_client.makeProtobufClientConstructor(test_service);
934 client = new Client('localhost:' + port, grpc.credentials.createInsecure());
935 server.start();
936 });
937 after(function() {
938 server.forceShutdown();
939 });
940 beforeEach(function() {
941 proxy = new grpc.Server();
942 proxy_impl = {
943 unary: function(call) {},
944 clientStream: function(stream) {},
945 serverStream: function(stream) {},
946 bidiStream: function(stream) {}
947 };
948 });
949 afterEach(function() {
950 proxy.forceShutdown();
951 });
952 describe('Cancellation', function() {
953 it('With a unary call', function(done) {
954 done = multiDone(done, 2);
955 var call;
956 proxy_impl.unary = function(parent, callback) {
957 client.unary(parent.request, function(err, value) {
958 try {
959 assert(err);
960 assert.strictEqual(err.code, grpc.status.CANCELLED);
961 } finally {
962 callback(err, value);
963 done();
964 }
965 }, null, {parent: parent});
966 call.cancel();
967 };
968 proxy.addProtoService(test_service, proxy_impl);
969 var proxy_port = proxy.bind('localhost:0', server_insecure_creds);
970 proxy.start();
971 var proxy_client = new Client('localhost:' + proxy_port,
972 grpc.credentials.createInsecure());
973 call = proxy_client.unary({}, function(err, value) { done(); });
974 });
975 it('With a client stream call', function(done) {
976 done = multiDone(done, 2);
977 var call;
978 proxy_impl.clientStream = function(parent, callback) {
979 client.clientStream(function(err, value) {
980 try {
981 assert(err);
982 assert.strictEqual(err.code, grpc.status.CANCELLED);
983 } finally {
984 callback(err, value);
985 done();
986 }
987 }, null, {parent: parent});
988 call.cancel();
989 };
990 proxy.addProtoService(test_service, proxy_impl);
991 var proxy_port = proxy.bind('localhost:0', server_insecure_creds);
992 proxy.start();
993 var proxy_client = new Client('localhost:' + proxy_port,
994 grpc.credentials.createInsecure());
995 call = proxy_client.clientStream(function(err, value) { done(); });
996 });
997 it('With a server stream call', function(done) {
998 done = multiDone(done, 2);
999 var call;
1000 proxy_impl.serverStream = function(parent) {
1001 var child = client.serverStream(parent.request, null,
1002 {parent: parent});
1003 child.on('data', function() {});
1004 child.on('error', function(err) {
1005 assert(err);
1006 assert.strictEqual(err.code, grpc.status.CANCELLED);
1007 done();
1008 });
1009 call.cancel();
1010 };
1011 proxy.addProtoService(test_service, proxy_impl);
1012 var proxy_port = proxy.bind('localhost:0', server_insecure_creds);
1013 proxy.start();
1014 var proxy_client = new Client('localhost:' + proxy_port,
1015 grpc.credentials.createInsecure());
1016 call = proxy_client.serverStream({});
1017 call.on('data', function() {});
1018 call.on('error', function(err) {
1019 done();
1020 });
1021 });
1022 it('With a bidi stream call', function(done) {
1023 done = multiDone(done, 2);
1024 var call;
1025 proxy_impl.bidiStream = function(parent) {
1026 var child = client.bidiStream(null, {parent: parent});
1027 child.on('data', function() {});
1028 child.on('error', function(err) {
1029 assert(err);
1030 assert.strictEqual(err.code, grpc.status.CANCELLED);
1031 done();
1032 });
1033 call.cancel();
1034 };
1035 proxy.addProtoService(test_service, proxy_impl);
1036 var proxy_port = proxy.bind('localhost:0', server_insecure_creds);
1037 proxy.start();
1038 var proxy_client = new Client('localhost:' + proxy_port,
1039 grpc.credentials.createInsecure());
1040 call = proxy_client.bidiStream();
1041 call.on('data', function() {});
1042 call.on('error', function(err) {
1043 done();
1044 });
1045 });
1046 });
1047 describe('Deadline', function() {
1048 /* jshint bitwise:false */
1049 var deadline_flags = (grpc.propagate.DEFAULTS &
1050 ~grpc.propagate.CANCELLATION);
1051 it('With a client stream call', function(done) {
1052 done = multiDone(done, 2);
1053 proxy_impl.clientStream = function(parent, callback) {
1054 client.clientStream(function(err, value) {
1055 try {
1056 assert(err);
1057 assert(err.code === grpc.status.DEADLINE_EXCEEDED ||
1058 err.code === grpc.status.INTERNAL);
1059 } finally {
1060 callback(err, value);
1061 done();
1062 }
1063 }, null, {parent: parent, propagate_flags: deadline_flags});
1064 };
1065 proxy.addProtoService(test_service, proxy_impl);
1066 var proxy_port = proxy.bind('localhost:0', server_insecure_creds);
1067 proxy.start();
1068 var proxy_client = new Client('localhost:' + proxy_port,
1069 grpc.credentials.createInsecure());
1070 var deadline = new Date();
1071 deadline.setSeconds(deadline.getSeconds() + 1);
1072 proxy_client.clientStream(function(err, value) {
1073 done();
1074 }, null, {deadline: deadline});
1075 });
1076 it('With a bidi stream call', function(done) {
1077 done = multiDone(done, 2);
1078 proxy_impl.bidiStream = function(parent) {
1079 var child = client.bidiStream(
1080 null, {parent: parent, propagate_flags: deadline_flags});
1081 child.on('data', function() {});
1082 child.on('error', function(err) {
1083 assert(err);
1084 assert(err.code === grpc.status.DEADLINE_EXCEEDED ||
1085 err.code === grpc.status.INTERNAL);
1086 done();
1087 });
1088 };
1089 proxy.addProtoService(test_service, proxy_impl);
1090 var proxy_port = proxy.bind('localhost:0', server_insecure_creds);
1091 proxy.start();
1092 var proxy_client = new Client('localhost:' + proxy_port,
1093 grpc.credentials.createInsecure());
1094 var deadline = new Date();
1095 deadline.setSeconds(deadline.getSeconds() + 1);
1096 var call = proxy_client.bidiStream(null, {deadline: deadline});
1097 call.on('data', function() {});
1098 call.on('error', function(err) {
1099 done();
1100 });
1101 });
1102 });
1103 });
1104 describe('Cancelling surface client', function() {
1105 var client;
1106 var server;
1107 before(function() {
1108 server = new grpc.Server();
1109 server.addProtoService(mathService, {
1110 'div': function(stream) {},
1111 'divMany': function(stream) {},
1112 'fib': function(stream) {},
1113 'sum': function(stream) {}
1114 });
1115 var port = server.bind('localhost:0', server_insecure_creds);
1116 var Client = surface_client.makeProtobufClientConstructor(mathService);
1117 client = new Client('localhost:' + port, grpc.credentials.createInsecure());
1118 server.start();
1119 });
1120 after(function() {
1121 server.forceShutdown();
1122 });
1123 it('Should correctly cancel a unary call', function(done) {
1124 var call = client.div({'divisor': 0, 'dividend': 0}, function(err, resp) {
1125 assert.strictEqual(err.code, surface_client.status.CANCELLED);
1126 done();
1127 });
1128 call.cancel();
1129 });
1130 it('Should correctly cancel a client stream call', function(done) {
1131 var call = client.sum(function(err, resp) {
1132 assert.strictEqual(err.code, surface_client.status.CANCELLED);
1133 done();
1134 });
1135 call.cancel();
1136 });
1137 it('Should correctly cancel a server stream call', function(done) {
1138 var call = client.fib({'limit': 5});
1139 call.on('data', function() {});
1140 call.on('error', function(error) {
1141 assert.strictEqual(error.code, surface_client.status.CANCELLED);
1142 done();
1143 });
1144 call.cancel();
1145 });
1146 it('Should correctly cancel a bidi stream call', function(done) {
1147 var call = client.divMany();
1148 call.on('data', function() {});
1149 call.on('error', function(error) {
1150 assert.strictEqual(error.code, surface_client.status.CANCELLED);
1151 done();
1152 });
1153 call.cancel();
1154 });
1155 });
OLDNEW
« no previous file with comments | « third_party/grpc/src/node/test/server_test.js ('k') | third_party/grpc/src/node/test/test_messages.proto » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698