|
|
|
@ -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; |
|
|
|
@ -365,6 +400,123 @@ describe('Echo metadata', function() { |
|
|
|
|
done(); |
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|
it('properly handles duplicate values', function(done) { |
|
|
|
|
var dup_metadata = metadata.clone(); |
|
|
|
|
dup_metadata.add('key', 'value2'); |
|
|
|
|
var call = client.unary({}, function(err, data) {assert.ifError(err); }, |
|
|
|
|
dup_metadata); |
|
|
|
|
call.on('metadata', function(resp_metadata) { |
|
|
|
|
// Two arrays are equal iff their symmetric difference is empty
|
|
|
|
|
assert.deepEqual(_.xor(dup_metadata.get('key'), resp_metadata.get('key')), |
|
|
|
|
[]); |
|
|
|
|
done(); |
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|
describe('Client malformed response handling', function() { |
|
|
|
|
var server; |
|
|
|
|
var client; |
|
|
|
|
var badArg = new Buffer([0xFF]); |
|
|
|
|
before(function() { |
|
|
|
|
var test_proto = ProtoBuf.loadProtoFile(__dirname + '/test_service.proto'); |
|
|
|
|
var test_service = test_proto.lookup('TestService'); |
|
|
|
|
var malformed_test_service = { |
|
|
|
|
unary: { |
|
|
|
|
path: '/TestService/Unary', |
|
|
|
|
requestStream: false, |
|
|
|
|
responseStream: false, |
|
|
|
|
requestDeserialize: _.identity, |
|
|
|
|
responseSerialize: _.identity |
|
|
|
|
}, |
|
|
|
|
clientStream: { |
|
|
|
|
path: '/TestService/ClientStream', |
|
|
|
|
requestStream: true, |
|
|
|
|
responseStream: false, |
|
|
|
|
requestDeserialize: _.identity, |
|
|
|
|
responseSerialize: _.identity |
|
|
|
|
}, |
|
|
|
|
serverStream: { |
|
|
|
|
path: '/TestService/ServerStream', |
|
|
|
|
requestStream: false, |
|
|
|
|
responseStream: true, |
|
|
|
|
requestDeserialize: _.identity, |
|
|
|
|
responseSerialize: _.identity |
|
|
|
|
}, |
|
|
|
|
bidiStream: { |
|
|
|
|
path: '/TestService/BidiStream', |
|
|
|
|
requestStream: true, |
|
|
|
|
responseStream: true, |
|
|
|
|
requestDeserialize: _.identity, |
|
|
|
|
responseSerialize: _.identity |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
server = new grpc.Server(); |
|
|
|
|
server.addService(malformed_test_service, { |
|
|
|
|
unary: function(call, cb) { |
|
|
|
|
cb(null, badArg); |
|
|
|
|
}, |
|
|
|
|
clientStream: function(stream, cb) { |
|
|
|
|
stream.on('data', function() {/* Ignore requests */}); |
|
|
|
|
stream.on('end', function() { |
|
|
|
|
cb(null, badArg); |
|
|
|
|
}); |
|
|
|
|
}, |
|
|
|
|
serverStream: function(stream) { |
|
|
|
|
stream.write(badArg); |
|
|
|
|
stream.end(); |
|
|
|
|
}, |
|
|
|
|
bidiStream: function(stream) { |
|
|
|
|
stream.on('data', function() { |
|
|
|
|
// Ignore requests
|
|
|
|
|
stream.write(badArg); |
|
|
|
|
}); |
|
|
|
|
stream.on('end', function() { |
|
|
|
|
stream.end(); |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
var port = server.bind('localhost:0', server_insecure_creds); |
|
|
|
|
var Client = surface_client.makeProtobufClientConstructor(test_service); |
|
|
|
|
client = new Client('localhost:' + port, grpc.credentials.createInsecure()); |
|
|
|
|
server.start(); |
|
|
|
|
}); |
|
|
|
|
after(function() { |
|
|
|
|
server.forceShutdown(); |
|
|
|
|
}); |
|
|
|
|
it('should get an INTERNAL status with a unary call', function(done) { |
|
|
|
|
client.unary({}, function(err, data) { |
|
|
|
|
assert(err); |
|
|
|
|
assert.strictEqual(err.code, grpc.status.INTERNAL); |
|
|
|
|
done(); |
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|
it('should get an INTERNAL status with a client stream call', function(done) { |
|
|
|
|
var call = client.clientStream(function(err, data) { |
|
|
|
|
assert(err); |
|
|
|
|
assert.strictEqual(err.code, grpc.status.INTERNAL); |
|
|
|
|
done(); |
|
|
|
|
}); |
|
|
|
|
call.write({}); |
|
|
|
|
call.end(); |
|
|
|
|
}); |
|
|
|
|
it('should get an INTERNAL status with a server stream call', function(done) { |
|
|
|
|
var call = client.serverStream({}); |
|
|
|
|
call.on('data', function(){}); |
|
|
|
|
call.on('error', function(err) { |
|
|
|
|
assert.strictEqual(err.code, grpc.status.INTERNAL); |
|
|
|
|
done(); |
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|
it('should get an INTERNAL status with a bidi stream call', function(done) { |
|
|
|
|
var call = client.bidiStream(); |
|
|
|
|
call.on('data', function(){}); |
|
|
|
|
call.on('error', function(err) { |
|
|
|
|
assert.strictEqual(err.code, grpc.status.INTERNAL); |
|
|
|
|
done(); |
|
|
|
|
}); |
|
|
|
|
call.write({}); |
|
|
|
|
call.end(); |
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|
describe('Other conditions', function() { |
|
|
|
|
var test_service; |
|
|
|
@ -382,7 +534,8 @@ describe('Other conditions', function() { |
|
|
|
|
unary: function(call, cb) { |
|
|
|
|
var req = call.request; |
|
|
|
|
if (req.error) { |
|
|
|
|
cb(new Error('Requested error'), null, trailer_metadata); |
|
|
|
|
cb({code: grpc.status.UNKNOWN, |
|
|
|
|
details: 'Requested error'}, null, trailer_metadata); |
|
|
|
|
} else { |
|
|
|
|
cb(null, {count: 1}, trailer_metadata); |
|
|
|
|
} |
|
|
|
@ -407,7 +560,8 @@ describe('Other conditions', function() { |
|
|
|
|
serverStream: function(stream) { |
|
|
|
|
var req = stream.request; |
|
|
|
|
if (req.error) { |
|
|
|
|
var err = new Error('Requested error'); |
|
|
|
|
var err = {code: grpc.status.UNKNOWN, |
|
|
|
|
details: 'Requested error'}; |
|
|
|
|
err.metadata = trailer_metadata; |
|
|
|
|
stream.emit('error', err); |
|
|
|
|
} else { |
|
|
|
@ -447,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]); |
|
|
|
|