From 10e71bed617ce363ea46dc7f61eaa9c4fadf20dc Mon Sep 17 00:00:00 2001 From: Kelvin Jin Date: Thu, 7 Dec 2017 14:36:43 -0800 Subject: [PATCH] test: convert tests to use client and server separately --- test/any_grpc.js | 138 ++++-- test/api/async_test.js | 14 +- test/api/credentials_api_test.js | 6 +- test/api/credentials_test.js | 195 ++------ test/api/file_load_test.js | 2 +- test/api/interop_sanity_test.js | 5 +- test/api/math/math_client.js | 10 + test/api/math/math_grpc_pb.js | 2 +- test/api/math/math_server.js | 2 +- test/api/math_client_test.js | 16 +- test/api/metadata_test.js | 4 +- test/api/surface_server_test.js | 147 ++++++ test/api/surface_test.js | 752 ++++++++++++++----------------- test/fixtures/native_js.js | 4 +- test/gulpfile.js | 11 +- test/interop/interop_client.js | 2 +- test/interop/interop_server.js | 2 +- test/package.json | 5 +- 18 files changed, 672 insertions(+), 645 deletions(-) create mode 100644 test/api/math/math_client.js create mode 100644 test/api/surface_server_test.js diff --git a/test/any_grpc.js b/test/any_grpc.js index d6d008c29..4373ebc51 100644 --- a/test/any_grpc.js +++ b/test/any_grpc.js @@ -1,39 +1,107 @@ -// TODO: Instead of attempting to expose both implementations of gRPC in -// a single object, the tests should be re-written in a way that makes it clear -// that two separate implementations are being tested against one another. - -const _ = require('lodash'); - -function getImplementation(globalField) { - if (global[globalField] !== 'js' && global[globalField] !== 'native') { - throw new Error([ - `Invalid value for global.${globalField}: ${global.globalField}.`, - 'If running from the command line, please --require a fixture first.' - ].join(' ')); +const assert = require('assert'); +const callerId = require('caller-id'); +const path = require('path'); +const semver = require('semver'); +const shimmer = require('shimmer'); +const Module = require('module'); + +const http2Available = semver.satisfies(process.version, '8.x'); + +// Handle Promise rejections by failing +process.on('unhandledRejection', err => assert.ifError(err)); + +const grpcProtobuf = require('../packages/grpc-protobufjs'); + +/** + * Returns a function that appears to be similar to require(), but substitutes + * the return value of require('grpc') to grpcImpl. + * + * If a module does call require('grpc'), its entry will be deleted in the + * require cache, to prevent cross-contamination between "client-side" and + * "server-side" modules. + * + * There are likely other subtle differences between this function and require + * itself, but we assume that this doesn't matter for our tests. + * + * @param grpcImpl The gRPC implementation to use. + */ +const requireAsFn = (grpcImpl) => (p) => { + // Use caller-id to get information about the file where requireAs* + // was called, so we can adjust the input path to be relative to this + // file path instead. + if (p.startsWith('.')) { + p = path.resolve(path.dirname(callerId.getData().filePath), p); } - const impl = global[globalField]; - return { - surface: require(`../packages/grpc-${impl}`), - pjson: require(`../packages/grpc-${impl}/package.json`), - core: require(`../packages/grpc-${impl}-core`), - corePjson: require(`../packages/grpc-${impl}-core/package.json`) - }; + // Wrap Module._load, which is called by require(), to short-circuit when + // called with 'grpc'. + shimmer.wrap(Module, '_load', (moduleLoad) => { + const uncache = new Set(); + return function Module_load(path, parent) { + if (path.startsWith('grpc')) { + // Mark the module that required 'grpc' to have its entry deleted from + // the require cache. + uncache.add(parent.filename); + return grpcImpl; + } else { + const result = moduleLoad.apply(this, arguments); + // Get the path of the loaded module. + const filename = Module._resolveFilename.apply(this, arguments); + // If this module called require('grpc'), immediately delete its entry + // from the cache. + if (uncache.has(filename)) { + uncache.delete(filename); + delete require.cache[filename]; + } + return result; + } + } + }); + const result = require(p); + shimmer.unwrap(Module, '_load'); + delete require.cache[p]; + return result; +} + +// Load implementations + +const implementations = { + js: http2Available ? require('../packages/grpc-js') : {}, + native: require('../packages/grpc-native') } -const clientImpl = getImplementation('_client_implementation'); -const serverImpl = getImplementation('_server_implementation'); - -// We export a "merged" gRPC API by merging client and server specified -// APIs together. Any function that is unspecific to client/server defaults -// to client-side implementation. -// This object also has a test-only field from which details about the -// modules may be read. -module.exports = Object.assign({ - '$implementationInfo': { - client: clientImpl, - server: serverImpl +const versions = { + js: require('../packages/grpc-js-core/package').version, + native: require('../packages/grpc-native-core/package').version +} + +const server = implementations[global._server_implementation]; +const client = implementations[global._client_implementation]; +const serverVersion = versions[global._server_implementation]; +const clientVersion = versions[global._client_implementation]; + +if (!client || !server) { + throw new Error('If running from the command line, please --require a ' + + 'fixture in ./fixtures first.'); +} + +// prefer requireAs* instead of these. +Object.assign(server, grpcProtobuf(server)); +Object.assign(client, grpcProtobuf(client)); + +module.exports = { + server, + client, + serverVersion, + clientVersion, + requireAsServer: requireAsFn(server), + requireAsClient: requireAsFn(client), + runAsServer: (fn) => fn(server), + runAsClient: (fn) => fn(client), + skipIfJsClient: (mochaVerb) => { + if (client === implementations.js) { + return mochaVerb.skip; + } else { + return mochaVerb; + } } -}, clientImpl.surface, _.pick(serverImpl.surface, [ - 'Server', - 'ServerCredentials' -])); +}; diff --git a/test/api/async_test.js b/test/api/async_test.js index 86cd62e21..96c804b43 100644 --- a/test/api/async_test.js +++ b/test/api/async_test.js @@ -20,8 +20,8 @@ var assert = require('assert'); -var grpc = require('../any_grpc'); -var math = grpc.load( +var anyGrpc = require('../any_grpc'); +var math = anyGrpc.client.load( __dirname + '/../../packages/grpc-native-core/deps/grpc/src/proto/math/math.proto').math; @@ -33,21 +33,21 @@ var math_client; /** * Server to test against */ -var getServer = require('./math/math_server.js'); +var getServer = anyGrpc.requireAsServer('./math/math_server.js'); var server = getServer(); describe('Async functionality', function() { before(function(done) { var port_num = server.bind('0.0.0.0:0', - grpc.ServerCredentials.createInsecure()); + anyGrpc.server.ServerCredentials.createInsecure()); server.start(); math_client = new math.Math('localhost:' + port_num, - grpc.credentials.createInsecure()); + anyGrpc.client.credentials.createInsecure()); done(); }); after(function() { - grpc.closeClient(math_client); + anyGrpc.client.closeClient(math_client); server.forceShutdown(); }); it('should not hang', function(done) { @@ -77,7 +77,7 @@ describe('Async functionality', function() { }); call.on('status', function checkStatus(status) { - assert.strictEqual(status.code, grpc.status.OK); + assert.strictEqual(status.code, anyGrpc.client.status.OK); done(); }); }); diff --git a/test/api/credentials_api_test.js b/test/api/credentials_api_test.js index e79fca07b..70a093a48 100644 --- a/test/api/credentials_api_test.js +++ b/test/api/credentials_api_test.js @@ -22,7 +22,7 @@ var assert = require('assert'); var fs = require('fs'); var path = require('path'); -var grpc = require('../any_grpc'); +var anyGrpc = require('../any_grpc'); var key_data, pem_data, ca_data; @@ -36,6 +36,7 @@ before(function() { }); describe('channel credentials', function() { + var grpc = anyGrpc.requireAsClient('grpc'); describe('#createSsl', function() { it('works with no arguments', function() { var creds; @@ -92,6 +93,7 @@ describe('channel credentials', function() { }); describe('server credentials', function() { + var grpc = anyGrpc.requireAsServer('grpc'); describe('#createSsl', function() { it('accepts a buffer and array as the first 2 arguments', function() { var creds; @@ -162,4 +164,4 @@ describe('server credentials', function() { }, TypeError); }); }); -}); \ No newline at end of file +}); diff --git a/test/api/credentials_test.js b/test/api/credentials_test.js index e05ec7648..89a61bea6 100644 --- a/test/api/credentials_test.js +++ b/test/api/credentials_test.js @@ -22,7 +22,10 @@ var assert = require('assert'); var fs = require('fs'); var path = require('path'); -var grpc = require('../any_grpc'); +var anyGrpc = require('../any_grpc'); +// TODO(kjin): Google credentials are currently not implemented in the +// JS client. +var maybeSkip = anyGrpc.skipIfJsClient; /** * This is used for testing functions with multiple asynchronous calls that @@ -75,174 +78,48 @@ before(function() { ca_data = fs.readFileSync(ca_path); }); -describe('channel credentials', function() { - describe('#createSsl', function() { - it('works with no arguments', function() { - var creds; - assert.doesNotThrow(function() { - creds = grpc.credentials.createSsl(); - }); - assert.notEqual(creds, null); - }); - it('works with just one Buffer argument', function() { - var creds; - assert.doesNotThrow(function() { - creds = grpc.credentials.createSsl(ca_data); - }); - assert.notEqual(creds, null); - }); - it('works with 3 Buffer arguments', function() { - var creds; - assert.doesNotThrow(function() { - creds = grpc.credentials.createSsl(ca_data, key_data, pem_data); - }); - assert.notEqual(creds, null); - }); - it('works if the first argument is null', function() { - var creds; - assert.doesNotThrow(function() { - creds = grpc.credentials.createSsl(null, key_data, pem_data); - }); - assert.notEqual(creds, null); - }); - it('fails if the first argument is a non-Buffer value', function() { - assert.throws(function() { - grpc.credentials.createSsl('test'); - }, TypeError); - }); - it('fails if the second argument is a non-Buffer value', function() { - assert.throws(function() { - grpc.credentials.createSsl(null, 'test', pem_data); - }, TypeError); - }); - it('fails if the third argument is a non-Buffer value', function() { - assert.throws(function() { - grpc.credentials.createSsl(null, key_data, 'test'); - }, TypeError); - }); - it('fails if only 1 of the last 2 arguments is provided', function() { - assert.throws(function() { - grpc.credentials.createSsl(null, key_data); - }); - assert.throws(function() { - grpc.credentials.createSsl(null, null, pem_data); - }); - }); - }); -}); - -describe('server credentials', function() { - describe('#createSsl', function() { - it('accepts a buffer and array as the first 2 arguments', function() { - var creds; - assert.doesNotThrow(function() { - creds = grpc.ServerCredentials.createSsl(ca_data, []); - }); - assert.notEqual(creds, null); - }); - it('accepts a boolean as the third argument', function() { - var creds; - assert.doesNotThrow(function() { - creds = grpc.ServerCredentials.createSsl(ca_data, [], true); - }); - assert.notEqual(creds, null); - }); - it('accepts an object with two buffers in the second argument', function() { - var creds; - assert.doesNotThrow(function() { - creds = grpc.ServerCredentials.createSsl(null, - [{private_key: key_data, - cert_chain: pem_data}]); - }); - assert.notEqual(creds, null); - }); - it('accepts multiple objects in the second argument', function() { - var creds; - assert.doesNotThrow(function() { - creds = grpc.ServerCredentials.createSsl(null, - [{private_key: key_data, - cert_chain: pem_data}, - {private_key: key_data, - cert_chain: pem_data}]); - }); - assert.notEqual(creds, null); - }); - it('fails if the second argument is not an Array', function() { - assert.throws(function() { - grpc.ServerCredentials.createSsl(ca_data, 'test'); - }, TypeError); - }); - it('fails if the first argument is a non-Buffer value', function() { - assert.throws(function() { - grpc.ServerCredentials.createSsl('test', []); - }, TypeError); - }); - it('fails if the third argument is a non-boolean value', function() { - assert.throws(function() { - grpc.ServerCredentials.createSsl(ca_data, [], 'test'); - }, TypeError); - }); - it('fails if the array elements are not objects', function() { - assert.throws(function() { - grpc.ServerCredentials.createSsl(ca_data, 'test'); - }, TypeError); - }); - it('fails if the object does not have a Buffer private_key', function() { - assert.throws(function() { - grpc.ServerCredentials.createSsl(null, - [{private_key: 'test', - cert_chain: pem_data}]); - }, TypeError); - }); - it('fails if the object does not have a Buffer cert_chain', function() { - assert.throws(function() { - grpc.ServerCredentials.createSsl(null, - [{private_key: key_data, - cert_chain: 'test'}]); - }, TypeError); - }); - }); -}); - describe('client credentials', function() { + var grpc = anyGrpc.requireAsClient('grpc'); var Client; var server; var port; var client_ssl_creds; var client_options = {}; before(function() { - var proto = grpc.load(__dirname + '/test_service.proto'); - server = new grpc.Server(); - server.addService(proto.TestService.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); + anyGrpc.runAsServer((grpc) => { + var proto = grpc.load(__dirname + '/test_service.proto'); + server = new grpc.Server(); + server.addService(proto.TestService.service, { + unary: function(call, cb) { + call.sendMetadata(call.metadata); cb(null, {}); - }); - }, - serverStream: function(stream) { - stream.sendMetadata(stream.metadata); - stream.end(); - }, - bidiStream: function(stream) { - stream.on('data', function(data) {}); - stream.on('end', function() { + }, + 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 creds = grpc.ServerCredentials.createSsl(null, + [{private_key: key_data, cert_chain: pem_data}]); + port = server.bind('localhost:0', creds); + server.start(); }); - var creds = grpc.ServerCredentials.createSsl(null, - [{private_key: key_data, - cert_chain: pem_data}]); - port = server.bind('localhost:0', creds); - server.start(); + var proto = grpc.load(__dirname + '/test_service.proto'); Client = proto.TestService; client_ssl_creds = grpc.credentials.createSsl(ca_data); var host_override = 'foo.test.google.fr'; @@ -326,7 +203,7 @@ describe('client credentials', function() { done(); }); }); - it('should successfully wrap a Google credential', function(done) { + maybeSkip(it)('should successfully wrap a Google credential', function(done) { var creds = grpc.credentials.createFromGoogleCredential( fakeSuccessfulGoogleCredentials); var combined_creds = grpc.credentials.combineChannelCredentials( @@ -360,7 +237,7 @@ describe('client credentials', function() { done(); }); }); - it('should get an error from a Google credential', function(done) { + maybeSkip(it)('should get an error from a Google credential', function(done) { var creds = grpc.credentials.createFromGoogleCredential( fakeFailingGoogleCredentials); var combined_creds = grpc.credentials.combineChannelCredentials( diff --git a/test/api/file_load_test.js b/test/api/file_load_test.js index c24a11002..8441bb10d 100644 --- a/test/api/file_load_test.js +++ b/test/api/file_load_test.js @@ -19,7 +19,7 @@ 'use strict'; var assert = require('assert'); -var grpc = require('../any_grpc'); +var grpc = require('../any_grpc').requireAsClient('grpc'); describe('File loader', function() { it('Should load a proto file by default', function() { diff --git a/test/api/interop_sanity_test.js b/test/api/interop_sanity_test.js index b3f65a034..406cfc3c3 100644 --- a/test/api/interop_sanity_test.js +++ b/test/api/interop_sanity_test.js @@ -18,8 +18,9 @@ 'use strict'; -var interop_server = require('../interop/interop_server.js'); -var interop_client = require('../interop/interop_client.js'); +var anyGrpc = require('../any_grpc'); +var interop_server = anyGrpc.requireAsServer('../interop/interop_server.js'); +var interop_client = anyGrpc.requireAsClient('../interop/interop_client.js'); var server; diff --git a/test/api/math/math_client.js b/test/api/math/math_client.js new file mode 100644 index 000000000..2546c10f1 --- /dev/null +++ b/test/api/math/math_client.js @@ -0,0 +1,10 @@ +const proxyquire = require('proxyquire'); + +module.exports = function getMathClientConstructor(grpc) { + const makeGenericClientConstructor = proxyquire('./math_grpc_pb', { + // note: this mutates the incoming grpc object. + // for or purposes it's unlikely to matter, though. + grpc: Object.assign(grpc, {'@noCallThru': true}) + }); + return makeGenericClientConstructor(); +} diff --git a/test/api/math/math_grpc_pb.js b/test/api/math/math_grpc_pb.js index 68001847c..afd08a34a 100644 --- a/test/api/math/math_grpc_pb.js +++ b/test/api/math/math_grpc_pb.js @@ -16,7 +16,7 @@ // limitations under the License. // 'use strict'; -var grpc = require('../../any_grpc.js'); +var grpc = require('grpc'); var math_math_pb = require('../math/math_pb.js'); function serialize_DivArgs(arg) { diff --git a/test/api/math/math_server.js b/test/api/math/math_server.js index 70ad2dc56..05e30f722 100644 --- a/test/api/math/math_server.js +++ b/test/api/math/math_server.js @@ -18,7 +18,7 @@ 'use strict'; -var grpc = require('../../any_grpc.js'); +var grpc = require('grpc'); var grpcMath = require('./math_grpc_pb'); var math = require('./math_pb'); diff --git a/test/api/math_client_test.js b/test/api/math_client_test.js index f4ba09518..20af475d0 100644 --- a/test/api/math_client_test.js +++ b/test/api/math_client_test.js @@ -20,9 +20,9 @@ var assert = require('assert'); -var grpc = require('../any_grpc'); +var anyGrpc = require('../any_grpc'); var math = require('./math/math_pb'); -var MathClient = require('./math/math_grpc_pb').MathClient; +var MathClient = anyGrpc.requireAsClient('./math/math_grpc_pb').MathClient; /** * Client to use to make requests to a running server. @@ -32,17 +32,17 @@ var math_client; /** * Server to test against */ -var getServer = require('./math/math_server.js'); +var getServer = anyGrpc.requireAsServer('./math/math_server.js'); var server = getServer(); describe('Math client', function() { before(function(done) { var port_num = server.bind('0.0.0.0:0', - grpc.ServerCredentials.createInsecure()); + anyGrpc.server.ServerCredentials.createInsecure()); server.start(); math_client = new MathClient('localhost:' + port_num, - grpc.credentials.createInsecure()); + anyGrpc.client.credentials.createInsecure()); done(); }); after(function() { @@ -79,7 +79,7 @@ describe('Math client', function() { next_expected += 1; }); call.on('status', function checkStatus(status) { - assert.strictEqual(status.code, grpc.status.OK); + assert.strictEqual(status.code, anyGrpc.client.status.OK); done(); }); }); @@ -95,7 +95,7 @@ describe('Math client', function() { } call.end(); call.on('status', function checkStatus(status) { - assert.strictEqual(status.code, grpc.status.OK); + assert.strictEqual(status.code, anyGrpc.client.status.OK); done(); }); }); @@ -118,7 +118,7 @@ describe('Math client', function() { } call.end(); call.on('status', function checkStatus(status) { - assert.strictEqual(status.code, grpc.status.OK); + assert.strictEqual(status.code, anyGrpc.client.status.OK); done(); }); }); diff --git a/test/api/metadata_test.js b/test/api/metadata_test.js index 7825383dd..e989aa038 100644 --- a/test/api/metadata_test.js +++ b/test/api/metadata_test.js @@ -18,7 +18,9 @@ 'use strict'; -var Metadata = require('../any_grpc').Metadata; +var anyGrpc = require('../any_grpc'); +// require as client since grpc-js client was implemented first. +var Metadata = anyGrpc.requireAsClient('grpc').Metadata; var assert = require('assert'); diff --git a/test/api/surface_server_test.js b/test/api/surface_server_test.js new file mode 100644 index 000000000..5c256b403 --- /dev/null +++ b/test/api/surface_server_test.js @@ -0,0 +1,147 @@ +var anyGrpc = require('../any_grpc'); +var assert = require('assert'); +var grpc = anyGrpc.requireAsServer('grpc'); + +var mathProtoPath = __dirname + + '/../../packages/grpc-native-core/deps/grpc/src/proto/math/math.proto'; + +var MathClient = grpc.load(mathProtoPath).math.Math; +var mathServiceAttrs = MathClient.service; + +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.addService', 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.addService(mathServiceAttrs, dummyImpls); + }); + }); + it('Should fail with conflicting method names', function() { + server.addService(mathServiceAttrs, dummyImpls); + assert.throws(function() { + server.addService(mathServiceAttrs, dummyImpls); + }); + }); + it('Should allow method names as originally written', function() { + var altDummyImpls = { + 'Div': function() {}, + 'DivMany': function() {}, + 'Fib': function() {}, + 'Sum': function() {} + }; + assert.doesNotThrow(function() { + server.addService(mathServiceAttrs, altDummyImpls); + }); + }); + it('Should have a conflict between name variations', function() { + /* This is really testing that both name variations are actually used, + by checking that the method actually gets registered, for the + corresponding function, in both cases */ + var altDummyImpls = { + 'Div': function() {}, + 'DivMany': function() {}, + 'Fib': function() {}, + 'Sum': function() {} + }; + server.addProtoService(mathServiceAttrs, altDummyImpls); + assert.throws(function() { + server.addProtoService(mathServiceAttrs, dummyImpls); + }); + }); + it('Should fail if the server has been started', function() { + server.start(); + assert.throws(function() { + server.addService(mathServiceAttrs, dummyImpls); + }); + }); + describe('Default handlers', function() { + var client; + beforeEach(function() { + server.addService(mathServiceAttrs, {}); + var port = server.bind('localhost:0', + grpc.ServerCredentials.createInsecure()); + server.start(); + + anyGrpc.runAsClient((grpc) => { + var MathClient = grpc.load(mathProtoPath).math.Math; + client = new MathClient('localhost:' + port, + grpc.credentials.createInsecure()); + }); + }); + it('should respond to a unary call with UNIMPLEMENTED', function(done) { + client.div({divisor: 4, dividend: 3}, function(error, response) { + assert(error); + assert.strictEqual(error.code, grpc.status.UNIMPLEMENTED); + done(); + }); + }); + it('should respond to a client stream with UNIMPLEMENTED', function(done) { + var call = client.sum(function(error, respones) { + assert(error); + assert.strictEqual(error.code, grpc.status.UNIMPLEMENTED); + done(); + }); + call.end(); + }); + it('should respond to a server stream with UNIMPLEMENTED', function(done) { + var call = client.fib({limit: 5}); + call.on('data', function(value) { + assert.fail('No messages expected'); + }); + call.on('error', function(err) { + assert.strictEqual(err.code, grpc.status.UNIMPLEMENTED); + done(); + }); + call.on('error', function(status) { /* Do nothing */ }); + }); + it('should respond to a bidi call with UNIMPLEMENTED', function(done) { + var call = client.divMany(); + call.on('data', function(value) { + assert.fail('No messages expected'); + }); + call.on('error', function(err) { + assert.strictEqual(err.code, grpc.status.UNIMPLEMENTED); + done(); + }); + call.on('error', function(status) { /* Do nothing */ }); + call.end(); + }); + }); +}); diff --git a/test/api/surface_test.js b/test/api/surface_test.js index 5fdcbcfb7..93290f187 100644 --- a/test/api/surface_test.js +++ b/test/api/surface_test.js @@ -21,12 +21,19 @@ var assert = require('assert'); var _ = require('lodash'); -var grpc = require('../any_grpc'); +var anyGrpc = require('../any_grpc'); +// TODO(kjin): Deadline propagation is not supported for the JS client. +var maybeSkip = anyGrpc.skipIfJsClient; +var grpc = anyGrpc.requireAsClient('grpc'); -var MathClient = grpc.load( - __dirname + '/../../packages/grpc-native-core/deps/grpc/src/proto/math/math.proto').math.Math; +var mathProtoPath = __dirname + + '/../../packages/grpc-native-core/deps/grpc/src/proto/math/math.proto'; + +var MathClient = grpc.load(mathProtoPath).math.Math; var mathServiceAttrs = MathClient.service; +var server_insecure_creds = anyGrpc.server.ServerCredentials.createInsecure(); + /** * This is used for testing functions with multiple asynchronous calls that * can happen in different orders. This should be passed the number of async @@ -48,156 +55,6 @@ function multiDone(done, count) { }; } -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'); - }); - }); -}); -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.addService', 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.addService(mathServiceAttrs, dummyImpls); - }); - }); - it('Should fail with conflicting method names', function() { - server.addService(mathServiceAttrs, dummyImpls); - assert.throws(function() { - server.addService(mathServiceAttrs, dummyImpls); - }); - }); - it('Should allow method names as originally written', function() { - var altDummyImpls = { - 'Div': function() {}, - 'DivMany': function() {}, - 'Fib': function() {}, - 'Sum': function() {} - }; - assert.doesNotThrow(function() { - server.addService(mathServiceAttrs, altDummyImpls); - }); - }); - it('Should have a conflict between name variations', function() { - /* This is really testing that both name variations are actually used, - by checking that the method actually gets registered, for the - corresponding function, in both cases */ - var altDummyImpls = { - 'Div': function() {}, - 'DivMany': function() {}, - 'Fib': function() {}, - 'Sum': function() {} - }; - server.addProtoService(mathServiceAttrs, altDummyImpls); - assert.throws(function() { - server.addProtoService(mathServiceAttrs, dummyImpls); - }); - }); - it('Should fail if the server has been started', function() { - server.start(); - assert.throws(function() { - server.addService(mathServiceAttrs, dummyImpls); - }); - }); - describe('Default handlers', function() { - var client; - beforeEach(function() { - server.addService(mathServiceAttrs, {}); - var port = server.bind('localhost:0', server_insecure_creds); - client = new MathClient('localhost:' + port, - grpc.credentials.createInsecure()); - server.start(); - }); - it('should respond to a unary call with UNIMPLEMENTED', function(done) { - client.div({divisor: 4, dividend: 3}, function(error, response) { - assert(error); - assert.strictEqual(error.code, grpc.status.UNIMPLEMENTED); - done(); - }); - }); - it('should respond to a client stream with UNIMPLEMENTED', function(done) { - var call = client.sum(function(error, respones) { - assert(error); - assert.strictEqual(error.code, grpc.status.UNIMPLEMENTED); - done(); - }); - call.end(); - }); - it('should respond to a server stream with UNIMPLEMENTED', function(done) { - var call = client.fib({limit: 5}); - call.on('data', function(value) { - assert.fail('No messages expected'); - }); - call.on('error', function(err) { - assert.strictEqual(err.code, grpc.status.UNIMPLEMENTED); - done(); - }); - call.on('error', function(status) { /* Do nothing */ }); - }); - it('should respond to a bidi call with UNIMPLEMENTED', function(done) { - var call = client.divMany(); - call.on('data', function(value) { - assert.fail('No messages expected'); - }); - call.on('error', function(err) { - assert.strictEqual(err.code, grpc.status.UNIMPLEMENTED); - done(); - }); - call.on('error', function(status) { /* Do nothing */ }); - call.end(); - }); - }); -}); describe('Client constructor building', function() { var illegal_service_attrs = { $method : { @@ -220,15 +77,18 @@ describe('Client constructor building', function() { assert.strictEqual(Client.prototype.add, Client.prototype.Add); }); }); + describe('waitForClientReady', function() { var server; var port; var Client = MathClient; var client; before(function() { - server = new grpc.Server(); - port = server.bind('localhost:0', grpc.ServerCredentials.createInsecure()); - server.start(); + anyGrpc.runAsServer((grpc) => { + server = new grpc.Server(); + port = server.bind('localhost:0', grpc.ServerCredentials.createInsecure()); + server.start(); + }); }); beforeEach(function() { client = new Client('localhost:' + port, grpc.credentials.createInsecure()); @@ -281,20 +141,26 @@ describe('waitForClientReady', function() { }); }); }); + describe('Echo service', function() { var server; var client; before(function() { - var Client = grpc.load(__dirname + '/echo_service.proto').EchoService; - server = new grpc.Server(); - server.addService(Client.service, { - echo: function(call, callback) { - callback(null, call.request); - } + var port; + anyGrpc.runAsServer((grpc) => { + var Client = grpc.load(__dirname + '/echo_service.proto').EchoService; + server = new grpc.Server(); + server.addService(Client.service, { + echo: function(call, callback) { + callback(null, call.request); + } + }); + port = server.bind('localhost:0', server_insecure_creds); + server.start(); }); - var port = server.bind('localhost:0', server_insecure_creds); + + var Client = grpc.load(__dirname + '/echo_service.proto').EchoService; client = new Client('localhost:' + port, grpc.credentials.createInsecure()); - server.start(); }); after(function() { server.forceShutdown(); @@ -314,6 +180,7 @@ describe('Echo service', function() { }); }); }); + describe('Generic client and server', function() { function toString(val) { return val.toString(); @@ -336,14 +203,18 @@ describe('Generic 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; + anyGrpc.runAsServer((grpc) => { + server = new grpc.Server(); + server.addService(string_service_attrs, { + capitalize: function(call, callback) { + callback(null, _.capitalize(call.request)); + } + }); + port = server.bind('localhost:0', server_insecure_creds); + server.start(); }); - 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()); @@ -360,6 +231,7 @@ describe('Generic client and server', function() { }); }); }); + describe('Server-side getPeer', function() { function toString(val) { return val.toString(); @@ -381,18 +253,22 @@ describe('Server-side getPeer', function() { 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; + anyGrpc.runAsServer((grpc) => { + server = new grpc.Server(); + server.addService(string_service_attrs, { + getPeer: function(call, callback) { + try { + callback(null, call.getPeer()); + } catch (e) { + call.emit('error', e); + } } - } + }); + port = server.bind('localhost:0', server_insecure_creds); + server.start(); }); - 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()); @@ -408,40 +284,46 @@ describe('Server-side getPeer', function() { }); }); }); + describe('Echo metadata', function() { var client; var server; var metadata; before(function() { - var Client = grpc.load(__dirname + '/test_service.proto').TestService; - server = new grpc.Server(); - server.addService(Client.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); + var port; + anyGrpc.runAsServer((grpc) => { + var Client = grpc.load(__dirname + '/test_service.proto').TestService; + server = new grpc.Server(); + server.addService(Client.service, { + unary: function(call, cb) { + call.sendMetadata(call.metadata); cb(null, {}); - }); - }, - serverStream: function(stream) { - stream.sendMetadata(stream.metadata); - stream.end(); - }, - bidiStream: function(stream) { - stream.on('data', function(data) {}); - stream.on('end', function() { + }, + 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(); + }); + } + }); + port = server.bind('localhost:8080', server_insecure_creds); + server.start(); }); - var port = server.bind('localhost:0', server_insecure_creds); + + var Client = grpc.load(__dirname + '/test_service.proto').TestService; client = new Client('localhost:' + port, grpc.credentials.createInsecure()); - server.start(); metadata = new grpc.Metadata(); metadata.set('key', 'value'); }); @@ -485,7 +367,7 @@ describe('Echo metadata', function() { call.end(); }); it('shows the correct user-agent string', function(done) { - var version = require('../any_grpc')['$implementationInfo'].client.corePjson.version; + var version = anyGrpc.clientVersion; var call = client.unary({}, metadata, function(err, data) { assert.ifError(err); }); call.on('metadata', function(metadata) { @@ -507,70 +389,74 @@ describe('Echo metadata', function() { }); }); }); + describe('Client malformed response handling', function() { var server; var client; var badArg = new Buffer([0xFF]); before(function() { - var Client = grpc.load(__dirname + '/test_service.proto').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() { + var port; + anyGrpc.runAsServer((grpc) => { + 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); - }); - }, - serverStream: function(stream) { - stream.write(badArg); - stream.end(); - }, - bidiStream: function(stream) { - stream.on('data', function() { - // Ignore requests + }, + clientStream: function(stream, cb) { + stream.on('data', function() {/* Ignore requests */}); + stream.on('end', function() { + cb(null, badArg); + }); + }, + serverStream: function(stream) { stream.write(badArg); - }); - stream.on('end', function() { stream.end(); - }); - } + }, + bidiStream: function(stream) { + stream.on('data', function() { + // Ignore requests + stream.write(badArg); + }); + stream.on('end', function() { + stream.end(); + }); + } + }); + port = server.bind('localhost:0', server_insecure_creds); + server.start(); }); - var port = server.bind('localhost:0', server_insecure_creds); + var Client = grpc.load(__dirname + '/test_service.proto').TestService; client = new Client('localhost:' + port, grpc.credentials.createInsecure()); - server.start(); }); after(function() { server.forceShutdown(); @@ -610,6 +496,7 @@ describe('Client malformed response handling', function() { call.end(); }); }); + describe('Server serialization failure handling', function() { function serializeFail(obj) { throw new Error('Serialization failed'); @@ -617,65 +504,69 @@ describe('Server serialization failure handling', function() { var client; var server; before(function() { - var Client = grpc.load(__dirname + '/test_service.proto').TestService; - 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 grpc.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() { + var port; + anyGrpc.runAsServer((grpc) => { + 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 grpc.Server(); + server.addService(malformed_test_service, { + unary: function(call, cb) { cb(null, {}); - }); - }, - serverStream: function(stream) { - stream.write({}); - stream.end(); - }, - bidiStream: function(stream) { - stream.on('data', function() { - // Ignore requests + }, + clientStream: function(stream, cb) { + stream.on('data', function() {/* Ignore requests */}); + stream.on('end', function() { + cb(null, {}); + }); + }, + serverStream: function(stream) { stream.write({}); - }); - stream.on('end', function() { stream.end(); - }); - } + }, + bidiStream: function(stream) { + stream.on('data', function() { + // Ignore requests + stream.write({}); + }); + stream.on('end', function() { + stream.end(); + }); + } + }); + port = server.bind('localhost:0', server_insecure_creds); + server.start(); }); - var port = server.bind('localhost:0', server_insecure_creds); + + var Client = grpc.load(__dirname + '/test_service.proto').TestService; client = new Client('localhost:' + port, grpc.credentials.createInsecure()); - server.start(); }); after(function() { server.forceShutdown(); @@ -715,78 +606,82 @@ describe('Server serialization failure handling', function() { call.end(); }); }); + describe('Other conditions', function() { - var Client; var client; var server; var port; before(function() { - Client = grpc.load(__dirname + '/test_service.proto').TestService; - server = new grpc.Server(); - var trailer_metadata = new grpc.Metadata(); - trailer_metadata.add('trailer-present', 'yes'); - server.addService(Client.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); + anyGrpc.runAsServer((grpc) => { + var Client = grpc.load(__dirname + '/test_service.proto').TestService; + server = new grpc.Server(); + var trailer_metadata = new grpc.Metadata(); + trailer_metadata.add('trailer-present', 'yes'); + server.addService(Client.service, { + unary: function(call, cb) { + var req = call.request; + if (req.error) { + cb({code: grpc.status.UNKNOWN, + details: '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}); + cb(null, {count: 1}, trailer_metadata); } - 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); + }, + 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 { - stream.write({count: count}); - count += 1; + for (var i = 0; i < 5; i++) { + stream.write({count: i}); + } + stream.end(trailer_metadata); } - }); - stream.on('end', function() { - 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); + server.start(); }); - port = server.bind('localhost:0', server_insecure_creds); + + var Client = grpc.load(__dirname + '/test_service.proto').TestService; client = new Client('localhost:' + port, grpc.credentials.createInsecure()); - server.start(); }); after(function() { server.forceShutdown(); @@ -1068,37 +963,44 @@ describe('Other conditions', function() { }); }); }); + describe('Call propagation', function() { var proxy; var proxy_impl; - var Client; + var Client = grpc.load(__dirname + '/test_service.proto').TestService; var client; var server; before(function() { - Client = grpc.load(__dirname + '/test_service.proto').TestService; - server = new grpc.Server(); - server.addService(Client.service, { - unary: function(call) {}, - clientStream: function(stream) {}, - serverStream: function(stream) {}, - bidiStream: function(stream) {} - }); - var port = server.bind('localhost:0', server_insecure_creds); + var port; + anyGrpc.runAsServer((grpc) => { + var Client = grpc.load(__dirname + '/test_service.proto').TestService; + server = new grpc.Server(); + server.addService(Client.service, { + unary: function(call) {}, + clientStream: function(stream) {}, + serverStream: function(stream) {}, + bidiStream: function(stream) {} + }); + port = server.bind('localhost:0', server_insecure_creds); + server.start(); + }); + 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) {} - }; + anyGrpc.runAsServer((grpc) => { + proxy = new grpc.Server(); + proxy_impl = { + unary: function(call) {}, + clientStream: function(stream) {}, + serverStream: function(stream) {}, + bidiStream: function(stream) {} + }; + }); }); afterEach(function() { proxy.forceShutdown(); @@ -1197,7 +1099,7 @@ describe('Call propagation', function() { }); }); }); - describe('Deadline', function() { + maybeSkip(describe)('Deadline', function() { /* jshint bitwise:false */ var deadline_flags = (grpc.propagate.DEFAULTS & ~grpc.propagate.CANCELLATION); @@ -1255,21 +1157,29 @@ describe('Call propagation', function() { }); }); }); + describe('Cancelling surface client', function() { var client; var server; before(function() { - server = new grpc.Server(); - server.addService(mathServiceAttrs, { - 'div': function(stream) {}, - 'divMany': function(stream) {}, - 'fib': function(stream) {}, - 'sum': function(stream) {} - }); - var port = server.bind('localhost:0', server_insecure_creds); + var port; + anyGrpc.runAsServer((grpc) => { + var MathClient = grpc.load(mathProtoPath).math.Math; + var mathServiceAttrs = MathClient.service; + + server = new grpc.Server(); + server.addService(mathServiceAttrs, { + 'div': function(stream) {}, + 'divMany': function(stream) {}, + 'fib': function(stream) {}, + 'sum': function(stream) {} + }); + port = server.bind('localhost:0', server_insecure_creds); + server.start(); + }); + var Client = grpc.makeGenericClientConstructor(mathServiceAttrs); client = new Client('localhost:' + port, grpc.credentials.createInsecure()); - server.start(); }); after(function() { server.forceShutdown(); @@ -1320,22 +1230,27 @@ describe('Cancelling surface client', function() { call.cancel(); }); }); + describe('Client reconnect', function() { var server; var Client; var client; var port; beforeEach(function() { - Client = grpc.load(__dirname + '/echo_service.proto').EchoService; - server = new grpc.Server(); - server.addService(Client.service, { - echo: function(call, callback) { - callback(null, call.request); - } + anyGrpc.runAsServer((grpc) => { + var Client = grpc.load(__dirname + '/echo_service.proto').EchoService; + server = new grpc.Server(); + server.addService(Client.service, { + echo: function(call, callback) { + callback(null, call.request); + } + }); + port = server.bind('localhost:0', server_insecure_creds); + server.start(); }); - port = server.bind('localhost:0', server_insecure_creds); + + Client = grpc.load(__dirname + '/echo_service.proto').EchoService; client = new Client('localhost:' + port, grpc.credentials.createInsecure()); - server.start(); }); afterEach(function() { server.forceShutdown(); @@ -1345,14 +1260,17 @@ describe('Client reconnect', function() { assert.ifError(error); assert.deepEqual(response, {value: 'test value', value2: 3}); server.tryShutdown(function() { - server = new grpc.Server(); - server.addService(Client.service, { - echo: function(call, callback) { - callback(null, call.request); - } + anyGrpc.runAsServer(grpc => { + var Client = grpc.load(__dirname + '/echo_service.proto').EchoService; + server = new grpc.Server(); + server.addService(Client.service, { + echo: function(call, callback) { + callback(null, call.request); + } + }); + server.bind('localhost:' + port, server_insecure_creds); + server.start(); }); - server.bind('localhost:' + port, server_insecure_creds); - server.start(); /* We create a new client, that will not throw an error if the server * is not immediately available. Instead, it will wait for the server diff --git a/test/fixtures/native_js.js b/test/fixtures/native_js.js index 5088df96d..e0ca3c588 100644 --- a/test/fixtures/native_js.js +++ b/test/fixtures/native_js.js @@ -1,2 +1,2 @@ -global._server_implementation = 'js'; -global._client_implementation = 'native'; \ No newline at end of file +global._server_implementation = 'native'; +global._client_implementation = 'js'; \ No newline at end of file diff --git a/test/gulpfile.js b/test/gulpfile.js index 70e057962..11c7aa313 100644 --- a/test/gulpfile.js +++ b/test/gulpfile.js @@ -21,6 +21,7 @@ const mocha = require('gulp-mocha'); const execa = require('execa'); const path = require('path'); const del = require('del'); +const semver = require('semver'); const linkSync = require('../util').linkSync; // gulp-help monkeypatches tasks to have an additional description parameter @@ -51,12 +52,10 @@ gulp.task('test', 'Run API-level tests', () => { .on('end', resolve) .on('error', reject); }); - const runTestsArgPairs = [ - ['native', 'native'], - // ['native', 'js'], - // ['js', 'native'], - // ['js', 'js'] - ]; + const runTestsArgPairs = [['native', 'native']]; + if (semver.satisfies(process.version, '8.x')) { + runTestsArgPairs.push(['native', 'js']); + } return runTestsArgPairs.reduce((previousPromise, argPair) => { return previousPromise.then(runTestsWithFixture.bind(null, argPair[0], argPair[1])); }, Promise.resolve()); diff --git a/test/interop/interop_client.js b/test/interop/interop_client.js index 73b84c38c..813cdc788 100644 --- a/test/interop/interop_client.js +++ b/test/interop/interop_client.js @@ -20,7 +20,7 @@ var fs = require('fs'); var path = require('path'); -var grpc = require('../any_grpc')['$implementationInfo'].client.surface; +var grpc = require('grpc'); var testProto = grpc.load({ root: __dirname + '/../../packages/grpc-native-core/deps/grpc', file: 'src/proto/grpc/testing/test.proto'}).grpc.testing; diff --git a/test/interop/interop_server.js b/test/interop/interop_server.js index fe1222dd3..b98137637 100644 --- a/test/interop/interop_server.js +++ b/test/interop/interop_server.js @@ -22,7 +22,7 @@ var fs = require('fs'); var path = require('path'); var _ = require('lodash'); var AsyncDelayQueue = require('./async_delay_queue'); -var grpc = require('../any_grpc')['$implementationInfo'].server.surface; +var grpc = require('grpc'); var testProto = grpc.load({ root: __dirname + '/../../packages/grpc-native-core/deps/grpc', file: 'src/proto/grpc/testing/test.proto'}).grpc.testing; diff --git a/test/package.json b/test/package.json index e3aa0eebd..3c44d0865 100644 --- a/test/package.json +++ b/test/package.json @@ -16,11 +16,14 @@ "dependencies": { "async": "^2.0.1", "body-parser": "^1.15.2", + "caller-id": "^0.1.0", "express": "^4.14.0", "google-auth-library": "^0.9.2", "google-protobuf": "^3.0.0", "lodash": "^4.17.4", "minimist": "^1.1.0", - "poisson-process": "^0.2.1" + "mocha": "^4.0.1", + "poisson-process": "^0.2.1", + "shimmer": "^1.2.0" } }