/*
 *
 * 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({}, 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 = 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, {parent: parent}, function(err, value) {
          try {
            assert(err);
            assert.strictEqual(err.code, grpc.status.CANCELLED);
          } finally {
            callback(err, value);
            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.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.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, {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({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) {
        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.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({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.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({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();
  });
});
