|  | @@ -92,6 +92,31 @@ describe('File loader', function() {
 | 
	
		
			
				|  |  |      });
 | 
	
		
			
				|  |  |    });
 | 
	
		
			
				|  |  |  });
 | 
	
		
			
				|  |  | +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 = {
 | 
	
	
		
			
				|  | @@ -202,6 +227,16 @@ describe('waitForClientReady', function() {
 | 
	
		
			
				|  |  |        });
 | 
	
		
			
				|  |  |      });
 | 
	
		
			
				|  |  |    });
 | 
	
		
			
				|  |  | +  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;
 | 
	
	
		
			
				|  | @@ -378,6 +413,111 @@ describe('Echo metadata', function() {
 | 
	
		
			
				|  |  |      });
 | 
	
		
			
				|  |  |    });
 | 
	
		
			
				|  |  |  });
 | 
	
		
			
				|  |  | +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;
 | 
	
	
		
			
				|  | @@ -461,6 +601,23 @@ describe('Other conditions', 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]);
 |