From 6c1f4bc621cb8810872fbd6b2b010b1d9e869d7f Mon Sep 17 00:00:00 2001 From: Kelvin Jin Date: Wed, 14 Mar 2018 13:15:38 -0700 Subject: [PATCH] client lib integration changes --- test/client-libraries-integration/.gitignore | 2 +- test/client-libraries-integration/init.sh | 8 +- .../libs/.gitkeep | 0 .../client-libraries-integration/package.json | 2 + .../repositories.json | 18 +-- .../use-grpc-js.js | 105 +++++++++++++++--- 6 files changed, 106 insertions(+), 29 deletions(-) create mode 100644 test/client-libraries-integration/libs/.gitkeep diff --git a/test/client-libraries-integration/.gitignore b/test/client-libraries-integration/.gitignore index 5fe2e366..611c25cc 100644 --- a/test/client-libraries-integration/.gitignore +++ b/test/client-libraries-integration/.gitignore @@ -1 +1 @@ -nodejs-*/ \ No newline at end of file +libs/nodejs-*/ \ No newline at end of file diff --git a/test/client-libraries-integration/init.sh b/test/client-libraries-integration/init.sh index c5834a77..d892cdc9 100755 --- a/test/client-libraries-integration/init.sh +++ b/test/client-libraries-integration/init.sh @@ -3,11 +3,13 @@ npm install for dir in $(node -p "require('./repositories.json').join('\n')"); do + pushd libs if [ ! -d $dir ]; then git clone https://github.com/googleapis/$dir + pushd $dir + npm install + popd fi - pushd $dir - npm install popd - node --require ./use-grpc-js.js $(npm bin)/_mocha --timeout 60000 $dir/system-test/*.js + SMOKE_TEST_PROJECT=$GCLOUD_PROJECT node --require ./use-grpc-js.js $(npm bin)/_mocha --timeout 60000 libs/$dir/system-test/*.js done diff --git a/test/client-libraries-integration/libs/.gitkeep b/test/client-libraries-integration/libs/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/test/client-libraries-integration/package.json b/test/client-libraries-integration/package.json index ea639a06..69e02475 100644 --- a/test/client-libraries-integration/package.json +++ b/test/client-libraries-integration/package.json @@ -3,6 +3,8 @@ "version": "0.0.1", "description": "", "dependencies": { + "dot-prop": "^4.2.0", + "google-proto-files": "^0.15.1", "mocha": "^5.0.4", "shimmer": "^1.2.0" } diff --git a/test/client-libraries-integration/repositories.json b/test/client-libraries-integration/repositories.json index 31a937e9..3333f58b 100644 --- a/test/client-libraries-integration/repositories.json +++ b/test/client-libraries-integration/repositories.json @@ -1,20 +1,14 @@ [ + "nodejs-bigtable", "nodejs-datastore", - "nodejs-language", - "nodejs-storage", - "nodejs-translate", - "nodejs-logging", - "nodejs-video-intelligence", "nodejs-dlp", "nodejs-firestore", + "nodejs-language", + "nodejs-logging", + "nodejs-monitoring", "nodejs-pubsub", "nodejs-spanner", "nodejs-speech", - "nodejs-vision", - "nodejs-bigquery", - "nodejs-monitoring", - "nodejs-bigtable", - "nodejs-dns", - "nodejs-resource", - "nodejs-compute" + "nodejs-video-intelligence", + "nodejs-vision" ] \ No newline at end of file diff --git a/test/client-libraries-integration/use-grpc-js.js b/test/client-libraries-integration/use-grpc-js.js index 05273944..a6e5093e 100644 --- a/test/client-libraries-integration/use-grpc-js.js +++ b/test/client-libraries-integration/use-grpc-js.js @@ -1,18 +1,97 @@ +require('source-map-support/register'); const Module = require('module'); const shimmer = require('shimmer'); -const grpcImpl = require('../../packages/grpc-js-core'); const grpcPJson = require('../../packages/grpc-js-core/package'); +const grpcImpl = require('../../packages/grpc-js-core'); +const grpcProtobuf = require('../../packages/grpc-protobufjs'); -shimmer.wrap(Module, '_load', (moduleLoad) => { - return function Module_load(path, parent) { - if (path === 'grpc') { - return grpcImpl; - } else if (path.startsWith('grpc/package')) { - return grpcPJson; - } else { - const result = moduleLoad.apply(this, arguments); - return result; - } - }; -}); +if (!process.env.USE_GRPC_NATIVE) { + shimmer.wrap(Module, '_load', (moduleLoad) => { + return function Module_load(moduleName, parent) { + if (moduleName === 'grpc') { + // load grpc-js when grpc is requested. + return grpcImpl; + } else if (moduleName.startsWith('grpc/package')) { + // load grpc-js's package.json when grpc's package.json is requested. + return grpcPJson; + } else { + const result = moduleLoad.apply(this, arguments); + // monkeypatch google-gax and @google-cloud/common-grpc to avoid all + // references to grpc.load and grpc.loadObject, implementing functions + // on top of the new API for loading proto files. + if (moduleName === 'google-gax') { + if (!result.grpc.prototype.load.__wrapped) { + shimmer.wrap(result.grpc.prototype, 'load', (gaxLoad) => { + return function (filename, format, options) { + if (Array.isArray(filename)) { + options = filename[2]; + filename = filename[0]; + } + const packageDef = grpcProtobuf.loadSync(filename.file, { + keepCase: false, + defaults: true, + enums: String, + include: [filename.root] + }); + return grpcImpl.loadPackageDefinition(packageDef); + } + }); + } + if (!result.grpc.prototype.loadProto.__wrapped) { + shimmer.wrap(result.grpc.prototype, 'loadProto', (gaxLoadProto) => { + const path = require('path'); + const googleProtoFilesDir = require('google-proto-files')('..'); + + return function (protoPath, filename) { + const packageDef = grpcProtobuf.loadSync(filename, { + keepCase: false, + defaults: true, + enums: String, + include: [protoPath, googleProtoFilesDir] + }); + return grpcImpl.loadPackageDefinition(packageDef); + }; + }); + } + } else if (moduleName === '@google-cloud/common-grpc') { + if (!result.Service.prototype.loadProtoFile_.__wrapped) { + shimmer.wrap(result.Service.prototype, 'loadProtoFile_', (commonLoad) => { + const dotProp = require('dot-prop'); + // loadProtoFile_ uses a module-scope cache of loaded proto + // objects which isn't referenced anywhere else + const protoObjectCache = {}; + + return function (protoConfig, config) { + if (typeof protoConfig === 'string') { + protoConfig = { path: protoConfig }; + } + + const protoObjectCacheKey = [ + config.protosDir, + protoConfig.path, + protoConfig.service, + ].join('$'); + + if (!protoObjectCache[protoObjectCacheKey]) { + const services = grpcProtobuf.loadSync(protoConfig.path, { + keepCase: false, + bytes: 'string', + defaults: true, + enums: String, + include: [config.protosDir] + }); + const service = dotProp.get(services.google, protoConfig.service); + protoObjectCache[protoObjectCacheKey] = service; + } + + return protoObjectCache[protoObjectCacheKey]; + } + }); + } + } + return result; + } + }; + }); +}