From 698af354570342687dd1fa53c9bec07372ac2ff0 Mon Sep 17 00:00:00 2001 From: Dominic Kramer Date: Fri, 14 Apr 2017 11:51:10 -0700 Subject: [PATCH 01/14] Initial commit --- config.js | 1 + src/plugins/plugin-bluebird.js | 41 ++++ test/plugins/fixtures/knex0.12/index.js | 1 + test/plugins/fixtures/knex0.12/package.json | 9 + test/plugins/test-trace-knex.js | 209 ++++++++++++++++++++ 5 files changed, 261 insertions(+) create mode 100644 src/plugins/plugin-bluebird.js create mode 100644 test/plugins/fixtures/knex0.12/index.js create mode 100644 test/plugins/fixtures/knex0.12/package.json create mode 100644 test/plugins/test-trace-knex.js diff --git a/config.js b/config.js index 27dc0b926..13ff0cac1 100644 --- a/config.js +++ b/config.js @@ -43,6 +43,7 @@ module.exports = { // value. Disabling any of the default plugins may cause unwanted behavior, // so use caution. plugins: { + 'bluebird': path.join(__dirname, 'src/plugins/plugin-bluebird.js'), 'connect': path.join(__dirname, 'src/plugins/plugin-connect.js'), 'express': path.join(__dirname, 'src/plugins/plugin-express.js'), 'generic-pool': path.join(__dirname, 'src/plugins/plugin-generic-pool.js'), diff --git a/src/plugins/plugin-bluebird.js b/src/plugins/plugin-bluebird.js new file mode 100644 index 000000000..e3d4d6a12 --- /dev/null +++ b/src/plugins/plugin-bluebird.js @@ -0,0 +1,41 @@ +/** + * Copyright 2017 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +'use strict'; + +var shimmer = require('shimmer'); +var is = require('is'); + +function wrapFunction(api, fn) { + return fn && is.fn(fn) ? api.wrap(fn) : fn; +} + +function patchPromise(Promise, api) { + shimmer.wrap(Promise.prototype, '_addCallbacks', function(original) { + return function(fulfill, reject, promise, receiver, domain) { + return original.call(this, wrapFunction(api, fulfill), + wrapFunction(api, reject), + promise, receiver, domain); + }; + }); +} + +module.exports = [ + { + file: 'js/release/bluebird.js', + versions: '3', + patch: patchPromise + } +]; diff --git a/test/plugins/fixtures/knex0.12/index.js b/test/plugins/fixtures/knex0.12/index.js new file mode 100644 index 000000000..93babbfa3 --- /dev/null +++ b/test/plugins/fixtures/knex0.12/index.js @@ -0,0 +1 @@ +module.exports = require('knex'); diff --git a/test/plugins/fixtures/knex0.12/package.json b/test/plugins/fixtures/knex0.12/package.json new file mode 100644 index 000000000..ee35de156 --- /dev/null +++ b/test/plugins/fixtures/knex0.12/package.json @@ -0,0 +1,9 @@ +{ + "name": "knex0.12", + "version": "1.0.0", + "main": "index.js", + "dependencies": { + "knex": "^0.12.9", + "mysql": "^2.13.0" + } +} diff --git a/test/plugins/test-trace-knex.js b/test/plugins/test-trace-knex.js new file mode 100644 index 000000000..24d443244 --- /dev/null +++ b/test/plugins/test-trace-knex.js @@ -0,0 +1,209 @@ +/** + * Copyright 2017 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +'use strict'; + +var common = require('./common.js'); +var traceLabels = require('../../src/trace-labels.js'); + +var RESULT_SIZE = 5; +var TABLE_NAME = 't'; + +var obj = { + k: 1, + v: 'obj' +}; + +describe('test-trace-knex with mysql', function() { + var agent; + var knex; + var assert; + before(function() { + agent = require('../..').start({ + logLevel: 2, + flushDelaySeconds: 1, + enhancedDatabaseReporting: true, + databaseResultReportingSize: RESULT_SIZE + }); + assert = require('assert'); + knex = require('./fixtures/knex0.12')({ + client: 'mysql', + connection: require('../mysql-config') + }); + }); + + beforeEach(function(done) { + knex.schema.createTable(TABLE_NAME, function(table) { + table.integer('k', 10); + table.string('v', 10); + }).then(function(result) { + assert.ok(result); + knex.insert(obj).into(TABLE_NAME).then(function(result) { + assert.ok(result); + common.cleanTraces(agent); + done(); + }); + }); + }); + + afterEach(function(done) { + knex.schema.dropTable(TABLE_NAME).then(function(result) { + assert.ok(result); + common.cleanTraces(agent); + done(); + }); + }); + + it('should perform basic operations', function(done) { + common.runInTransaction(agent, function(endRootSpan) { + knex(TABLE_NAME).select().then(function(res) { + endRootSpan(); + assert(res); + assert.equal(res.length, 1); + assert.equal(res[0].k, 1); + assert.equal(res[0].v, 'obj'); + var spans = common.getMatchingSpans(agent, function (span) { + return span.name === 'mysql-query'; + }); + assert.equal(spans.length, 1); + assert.equal(spans[0].labels.sql, 'select * from `t`'); + done(); + }); + }); + }); + + it('should propagate context', function(done) { + common.runInTransaction(agent, function(endRootSpan) { + knex.select().from(TABLE_NAME).then(function(res) { + assert.ok(common.hasContext()); + endRootSpan(); + done(); + }).catch(function(e) { + assert.ifError(e); + }); + }); + }); + + it('should remove trace frames from stack', function(done) { + common.runInTransaction(agent, function(endRootSpan) { + knex.select().from(TABLE_NAME).then(function(res) { + endRootSpan(); + var spans = common.getMatchingSpans(agent, function (span) { + return span.name === 'mysql-query'; + }); + var labels = spans[0].labels; + var stackTrace = JSON.parse(labels[traceLabels.STACK_TRACE_DETAILS_KEY]); + // Ensure that our patch is on top of the stack + assert( + stackTrace.stack_frame[0].method_name.indexOf('createQuery_trace') !== -1); + done(); + }).catch(function(e) { + assert.ifError(e); + }); + }); + }); + + it('should work with events', function(done) { + common.runInTransaction(agent, function(endRootSpan) { + knex.select().from(TABLE_NAME).on('query-response', function(response, obj, builder) { + var row = response[0]; + assert.ok(row); + assert.equal(row.k, 1); + assert.equal(row.v, 'obj'); + }).on('query-error', function(err, obj) { + assert.ifError(err); + }).then(function(res) { + endRootSpan(); + var spans = common.getMatchingSpans(agent, function (span) { + return span.name === 'mysql-query'; + }); + assert.equal(spans.length, 1); + assert.equal(spans[0 ].labels.sql, 'select * from `t`'); + done(); + }).catch(function(e) { + assert.ifError(e); + }); + }); + }); + + it('should work without events or callback', function(done) { + common.runInTransaction(agent, function(endRootSpan) { + knex.select().from(TABLE_NAME).then(function(result) { + setTimeout(function() { + endRootSpan(); + var spans = common.getMatchingSpans(agent, function (span) { + return span.name === 'mysql-query'; + }); + assert.equal(spans.length, 1); + assert.equal(spans[0].labels.sql, 'select * from `t`'); + done(); + }, 50); + }); + }); + }); + + it('should perform basic transaction', function(done) { + var obj2 = { + k: 2, + v: 'obj2' + }; + common.runInTransaction(agent, function(endRootSpan) { + knex.transaction(function(trx) { + trx.insert(obj2) + .into(TABLE_NAME) + .transacting(trx) + .then(function() { + trx.select() + .from(TABLE_NAME) + .transacting(trx) + .then(function(res) { + assert.equal(res.length, 2); + assert.equal(res[0].k, 1); + assert.equal(res[0].v, 'obj'); + assert.equal(res[1].k, 2); + assert.equal(res[1].v, 'obj2'); + }) + .then(trx.rollback) + .then(function() { + knex.select() + .from(TABLE_NAME) + .then(function(res) { + endRootSpan(); + assert.equal(res.length, 1); + assert.equal(res[0].k, 1); + assert.equal(res[0].v, 'obj'); + var spans = common.getMatchingSpans(agent, function (span) { + return span.name === 'mysql-query'; + }); + var expectedCmds = ['BEGIN;', 'insert into `t` (`k`, `v`) values (?, ?)', + 'select * from `t`', 'ROLLBACK;', 'select * from `t`']; + assert.equal(expectedCmds.length, spans.length); + for (var i = 0; i < spans.length; i++) { + assert.equal(spans[i].labels.sql, expectedCmds[i]); + } + done(); + }); + }).catch(function(err) { + assert.ifError(err); + }); + }).catch(function(err) { + assert.ifError(err); + }); + }).catch(function(err) { + assert.ifError(err); + }); + }); + }); +}); From 6b9b5da749a9976f52326375dcc5584183523be4 Mon Sep 17 00:00:00 2001 From: Dominic Kramer Date: Fri, 14 Apr 2017 12:08:04 -0700 Subject: [PATCH 02/14] Fix the `test-config-plugins.js` test --- test/test-config-plugins.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/test-config-plugins.js b/test/test-config-plugins.js index 1275ba090..8a0129c40 100644 --- a/test/test-config-plugins.js +++ b/test/test-config-plugins.js @@ -21,8 +21,8 @@ var trace = require('..'); var common = require('./plugins/common.js'); -var instrumentedModules = ['connect', 'express', 'generic-pool', 'grpc', - 'hapi', 'http', 'koa', 'mongodb-core', 'mysql', 'pg', 'redis', 'restify']; +var instrumentedModules = ['bluebird', 'connect', 'express', 'grpc', 'hapi', + 'http', 'koa', 'mongodb-core', 'mysql', 'pg', 'redis', 'restify']; describe('plugin configuration', function() { it('should have correct defaults', function() { From a7c6bdfb400ab54f15033d9e7b6e9c5720e169f4 Mon Sep 17 00:00:00 2001 From: Dominic Kramer Date: Mon, 8 May 2017 17:39:05 -0700 Subject: [PATCH 03/14] Fix context loss in knex without patching bluebird I think this patch is specific to mysql. I will investigate this further. --- config.js | 2 +- src/plugins/plugin-bluebird.js | 41 --------------------- src/plugins/plugin-knex.js | 65 +++++++++++++++++++++++++++++++++ test/plugins/test-trace-knex.js | 2 +- test/test-config-plugins.js | 4 +- 5 files changed, 69 insertions(+), 45 deletions(-) delete mode 100644 src/plugins/plugin-bluebird.js create mode 100644 src/plugins/plugin-knex.js diff --git a/config.js b/config.js index 13ff0cac1..d300b44ce 100644 --- a/config.js +++ b/config.js @@ -43,13 +43,13 @@ module.exports = { // value. Disabling any of the default plugins may cause unwanted behavior, // so use caution. plugins: { - 'bluebird': path.join(__dirname, 'src/plugins/plugin-bluebird.js'), 'connect': path.join(__dirname, 'src/plugins/plugin-connect.js'), 'express': path.join(__dirname, 'src/plugins/plugin-express.js'), 'generic-pool': path.join(__dirname, 'src/plugins/plugin-generic-pool.js'), 'grpc': path.join(__dirname, 'src/plugins/plugin-grpc.js'), 'hapi': path.join(__dirname, 'src/plugins/plugin-hapi.js'), 'http': path.join(__dirname, 'src/plugins/plugin-http.js'), + 'knex': path.join(__dirname, 'src/plugins/plugin-knex.js'), 'koa': path.join(__dirname, 'src/plugins/plugin-koa.js'), 'mongodb-core': path.join(__dirname, 'src/plugins/plugin-mongodb-core.js'), 'mysql': path.join(__dirname, 'src/plugins/plugin-mysql.js'), diff --git a/src/plugins/plugin-bluebird.js b/src/plugins/plugin-bluebird.js deleted file mode 100644 index e3d4d6a12..000000000 --- a/src/plugins/plugin-bluebird.js +++ /dev/null @@ -1,41 +0,0 @@ -/** - * Copyright 2017 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -'use strict'; - -var shimmer = require('shimmer'); -var is = require('is'); - -function wrapFunction(api, fn) { - return fn && is.fn(fn) ? api.wrap(fn) : fn; -} - -function patchPromise(Promise, api) { - shimmer.wrap(Promise.prototype, '_addCallbacks', function(original) { - return function(fulfill, reject, promise, receiver, domain) { - return original.call(this, wrapFunction(api, fulfill), - wrapFunction(api, reject), - promise, receiver, domain); - }; - }); -} - -module.exports = [ - { - file: 'js/release/bluebird.js', - versions: '3', - patch: patchPromise - } -]; diff --git a/src/plugins/plugin-knex.js b/src/plugins/plugin-knex.js new file mode 100644 index 000000000..ffa77c5fc --- /dev/null +++ b/src/plugins/plugin-knex.js @@ -0,0 +1,65 @@ +/** + * Copyright 2017 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +'use strict'; + +var shimmer = require('shimmer'); +var is = require('is'); + +var VERSIONS = '0.12.x'; + +function patchClient(Client, api) { + shimmer.wrap(Client.prototype, 'runner', function(original) { + return function() { + var runner = original.apply(this, arguments); + runner.query = api.wrap(runner.query); + return runner; + }; + }); +} + +function unpatchClient(Client) { + shimmer.unwrap(Client.prototype, 'runner'); +} + +function patchMysqlIndex(Mysql, api) { + shimmer.wrap(Mysql.prototype, 'transaction', function(original) { + return function() { + var args = Array.prototype.slice.call(arguments).map(function(item) { + return item && is.fn(item) ? api.wrap(item) : item; + }); + return original.apply(this, args); + }; + }); +} + +function unpatchMysqlIndex(Mysql) { + shimmer.unwrap(Mysql.prototype, 'transaction'); +} + +module.exports = [ + { + file: 'lib/client.js', + versions: VERSIONS, + patch: patchClient, + unpatch: unpatchClient + }, + { + file: 'lib/dialects/mysql/index.js', + version: VERSIONS, + patch: patchMysqlIndex, + unpatch: unpatchMysqlIndex + } +]; diff --git a/test/plugins/test-trace-knex.js b/test/plugins/test-trace-knex.js index 24d443244..3bcf8992e 100644 --- a/test/plugins/test-trace-knex.js +++ b/test/plugins/test-trace-knex.js @@ -187,7 +187,7 @@ describe('test-trace-knex with mysql', function() { var spans = common.getMatchingSpans(agent, function (span) { return span.name === 'mysql-query'; }); - var expectedCmds = ['BEGIN;', 'insert into `t` (`k`, `v`) values (?, ?)', + var expectedCmds = ['insert into `t` (`k`, `v`) values (?, ?)', 'select * from `t`', 'ROLLBACK;', 'select * from `t`']; assert.equal(expectedCmds.length, spans.length); for (var i = 0; i < spans.length; i++) { diff --git a/test/test-config-plugins.js b/test/test-config-plugins.js index 8a0129c40..4933fbbcb 100644 --- a/test/test-config-plugins.js +++ b/test/test-config-plugins.js @@ -21,8 +21,8 @@ var trace = require('..'); var common = require('./plugins/common.js'); -var instrumentedModules = ['bluebird', 'connect', 'express', 'grpc', 'hapi', - 'http', 'koa', 'mongodb-core', 'mysql', 'pg', 'redis', 'restify']; +var instrumentedModules = ['connect', 'express', 'grpc', 'hapi', + 'http', 'knex', 'koa', 'mongodb-core', 'mysql', 'pg', 'redis', 'restify']; describe('plugin configuration', function() { it('should have correct defaults', function() { From f80681fbee3726d2b5ff821f1fc6ca206c0cf255 Mon Sep 17 00:00:00 2001 From: Dominic Kramer Date: Tue, 9 May 2017 09:44:40 -0700 Subject: [PATCH 04/14] Fix the test-config-plugins.js test --- test/test-config-plugins.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test-config-plugins.js b/test/test-config-plugins.js index 4933fbbcb..31dfbd958 100644 --- a/test/test-config-plugins.js +++ b/test/test-config-plugins.js @@ -21,7 +21,7 @@ var trace = require('..'); var common = require('./plugins/common.js'); -var instrumentedModules = ['connect', 'express', 'grpc', 'hapi', +var instrumentedModules = ['connect', 'express', 'generic-pool', 'grpc', 'hapi', 'http', 'knex', 'koa', 'mongodb-core', 'mysql', 'pg', 'redis', 'restify']; describe('plugin configuration', function() { From aa7279ad5c9d0dc0315813a019af603e6ae10282 Mon Sep 17 00:00:00 2001 From: Dominic Kramer Date: Wed, 10 May 2017 16:10:26 -0700 Subject: [PATCH 05/14] Intercept the module root to patch `transaction` This commit intercepts the module root to patch the `transaction` method. This works because the `knex` module exports a constructor and the object that the constructor constructs has a `client` property that is the client being used. This client can have its `transaction` method updated in a way to preserve context. --- src/plugins/plugin-knex.js | 42 +++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/plugins/plugin-knex.js b/src/plugins/plugin-knex.js index ffa77c5fc..c36c48bbe 100644 --- a/src/plugins/plugin-knex.js +++ b/src/plugins/plugin-knex.js @@ -30,36 +30,36 @@ function patchClient(Client, api) { }); } -function unpatchClient(Client) { - shimmer.unwrap(Client.prototype, 'runner'); -} - -function patchMysqlIndex(Mysql, api) { - shimmer.wrap(Mysql.prototype, 'transaction', function(original) { - return function() { - var args = Array.prototype.slice.call(arguments).map(function(item) { - return item && is.fn(item) ? api.wrap(item) : item; - }); - return original.apply(this, args); - }; - }); +function interceptKnex(Knex, api) { + return function() { + var result = Knex.apply(this, arguments); + var proto = Object.getPrototypeOf(result.client); + shimmer.wrap(proto, 'transaction', function(original) { + return function() { + var args = Array.prototype.slice.call(arguments).map(function(item) { + return item && is.fn(item) ? api.wrap(item) : item; + }); + return original.apply(this, args); + }; + }); + return result; + }; } -function unpatchMysqlIndex(Mysql) { - shimmer.unwrap(Mysql.prototype, 'transaction'); +function unpatchClient(Client) { + shimmer.unwrap(Client.prototype, 'runner'); } module.exports = [ + { + file: '', + versions: VERSIONS, + intercept: interceptKnex + }, { file: 'lib/client.js', versions: VERSIONS, patch: patchClient, unpatch: unpatchClient - }, - { - file: 'lib/dialects/mysql/index.js', - version: VERSIONS, - patch: patchMysqlIndex, - unpatch: unpatchMysqlIndex } ]; From cead626c2a5c014baf2de35229bb0d6d9b79afd5 Mon Sep 17 00:00:00 2001 From: Dominic Kramer Date: Tue, 16 May 2017 13:45:51 -0700 Subject: [PATCH 06/14] Intercept `lib/transaction.js` to preserve context --- src/plugins/plugin-knex.js | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/src/plugins/plugin-knex.js b/src/plugins/plugin-knex.js index c36c48bbe..7e4beb179 100644 --- a/src/plugins/plugin-knex.js +++ b/src/plugins/plugin-knex.js @@ -16,6 +16,7 @@ 'use strict'; var shimmer = require('shimmer'); +var util = require('util'); var is = require('is'); var VERSIONS = '0.12.x'; @@ -30,20 +31,16 @@ function patchClient(Client, api) { }); } -function interceptKnex(Knex, api) { - return function() { - var result = Knex.apply(this, arguments); - var proto = Object.getPrototypeOf(result.client); - shimmer.wrap(proto, 'transaction', function(original) { - return function() { - var args = Array.prototype.slice.call(arguments).map(function(item) { - return item && is.fn(item) ? api.wrap(item) : item; - }); - return original.apply(this, args); - }; - }); - return result; - }; +function wrapIfFn(fn, api) { + return fn && is.fn(fn) ? api.wrap(fn) : fn; +} + +function interceptTransaction(Transaction, api) { + function WrappedTransaction(client, container, config, outerTx) { + Transaction.call(this, client, wrapIfFn(container, api), config, outerTx); + } + util.inherits(WrappedTransaction, Transaction); + return WrappedTransaction; } function unpatchClient(Client) { @@ -52,9 +49,9 @@ function unpatchClient(Client) { module.exports = [ { - file: '', + file: 'lib/transaction.js', versions: VERSIONS, - intercept: interceptKnex + intercept: interceptTransaction }, { file: 'lib/client.js', From 93b2db2ddcea7da377cb7972557864a4b4f91530 Mon Sep 17 00:00:00 2001 From: Dominic Kramer Date: Thu, 18 May 2017 14:30:50 -0700 Subject: [PATCH 07/14] Fix the use of rollback in the unit tests --- test/plugins/test-trace-knex.js | 80 +++++++++++++++++---------------- 1 file changed, 41 insertions(+), 39 deletions(-) diff --git a/test/plugins/test-trace-knex.js b/test/plugins/test-trace-knex.js index 3bcf8992e..fa44737de 100644 --- a/test/plugins/test-trace-knex.js +++ b/test/plugins/test-trace-knex.js @@ -161,48 +161,50 @@ describe('test-trace-knex with mysql', function() { }; common.runInTransaction(agent, function(endRootSpan) { knex.transaction(function(trx) { - trx.insert(obj2) - .into(TABLE_NAME) - .transacting(trx) - .then(function() { - trx.select() - .from(TABLE_NAME) - .transacting(trx) - .then(function(res) { - assert.equal(res.length, 2); - assert.equal(res[0].k, 1); - assert.equal(res[0].v, 'obj'); - assert.equal(res[1].k, 2); - assert.equal(res[1].v, 'obj2'); - }) - .then(trx.rollback) - .then(function() { - knex.select() - .from(TABLE_NAME) - .then(function(res) { - endRootSpan(); - assert.equal(res.length, 1); - assert.equal(res[0].k, 1); - assert.equal(res[0].v, 'obj'); - var spans = common.getMatchingSpans(agent, function (span) { - return span.name === 'mysql-query'; - }); - var expectedCmds = ['insert into `t` (`k`, `v`) values (?, ?)', - 'select * from `t`', 'ROLLBACK;', 'select * from `t`']; - assert.equal(expectedCmds.length, spans.length); - for (var i = 0; i < spans.length; i++) { - assert.equal(spans[i].labels.sql, expectedCmds[i]); - } - done(); - }); - }).catch(function(err) { - assert.ifError(err); - }); + knex.insert(obj2) + .into(TABLE_NAME) + .transacting(trx) + .then(function(res) { + return trx.select() + .from(TABLE_NAME) + .then(function(res) { + assert.equal(res.length, 2); + assert.equal(res[0].k, 1); + assert.equal(res[0].v, 'obj'); + assert.equal(res[1].k, 2); + assert.equal(res[1].v, 'obj2'); + }).catch(function(err) { + assert.ifError(err); + }); + }) + .then(function() { + trx.rollback(new Error('Rolling back')); + }).catch(function(err) { + assert.ifError(err); + }); + }).catch(function(err) { + assert.ok(err); + assert.strictEqual(err.message, 'Rolling back'); + knex.select() + .from(TABLE_NAME) + .then(function(res) { + endRootSpan(); + assert.equal(res.length, 1); + assert.equal(res[0].k, 1); + assert.equal(res[0].v, 'obj'); + var spans = common.getMatchingSpans(agent, function (span) { + return span.name === 'mysql-query'; + }); + var expectedCmds = ['insert into `t` (`k`, `v`) values (?, ?)', + 'select * from `t`', 'ROLLBACK;', 'select * from `t`']; + assert.equal(expectedCmds.length, spans.length); + for (var i = 0; i < spans.length; i++) { + assert.equal(spans[i].labels.sql, expectedCmds[i]); + } + done(); }).catch(function(err) { assert.ifError(err); }); - }).catch(function(err) { - assert.ifError(err); }); }); }); From 4b041f782f91789d76746e36b7da73a2da0fa603 Mon Sep 17 00:00:00 2001 From: Dominic Kramer Date: Thu, 18 May 2017 14:49:37 -0700 Subject: [PATCH 08/14] Add support for Knex 0.13 --- src/plugins/plugin-knex.js | 2 +- test/plugins/fixtures/knex0.13/index.js | 1 + test/plugins/fixtures/knex0.13/package.json | 9 + test/plugins/test-trace-knex.js | 300 ++++++++++---------- 4 files changed, 167 insertions(+), 145 deletions(-) create mode 100644 test/plugins/fixtures/knex0.13/index.js create mode 100644 test/plugins/fixtures/knex0.13/package.json diff --git a/src/plugins/plugin-knex.js b/src/plugins/plugin-knex.js index 7e4beb179..329a0a723 100644 --- a/src/plugins/plugin-knex.js +++ b/src/plugins/plugin-knex.js @@ -19,7 +19,7 @@ var shimmer = require('shimmer'); var util = require('util'); var is = require('is'); -var VERSIONS = '0.12.x'; +var VERSIONS = '>=0.12 <=0.13'; function patchClient(Client, api) { shimmer.wrap(Client.prototype, 'runner', function(original) { diff --git a/test/plugins/fixtures/knex0.13/index.js b/test/plugins/fixtures/knex0.13/index.js new file mode 100644 index 000000000..93babbfa3 --- /dev/null +++ b/test/plugins/fixtures/knex0.13/index.js @@ -0,0 +1 @@ +module.exports = require('knex'); diff --git a/test/plugins/fixtures/knex0.13/package.json b/test/plugins/fixtures/knex0.13/package.json new file mode 100644 index 000000000..4627d2551 --- /dev/null +++ b/test/plugins/fixtures/knex0.13/package.json @@ -0,0 +1,9 @@ +{ + "name": "knex0.13", + "version": "1.0.0", + "main": "index.js", + "dependencies": { + "knex": "^0.13.0", + "mysql": "^2.13.0" + } +} diff --git a/test/plugins/test-trace-knex.js b/test/plugins/test-trace-knex.js index fa44737de..49ca59b4d 100644 --- a/test/plugins/test-trace-knex.js +++ b/test/plugins/test-trace-knex.js @@ -26,9 +26,13 @@ var obj = { v: 'obj' }; -describe('test-trace-knex with mysql', function() { +var versions = { + knex12: './fixtures/knex0.12', + knex13: './fixtures/knex0.13' +}; + +describe('test-trace-knex', function() { var agent; - var knex; var assert; before(function() { agent = require('../..').start({ @@ -38,173 +42,181 @@ describe('test-trace-knex with mysql', function() { databaseResultReportingSize: RESULT_SIZE }); assert = require('assert'); - knex = require('./fixtures/knex0.12')({ - client: 'mysql', - connection: require('../mysql-config') - }); }); - beforeEach(function(done) { - knex.schema.createTable(TABLE_NAME, function(table) { - table.integer('k', 10); - table.string('v', 10); - }).then(function(result) { - assert.ok(result); - knex.insert(obj).into(TABLE_NAME).then(function(result) { - assert.ok(result); - common.cleanTraces(agent); - done(); + Object.keys(versions).forEach(function(version) { + describe('with mysql and ' + version, function() { + var knex; + before(function() { + knex = require(versions[version])({ + client: 'mysql', + connection: require('../mysql-config') + }); }); - }); - }); - afterEach(function(done) { - knex.schema.dropTable(TABLE_NAME).then(function(result) { - assert.ok(result); - common.cleanTraces(agent); - done(); - }); - }); - - it('should perform basic operations', function(done) { - common.runInTransaction(agent, function(endRootSpan) { - knex(TABLE_NAME).select().then(function(res) { - endRootSpan(); - assert(res); - assert.equal(res.length, 1); - assert.equal(res[0].k, 1); - assert.equal(res[0].v, 'obj'); - var spans = common.getMatchingSpans(agent, function (span) { - return span.name === 'mysql-query'; + beforeEach(function(done) { + knex.schema.createTable(TABLE_NAME, function(table) { + table.integer('k', 10); + table.string('v', 10); + }).then(function(result) { + assert.ok(result); + knex.insert(obj).into(TABLE_NAME).then(function(result) { + assert.ok(result); + common.cleanTraces(agent); + done(); + }); }); - assert.equal(spans.length, 1); - assert.equal(spans[0].labels.sql, 'select * from `t`'); - done(); }); - }); - }); - it('should propagate context', function(done) { - common.runInTransaction(agent, function(endRootSpan) { - knex.select().from(TABLE_NAME).then(function(res) { - assert.ok(common.hasContext()); - endRootSpan(); - done(); - }).catch(function(e) { - assert.ifError(e); + afterEach(function(done) { + knex.schema.dropTable(TABLE_NAME).then(function(result) { + assert.ok(result); + common.cleanTraces(agent); + done(); + }); }); - }); - }); - it('should remove trace frames from stack', function(done) { - common.runInTransaction(agent, function(endRootSpan) { - knex.select().from(TABLE_NAME).then(function(res) { - endRootSpan(); - var spans = common.getMatchingSpans(agent, function (span) { - return span.name === 'mysql-query'; + it('should perform basic operations using ' + version, function(done) { + common.runInTransaction(agent, function(endRootSpan) { + knex(TABLE_NAME).select().then(function(res) { + endRootSpan(); + assert(res); + assert.equal(res.length, 1); + assert.equal(res[0].k, 1); + assert.equal(res[0].v, 'obj'); + var spans = common.getMatchingSpans(agent, function (span) { + return span.name === 'mysql-query'; + }); + assert.equal(spans.length, 1); + assert.equal(spans[0].labels.sql, 'select * from `t`'); + done(); + }); }); - var labels = spans[0].labels; - var stackTrace = JSON.parse(labels[traceLabels.STACK_TRACE_DETAILS_KEY]); - // Ensure that our patch is on top of the stack - assert( - stackTrace.stack_frame[0].method_name.indexOf('createQuery_trace') !== -1); - done(); - }).catch(function(e) { - assert.ifError(e); }); - }); - }); - it('should work with events', function(done) { - common.runInTransaction(agent, function(endRootSpan) { - knex.select().from(TABLE_NAME).on('query-response', function(response, obj, builder) { - var row = response[0]; - assert.ok(row); - assert.equal(row.k, 1); - assert.equal(row.v, 'obj'); - }).on('query-error', function(err, obj) { - assert.ifError(err); - }).then(function(res) { - endRootSpan(); - var spans = common.getMatchingSpans(agent, function (span) { - return span.name === 'mysql-query'; + it('should propagate context using ' + version, function(done) { + common.runInTransaction(agent, function(endRootSpan) { + knex.select().from(TABLE_NAME).then(function(res) { + assert.ok(common.hasContext()); + endRootSpan(); + done(); + }).catch(function(e) { + assert.ifError(e); + }); }); - assert.equal(spans.length, 1); - assert.equal(spans[0 ].labels.sql, 'select * from `t`'); - done(); - }).catch(function(e) { - assert.ifError(e); }); - }); - }); - it('should work without events or callback', function(done) { - common.runInTransaction(agent, function(endRootSpan) { - knex.select().from(TABLE_NAME).then(function(result) { - setTimeout(function() { - endRootSpan(); - var spans = common.getMatchingSpans(agent, function (span) { - return span.name === 'mysql-query'; + it('should remove trace frames from stack using ' + version, function(done) { + common.runInTransaction(agent, function(endRootSpan) { + knex.select().from(TABLE_NAME).then(function(res) { + endRootSpan(); + var spans = common.getMatchingSpans(agent, function (span) { + return span.name === 'mysql-query'; + }); + var labels = spans[0].labels; + var stackTrace = JSON.parse(labels[traceLabels.STACK_TRACE_DETAILS_KEY]); + // Ensure that our patch is on top of the stack + assert( + stackTrace.stack_frame[0].method_name.indexOf('createQuery_trace') !== -1); + done(); + }).catch(function(e) { + assert.ifError(e); }); - assert.equal(spans.length, 1); - assert.equal(spans[0].labels.sql, 'select * from `t`'); - done(); - }, 50); + }); }); - }); - }); - it('should perform basic transaction', function(done) { - var obj2 = { - k: 2, - v: 'obj2' - }; - common.runInTransaction(agent, function(endRootSpan) { - knex.transaction(function(trx) { - knex.insert(obj2) - .into(TABLE_NAME) - .transacting(trx) - .then(function(res) { - return trx.select() - .from(TABLE_NAME) - .then(function(res) { - assert.equal(res.length, 2); - assert.equal(res[0].k, 1); - assert.equal(res[0].v, 'obj'); - assert.equal(res[1].k, 2); - assert.equal(res[1].v, 'obj2'); - }).catch(function(err) { - assert.ifError(err); - }); - }) - .then(function() { - trx.rollback(new Error('Rolling back')); - }).catch(function(err) { - assert.ifError(err); - }); - }).catch(function(err) { - assert.ok(err); - assert.strictEqual(err.message, 'Rolling back'); - knex.select() - .from(TABLE_NAME) - .then(function(res) { + it('should work with events using ' + version, function(done) { + common.runInTransaction(agent, function(endRootSpan) { + knex.select().from(TABLE_NAME).on('query-response', function(response, obj, builder) { + var row = response[0]; + assert.ok(row); + assert.equal(row.k, 1); + assert.equal(row.v, 'obj'); + }).on('query-error', function(err, obj) { + assert.ifError(err); + }).then(function(res) { endRootSpan(); - assert.equal(res.length, 1); - assert.equal(res[0].k, 1); - assert.equal(res[0].v, 'obj'); var spans = common.getMatchingSpans(agent, function (span) { return span.name === 'mysql-query'; }); - var expectedCmds = ['insert into `t` (`k`, `v`) values (?, ?)', - 'select * from `t`', 'ROLLBACK;', 'select * from `t`']; - assert.equal(expectedCmds.length, spans.length); - for (var i = 0; i < spans.length; i++) { - assert.equal(spans[i].labels.sql, expectedCmds[i]); - } + assert.equal(spans.length, 1); + assert.equal(spans[0 ].labels.sql, 'select * from `t`'); done(); + }).catch(function(e) { + assert.ifError(e); + }); + }); + }); + + it('should work without events or callback using ' + version, function(done) { + common.runInTransaction(agent, function(endRootSpan) { + knex.select().from(TABLE_NAME).then(function(result) { + setTimeout(function() { + endRootSpan(); + var spans = common.getMatchingSpans(agent, function (span) { + return span.name === 'mysql-query'; + }); + assert.equal(spans.length, 1); + assert.equal(spans[0].labels.sql, 'select * from `t`'); + done(); + }, 50); + }); + }); + }); + + it('should perform basic transaction using ' + version, function(done) { + var obj2 = { + k: 2, + v: 'obj2' + }; + common.runInTransaction(agent, function(endRootSpan) { + knex.transaction(function(trx) { + knex.insert(obj2) + .into(TABLE_NAME) + .transacting(trx) + .then(function(res) { + return trx.select() + .from(TABLE_NAME) + .then(function(res) { + assert.equal(res.length, 2); + assert.equal(res[0].k, 1); + assert.equal(res[0].v, 'obj'); + assert.equal(res[1].k, 2); + assert.equal(res[1].v, 'obj2'); + }).catch(function(err) { + assert.ifError(err); + }); + }) + .then(function() { + trx.rollback(new Error('Rolling back')); + }).catch(function(err) { + assert.ifError(err); + }); }).catch(function(err) { - assert.ifError(err); + assert.ok(err); + assert.strictEqual(err.message, 'Rolling back'); + knex.select() + .from(TABLE_NAME) + .then(function(res) { + endRootSpan(); + assert.equal(res.length, 1); + assert.equal(res[0].k, 1); + assert.equal(res[0].v, 'obj'); + var spans = common.getMatchingSpans(agent, function (span) { + return span.name === 'mysql-query'; + }); + var expectedCmds = ['insert into `t` (`k`, `v`) values (?, ?)', + 'select * from `t`', 'ROLLBACK;', 'select * from `t`']; + assert.equal(expectedCmds.length, spans.length); + for (var i = 0; i < spans.length; i++) { + assert.equal(spans[i].labels.sql, expectedCmds[i]); + } + done(); + }).catch(function(err) { + assert.ifError(err); + }); }); + }); }); }); }); From fe7dc68ac7a50045ff215d84c3ca886b0850ebb8 Mon Sep 17 00:00:00 2001 From: Dominic Kramer Date: Thu, 18 May 2017 15:17:45 -0700 Subject: [PATCH 09/14] Add tests for knex 0.11.x --- src/plugins/plugin-knex.js | 1 + test/plugins/fixtures/knex0.11/index.js | 1 + test/plugins/fixtures/knex0.11/package.json | 9 ++++ test/plugins/test-trace-knex.js | 52 +++++++++++++++++---- 4 files changed, 55 insertions(+), 8 deletions(-) create mode 100644 test/plugins/fixtures/knex0.11/index.js create mode 100644 test/plugins/fixtures/knex0.11/package.json diff --git a/src/plugins/plugin-knex.js b/src/plugins/plugin-knex.js index 329a0a723..81cd64ba3 100644 --- a/src/plugins/plugin-knex.js +++ b/src/plugins/plugin-knex.js @@ -19,6 +19,7 @@ var shimmer = require('shimmer'); var util = require('util'); var is = require('is'); +// knex 0.11.x does not need patching var VERSIONS = '>=0.12 <=0.13'; function patchClient(Client, api) { diff --git a/test/plugins/fixtures/knex0.11/index.js b/test/plugins/fixtures/knex0.11/index.js new file mode 100644 index 000000000..93babbfa3 --- /dev/null +++ b/test/plugins/fixtures/knex0.11/index.js @@ -0,0 +1 @@ +module.exports = require('knex'); diff --git a/test/plugins/fixtures/knex0.11/package.json b/test/plugins/fixtures/knex0.11/package.json new file mode 100644 index 000000000..b42259f95 --- /dev/null +++ b/test/plugins/fixtures/knex0.11/package.json @@ -0,0 +1,9 @@ +{ + "name": "knex0.11", + "version": "1.0.0", + "main": "index.js", + "dependencies": { + "knex": "^0.11.0", + "mysql": "^2.13.0" + } +} diff --git a/test/plugins/test-trace-knex.js b/test/plugins/test-trace-knex.js index 49ca59b4d..fa473e4fd 100644 --- a/test/plugins/test-trace-knex.js +++ b/test/plugins/test-trace-knex.js @@ -27,6 +27,7 @@ var obj = { }; var versions = { + knex11: './fixtures/knex0.11', knex12: './fixtures/knex0.12', knex13: './fixtures/knex0.13' }; @@ -87,8 +88,15 @@ describe('test-trace-knex', function() { var spans = common.getMatchingSpans(agent, function (span) { return span.name === 'mysql-query'; }); - assert.equal(spans.length, 1); - assert.equal(spans[0].labels.sql, 'select * from `t`'); + if (version === 'knex11') { + assert.equal(spans.length, 2); + assert.equal(spans[0].labels.sql, 'SELECT 1'); + assert.equal(spans[1].labels.sql, 'select * from `t`'); + } + else { + assert.equal(spans.length, 1); + assert.equal(spans[0].labels.sql, 'select * from `t`'); + } done(); }); }); @@ -139,8 +147,15 @@ describe('test-trace-knex', function() { var spans = common.getMatchingSpans(agent, function (span) { return span.name === 'mysql-query'; }); - assert.equal(spans.length, 1); - assert.equal(spans[0 ].labels.sql, 'select * from `t`'); + if (version === 'knex11') { + assert.equal(spans.length, 2); + assert.equal(spans[0].labels.sql, 'SELECT 1'); + assert.equal(spans[1].labels.sql, 'select * from `t`'); + } + else { + assert.equal(spans.length, 1); + assert.equal(spans[0].labels.sql, 'select * from `t`'); + } done(); }).catch(function(e) { assert.ifError(e); @@ -156,8 +171,15 @@ describe('test-trace-knex', function() { var spans = common.getMatchingSpans(agent, function (span) { return span.name === 'mysql-query'; }); - assert.equal(spans.length, 1); - assert.equal(spans[0].labels.sql, 'select * from `t`'); + if (version === 'knex11') { + assert.equal(spans.length, 2); + assert.equal(spans[0].labels.sql, 'SELECT 1'); + assert.equal(spans[1].labels.sql, 'select * from `t`'); + } + else { + assert.equal(spans.length, 1); + assert.equal(spans[0].labels.sql, 'select * from `t`'); + } done(); }, 50); }); @@ -205,8 +227,22 @@ describe('test-trace-knex', function() { var spans = common.getMatchingSpans(agent, function (span) { return span.name === 'mysql-query'; }); - var expectedCmds = ['insert into `t` (`k`, `v`) values (?, ?)', - 'select * from `t`', 'ROLLBACK;', 'select * from `t`']; + var expectedCmds; + if (version === 'knex11') { + expectedCmds = ['SELECT 1', + 'BEGIN;', + 'insert into `t` (`k`, `v`) values (?, ?)', + 'select * from `t`', + 'ROLLBACK;', + 'SELECT 1', + 'select * from `t`']; + } + else { + expectedCmds = ['insert into `t` (`k`, `v`) values (?, ?)', + 'select * from `t`', + 'ROLLBACK;', + 'select * from `t`']; + } assert.equal(expectedCmds.length, spans.length); for (var i = 0; i < spans.length; i++) { assert.equal(spans[i].labels.sql, expectedCmds[i]); From cdd2c11bd47bde71f435f7a97bcf0dc724453197 Mon Sep 17 00:00:00 2001 From: Dominic Kramer Date: Thu, 18 May 2017 15:24:03 -0700 Subject: [PATCH 10/14] Add tests for knex 0.10.x --- src/plugins/plugin-knex.js | 2 +- test/plugins/fixtures/knex0.10/index.js | 1 + test/plugins/fixtures/knex0.10/package.json | 9 +++++++++ test/plugins/test-trace-knex.js | 10 +++++++++- 4 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 test/plugins/fixtures/knex0.10/index.js create mode 100644 test/plugins/fixtures/knex0.10/package.json diff --git a/src/plugins/plugin-knex.js b/src/plugins/plugin-knex.js index 81cd64ba3..f789b1c89 100644 --- a/src/plugins/plugin-knex.js +++ b/src/plugins/plugin-knex.js @@ -19,7 +19,7 @@ var shimmer = require('shimmer'); var util = require('util'); var is = require('is'); -// knex 0.11.x does not need patching +// knex 0.10.x and 0.11.x do not need patching var VERSIONS = '>=0.12 <=0.13'; function patchClient(Client, api) { diff --git a/test/plugins/fixtures/knex0.10/index.js b/test/plugins/fixtures/knex0.10/index.js new file mode 100644 index 000000000..93babbfa3 --- /dev/null +++ b/test/plugins/fixtures/knex0.10/index.js @@ -0,0 +1 @@ +module.exports = require('knex'); diff --git a/test/plugins/fixtures/knex0.10/package.json b/test/plugins/fixtures/knex0.10/package.json new file mode 100644 index 000000000..9f9535313 --- /dev/null +++ b/test/plugins/fixtures/knex0.10/package.json @@ -0,0 +1,9 @@ +{ + "name": "knex0.10", + "version": "1.0.0", + "main": "index.js", + "dependencies": { + "knex": "^0.10.0", + "mysql": "^2.13.0" + } +} diff --git a/test/plugins/test-trace-knex.js b/test/plugins/test-trace-knex.js index fa473e4fd..43357acf8 100644 --- a/test/plugins/test-trace-knex.js +++ b/test/plugins/test-trace-knex.js @@ -27,6 +27,7 @@ var obj = { }; var versions = { + knex10: './fixtures/knex0.10', knex11: './fixtures/knex0.11', knex12: './fixtures/knex0.12', knex13: './fixtures/knex0.13' @@ -228,7 +229,14 @@ describe('test-trace-knex', function() { return span.name === 'mysql-query'; }); var expectedCmds; - if (version === 'knex11') { + if (version === 'knex10') { + expectedCmds = ['BEGIN;', + 'insert into `t` (`k`, `v`) values (?, ?)', + 'select * from `t`', + 'ROLLBACK;', + 'select * from `t`']; + } + else if (version === 'knex11') { expectedCmds = ['SELECT 1', 'BEGIN;', 'insert into `t` (`k`, `v`) values (?, ?)', From 74c46ab739003fa35050edfc0e117dd22f8e4f0d Mon Sep 17 00:00:00 2001 From: Dominic Kramer Date: Thu, 18 May 2017 15:30:34 -0700 Subject: [PATCH 11/14] Address GitHub comments --- src/plugins/plugin-knex.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/plugins/plugin-knex.js b/src/plugins/plugin-knex.js index f789b1c89..4d332cf3e 100644 --- a/src/plugins/plugin-knex.js +++ b/src/plugins/plugin-knex.js @@ -32,13 +32,9 @@ function patchClient(Client, api) { }); } -function wrapIfFn(fn, api) { - return fn && is.fn(fn) ? api.wrap(fn) : fn; -} - function interceptTransaction(Transaction, api) { function WrappedTransaction(client, container, config, outerTx) { - Transaction.call(this, client, wrapIfFn(container, api), config, outerTx); + Transaction.call(this, client, api.wrap(container), config, outerTx); } util.inherits(WrappedTransaction, Transaction); return WrappedTransaction; From c74a04a79be5098fd5a6baca7a33d030a393bd8f Mon Sep 17 00:00:00 2001 From: Dominic Kramer Date: Thu, 18 May 2017 15:48:47 -0700 Subject: [PATCH 12/14] Remove an unused require --- src/plugins/plugin-knex.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/plugins/plugin-knex.js b/src/plugins/plugin-knex.js index 4d332cf3e..225d877aa 100644 --- a/src/plugins/plugin-knex.js +++ b/src/plugins/plugin-knex.js @@ -17,7 +17,6 @@ var shimmer = require('shimmer'); var util = require('util'); -var is = require('is'); // knex 0.10.x and 0.11.x do not need patching var VERSIONS = '>=0.12 <=0.13'; From 19663cea3e60d4d2fea947a1ac30783240460daa Mon Sep 17 00:00:00 2001 From: Dominic Kramer Date: Mon, 22 May 2017 13:54:08 -0700 Subject: [PATCH 13/14] Rearrange functions to group related items --- src/plugins/plugin-knex.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/plugins/plugin-knex.js b/src/plugins/plugin-knex.js index 225d877aa..538783720 100644 --- a/src/plugins/plugin-knex.js +++ b/src/plugins/plugin-knex.js @@ -31,6 +31,10 @@ function patchClient(Client, api) { }); } +function unpatchClient(Client) { + shimmer.unwrap(Client.prototype, 'runner'); +} + function interceptTransaction(Transaction, api) { function WrappedTransaction(client, container, config, outerTx) { Transaction.call(this, client, api.wrap(container), config, outerTx); @@ -39,10 +43,6 @@ function interceptTransaction(Transaction, api) { return WrappedTransaction; } -function unpatchClient(Client) { - shimmer.unwrap(Client.prototype, 'runner'); -} - module.exports = [ { file: 'lib/transaction.js', From ec1d9c063f174a5324ea2736bbd1014c08fa2141 Mon Sep 17 00:00:00 2001 From: Dominic Kramer Date: Tue, 23 May 2017 10:56:50 -0700 Subject: [PATCH 14/14] Move `require('assert')` to the top of the file --- test/plugins/test-trace-knex.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/plugins/test-trace-knex.js b/test/plugins/test-trace-knex.js index 43357acf8..39cafb313 100644 --- a/test/plugins/test-trace-knex.js +++ b/test/plugins/test-trace-knex.js @@ -15,6 +15,8 @@ */ 'use strict'; +var assert = require('assert'); + var common = require('./common.js'); var traceLabels = require('../../src/trace-labels.js'); @@ -35,7 +37,6 @@ var versions = { describe('test-trace-knex', function() { var agent; - var assert; before(function() { agent = require('../..').start({ logLevel: 2, @@ -43,7 +44,6 @@ describe('test-trace-knex', function() { enhancedDatabaseReporting: true, databaseResultReportingSize: RESULT_SIZE }); - assert = require('assert'); }); Object.keys(versions).forEach(function(version) {