| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717 | 
							- /*
 
-  *
 
-  * Copyright 2015, 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 + '/../examples/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('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.shutdown();
 
-   });
 
-   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#$waitForReady', 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.shutdown();
 
-   });
 
-   it('should complete when called alone', function(done) {
 
-     client.$waitForReady(Infinity, function(error) {
 
-       assert.ifError(error);
 
-       done();
 
-     });
 
-   });
 
-   it('should complete when a call is initiated', function(done) {
 
-     client.$waitForReady(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);
 
-     client.$waitForReady(Infinity, function(error) {
 
-       assert.ifError(error);
 
-       done();
 
-     });
 
-     client.$waitForReady(Infinity, function(error) {
 
-       assert.ifError(error);
 
-       done();
 
-     });
 
-   });
 
-   it('should complete if called when already ready', function(done) {
 
-     client.$waitForReady(Infinity, function(error) {
 
-       assert.ifError(error);
 
-       client.$waitForReady(Infinity, function(error) {
 
-         assert.ifError(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.shutdown();
 
-   });
 
-   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.shutdown();
 
-     });
 
-     it('Should respond with a capitalized string', function(done) {
 
-       client.capitalize('abc', function(err, response) {
 
-         assert.ifError(err);
 
-         assert.strictEqual(response, 'Abc');
 
-         done();
 
-       });
 
-     });
 
-   });
 
- });
 
- describe('Echo metadata', function() {
 
-   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();
 
-     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();
 
-   });
 
-   after(function() {
 
-     server.shutdown();
 
-   });
 
-   it('with unary call', function(done) {
 
-     var call = client.unary({}, function(err, data) {
 
-       assert.ifError(err);
 
-     }, {key: ['value']});
 
-     call.on('metadata', function(metadata) {
 
-       assert.deepEqual(metadata.key, ['value']);
 
-       done();
 
-     });
 
-   });
 
-   it('with client stream call', function(done) {
 
-     var call = client.clientStream(function(err, data) {
 
-       assert.ifError(err);
 
-     }, {key: ['value']});
 
-     call.on('metadata', function(metadata) {
 
-       assert.deepEqual(metadata.key, ['value']);
 
-       done();
 
-     });
 
-     call.end();
 
-   });
 
-   it('with server stream call', function(done) {
 
-     var call = client.serverStream({}, {key: ['value']});
 
-     call.on('data', function() {});
 
-     call.on('metadata', function(metadata) {
 
-       assert.deepEqual(metadata.key, ['value']);
 
-       done();
 
-     });
 
-   });
 
-   it('with bidi stream call', function(done) {
 
-     var call = client.bidiStream({key: ['value']});
 
-     call.on('data', function() {});
 
-     call.on('metadata', function(metadata) {
 
-       assert.deepEqual(metadata.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); },
 
-                             {key: ['value']});
 
-     call.on('metadata', function(metadata) {
 
-       assert(_.startsWith(metadata['user-agent'], 'grpc-node/' + version));
 
-       done();
 
-     });
 
-   });
 
- });
 
- describe('Other conditions', function() {
 
-   var client;
 
-   var server;
 
-   var port;
 
-   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) {
 
-         var req = call.request;
 
-         if (req.error) {
 
-           cb(new Error('Requested error'), null, {trailer_present: ['yes']});
 
-         } else {
 
-           cb(null, {count: 1}, {trailer_present: ['yes']});
 
-         }
 
-       },
 
-       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_present: ['yes']});
 
-           } else {
 
-             count += 1;
 
-           }
 
-         });
 
-         stream.on('end', function() {
 
-           if (!errored) {
 
-             cb(null, {count: count}, {trailer_present: ['yes']});
 
-           }
 
-         });
 
-       },
 
-       serverStream: function(stream) {
 
-         var req = stream.request;
 
-         if (req.error) {
 
-           var err = new Error('Requested error');
 
-           err.metadata = {trailer_present: ['yes']};
 
-           stream.emit('error', err);
 
-         } else {
 
-           for (var i = 0; i < 5; i++) {
 
-             stream.write({count: i});
 
-           }
 
-           stream.end({trailer_present: ['yes']});
 
-         }
 
-       },
 
-       bidiStream: function(stream) {
 
-         var count = 0;
 
-         stream.on('data', function(data) {
 
-           if (data.error) {
 
-             var err = new Error('Requested error');
 
-             err.metadata = {
 
-               trailer_present: ['yes'],
 
-               count: ['' + count]
 
-             };
 
-             stream.emit('error', err);
 
-           } else {
 
-             stream.write({count: count});
 
-             count += 1;
 
-           }
 
-         });
 
-         stream.on('end', function() {
 
-           stream.end({trailer_present: ['yes']});
 
-         });
 
-       }
 
-     });
 
-     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.shutdown();
 
-   });
 
-   it('channel.getTarget should be available', function() {
 
-     assert.strictEqual(typeof client.channel.getTarget(), 'string');
 
-   });
 
-   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.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.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.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.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.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.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.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.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('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.shutdown();
 
-   });
 
-   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('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('error', function(error) {
 
-       assert.strictEqual(error.code, surface_client.status.CANCELLED);
 
-       done();
 
-     });
 
-     call.cancel();
 
-   });
 
- });
 
 
  |