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

Unified 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, 8 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 side-by-side diff with in-line comments
Download patch
« 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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/grpc/src/node/test/surface_test.js
diff --git a/third_party/grpc/src/node/test/surface_test.js b/third_party/grpc/src/node/test/surface_test.js
new file mode 100644
index 0000000000000000000000000000000000000000..8a232d6fc44a1ba9c4e89df5891b0d87ce6832d8
--- /dev/null
+++ b/third_party/grpc/src/node/test/surface_test.js
@@ -0,0 +1,1155 @@
+/*
+ *
+ * Copyright 2015-2016, 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.
+ *
+ */
+
+'use strict';
+
+var assert = require('assert');
+
+var surface_client = require('../src/client.js');
+
+var ProtoBuf = require('protobufjs');
+
+var grpc = require('..');
+
+var math_proto = ProtoBuf.loadProtoFile(__dirname +
+ '/../../proto/math/math.proto');
+
+var mathService = math_proto.lookup('math.Math');
+
+var _ = require('lodash');
+
+/**
+ * This is used for testing functions with multiple asynchronous calls that
+ * can happen in different orders. This should be passed the number of async
+ * function invocations that can occur last, and each of those should call this
+ * function's return value
+ * @param {function()} done The function that should be called when a test is
+ * complete.
+ * @param {number} count The number of calls to the resulting function if the
+ * test passes.
+ * @return {function()} The function that should be called at the end of each
+ * sequence of asynchronous functions.
+ */
+function multiDone(done, count) {
+ return function() {
+ count -= 1;
+ if (count <= 0) {
+ done();
+ }
+ };
+}
+
+var server_insecure_creds = grpc.ServerCredentials.createInsecure();
+
+describe('File loader', function() {
+ it('Should load a proto file by default', function() {
+ assert.doesNotThrow(function() {
+ grpc.load(__dirname + '/test_service.proto');
+ });
+ });
+ it('Should load a proto file with the proto format', function() {
+ assert.doesNotThrow(function() {
+ grpc.load(__dirname + '/test_service.proto', 'proto');
+ });
+ });
+ it('Should load a json file with the json format', function() {
+ assert.doesNotThrow(function() {
+ grpc.load(__dirname + '/test_service.json', 'json');
+ });
+ });
+ it('Should fail to load a file with an unknown format', function() {
+ assert.throws(function() {
+ grpc.load(__dirname + '/test_service.proto', 'fake_format');
+ });
+ });
+});
+describe('surface Server', function() {
+ var server;
+ beforeEach(function() {
+ server = new grpc.Server();
+ });
+ afterEach(function() {
+ server.forceShutdown();
+ });
+ it('should error if started twice', function() {
+ server.start();
+ assert.throws(function() {
+ server.start();
+ });
+ });
+ it('should error if a port is bound after the server starts', function() {
+ server.start();
+ assert.throws(function() {
+ server.bind('localhost:0', grpc.ServerCredentials.createInsecure());
+ });
+ });
+ it('should successfully shutdown if tryShutdown is called', function(done) {
+ server.start();
+ server.tryShutdown(done);
+ });
+});
+describe('Server.prototype.addProtoService', function() {
+ var server;
+ var dummyImpls = {
+ 'div': function() {},
+ 'divMany': function() {},
+ 'fib': function() {},
+ 'sum': function() {}
+ };
+ beforeEach(function() {
+ server = new grpc.Server();
+ });
+ afterEach(function() {
+ server.forceShutdown();
+ });
+ it('Should succeed with a single service', function() {
+ assert.doesNotThrow(function() {
+ server.addProtoService(mathService, dummyImpls);
+ });
+ });
+ it('Should fail with conflicting method names', function() {
+ server.addProtoService(mathService, dummyImpls);
+ assert.throws(function() {
+ server.addProtoService(mathService, dummyImpls);
+ });
+ });
+ it('Should fail with missing handlers', function() {
+ assert.throws(function() {
+ server.addProtoService(mathService, {
+ 'div': function() {},
+ 'divMany': function() {},
+ 'fib': function() {}
+ });
+ }, /math.Math.Sum/);
+ });
+ it('Should fail if the server has been started', function() {
+ server.start();
+ assert.throws(function() {
+ server.addProtoService(mathService, dummyImpls);
+ });
+ });
+});
+describe('Client constructor building', function() {
+ var illegal_service_attrs = {
+ $method : {
+ path: '/illegal/$method',
+ requestStream: false,
+ responseStream: false,
+ requestSerialize: _.identity,
+ requestDeserialize: _.identity,
+ responseSerialize: _.identity,
+ responseDeserialize: _.identity
+ }
+ };
+ it('Should reject method names starting with $', function() {
+ assert.throws(function() {
+ grpc.makeGenericClientConstructor(illegal_service_attrs);
+ }, /\$/);
+ });
+});
+describe('waitForClientReady', function() {
+ var server;
+ var port;
+ var Client;
+ var client;
+ before(function() {
+ server = new grpc.Server();
+ port = server.bind('localhost:0', grpc.ServerCredentials.createInsecure());
+ server.start();
+ Client = surface_client.makeProtobufClientConstructor(mathService);
+ });
+ beforeEach(function() {
+ client = new Client('localhost:' + port, grpc.credentials.createInsecure());
+ });
+ after(function() {
+ server.forceShutdown();
+ });
+ it('should complete when called alone', function(done) {
+ grpc.waitForClientReady(client, Infinity, function(error) {
+ assert.ifError(error);
+ done();
+ });
+ });
+ it('should complete when a call is initiated', function(done) {
+ grpc.waitForClientReady(client, Infinity, function(error) {
+ assert.ifError(error);
+ done();
+ });
+ var call = client.div({}, function(err, response) {});
+ call.cancel();
+ });
+ it('should complete if called more than once', function(done) {
+ done = multiDone(done, 2);
+ grpc.waitForClientReady(client, Infinity, function(error) {
+ assert.ifError(error);
+ done();
+ });
+ grpc.waitForClientReady(client, Infinity, function(error) {
+ assert.ifError(error);
+ done();
+ });
+ });
+ it('should complete if called when already ready', function(done) {
+ grpc.waitForClientReady(client, Infinity, function(error) {
+ assert.ifError(error);
+ grpc.waitForClientReady(client, Infinity, function(error) {
+ assert.ifError(error);
+ done();
+ });
+ });
+ });
+ it('should time out if the server does not exist', function(done) {
+ var bad_client = new Client('nonexistent_hostname',
+ grpc.credentials.createInsecure());
+ var deadline = new Date();
+ deadline.setSeconds(deadline.getSeconds() + 1);
+ grpc.waitForClientReady(bad_client, deadline, function(error) {
+ assert(error);
+ done();
+ });
+ });
+});
+describe('Echo service', function() {
+ var server;
+ var client;
+ before(function() {
+ var test_proto = ProtoBuf.loadProtoFile(__dirname + '/echo_service.proto');
+ var echo_service = test_proto.lookup('EchoService');
+ server = new grpc.Server();
+ server.addProtoService(echo_service, {
+ echo: function(call, callback) {
+ callback(null, call.request);
+ }
+ });
+ var port = server.bind('localhost:0', server_insecure_creds);
+ var Client = surface_client.makeProtobufClientConstructor(echo_service);
+ client = new Client('localhost:' + port, grpc.credentials.createInsecure());
+ server.start();
+ });
+ after(function() {
+ server.forceShutdown();
+ });
+ it('should echo the recieved message directly', function(done) {
+ client.echo({value: 'test value', value2: 3}, function(error, response) {
+ assert.ifError(error);
+ assert.deepEqual(response, {value: 'test value', value2: 3});
+ done();
+ });
+ });
+});
+describe('Generic client and server', function() {
+ function toString(val) {
+ return val.toString();
+ }
+ function toBuffer(str) {
+ return new Buffer(str);
+ }
+ var string_service_attrs = {
+ 'capitalize' : {
+ path: '/string/capitalize',
+ requestStream: false,
+ responseStream: false,
+ requestSerialize: toBuffer,
+ requestDeserialize: toString,
+ responseSerialize: toBuffer,
+ responseDeserialize: toString
+ }
+ };
+ describe('String client and server', function() {
+ var client;
+ var server;
+ before(function() {
+ server = new grpc.Server();
+ server.addService(string_service_attrs, {
+ capitalize: function(call, callback) {
+ callback(null, _.capitalize(call.request));
+ }
+ });
+ var port = server.bind('localhost:0', server_insecure_creds);
+ server.start();
+ var Client = grpc.makeGenericClientConstructor(string_service_attrs);
+ client = new Client('localhost:' + port,
+ grpc.credentials.createInsecure());
+ });
+ after(function() {
+ server.forceShutdown();
+ });
+ it('Should respond with a capitalized string', function(done) {
+ client.capitalize('abc', function(err, response) {
+ assert.ifError(err);
+ assert.strictEqual(response, 'Abc');
+ done();
+ });
+ });
+ });
+});
+describe('Server-side getPeer', function() {
+ function toString(val) {
+ return val.toString();
+ }
+ function toBuffer(str) {
+ return new Buffer(str);
+ }
+ var string_service_attrs = {
+ 'getPeer' : {
+ path: '/string/getPeer',
+ requestStream: false,
+ responseStream: false,
+ requestSerialize: toBuffer,
+ requestDeserialize: toString,
+ responseSerialize: toBuffer,
+ responseDeserialize: toString
+ }
+ };
+ var client;
+ var server;
+ before(function() {
+ server = new grpc.Server();
+ server.addService(string_service_attrs, {
+ getPeer: function(call, callback) {
+ try {
+ callback(null, call.getPeer());
+ } catch (e) {
+ call.emit('error', e);
+ }
+ }
+ });
+ var port = server.bind('localhost:0', server_insecure_creds);
+ server.start();
+ var Client = grpc.makeGenericClientConstructor(string_service_attrs);
+ client = new Client('localhost:' + port,
+ grpc.credentials.createInsecure());
+ });
+ after(function() {
+ server.forceShutdown();
+ });
+ it('should respond with a string representing the client', function(done) {
+ client.getPeer('', function(err, response) {
+ assert.ifError(err);
+ // We don't expect a specific value, just that it worked without error
+ done();
+ });
+ });
+});
+describe('Echo metadata', function() {
+ var client;
+ var server;
+ var metadata;
+ before(function() {
+ var test_proto = ProtoBuf.loadProtoFile(__dirname + '/test_service.proto');
+ var test_service = test_proto.lookup('TestService');
+ server = new grpc.Server();
+ server.addProtoService(test_service, {
+ unary: function(call, cb) {
+ call.sendMetadata(call.metadata);
+ cb(null, {});
+ },
+ clientStream: function(stream, cb){
+ stream.on('data', function(data) {});
+ stream.on('end', function() {
+ stream.sendMetadata(stream.metadata);
+ cb(null, {});
+ });
+ },
+ serverStream: function(stream) {
+ stream.sendMetadata(stream.metadata);
+ stream.end();
+ },
+ bidiStream: function(stream) {
+ stream.on('data', function(data) {});
+ stream.on('end', function() {
+ stream.sendMetadata(stream.metadata);
+ stream.end();
+ });
+ }
+ });
+ var port = server.bind('localhost:0', server_insecure_creds);
+ var Client = surface_client.makeProtobufClientConstructor(test_service);
+ client = new Client('localhost:' + port, grpc.credentials.createInsecure());
+ server.start();
+ metadata = new grpc.Metadata();
+ metadata.set('key', 'value');
+ });
+ after(function() {
+ server.forceShutdown();
+ });
+ it('with unary call', function(done) {
+ var call = client.unary({}, function(err, data) {
+ assert.ifError(err);
+ }, metadata);
+ call.on('metadata', function(metadata) {
+ assert.deepEqual(metadata.get('key'), ['value']);
+ done();
+ });
+ });
+ it('with client stream call', function(done) {
+ var call = client.clientStream(function(err, data) {
+ assert.ifError(err);
+ }, metadata);
+ call.on('metadata', function(metadata) {
+ assert.deepEqual(metadata.get('key'), ['value']);
+ done();
+ });
+ call.end();
+ });
+ it('with server stream call', function(done) {
+ var call = client.serverStream({}, metadata);
+ call.on('data', function() {});
+ call.on('metadata', function(metadata) {
+ assert.deepEqual(metadata.get('key'), ['value']);
+ done();
+ });
+ });
+ it('with bidi stream call', function(done) {
+ var call = client.bidiStream(metadata);
+ call.on('data', function() {});
+ call.on('metadata', function(metadata) {
+ assert.deepEqual(metadata.get('key'), ['value']);
+ done();
+ });
+ call.end();
+ });
+ it('shows the correct user-agent string', function(done) {
+ var version = require('../../../package.json').version;
+ var call = client.unary({}, function(err, data) { assert.ifError(err); },
+ metadata);
+ call.on('metadata', function(metadata) {
+ assert(_.startsWith(metadata.get('user-agent')[0],
+ 'grpc-node/' + version));
+ done();
+ });
+ });
+ it('properly handles duplicate values', function(done) {
+ var dup_metadata = metadata.clone();
+ dup_metadata.add('key', 'value2');
+ var call = client.unary({}, function(err, data) {assert.ifError(err); },
+ dup_metadata);
+ call.on('metadata', function(resp_metadata) {
+ // Two arrays are equal iff their symmetric difference is empty
+ assert.deepEqual(_.xor(dup_metadata.get('key'), resp_metadata.get('key')),
+ []);
+ done();
+ });
+ });
+});
+describe('Client malformed response handling', function() {
+ var server;
+ var client;
+ var badArg = new Buffer([0xFF]);
+ before(function() {
+ var test_proto = ProtoBuf.loadProtoFile(__dirname + '/test_service.proto');
+ var test_service = test_proto.lookup('TestService');
+ var malformed_test_service = {
+ unary: {
+ path: '/TestService/Unary',
+ requestStream: false,
+ responseStream: false,
+ requestDeserialize: _.identity,
+ responseSerialize: _.identity
+ },
+ clientStream: {
+ path: '/TestService/ClientStream',
+ requestStream: true,
+ responseStream: false,
+ requestDeserialize: _.identity,
+ responseSerialize: _.identity
+ },
+ serverStream: {
+ path: '/TestService/ServerStream',
+ requestStream: false,
+ responseStream: true,
+ requestDeserialize: _.identity,
+ responseSerialize: _.identity
+ },
+ bidiStream: {
+ path: '/TestService/BidiStream',
+ requestStream: true,
+ responseStream: true,
+ requestDeserialize: _.identity,
+ responseSerialize: _.identity
+ }
+ };
+ server = new grpc.Server();
+ server.addService(malformed_test_service, {
+ unary: function(call, cb) {
+ cb(null, badArg);
+ },
+ clientStream: function(stream, cb) {
+ stream.on('data', function() {/* Ignore requests */});
+ stream.on('end', function() {
+ cb(null, badArg);
+ });
+ },
+ serverStream: function(stream) {
+ stream.write(badArg);
+ stream.end();
+ },
+ bidiStream: function(stream) {
+ stream.on('data', function() {
+ // Ignore requests
+ stream.write(badArg);
+ });
+ stream.on('end', function() {
+ stream.end();
+ });
+ }
+ });
+ var port = server.bind('localhost:0', server_insecure_creds);
+ var Client = surface_client.makeProtobufClientConstructor(test_service);
+ client = new Client('localhost:' + port, grpc.credentials.createInsecure());
+ server.start();
+ });
+ after(function() {
+ server.forceShutdown();
+ });
+ it('should get an INTERNAL status with a unary call', function(done) {
+ client.unary({}, function(err, data) {
+ assert(err);
+ assert.strictEqual(err.code, grpc.status.INTERNAL);
+ done();
+ });
+ });
+ it('should get an INTERNAL status with a client stream call', function(done) {
+ var call = client.clientStream(function(err, data) {
+ assert(err);
+ assert.strictEqual(err.code, grpc.status.INTERNAL);
+ done();
+ });
+ call.write({});
+ call.end();
+ });
+ it('should get an INTERNAL status with a server stream call', function(done) {
+ var call = client.serverStream({});
+ call.on('data', function(){});
+ call.on('error', function(err) {
+ assert.strictEqual(err.code, grpc.status.INTERNAL);
+ done();
+ });
+ });
+ it('should get an INTERNAL status with a bidi stream call', function(done) {
+ var call = client.bidiStream();
+ call.on('data', function(){});
+ call.on('error', function(err) {
+ assert.strictEqual(err.code, grpc.status.INTERNAL);
+ done();
+ });
+ call.write({});
+ call.end();
+ });
+});
+describe('Other conditions', function() {
+ var test_service;
+ var Client;
+ var client;
+ var server;
+ var port;
+ before(function() {
+ var test_proto = ProtoBuf.loadProtoFile(__dirname + '/test_service.proto');
+ test_service = test_proto.lookup('TestService');
+ server = new grpc.Server();
+ var trailer_metadata = new grpc.Metadata();
+ trailer_metadata.add('trailer-present', 'yes');
+ server.addProtoService(test_service, {
+ unary: function(call, cb) {
+ var req = call.request;
+ if (req.error) {
+ cb({code: grpc.status.UNKNOWN,
+ details: 'Requested error'}, null, trailer_metadata);
+ } else {
+ cb(null, {count: 1}, trailer_metadata);
+ }
+ },
+ clientStream: function(stream, cb){
+ var count = 0;
+ var errored;
+ stream.on('data', function(data) {
+ if (data.error) {
+ errored = true;
+ cb(new Error('Requested error'), null, trailer_metadata);
+ } else {
+ count += 1;
+ }
+ });
+ stream.on('end', function() {
+ if (!errored) {
+ cb(null, {count: count}, trailer_metadata);
+ }
+ });
+ },
+ serverStream: function(stream) {
+ var req = stream.request;
+ if (req.error) {
+ var err = {code: grpc.status.UNKNOWN,
+ details: 'Requested error'};
+ err.metadata = trailer_metadata;
+ stream.emit('error', err);
+ } else {
+ for (var i = 0; i < 5; i++) {
+ stream.write({count: i});
+ }
+ stream.end(trailer_metadata);
+ }
+ },
+ bidiStream: function(stream) {
+ var count = 0;
+ stream.on('data', function(data) {
+ if (data.error) {
+ var err = new Error('Requested error');
+ err.metadata = trailer_metadata.clone();
+ err.metadata.add('count', '' + count);
+ stream.emit('error', err);
+ } else {
+ stream.write({count: count});
+ count += 1;
+ }
+ });
+ stream.on('end', function() {
+ stream.end(trailer_metadata);
+ });
+ }
+ });
+ port = server.bind('localhost:0', server_insecure_creds);
+ Client = surface_client.makeProtobufClientConstructor(test_service);
+ client = new Client('localhost:' + port, grpc.credentials.createInsecure());
+ server.start();
+ });
+ after(function() {
+ server.forceShutdown();
+ });
+ it('channel.getTarget should be available', function() {
+ assert.strictEqual(typeof grpc.getClientChannel(client).getTarget(),
+ 'string');
+ });
+ it('client should be able to pause and resume a stream', function(done) {
+ var call = client.bidiStream();
+ call.on('data', function(data) {
+ assert(data.count < 3);
+ call.pause();
+ setTimeout(function() {
+ call.resume();
+ }, 10);
+ });
+ call.on('end', function() {
+ done();
+ });
+ call.write({});
+ call.write({});
+ call.write({});
+ call.end();
+ });
+ describe('Server recieving bad input', function() {
+ var misbehavingClient;
+ var badArg = new Buffer([0xFF]);
+ before(function() {
+ var test_service_attrs = {
+ unary: {
+ path: '/TestService/Unary',
+ requestStream: false,
+ responseStream: false,
+ requestSerialize: _.identity,
+ responseDeserialize: _.identity
+ },
+ clientStream: {
+ path: '/TestService/ClientStream',
+ requestStream: true,
+ responseStream: false,
+ requestSerialize: _.identity,
+ responseDeserialize: _.identity
+ },
+ serverStream: {
+ path: '/TestService/ServerStream',
+ requestStream: false,
+ responseStream: true,
+ requestSerialize: _.identity,
+ responseDeserialize: _.identity
+ },
+ bidiStream: {
+ path: '/TestService/BidiStream',
+ requestStream: true,
+ responseStream: true,
+ requestSerialize: _.identity,
+ responseDeserialize: _.identity
+ }
+ };
+ var Client = surface_client.makeClientConstructor(test_service_attrs,
+ 'TestService');
+ misbehavingClient = new Client('localhost:' + port,
+ grpc.credentials.createInsecure());
+ });
+ it('should respond correctly to a unary call', function(done) {
+ misbehavingClient.unary(badArg, function(err, data) {
+ assert(err);
+ assert.strictEqual(err.code, grpc.status.INVALID_ARGUMENT);
+ done();
+ });
+ });
+ it('should respond correctly to a client stream', function(done) {
+ var call = misbehavingClient.clientStream(function(err, data) {
+ assert(err);
+ assert.strictEqual(err.code, grpc.status.INVALID_ARGUMENT);
+ done();
+ });
+ call.write(badArg);
+ // TODO(mlumish): Remove call.end()
+ call.end();
+ });
+ it('should respond correctly to a server stream', function(done) {
+ var call = misbehavingClient.serverStream(badArg);
+ call.on('data', function(data) {
+ assert.fail(data, null, 'Unexpected data', '===');
+ });
+ call.on('error', function(err) {
+ assert.strictEqual(err.code, grpc.status.INVALID_ARGUMENT);
+ done();
+ });
+ });
+ it('should respond correctly to a bidi stream', function(done) {
+ var call = misbehavingClient.bidiStream();
+ call.on('data', function(data) {
+ assert.fail(data, null, 'Unexpected data', '===');
+ });
+ call.on('error', function(err) {
+ assert.strictEqual(err.code, grpc.status.INVALID_ARGUMENT);
+ done();
+ });
+ call.write(badArg);
+ // TODO(mlumish): Remove call.end()
+ call.end();
+ });
+ });
+ describe('Trailing metadata', function() {
+ it('should be present when a unary call succeeds', function(done) {
+ var call = client.unary({error: false}, function(err, data) {
+ assert.ifError(err);
+ });
+ call.on('status', function(status) {
+ assert.deepEqual(status.metadata.get('trailer-present'), ['yes']);
+ done();
+ });
+ });
+ it('should be present when a unary call fails', function(done) {
+ var call = client.unary({error: true}, function(err, data) {
+ assert(err);
+ });
+ call.on('status', function(status) {
+ assert.deepEqual(status.metadata.get('trailer-present'), ['yes']);
+ done();
+ });
+ });
+ it('should be present when a client stream call succeeds', function(done) {
+ var call = client.clientStream(function(err, data) {
+ assert.ifError(err);
+ });
+ call.write({error: false});
+ call.write({error: false});
+ call.end();
+ call.on('status', function(status) {
+ assert.deepEqual(status.metadata.get('trailer-present'), ['yes']);
+ done();
+ });
+ });
+ it('should be present when a client stream call fails', function(done) {
+ var call = client.clientStream(function(err, data) {
+ assert(err);
+ });
+ call.write({error: false});
+ call.write({error: true});
+ call.end();
+ call.on('status', function(status) {
+ assert.deepEqual(status.metadata.get('trailer-present'), ['yes']);
+ done();
+ });
+ });
+ it('should be present when a server stream call succeeds', function(done) {
+ var call = client.serverStream({error: false});
+ call.on('data', function(){});
+ call.on('status', function(status) {
+ assert.strictEqual(status.code, grpc.status.OK);
+ assert.deepEqual(status.metadata.get('trailer-present'), ['yes']);
+ done();
+ });
+ });
+ it('should be present when a server stream call fails', function(done) {
+ var call = client.serverStream({error: true});
+ call.on('data', function(){});
+ call.on('error', function(error) {
+ assert.deepEqual(error.metadata.get('trailer-present'), ['yes']);
+ done();
+ });
+ });
+ it('should be present when a bidi stream succeeds', function(done) {
+ var call = client.bidiStream();
+ call.write({error: false});
+ call.write({error: false});
+ call.end();
+ call.on('data', function(){});
+ call.on('status', function(status) {
+ assert.strictEqual(status.code, grpc.status.OK);
+ assert.deepEqual(status.metadata.get('trailer-present'), ['yes']);
+ done();
+ });
+ });
+ it('should be present when a bidi stream fails', function(done) {
+ var call = client.bidiStream();
+ call.write({error: false});
+ call.write({error: true});
+ call.end();
+ call.on('data', function(){});
+ call.on('error', function(error) {
+ assert.deepEqual(error.metadata.get('trailer-present'), ['yes']);
+ done();
+ });
+ });
+ });
+ describe('Error object should contain the status', function() {
+ it('for a unary call', function(done) {
+ client.unary({error: true}, function(err, data) {
+ assert(err);
+ assert.strictEqual(err.code, grpc.status.UNKNOWN);
+ assert.strictEqual(err.message, 'Requested error');
+ done();
+ });
+ });
+ it('for a client stream call', function(done) {
+ var call = client.clientStream(function(err, data) {
+ assert(err);
+ assert.strictEqual(err.code, grpc.status.UNKNOWN);
+ assert.strictEqual(err.message, 'Requested error');
+ done();
+ });
+ call.write({error: false});
+ call.write({error: true});
+ call.end();
+ });
+ it('for a server stream call', function(done) {
+ var call = client.serverStream({error: true});
+ call.on('data', function(){});
+ call.on('error', function(error) {
+ assert.strictEqual(error.code, grpc.status.UNKNOWN);
+ assert.strictEqual(error.message, 'Requested error');
+ done();
+ });
+ });
+ it('for a bidi stream call', function(done) {
+ var call = client.bidiStream();
+ call.write({error: false});
+ call.write({error: true});
+ call.end();
+ call.on('data', function(){});
+ call.on('error', function(error) {
+ assert.strictEqual(error.code, grpc.status.UNKNOWN);
+ assert.strictEqual(error.message, 'Requested error');
+ done();
+ });
+ });
+ });
+ describe('call.getPeer should return the peer', function() {
+ it('for a unary call', function(done) {
+ var call = client.unary({error: false}, function(err, data) {
+ assert.ifError(err);
+ done();
+ });
+ assert.strictEqual(typeof call.getPeer(), 'string');
+ });
+ it('for a client stream call', function(done) {
+ var call = client.clientStream(function(err, data) {
+ assert.ifError(err);
+ done();
+ });
+ assert.strictEqual(typeof call.getPeer(), 'string');
+ call.write({error: false});
+ call.end();
+ });
+ it('for a server stream call', function(done) {
+ var call = client.serverStream({error: false});
+ assert.strictEqual(typeof call.getPeer(), 'string');
+ call.on('data', function(){});
+ call.on('status', function(status) {
+ assert.strictEqual(status.code, grpc.status.OK);
+ done();
+ });
+ });
+ it('for a bidi stream call', function(done) {
+ var call = client.bidiStream();
+ assert.strictEqual(typeof call.getPeer(), 'string');
+ call.write({error: false});
+ call.end();
+ call.on('data', function(){});
+ call.on('status', function(status) {
+ done();
+ });
+ });
+ });
+});
+describe('Call propagation', function() {
+ var proxy;
+ var proxy_impl;
+
+ var test_service;
+ var Client;
+ var client;
+ var server;
+ before(function() {
+ var test_proto = ProtoBuf.loadProtoFile(__dirname + '/test_service.proto');
+ test_service = test_proto.lookup('TestService');
+ server = new grpc.Server();
+ server.addProtoService(test_service, {
+ unary: function(call) {},
+ clientStream: function(stream) {},
+ serverStream: function(stream) {},
+ bidiStream: function(stream) {}
+ });
+ var port = server.bind('localhost:0', server_insecure_creds);
+ Client = surface_client.makeProtobufClientConstructor(test_service);
+ client = new Client('localhost:' + port, grpc.credentials.createInsecure());
+ server.start();
+ });
+ after(function() {
+ server.forceShutdown();
+ });
+ beforeEach(function() {
+ proxy = new grpc.Server();
+ proxy_impl = {
+ unary: function(call) {},
+ clientStream: function(stream) {},
+ serverStream: function(stream) {},
+ bidiStream: function(stream) {}
+ };
+ });
+ afterEach(function() {
+ proxy.forceShutdown();
+ });
+ describe('Cancellation', function() {
+ it('With a unary call', function(done) {
+ done = multiDone(done, 2);
+ var call;
+ proxy_impl.unary = function(parent, callback) {
+ client.unary(parent.request, function(err, value) {
+ try {
+ assert(err);
+ assert.strictEqual(err.code, grpc.status.CANCELLED);
+ } finally {
+ callback(err, value);
+ done();
+ }
+ }, null, {parent: parent});
+ call.cancel();
+ };
+ proxy.addProtoService(test_service, proxy_impl);
+ var proxy_port = proxy.bind('localhost:0', server_insecure_creds);
+ proxy.start();
+ var proxy_client = new Client('localhost:' + proxy_port,
+ grpc.credentials.createInsecure());
+ call = proxy_client.unary({}, function(err, value) { done(); });
+ });
+ it('With a client stream call', function(done) {
+ done = multiDone(done, 2);
+ var call;
+ proxy_impl.clientStream = function(parent, callback) {
+ client.clientStream(function(err, value) {
+ try {
+ assert(err);
+ assert.strictEqual(err.code, grpc.status.CANCELLED);
+ } finally {
+ callback(err, value);
+ done();
+ }
+ }, null, {parent: parent});
+ call.cancel();
+ };
+ proxy.addProtoService(test_service, proxy_impl);
+ var proxy_port = proxy.bind('localhost:0', server_insecure_creds);
+ proxy.start();
+ var proxy_client = new Client('localhost:' + proxy_port,
+ grpc.credentials.createInsecure());
+ call = proxy_client.clientStream(function(err, value) { done(); });
+ });
+ it('With a server stream call', function(done) {
+ done = multiDone(done, 2);
+ var call;
+ proxy_impl.serverStream = function(parent) {
+ var child = client.serverStream(parent.request, null,
+ {parent: parent});
+ child.on('data', function() {});
+ child.on('error', function(err) {
+ assert(err);
+ assert.strictEqual(err.code, grpc.status.CANCELLED);
+ done();
+ });
+ call.cancel();
+ };
+ proxy.addProtoService(test_service, proxy_impl);
+ var proxy_port = proxy.bind('localhost:0', server_insecure_creds);
+ proxy.start();
+ var proxy_client = new Client('localhost:' + proxy_port,
+ grpc.credentials.createInsecure());
+ call = proxy_client.serverStream({});
+ call.on('data', function() {});
+ call.on('error', function(err) {
+ done();
+ });
+ });
+ it('With a bidi stream call', function(done) {
+ done = multiDone(done, 2);
+ var call;
+ proxy_impl.bidiStream = function(parent) {
+ var child = client.bidiStream(null, {parent: parent});
+ child.on('data', function() {});
+ child.on('error', function(err) {
+ assert(err);
+ assert.strictEqual(err.code, grpc.status.CANCELLED);
+ done();
+ });
+ call.cancel();
+ };
+ proxy.addProtoService(test_service, proxy_impl);
+ var proxy_port = proxy.bind('localhost:0', server_insecure_creds);
+ proxy.start();
+ var proxy_client = new Client('localhost:' + proxy_port,
+ grpc.credentials.createInsecure());
+ call = proxy_client.bidiStream();
+ call.on('data', function() {});
+ call.on('error', function(err) {
+ done();
+ });
+ });
+ });
+ describe('Deadline', function() {
+ /* jshint bitwise:false */
+ var deadline_flags = (grpc.propagate.DEFAULTS &
+ ~grpc.propagate.CANCELLATION);
+ it('With a client stream call', function(done) {
+ done = multiDone(done, 2);
+ proxy_impl.clientStream = function(parent, callback) {
+ client.clientStream(function(err, value) {
+ try {
+ assert(err);
+ assert(err.code === grpc.status.DEADLINE_EXCEEDED ||
+ err.code === grpc.status.INTERNAL);
+ } finally {
+ callback(err, value);
+ done();
+ }
+ }, null, {parent: parent, propagate_flags: deadline_flags});
+ };
+ proxy.addProtoService(test_service, proxy_impl);
+ var proxy_port = proxy.bind('localhost:0', server_insecure_creds);
+ proxy.start();
+ var proxy_client = new Client('localhost:' + proxy_port,
+ grpc.credentials.createInsecure());
+ var deadline = new Date();
+ deadline.setSeconds(deadline.getSeconds() + 1);
+ proxy_client.clientStream(function(err, value) {
+ done();
+ }, null, {deadline: deadline});
+ });
+ it('With a bidi stream call', function(done) {
+ done = multiDone(done, 2);
+ proxy_impl.bidiStream = function(parent) {
+ var child = client.bidiStream(
+ null, {parent: parent, propagate_flags: deadline_flags});
+ child.on('data', function() {});
+ child.on('error', function(err) {
+ assert(err);
+ assert(err.code === grpc.status.DEADLINE_EXCEEDED ||
+ err.code === grpc.status.INTERNAL);
+ done();
+ });
+ };
+ proxy.addProtoService(test_service, proxy_impl);
+ var proxy_port = proxy.bind('localhost:0', server_insecure_creds);
+ proxy.start();
+ var proxy_client = new Client('localhost:' + proxy_port,
+ grpc.credentials.createInsecure());
+ var deadline = new Date();
+ deadline.setSeconds(deadline.getSeconds() + 1);
+ var call = proxy_client.bidiStream(null, {deadline: deadline});
+ call.on('data', function() {});
+ call.on('error', function(err) {
+ done();
+ });
+ });
+ });
+});
+describe('Cancelling surface client', function() {
+ var client;
+ var server;
+ before(function() {
+ server = new grpc.Server();
+ server.addProtoService(mathService, {
+ 'div': function(stream) {},
+ 'divMany': function(stream) {},
+ 'fib': function(stream) {},
+ 'sum': function(stream) {}
+ });
+ var port = server.bind('localhost:0', server_insecure_creds);
+ var Client = surface_client.makeProtobufClientConstructor(mathService);
+ client = new Client('localhost:' + port, grpc.credentials.createInsecure());
+ server.start();
+ });
+ after(function() {
+ server.forceShutdown();
+ });
+ it('Should correctly cancel a unary call', function(done) {
+ var call = client.div({'divisor': 0, 'dividend': 0}, function(err, resp) {
+ assert.strictEqual(err.code, surface_client.status.CANCELLED);
+ done();
+ });
+ call.cancel();
+ });
+ it('Should correctly cancel a client stream call', function(done) {
+ var call = client.sum(function(err, resp) {
+ assert.strictEqual(err.code, surface_client.status.CANCELLED);
+ done();
+ });
+ call.cancel();
+ });
+ it('Should correctly cancel a server stream call', function(done) {
+ var call = client.fib({'limit': 5});
+ call.on('data', function() {});
+ call.on('error', function(error) {
+ assert.strictEqual(error.code, surface_client.status.CANCELLED);
+ done();
+ });
+ call.cancel();
+ });
+ it('Should correctly cancel a bidi stream call', function(done) {
+ var call = client.divMany();
+ call.on('data', function() {});
+ call.on('error', function(error) {
+ assert.strictEqual(error.code, surface_client.status.CANCELLED);
+ done();
+ });
+ call.cancel();
+ });
+});
« 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