diff options
Diffstat (limited to 'src/node/test/surface_test.js')
-rw-r--r-- | src/node/test/surface_test.js | 1424 |
1 files changed, 0 insertions, 1424 deletions
diff --git a/src/node/test/surface_test.js b/src/node/test/surface_test.js deleted file mode 100644 index 0b0b393e32..0000000000 --- a/src/node/test/surface_test.js +++ /dev/null @@ -1,1424 +0,0 @@ -/* - * - * Copyright 2015 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -'use strict'; - -var assert = require('assert'); -var _ = require('lodash'); - -var surface_client = require('../src/client.js'); -var common = require('../src/common'); - -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 mathServiceAttrs = grpc.loadObject( - mathService, common.defaultGrpcOptions).service; - -/** - * 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'); - }); - }); -}); -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 proto service', function() { - assert.doesNotThrow(function() { - server.addProtoService(mathService, dummyImpls); - }); - }); - it('Should succeed with a single service attributes object', function() { - assert.doesNotThrow(function() { - server.addProtoService(mathServiceAttrs, dummyImpls); - }); - }); -}); -describe('Server.prototype.addService', 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.addService(mathServiceAttrs, dummyImpls); - }); - }); - it('Should fail with conflicting method names', function() { - server.addService(mathServiceAttrs, dummyImpls); - assert.throws(function() { - server.addService(mathServiceAttrs, dummyImpls); - }); - }); - it('Should allow method names as originally written', function() { - var altDummyImpls = { - 'Div': function() {}, - 'DivMany': function() {}, - 'Fib': function() {}, - 'Sum': function() {} - }; - assert.doesNotThrow(function() { - server.addProtoService(mathService, altDummyImpls); - }); - }); - it('Should have a conflict between name variations', function() { - /* This is really testing that both name variations are actually used, - by checking that the method actually gets registered, for the - corresponding function, in both cases */ - var altDummyImpls = { - 'Div': function() {}, - 'DivMany': function() {}, - 'Fib': function() {}, - 'Sum': function() {} - }; - server.addProtoService(mathService, altDummyImpls); - assert.throws(function() { - server.addProtoService(mathService, dummyImpls); - }); - }); - it('Should fail if the server has been started', function() { - server.start(); - assert.throws(function() { - server.addService(mathServiceAttrs, dummyImpls); - }); - }); - describe('Default handlers', function() { - var client; - beforeEach(function() { - server.addService(mathServiceAttrs, {}); - var port = server.bind('localhost:0', server_insecure_creds); - var Client = grpc.loadObject(mathService); - client = new Client('localhost:' + port, - grpc.credentials.createInsecure()); - server.start(); - }); - it('should respond to a unary call with UNIMPLEMENTED', function(done) { - client.div({divisor: 4, dividend: 3}, function(error, response) { - assert(error); - assert.strictEqual(error.code, grpc.status.UNIMPLEMENTED); - done(); - }); - }); - it('should respond to a client stream with UNIMPLEMENTED', function(done) { - var call = client.sum(function(error, respones) { - assert(error); - assert.strictEqual(error.code, grpc.status.UNIMPLEMENTED); - done(); - }); - call.end(); - }); - it('should respond to a server stream with UNIMPLEMENTED', function(done) { - var call = client.fib({limit: 5}); - call.on('data', function(value) { - assert.fail('No messages expected'); - }); - call.on('error', function(err) { - assert.strictEqual(err.code, grpc.status.UNIMPLEMENTED); - done(); - }); - call.on('error', function(status) { /* Do nothing */ }); - }); - it('should respond to a bidi call with UNIMPLEMENTED', function(done) { - var call = client.divMany(); - call.on('data', function(value) { - assert.fail('No messages expected'); - }); - call.on('error', function(err) { - assert.strictEqual(err.code, grpc.status.UNIMPLEMENTED); - done(); - }); - call.on('error', function(status) { /* Do nothing */ }); - call.end(); - }); - }); -}); -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 = grpc.loadObject(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'); - var Client = grpc.loadObject(echo_service); - server = new grpc.Server(); - server.addService(Client.service, { - echo: function(call, callback) { - callback(null, call.request); - } - }); - var port = server.bind('localhost:0', server_insecure_creds); - 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(); - }); - }); - it('Should convert an undefined argument to default values', function(done) { - client.echo(undefined, function(error, response) { - assert.ifError(error); - assert.deepEqual(response, {value: '', value2: 0}); - 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'); - var Client = grpc.loadObject(test_service); - server = new grpc.Server(); - server.addService(Client.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); - 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({}, metadata, function(err, data) { - assert.ifError(err); - }); - call.on('metadata', function(metadata) { - assert.deepEqual(metadata.get('key'), ['value']); - done(); - }); - }); - it('with client stream call', function(done) { - var call = client.clientStream(metadata, function(err, data) { - assert.ifError(err); - }); - 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({}, metadata, - function(err, data) { assert.ifError(err); }); - 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({}, dup_metadata, - function(err, data) {assert.ifError(err); }); - 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 = grpc.loadObject(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('Server serialization failure handling', function() { - function serializeFail(obj) { - throw new Error('Serialization failed'); - } - var client; - var server; - 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: serializeFail - }, - clientStream: { - path: '/TestService/ClientStream', - requestStream: true, - responseStream: false, - requestDeserialize: _.identity, - responseSerialize: serializeFail - }, - serverStream: { - path: '/TestService/ServerStream', - requestStream: false, - responseStream: true, - requestDeserialize: _.identity, - responseSerialize: serializeFail - }, - bidiStream: { - path: '/TestService/BidiStream', - requestStream: true, - responseStream: true, - requestDeserialize: _.identity, - responseSerialize: serializeFail - } - }; - server = new grpc.Server(); - server.addService(malformed_test_service, { - unary: function(call, cb) { - cb(null, {}); - }, - clientStream: function(stream, cb) { - stream.on('data', function() {/* Ignore requests */}); - stream.on('end', function() { - cb(null, {}); - }); - }, - serverStream: function(stream) { - stream.write({}); - stream.end(); - }, - bidiStream: function(stream) { - stream.on('data', function() { - // Ignore requests - stream.write({}); - }); - stream.on('end', function() { - stream.end(); - }); - } - }); - var port = server.bind('localhost:0', server_insecure_creds); - var Client = grpc.loadObject(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 Client; - var client; - var server; - var port; - before(function() { - var test_proto = ProtoBuf.loadProtoFile(__dirname + '/test_service.proto'); - var test_service = test_proto.lookup('TestService'); - Client = grpc.loadObject(test_service); - server = new grpc.Server(); - var trailer_metadata = new grpc.Metadata(); - trailer_metadata.add('trailer-present', 'yes'); - server.addService(Client.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 = 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.INTERNAL); - 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.INTERNAL); - 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.INTERNAL); - 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.INTERNAL); - 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(); - }); - }); - it('after the call has fully completed', function(done) { - var peer; - var call = client.unary({error: false}, function(err, data) { - assert.ifError(err); - setImmediate(function() { - assert.strictEqual(peer, call.getPeer()); - done(); - }); - }); - peer = call.getPeer(); - assert.strictEqual(typeof peer, 'string'); - }); - }); -}); -describe('Call propagation', function() { - var proxy; - var proxy_impl; - - var Client; - var client; - var server; - before(function() { - var test_proto = ProtoBuf.loadProtoFile(__dirname + '/test_service.proto'); - var test_service = test_proto.lookup('TestService'); - server = new grpc.Server(); - Client = grpc.loadObject(test_service); - server.addService(Client.service, { - unary: function(call) {}, - clientStream: function(stream) {}, - serverStream: function(stream) {}, - bidiStream: function(stream) {} - }); - var port = server.bind('localhost:0', server_insecure_creds); - 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, {parent: parent}, function(err, value) { - try { - assert(err); - assert.strictEqual(err.code, grpc.status.CANCELLED); - } finally { - callback(err, value); - done(); - } - }); - call.cancel(); - }; - proxy.addService(Client.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({parent: parent}, function(err, value) { - try { - assert(err); - assert.strictEqual(err.code, grpc.status.CANCELLED); - } finally { - callback(err, value); - done(); - } - }); - call.cancel(); - }; - proxy.addService(Client.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, {parent: parent}); - child.on('data', function() {}); - child.on('error', function(err) { - assert(err); - assert.strictEqual(err.code, grpc.status.CANCELLED); - done(); - }); - call.cancel(); - }; - proxy.addService(Client.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({parent: parent}); - child.on('data', function() {}); - child.on('error', function(err) { - assert(err); - assert.strictEqual(err.code, grpc.status.CANCELLED); - done(); - }); - call.cancel(); - }; - proxy.addService(Client.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) { - var options = {parent: parent, propagate_flags: deadline_flags}; - client.clientStream(options, function(err, value) { - try { - assert(err); - assert(err.code === grpc.status.DEADLINE_EXCEEDED || - err.code === grpc.status.INTERNAL); - } finally { - callback(err, value); - done(); - } - }); - }; - proxy.addService(Client.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({deadline: deadline}, function(err, value) { - done(); - }); - }); - it('With a bidi stream call', function(done) { - done = multiDone(done, 2); - proxy_impl.bidiStream = function(parent) { - var child = client.bidiStream( - {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.addService(Client.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({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.addService(mathServiceAttrs, { - '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.makeClientConstructor(mathServiceAttrs); - 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, grpc.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, grpc.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, grpc.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, grpc.status.CANCELLED); - done(); - }); - call.cancel(); - }); - it('Should be idempotent', function(done) { - var call = client.div({'divisor': 0, 'dividend': 0}, function(err, resp) { - assert.strictEqual(err.code, grpc.status.CANCELLED); - // Call asynchronously to try cancelling after call is fully completed - setImmediate(function() { - assert.doesNotThrow(function() { - call.cancel(); - }); - done(); - }); - }); - call.cancel(); - }); -}); -describe('Client reconnect', function() { - var server; - var Client; - var client; - var port; - beforeEach(function() { - var test_proto = ProtoBuf.loadProtoFile(__dirname + '/echo_service.proto'); - var echo_service = test_proto.lookup('EchoService'); - Client = grpc.loadObject(echo_service); - server = new grpc.Server(); - server.addService(Client.service, { - echo: function(call, callback) { - callback(null, call.request); - } - }); - port = server.bind('localhost:0', server_insecure_creds); - client = new Client('localhost:' + port, grpc.credentials.createInsecure()); - server.start(); - }); - afterEach(function() { - server.forceShutdown(); - }); - it('should reconnect after server restart', function(done) { - client.echo({value: 'test value', value2: 3}, function(error, response) { - assert.ifError(error); - assert.deepEqual(response, {value: 'test value', value2: 3}); - server.tryShutdown(function() { - server = new grpc.Server(); - server.addService(Client.service, { - echo: function(call, callback) { - callback(null, call.request); - } - }); - server.bind('localhost:' + port, server_insecure_creds); - server.start(); - - /* We create a new client, that will not throw an error if the server - * is not immediately available. Instead, it will wait for the server - * to be available, then the call will complete. Once this happens, the - * original client should be able to make a new call and connect to the - * restarted server without having the call fail due to connection - * errors. */ - var client2 = new Client('localhost:' + port, - grpc.credentials.createInsecure()); - client2.echo({value: 'test', value2: 3}, function(error, response) { - assert.ifError(error); - client.echo(undefined, function(error, response) { - if (error) { - console.log(error); - } - assert.ifError(error); - assert.deepEqual(response, {value: '', value2: 0}); - done(); - }); - }); - }); - }); - }); -}); |