Specify client and server implementation in test description

This commit is contained in:
murgatroid99 2019-10-10 14:47:10 -07:00
parent ee0554231b
commit e7ca0da409
5 changed files with 639 additions and 629 deletions

View File

@ -41,5 +41,7 @@ const serverImpl = getImplementation('_server_implementation');
module.exports = {
client: clientImpl,
server: serverImpl
server: serverImpl,
clientName: global._client_implementation,
serverName: global._server_implementation
};

View File

@ -58,64 +58,66 @@ const serviceImpl = {
}
};
describe('Reconnection', function() {
let server1;
let server2;
let port;
before(function(done) {
server1 = new serverGrpc.Server();
server1.addService(TestService, serviceImpl);
server2 = new serverGrpc.Server();
server2.addService(TestService, serviceImpl);
server1.bindAsync('localhost:0', serverCreds, (err, _port) => {
assert.ifError(err);
server1.start();
port = _port;
client = new TestServiceClient(`localhost:${port}`, clientCreds);
done();
});
});
after(function() {
client.close();
server1.forceShutdown();
server2.forceShutdown();
});
it.skip('Should end with either OK or UNAVAILABLE when querying a server that is shutting down', function(done) {
this.timeout(10000);
let pendingCalls = 0;
let testDone = false;
let callInterval;
function maybeDone() {
if (testDone && pendingCalls === 0) {
describe(`${anyGrpc.clientName} client -> ${anyGrpc.serverName} server`, function() {
describe('Reconnection', function() {
let server1;
let server2;
let port;
before(function(done) {
server1 = new serverGrpc.Server();
server1.addService(TestService, serviceImpl);
server2 = new serverGrpc.Server();
server2.addService(TestService, serviceImpl);
server1.bindAsync('localhost:0', serverCreds, (err, _port) => {
assert.ifError(err);
server1.start();
port = _port;
client = new TestServiceClient(`localhost:${port}`, clientCreds);
done();
}
};
client.unary({}, (err, data) => {
assert.ifError(err);
server1.tryShutdown(() => {
server2.bindAsync(`localhost:${port}`, serverCreds, (err) => {
assert.ifError(err);
server2.start();
const metadata = new clientGrpc.Metadata({ waitForReady: true });
client.unary({}, metadata, (err, data) => {
});
});
after(function() {
client.close();
server1.forceShutdown();
server2.forceShutdown();
});
it.skip('Should end with either OK or UNAVAILABLE when querying a server that is shutting down', function(done) {
this.timeout(10000);
let pendingCalls = 0;
let testDone = false;
let callInterval;
function maybeDone() {
if (testDone && pendingCalls === 0) {
done();
}
};
client.unary({}, (err, data) => {
assert.ifError(err);
server1.tryShutdown(() => {
server2.bindAsync(`localhost:${port}`, serverCreds, (err) => {
assert.ifError(err);
clearInterval(callInterval);
testDone = true;
maybeDone();
server2.start();
const metadata = new clientGrpc.Metadata({ waitForReady: true });
client.unary({}, metadata, (err, data) => {
assert.ifError(err);
clearInterval(callInterval);
testDone = true;
maybeDone();
});
});
});
callInterval = setInterval(() => {
assert.strictEqual(testDone, false);
pendingCalls += 1;
client.unary({}, (err, data) => {
pendingCalls -= 1;
if (err) {
assert.strictEqual(err.code, clientGrpc.status.UNAVAILABLE);
}
maybeDone();
});
}, 0);
});
callInterval = setInterval(() => {
assert.strictEqual(testDone, false);
pendingCalls += 1;
client.unary({}, (err, data) => {
pendingCalls -= 1;
if (err) {
assert.strictEqual(err.code, clientGrpc.status.UNAVAILABLE);
}
maybeDone();
});
}, 0);
});
});
});

View File

@ -33,524 +33,526 @@ const TestServiceClient = clientGrpc.loadPackageDefinition(testServiceDef).TestS
const clientInsecureCreds = clientGrpc.credentials.createInsecure();
const serverInsecureCreds = serverGrpc.ServerCredentials.createInsecure();
describe('Client malformed response handling', function() {
var server;
var client;
var badArg = Buffer.from([0xFF]);
before(function(done) {
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 serverGrpc.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();
});
}
});
server.bindAsync('localhost:0', serverInsecureCreds, (err, port) => {
assert.ifError(err);
client = new TestServiceClient('localhost:' + port, clientInsecureCreds);
server.start();
done();
});
});
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, clientGrpc.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, clientGrpc.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, clientGrpc.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, clientGrpc.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(done) {
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 serverGrpc.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();
});
}
});
server.bindAsync('localhost:0', serverInsecureCreds, (err, port) => {
assert.ifError(err);
client = new TestServiceClient('localhost:' + port, clientInsecureCreds);
server.start();
done();
});
});
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, clientGrpc.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, clientGrpc.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, clientGrpc.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, clientGrpc.status.INTERNAL);
done();
});
call.write({});
call.end();
});
});
describe('Other conditions', function() {
var Client;
var client;
var server;
var port;
before(function(done) {
server = new serverGrpc.Server();
var trailer_metadata = new serverGrpc.Metadata();
trailer_metadata.add('trailer-present', 'yes');
server.addService(TestServiceClient.service, {
unary: function(call, cb) {
var req = call.request;
if (req.error) {
var message = 'Requested error';
if (req.message) {
message = req.message;
}
cb({code: serverGrpc.status.UNKNOWN,
details: message}, 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) {
var message = 'Requested error';
if (data.message) {
message = data.message;
}
errored = true;
cb(new Error(message), 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 message = 'Requested error';
if (req.message) {
message = req.message;
}
var err = {code: serverGrpc.status.UNKNOWN,
details: message};
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 message = 'Requested error';
if (data.message) {
message = data.message;
}
var err = new Error(message);
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);
});
}
});
server.bindAsync('localhost:0', serverInsecureCreds, (err, _port) => {
assert.ifError(err);
port = _port;
client = new TestServiceClient('localhost:' + port, clientInsecureCreds);
server.start();
done();
});
});
after(function() {
server.forceShutdown();
});
describe('Server recieving bad input', function() {
var misbehavingClient;
describe(`${anyGrpc.clientName} client -> ${anyGrpc.serverName} server`, function() {
describe('Client malformed response handling', function() {
var server;
var client;
var badArg = Buffer.from([0xFF]);
before(function() {
var test_service_attrs = {
before(function(done) {
var malformed_test_service = {
unary: {
path: '/TestService/Unary',
requestStream: false,
responseStream: false,
requestSerialize: _.identity,
responseDeserialize: _.identity
requestDeserialize: _.identity,
responseSerialize: _.identity
},
clientStream: {
path: '/TestService/ClientStream',
requestStream: true,
responseStream: false,
requestSerialize: _.identity,
responseDeserialize: _.identity
requestDeserialize: _.identity,
responseSerialize: _.identity
},
serverStream: {
path: '/TestService/ServerStream',
requestStream: false,
responseStream: true,
requestSerialize: _.identity,
responseDeserialize: _.identity
requestDeserialize: _.identity,
responseSerialize: _.identity
},
bidiStream: {
path: '/TestService/BidiStream',
requestStream: true,
responseStream: true,
requestSerialize: _.identity,
responseDeserialize: _.identity
requestDeserialize: _.identity,
responseSerialize: _.identity
}
};
var Client = clientGrpc.makeGenericClientConstructor(test_service_attrs,
'TestService');
misbehavingClient = new Client('localhost:' + port, clientInsecureCreds);
server = new serverGrpc.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();
});
}
});
server.bindAsync('localhost:0', serverInsecureCreds, (err, port) => {
assert.ifError(err);
client = new TestServiceClient('localhost:' + port, clientInsecureCreds);
server.start();
done();
});
});
it('should respond correctly to a unary call', function(done) {
misbehavingClient.unary(badArg, function(err, data) {
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, clientGrpc.status.INTERNAL);
done();
});
});
it('should respond correctly to a client stream', function(done) {
var call = misbehavingClient.clientStream(function(err, data) {
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, clientGrpc.status.INTERNAL);
done();
});
call.write(badArg);
// TODO(mlumish): Remove call.end()
call.write({});
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', '===');
});
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, clientGrpc.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', '===');
});
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, clientGrpc.status.INTERNAL);
done();
});
call.write(badArg);
// TODO(mlumish): Remove call.end()
call.write({});
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) {
describe('Server serialization failure handling', function() {
function serializeFail(obj) {
throw new Error('Serialization failed');
}
var client;
var server;
before(function(done) {
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 serverGrpc.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();
});
}
});
server.bindAsync('localhost:0', serverInsecureCreds, (err, port) => {
assert.ifError(err);
});
call.on('status', function(status) {
assert.deepEqual(status.metadata.get('trailer-present'), ['yes']);
client = new TestServiceClient('localhost:' + port, clientInsecureCreds);
server.start();
done();
});
});
it('should be present when a unary call fails', function(done) {
var call = client.unary({error: true}, function(err, data) {
after(function() {
server.forceShutdown();
});
it('should get an INTERNAL status with a unary call', function(done) {
client.unary({}, function(err, data) {
assert(err);
});
call.on('status', function(status) {
assert.deepEqual(status.metadata.get('trailer-present'), ['yes']);
assert.strictEqual(err.code, clientGrpc.status.INTERNAL);
done();
});
});
it('should be present when a client stream call succeeds', function(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, clientGrpc.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, clientGrpc.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, clientGrpc.status.INTERNAL);
done();
});
call.write({});
call.end();
});
});
describe('Other conditions', function() {
var Client;
var client;
var server;
var port;
before(function(done) {
server = new serverGrpc.Server();
var trailer_metadata = new serverGrpc.Metadata();
trailer_metadata.add('trailer-present', 'yes');
server.addService(TestServiceClient.service, {
unary: function(call, cb) {
var req = call.request;
if (req.error) {
var message = 'Requested error';
if (req.message) {
message = req.message;
}
cb({code: serverGrpc.status.UNKNOWN,
details: message}, 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) {
var message = 'Requested error';
if (data.message) {
message = data.message;
}
errored = true;
cb(new Error(message), 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 message = 'Requested error';
if (req.message) {
message = req.message;
}
var err = {code: serverGrpc.status.UNKNOWN,
details: message};
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 message = 'Requested error';
if (data.message) {
message = data.message;
}
var err = new Error(message);
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);
});
}
});
server.bindAsync('localhost:0', serverInsecureCreds, (err, _port) => {
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']);
port = _port;
client = new TestServiceClient('localhost:' + port, clientInsecureCreds);
server.start();
done();
});
});
it('should be present when a client stream call fails', function(done) {
var call = client.clientStream(function(err, data) {
assert(err);
after(function() {
server.forceShutdown();
});
describe('Server recieving bad input', function() {
var misbehavingClient;
var badArg = Buffer.from([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 = clientGrpc.makeGenericClientConstructor(test_service_attrs,
'TestService');
misbehavingClient = new Client('localhost:' + port, clientInsecureCreds);
});
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 respond correctly to a unary call', function(done) {
misbehavingClient.unary(badArg, function(err, data) {
assert(err);
assert.strictEqual(err.code, clientGrpc.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, clientGrpc.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, clientGrpc.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, clientGrpc.status.INTERNAL);
done();
});
call.write(badArg);
// TODO(mlumish): Remove call.end()
call.end();
});
});
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, clientGrpc.status.OK);
assert.deepEqual(status.metadata.get('trailer-present'), ['yes']);
done();
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, clientGrpc.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, clientGrpc.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();
});
});
});
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();
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, clientGrpc.status.UNKNOWN);
assert.strictEqual(err.details, 'Requested error');
done();
});
});
it('for a client stream call', function(done) {
var call = client.clientStream(function(err, data) {
assert(err);
assert.strictEqual(err.code, clientGrpc.status.UNKNOWN);
assert.strictEqual(err.details, '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, clientGrpc.status.UNKNOWN);
assert.strictEqual(error.details, '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, clientGrpc.status.UNKNOWN);
assert.strictEqual(error.details, 'Requested error');
done();
});
});
it('for a UTF-8 error message', function(done) {
client.unary({error: true, message: '測試字符串'}, function(err, data) {
assert(err);
assert.strictEqual(err.code, clientGrpc.status.UNKNOWN);
assert.strictEqual(err.details, '測試字符串');
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, clientGrpc.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, clientGrpc.status.UNKNOWN);
assert.strictEqual(err.details, 'Requested error');
done();
});
});
it('for a client stream call', function(done) {
var call = client.clientStream(function(err, data) {
assert(err);
assert.strictEqual(err.code, clientGrpc.status.UNKNOWN);
assert.strictEqual(err.details, '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, clientGrpc.status.UNKNOWN);
assert.strictEqual(error.details, '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, clientGrpc.status.UNKNOWN);
assert.strictEqual(error.details, 'Requested error');
done();
});
});
it('for a UTF-8 error message', function(done) {
client.unary({error: true, message: '測試字符串'}, function(err, data) {
assert(err);
assert.strictEqual(err.code, clientGrpc.status.UNKNOWN);
assert.strictEqual(err.details, '測試字符串');
done();
});
});
});
});
});
});

View File

@ -52,85 +52,87 @@ function echoMetadataGenerator(options, callback) {
const credentials = grpc.credentials.createFromMetadataGenerator(echoMetadataGenerator);
describe('Interop-adjacent tests', function() {
let server;
let client;
before(function(done) {
interopServer.getServer(0, true, (err, serverObj) => {
if (err) {
done(err);
} else {
server = serverObj.server;
server.start();
const ca_path = path.join(__dirname, '../data/ca.pem');
const ca_data = fs.readFileSync(ca_path);
const creds = grpc.credentials.createSsl(ca_data);
const options = {
'grpc.ssl_target_name_override': 'foo.test.google.fr',
'grpc.default_authority': 'foo.test.google.fr'
};
client = new testProto.TestService(`localhost:${serverObj.port}`, creds, options);
done();
describe(`${anyGrpc.clientName} client -> ${anyGrpc.serverName} server`, function() {
describe('Interop-adjacent tests', function() {
let server;
let client;
before(function(done) {
interopServer.getServer(0, true, (err, serverObj) => {
if (err) {
done(err);
} else {
server = serverObj.server;
server.start();
const ca_path = path.join(__dirname, '../data/ca.pem');
const ca_data = fs.readFileSync(ca_path);
const creds = grpc.credentials.createSsl(ca_data);
const options = {
'grpc.ssl_target_name_override': 'foo.test.google.fr',
'grpc.default_authority': 'foo.test.google.fr'
};
client = new testProto.TestService(`localhost:${serverObj.port}`, creds, options);
done();
}
});
});
after(function() {
server.forceShutdown();
});
it('Should be able to start many concurrent calls', function(done) {
const callCount = 1000;
done = multiDone(done, callCount);
for (let i = 0; i < callCount; i++) {
client.unaryCall({}, (error, result) => {
assert.ifError(error);
done();
});
}
});
});
after(function() {
server.forceShutdown();
});
it('Should be able to start many concurrent calls', function(done) {
const callCount = 1000;
done = multiDone(done, callCount);
for (let i = 0; i < callCount; i++) {
client.unaryCall({}, (error, result) => {
it('Should echo metadata from call credentials', function(done) {
done = multiDone(done, 2);
const call = client.unaryCall({}, {credentials}, (error, result) => {
assert.ifError(error);
done();
});
}
});
it('Should echo metadata from call credentials', function(done) {
done = multiDone(done, 2);
const call = client.unaryCall({}, {credentials}, (error, result) => {
assert.ifError(error);
done();
});
call.on('metadata', (metadata) => {
assert.deepEqual(metadata.get('x-grpc-test-echo-initial'),
['test_initial_metadata_value']);
done();
});
});
it('Should be able to send the same metadata on two calls with call creds', function(done) {
done = multiDone(done, 5);
const metadata = new grpc.Metadata();
metadata.set('x-grpc-test-echo-trailing-bin', Buffer.from('ababab', 'hex'));
const call1 = client.unaryCall({}, metadata, {credentials}, (error, result) => {
assert.ifError(error);
const call2 = client.unaryCall({}, metadata, {credentials}, (error, result) => {
assert.ifError(error);
done();
});
call2.on('metadata', (metadata) => {
call.on('metadata', (metadata) => {
assert.deepEqual(metadata.get('x-grpc-test-echo-initial'),
['test_initial_metadata_value']);
['test_initial_metadata_value']);
done();
});
call2.on('status', function(status) {
});
it('Should be able to send the same metadata on two calls with call creds', function(done) {
done = multiDone(done, 5);
const metadata = new grpc.Metadata();
metadata.set('x-grpc-test-echo-trailing-bin', Buffer.from('ababab', 'hex'));
const call1 = client.unaryCall({}, metadata, {credentials}, (error, result) => {
assert.ifError(error);
const call2 = client.unaryCall({}, metadata, {credentials}, (error, result) => {
assert.ifError(error);
done();
});
call2.on('metadata', (metadata) => {
assert.deepEqual(metadata.get('x-grpc-test-echo-initial'),
['test_initial_metadata_value']);
done();
});
call2.on('status', function(status) {
var echo_trailer = status.metadata.get('x-grpc-test-echo-trailing-bin');
assert(echo_trailer.length === 1);
assert.strictEqual(echo_trailer[0].toString('hex'), 'ababab');
done();
});
});
call1.on('metadata', (metadata) => {
assert.deepEqual(metadata.get('x-grpc-test-echo-initial'),
['test_initial_metadata_value']);
done();
});
call1.on('status', function(status) {
var echo_trailer = status.metadata.get('x-grpc-test-echo-trailing-bin');
assert(echo_trailer.length === 1);
assert.strictEqual(echo_trailer[0].toString('hex'), 'ababab');
done();
});
});
call1.on('metadata', (metadata) => {
assert.deepEqual(metadata.get('x-grpc-test-echo-initial'),
['test_initial_metadata_value']);
done();
});
call1.on('status', function(status) {
var echo_trailer = status.metadata.get('x-grpc-test-echo-trailing-bin');
assert(echo_trailer.length === 1);
assert.strictEqual(echo_trailer[0].toString('hex'), 'ababab');
done();
});
});
});

View File

@ -45,60 +45,62 @@ const testCases = [
var childExecArgv = [];
describe('Interop tests', function() {
this.timeout(4000);
before(function(done) {
for (let arg of process.argv) {
if (arg.startsWith('--require=')) {
childExecArgv.push('--require');
childExecArgv.push(arg.substring('--require='.length));
describe(`${anyGrpc.clientName} client -> ${anyGrpc.serverName} server`, function() {
describe('Interop tests', function() {
this.timeout(4000);
before(function(done) {
for (let arg of process.argv) {
if (arg.startsWith('--require=')) {
childExecArgv.push('--require');
childExecArgv.push(arg.substring('--require='.length));
}
}
serverProcess = childProcess.fork(`${__dirname}/interop_helper/server.js`, {
execArgv: childExecArgv
});
serverProcess.on('message', (message) => {
port = message.port;
done();
});
serverProcess.on('exit', (code, signal) => {
if (code !== 0) {
if (code !== null) {
throw new Error(`Server exited with error code ${code}`);
} else {
throw new Error(`Server exited with signal ${signal}`);
}
}
});
});
after(function() {
serverProcess.send({});
});
for (let testName of testCases) {
it(`should pass ${testName}`, function(done) {
/* We need to run a client process per test to most closely match
* how the main interop test suite works */
let clientProcess = childProcess.fork(`${__dirname}/../interop/interop_client`, [
'--server_host=localhost',
`--server_port=${port}`,
`--server_host_override=${name_override}`,
`--test_case=${testName}`,
'--use_tls=true',
'--use_test_ca=true'
], {
execArgv: childExecArgv
});
clientProcess.on('exit', (code, signal) => {
if (code === 0) {
done();
} else {
if (code !== null) {
done(new Error(`Client exited with error code ${code}`));
} else {
done(new Error(`Client exited with signal ${signal}`));
}
}
serverProcess = childProcess.fork(`${__dirname}/interop_helper/server.js`, {
execArgv: childExecArgv
});
serverProcess.on('message', (message) => {
port = message.port;
done();
});
serverProcess.on('exit', (code, signal) => {
if (code !== 0) {
if (code !== null) {
throw new Error(`Server exited with error code ${code}`);
} else {
throw new Error(`Server exited with signal ${signal}`);
}
}
});
});
after(function() {
serverProcess.send({});
});
for (let testName of testCases) {
it(`should pass ${testName}`, function(done) {
/* We need to run a client process per test to most closely match
* how the main interop test suite works */
let clientProcess = childProcess.fork(`${__dirname}/../interop/interop_client`, [
'--server_host=localhost',
`--server_port=${port}`,
`--server_host_override=${name_override}`,
`--test_case=${testName}`,
'--use_tls=true',
'--use_test_ca=true'
], {
execArgv: childExecArgv
});
});
clientProcess.on('exit', (code, signal) => {
if (code === 0) {
done();
} else {
if (code !== null) {
done(new Error(`Client exited with error code ${code}`));
} else {
done(new Error(`Client exited with signal ${signal}`));
}
}
});
});
}
});
}
});
});