diff --git a/integration-tests/helpers/index.js b/integration-tests/helpers/index.js index 824c4398dcf..92b64faf1d7 100644 --- a/integration-tests/helpers/index.js +++ b/integration-tests/helpers/index.js @@ -273,6 +273,35 @@ async function createSandbox (dependencies = [], isGitRepo = false, } } +/** + * Creates a bunch of files based on an original file in sandbox. Useful for varying test files + * without having to create a bunch of them yourself. + * + * The variants object should have keys that are named variants, and values that are the text + * in the file that's different in each variant. There must always be a "default" variant, + * whose value is the original text within the file that will be replaced. + * + * @param {object} sandbox - A `sandbox` as returned from `createSandbox` + * @param {string} filename - The file that will be copied and modified for each variant. + * @param {object} variants - The variants. + * @returns {object} A map from variant names to resulting filenames + */ +function varySandbox(sandbox, filename, variants) { + const origFileData = fs.readFileSync(path.join(sandbox.folder, filename), 'utf8') + const [prefix, suffix] = filename.split('.') + const variantFilenames = {} + for (const variant in variants) { + const variantFilename = `${prefix}-${variant}.${suffix}` + variantFilenames[variant] = variantFilename + let newFileData = origFileData + if (variant !== 'default') { + newFileData = origFileData.replace(variants.default, `${variants[variant]}`) + } + fs.writeFileSync(path.join(sandbox.folder, variantFilename), newFileData) + } + return variantFilenames +} + function telemetryForwarder (shouldExpectTelemetryPoints = true) { process.env.DD_TELEMETRY_FORWARDER_PATH = path.join(__dirname, '..', 'telemetry-forwarder.sh') @@ -381,7 +410,7 @@ function checkSpansForServiceName (spans, name) { async function spawnPluginIntegrationTestProc (cwd, serverFile, agentPort, stdioHandler, additionalEnvArgs = {}) { let env = { - NODE_OPTIONS: `--loader=${hookFile}`, + NODE_OPTIONS: `--no-warnings --loader=${hookFile}`, DD_TRACE_AGENT_PORT: agentPort } env = { ...process.env, ...env, ...additionalEnvArgs } @@ -487,5 +516,6 @@ module.exports = { useEnv, useSandbox, sandboxCwd, - setShouldKill + setShouldKill, + varySandbox } diff --git a/packages/datadog-instrumentations/src/bunyan.js b/packages/datadog-instrumentations/src/bunyan.js index 039e7740c7a..9b7e7e42da4 100644 --- a/packages/datadog-instrumentations/src/bunyan.js +++ b/packages/datadog-instrumentations/src/bunyan.js @@ -8,6 +8,7 @@ const shimmer = require('../../datadog-shimmer') addHook({ name: 'bunyan', versions: ['>=1'] }, Logger => { const logCh = channel('apm:bunyan:log') + shimmer.wrap(Logger.prototype, '_emit', emit => { return function wrappedEmit (rec) { if (logCh.hasSubscribers) { diff --git a/packages/datadog-instrumentations/src/cassandra-driver.js b/packages/datadog-instrumentations/src/cassandra-driver.js index 006f85809e0..40c98c3161e 100644 --- a/packages/datadog-instrumentations/src/cassandra-driver.js +++ b/packages/datadog-instrumentations/src/cassandra-driver.js @@ -45,7 +45,11 @@ addHook({ name: 'cassandra-driver', versions: ['>=3.0.0'] }, cassandra => { return cassandra }) -addHook({ name: 'cassandra-driver', versions: ['>=4.4'] }, cassandra => { +addHook({ name: 'cassandra-driver', versions: ['>=4.4'] }, (cassandra, _1, _2, isIitm) => { + if (!cassandra.default && isIitm) { + return cassandra + } + shimmer.wrap(cassandra.Client.prototype, '_execute', _execute => function (query, params, execOptions, callback) { if (!startCh.hasSubscribers) { return _execute.apply(this, arguments) @@ -68,7 +72,11 @@ const isValid = (args) => { return args.length === 4 || typeof args[3] === 'function' } -addHook({ name: 'cassandra-driver', versions: ['3 - 4.3'] }, cassandra => { +addHook({ name: 'cassandra-driver', versions: ['3 - 4.3'] }, (cassandra, _1, _2, isIitm) => { + if (!cassandra.default && isIitm) { + return cassandra + } + shimmer.wrap(cassandra.Client.prototype, '_innerExecute', _innerExecute => function (query, params, execOptions, callback) { if (!startCh.hasSubscribers) { diff --git a/packages/datadog-instrumentations/src/connect.js b/packages/datadog-instrumentations/src/connect.js index 507811f6dd3..867ee63a857 100644 --- a/packages/datadog-instrumentations/src/connect.js +++ b/packages/datadog-instrumentations/src/connect.js @@ -102,11 +102,15 @@ function wrapNext (req, next) { }) } -addHook({ name: 'connect', versions: ['>=3'] }, connect => { +addHook({ name: 'connect', versions: ['>=3.4.0'] }, (connect) => { return shimmer.wrapFunction(connect, connect => wrapConnect(connect)) }) -addHook({ name: 'connect', versions: ['2.2.2'] }, connect => { +addHook({ name: 'connect', versions: ['>=3 <3.4.0'], file: 'lib/connect.js' }, (connect) => { + return shimmer.wrapFunction(connect, connect => wrapConnect(connect)) +}) + +addHook({ name: 'connect', versions: ['2.2.2'], file: 'lib/connect.js' }, connect => { shimmer.wrap(connect.proto, 'use', wrapUse) shimmer.wrap(connect.proto, 'handle', wrapHandle) diff --git a/packages/datadog-instrumentations/src/express.js b/packages/datadog-instrumentations/src/express.js index 50314c0b4e0..4ed7394e4bc 100644 --- a/packages/datadog-instrumentations/src/express.js +++ b/packages/datadog-instrumentations/src/express.js @@ -39,6 +39,7 @@ function wrapResponseJson (json) { const responseRenderChannel = tracingChannel('datadog:express:response:render') function wrapResponseRender (render) { + // random comment !!!!!!!!!!!! return function wrappedRender (view, options, callback) { if (!responseRenderChannel.start.hasSubscribers) { return render.apply(this, arguments) @@ -57,7 +58,7 @@ function wrapResponseRender (render) { } } -addHook({ name: 'express', versions: ['>=4'] }, express => { +addHook({ name: 'express', versions: ['>=4'], file: ['lib/express.js'] }, express => { shimmer.wrap(express.application, 'handle', wrapHandle) shimmer.wrap(express.response, 'json', wrapResponseJson) @@ -70,7 +71,7 @@ addHook({ name: 'express', versions: ['>=4'] }, express => { // Express 5 does not rely on router in the same way as v4 and should not be instrumented anymore. // It would otherwise produce spans for router and express, and so duplicating them. // We now fall back to router instrumentation -addHook({ name: 'express', versions: ['4'] }, express => { +addHook({ name: 'express', versions: ['4'], file: ['lib/express.js'] }, express => { shimmer.wrap(express.Router, 'use', wrapRouterMethod) shimmer.wrap(express.Router, 'route', wrapRouterMethod) diff --git a/packages/datadog-instrumentations/src/fastify.js b/packages/datadog-instrumentations/src/fastify.js index 67c94dd0bf1..8da6f516e09 100644 --- a/packages/datadog-instrumentations/src/fastify.js +++ b/packages/datadog-instrumentations/src/fastify.js @@ -265,8 +265,8 @@ function canPublishResponsePayload (payload) { !ArrayBuffer.isView(payload) // TypedArray } -addHook({ name: 'fastify', versions: ['>=3'] }, fastify => { - const wrapped = shimmer.wrapFunction(fastify, fastify => wrapFastify(fastify, true)) +addHook({ name: 'fastify', versions: ['>=3'] }, (fastify, _1, _2, isIitm) => { + const wrapped = shimmer.wrapFunction(fastify, fastify => wrapFastify(isIitm ? fastify.default : fastify, true)) wrapped.fastify = wrapped wrapped.default = wrapped @@ -274,12 +274,12 @@ addHook({ name: 'fastify', versions: ['>=3'] }, fastify => { return wrapped }) -addHook({ name: 'fastify', versions: ['2'] }, fastify => { - return shimmer.wrapFunction(fastify, fastify => wrapFastify(fastify, true)) +addHook({ name: 'fastify', versions: ['2'] }, (fastify, _1, _2, isIitm) => { + return shimmer.wrapFunction(fastify, fastify => wrapFastify(isIitm ? fastify.default : fastify, true)) }) -addHook({ name: 'fastify', versions: ['1'] }, fastify => { - return shimmer.wrapFunction(fastify, fastify => wrapFastify(fastify, false)) +addHook({ name: 'fastify', versions: ['1'] }, (fastify, _1, _2, isIitm) => { + return shimmer.wrapFunction(fastify, fastify => wrapFastify(isIitm ? fastify.default : fastify, false)) }) function wrapReplyHeader (Reply) { diff --git a/packages/datadog-instrumentations/src/helpers/hook.js b/packages/datadog-instrumentations/src/helpers/hook.js index 5ca81bb5408..7ec08b40957 100644 --- a/packages/datadog-instrumentations/src/helpers/hook.js +++ b/packages/datadog-instrumentations/src/helpers/hook.js @@ -19,37 +19,38 @@ function Hook (modules, hookOptions, onrequire) { hookOptions = {} } - this._patched = Object.create(null) + const patched = new WeakMap() - const safeHook = (moduleExports, moduleName, moduleBaseDir, moduleVersion) => { - const parts = [moduleBaseDir, moduleName].filter(Boolean) - const filename = path.join(...parts) + const safeHook = (moduleExports, moduleName, moduleBaseDir, moduleVersion, isIitm) => { + if (patched.has(moduleExports)) { + return patched.get(moduleExports) + } + + const newExports = onrequire(moduleExports, moduleName, moduleBaseDir, moduleVersion, isIitm) - if (this._patched[filename]) return moduleExports + if ( + isIitm && + moduleExports.default && + (typeof moduleExports.default === 'object' || + typeof moduleExports.default === 'function') + ) { + newExports.default = onrequire(moduleExports.default, moduleName, moduleBaseDir, moduleVersion, isIitm) + } - this._patched[filename] = true + patched.set(moduleExports, newExports) - return onrequire(moduleExports, moduleName, moduleBaseDir, moduleVersion) + return newExports } this._ritmHook = ritm(modules, {}, safeHook) this._iitmHook = iitm(modules, hookOptions, (moduleExports, moduleName, moduleBaseDir) => { - // TODO: Move this logic to import-in-the-middle and only do it for CommonJS - // modules and not ESM. In the meantime, all the modules we instrument are - // CommonJS modules for which the default export is always moved to - // `default` anyway. - if (moduleExports && moduleExports.default) { - moduleExports.default = safeHook(moduleExports.default, moduleName, moduleBaseDir) - return moduleExports - } - return safeHook(moduleExports, moduleName, moduleBaseDir) + return safeHook(moduleExports, moduleName, moduleBaseDir, null, true) }) } Hook.prototype.unhook = function () { this._ritmHook.unhook() this._iitmHook.unhook() - this._patched = Object.create(null) } module.exports = Hook diff --git a/packages/datadog-instrumentations/src/helpers/register.js b/packages/datadog-instrumentations/src/helpers/register.js index eb3bc5a0e37..3c552d4efca 100644 --- a/packages/datadog-instrumentations/src/helpers/register.js +++ b/packages/datadog-instrumentations/src/helpers/register.js @@ -66,7 +66,7 @@ for (const packageName of names) { // get the instrumentation file name to save all hooked versions const instrumentationFileName = parseHookInstrumentationFileName(packageName) - Hook([packageName], hookOptions, (moduleExports, moduleName, moduleBaseDir, moduleVersion) => { + Hook([packageName], hookOptions, (moduleExports, moduleName, moduleBaseDir, moduleVersion, isIitm) => { moduleName = moduleName.replace(pathSepExpr, '/') // This executes the integration file thus adding its entries to `instrumentations` @@ -137,7 +137,8 @@ for (const packageName of names) { // picked up due to the unification. Check what modules actually use the name. // TODO(BridgeAR): Only replace moduleExports if the hook returns a new value. // This allows to reduce the instrumentation code (no return needed). - moduleExports = hook(moduleExports, version, name) ?? moduleExports + + moduleExports = hook(moduleExports, version, name, isIitm) ?? moduleExports // Set the moduleExports in the hooks WeakSet hook[HOOK_SYMBOL].add(moduleExports) } catch (e) { diff --git a/packages/datadog-instrumentations/src/http2/client.js b/packages/datadog-instrumentations/src/http2/client.js index 651c9ed6edd..b335df7c4cd 100644 --- a/packages/datadog-instrumentations/src/http2/client.js +++ b/packages/datadog-instrumentations/src/http2/client.js @@ -70,6 +70,7 @@ function wrapConnect (connect) { addHook({ name: names }, http2 => { shimmer.wrap(http2, 'connect', wrapConnect) + if (http2.default) http2.default.connect = http2.connect return http2 }) diff --git a/packages/datadog-instrumentations/src/http2/server.js b/packages/datadog-instrumentations/src/http2/server.js index df1a834ba03..5977d738554 100644 --- a/packages/datadog-instrumentations/src/http2/server.js +++ b/packages/datadog-instrumentations/src/http2/server.js @@ -18,7 +18,6 @@ const names = ['http2', 'node:http2'] addHook({ name: names }, http2 => { shimmer.wrap(http2, 'createSecureServer', wrapCreateServer) shimmer.wrap(http2, 'createServer', wrapCreateServer) - return http2 }) function wrapCreateServer (createServer) { diff --git a/packages/datadog-instrumentations/src/ioredis.js b/packages/datadog-instrumentations/src/ioredis.js index 43ed093893e..466130594c0 100644 --- a/packages/datadog-instrumentations/src/ioredis.js +++ b/packages/datadog-instrumentations/src/ioredis.js @@ -10,7 +10,7 @@ const startCh = channel('apm:ioredis:command:start') const finishCh = channel('apm:ioredis:command:finish') const errorCh = channel('apm:ioredis:command:error') -addHook({ name: 'ioredis', versions: ['>=2'] }, Redis => { +function wrapRedis(Redis) { shimmer.wrap(Redis.prototype, 'sendCommand', sendCommand => function (command, stream) { if (!startCh.hasSubscribers) return sendCommand.apply(this, arguments) @@ -35,8 +35,19 @@ addHook({ name: 'ioredis', versions: ['>=2'] }, Redis => { }) }) return Redis +} + +addHook({ name: 'ioredis', versions: ['>=2 <4'], file: 'lib/redis.js' }, wrapRedis) + +addHook({ name: 'ioredis', versions: [ '>=4 <4.11.0'], file: 'built/redis.js' }, wrapRedis) + +addHook({ name: 'ioredis', versions: [ '>=4.11.0 <5'], file: 'built/redis/index.js' }, (exports) => { + wrapRedis(exports.default) + return exports }) +addHook({ name: 'ioredis', versions: [ '>=5'] }, wrapRedis) + function finish (finishCh, errorCh, ctx, error) { if (error) { ctx.error = error diff --git a/packages/datadog-instrumentations/src/pino.js b/packages/datadog-instrumentations/src/pino.js index 503986519ae..fad64bff920 100644 --- a/packages/datadog-instrumentations/src/pino.js +++ b/packages/datadog-instrumentations/src/pino.js @@ -73,22 +73,36 @@ function wrapPrettyFactory (prettyFactory) { } } -addHook({ name: 'pino', versions: ['2 - 3', '4', '>=5 <5.14.0'] }, pino => { +addHook({ name: 'pino', versions: ['2 - 3', '4'] }, (pino,_1, _2, isIitm) => { + if (!pino.default && isIitm) return const asJsonSym = (pino.symbols && pino.symbols.asJsonSym) || 'asJson' - return shimmer.wrapFunction(pino, pino => wrapPino(asJsonSym, wrapAsJson, pino)) + const wrapped = shimmer.wrapFunction(pino, pino => wrapPino(asJsonSym, wrapAsJson, isIitm ? pino.default : pino)) + + return wrapped }) -addHook({ name: 'pino', versions: ['>=5.14.0 <6.8.0'] }, pino => { - const mixinSym = pino.symbols.mixinSym +addHook({ name: 'pino', versions: ['>=5 <5.14.0'] }, (pino,_1, _2, isIitm) => { + const asJsonSym = ((pino.default || pino)?.symbols.asJsonSym) || 'asJson' + + const wrapped = shimmer.wrapFunction(pino, pino => wrapPino(asJsonSym, wrapAsJson, isIitm ? pino.default : pino)) + + return wrapped +}) + +addHook({ name: 'pino', versions: ['>=5.14.0 <6.8.0'] }, (pino) => { + const mixinSym = (pino.default || pino).symbols.mixinSym - return shimmer.wrapFunction(pino, pino => wrapPino(mixinSym, wrapMixin, pino)) + const wrapped = shimmer.wrapFunction(pino, pino => wrapPino(mixinSym, wrapMixin, pino.default || pino)) + + return wrapped }) -addHook({ name: 'pino', versions: ['>=6.8.0'] }, pino => { +addHook({ name: 'pino', versions: ['>=6.8.0'] }, (pino,_1, _2,isIitm) => { + if (isIitm && !pino.default) return const mixinSym = pino.symbols.mixinSym - const wrapped = shimmer.wrapFunction(pino, pino => wrapPino(mixinSym, wrapMixin, pino)) + const wrapped = shimmer.wrapFunction(pino, pino => wrapPino(mixinSym, wrapMixin, isIitm ? pino.default : pino)) wrapped.pino = wrapped wrapped.default = wrapped diff --git a/packages/datadog-plugin-amqplib/test/integration-test/client.spec.js b/packages/datadog-plugin-amqplib/test/integration-test/client.spec.js index 849fc4a454a..106022a2ffa 100644 --- a/packages/datadog-plugin-amqplib/test/integration-test/client.spec.js +++ b/packages/datadog-plugin-amqplib/test/integration-test/client.spec.js @@ -4,7 +4,8 @@ const { FakeAgent, createSandbox, checkSpansForServiceName, - spawnPluginIntegrationTestProc + spawnPluginIntegrationTestProc, + varySandbox } = require('../../../../integration-tests/helpers') const { withVersions } = require('../../../dd-trace/test/setup/mocha') const { assert } = require('chai') @@ -13,12 +14,19 @@ describe('esm', () => { let agent let proc let sandbox + let variants + // test against later versions because server.mjs uses newer package syntax withVersions('amqplib', 'amqplib', '>=0.10.0', version => { before(async function () { this.timeout(20000) sandbox = await createSandbox([`'amqplib@${version}'`], false, ['./packages/datadog-plugin-amqplib/test/integration-test/*']) + variants = varySandbox(sandbox, 'server.mjs', { + default: `import amqplib from 'amqplib'`, + star: `import * as amqplib from 'amqplib'`, + destructure: `import { connect } from 'amqplib'; const amqplib = { connect }` + }) }) after(async () => { @@ -34,16 +42,18 @@ describe('esm', () => { await agent.stop() }) - it('is instrumented', async () => { - const res = agent.assertMessageReceived(({ headers, payload }) => { - assert.propertyVal(headers, 'host', `127.0.0.1:${agent.port}`) - assert.isArray(payload) - assert.strictEqual(checkSpansForServiceName(payload, 'amqp.command'), true) - }) + for (const variant of ['default', 'destructure', 'star']) { + it('is instrumented', async () => { + const res = agent.assertMessageReceived(({ headers, payload }) => { + assert.propertyVal(headers, 'host', `127.0.0.1:${agent.port}`) + assert.isArray(payload) + assert.strictEqual(checkSpansForServiceName(payload, 'amqp.command'), true) + }) - proc = await spawnPluginIntegrationTestProc(sandbox.folder, 'server.mjs', agent.port) + proc = await spawnPluginIntegrationTestProc(sandbox.folder, variants[variant], agent.port) - await res - }).timeout(20000) + await res + }).timeout(20000) + } }) }) diff --git a/packages/datadog-plugin-bunyan/test/integration-test/client.spec.js b/packages/datadog-plugin-bunyan/test/integration-test/client.spec.js index 2777b5b84e2..2335dbce039 100644 --- a/packages/datadog-plugin-bunyan/test/integration-test/client.spec.js +++ b/packages/datadog-plugin-bunyan/test/integration-test/client.spec.js @@ -3,7 +3,8 @@ const { FakeAgent, createSandbox, - spawnPluginIntegrationTestProc + spawnPluginIntegrationTestProc, + varySandbox } = require('../../../../integration-tests/helpers') const { withVersions } = require('../../../dd-trace/test/setup/mocha') const { expect } = require('chai') @@ -12,11 +13,18 @@ describe('esm', () => { let agent let proc let sandbox + let variants + withVersions('bunyan', 'bunyan', version => { before(async function () { this.timeout(20000) sandbox = await createSandbox([`'bunyan@${version}'`], false, ['./packages/datadog-plugin-bunyan/test/integration-test/*']) + variants = varySandbox(sandbox, 'server.mjs', { + default: `import bunyan from 'bunyan'`, + star: `import * as bunyan from 'bunyan'`, + destructure: `import { default as bunyan } from 'bunyan'` + }) }) after(async () => { @@ -31,16 +39,18 @@ describe('esm', () => { proc && proc.kill() await agent.stop() }) - it('is instrumented', async () => { - proc = await spawnPluginIntegrationTestProc( - sandbox.folder, - 'server.mjs', - agent.port, - (data) => { - const jsonObject = JSON.parse(data.toString()) - expect(jsonObject).to.have.property('dd') - } - ) - }).timeout(20000) + for (const variant of ['default', 'destructure', 'star']) { + it(`is instrumented (${variant})`, async () => { + proc = await spawnPluginIntegrationTestProc( + sandbox.folder, + variants[variant], + agent.port, + (data) => { + const jsonObject = JSON.parse(data.toString()) + expect(jsonObject).to.have.property('dd') + } + ) + }).timeout(20000) + } }) }) diff --git a/packages/datadog-plugin-cassandra-driver/test/integration-test/client.spec.js b/packages/datadog-plugin-cassandra-driver/test/integration-test/client.spec.js index 7ebeb665d31..0f9ae62e683 100644 --- a/packages/datadog-plugin-cassandra-driver/test/integration-test/client.spec.js +++ b/packages/datadog-plugin-cassandra-driver/test/integration-test/client.spec.js @@ -4,7 +4,8 @@ const { FakeAgent, createSandbox, checkSpansForServiceName, - spawnPluginIntegrationTestProc + spawnPluginIntegrationTestProc, + varySandbox } = require('../../../../integration-tests/helpers') const { withVersions } = require('../../../dd-trace/test/setup/mocha') const { assert } = require('chai') @@ -13,6 +14,7 @@ describe('esm', () => { let agent let proc let sandbox + let variants // test against later versions because server.mjs uses newer package syntax withVersions('cassandra-driver', 'cassandra-driver', '>=4.4.0', version => { @@ -20,6 +22,11 @@ describe('esm', () => { this.timeout(20000) sandbox = await createSandbox([`'cassandra-driver@${version}'`], false, [ './packages/datadog-plugin-cassandra-driver/test/integration-test/*']) + variants = varySandbox(sandbox, 'server.mjs', { + default: 'import cassandra from \'cassandra-driver\'', + star: 'import * as cassandra from \'cassandra-driver\'', + destructure: 'import { Client } from \'cassandra-driver\'; const cassandra = { Client }' + }) }) after(async () => { @@ -35,16 +42,18 @@ describe('esm', () => { await agent.stop() }) - it('is instrumented', async () => { - const res = agent.assertMessageReceived(({ headers, payload }) => { - assert.propertyVal(headers, 'host', `127.0.0.1:${agent.port}`) - assert.isArray(payload) - assert.strictEqual(checkSpansForServiceName(payload, 'cassandra.query'), true) - }) + for (const variant of ['default', 'destructure', 'star']) { + it('is instrumented', async () => { + const res = agent.assertMessageReceived(({ headers, payload }) => { + assert.propertyVal(headers, 'host', `127.0.0.1:${agent.port}`) + assert.isArray(payload) + assert.strictEqual(checkSpansForServiceName(payload, 'cassandra.query'), true) + }) - proc = await spawnPluginIntegrationTestProc(sandbox.folder, 'server.mjs', agent.port) + proc = await spawnPluginIntegrationTestProc(sandbox.folder, variants[variant], agent.port) - await res - }).timeout(20000) + await res + }).timeout(20000) + } }) }) diff --git a/packages/datadog-plugin-cassandra-driver/test/integration-test/server.mjs b/packages/datadog-plugin-cassandra-driver/test/integration-test/server.mjs index c65ebffe78d..c4b6ebd518c 100644 --- a/packages/datadog-plugin-cassandra-driver/test/integration-test/server.mjs +++ b/packages/datadog-plugin-cassandra-driver/test/integration-test/server.mjs @@ -1,7 +1,7 @@ import 'dd-trace/init.js' -import { Client } from 'cassandra-driver' +import cassandra from 'cassandra-driver' -const client = new Client({ +const client = new cassandra.Client({ contactPoints: ['127.0.0.1'], localDataCenter: 'datacenter1', keyspace: 'system' diff --git a/packages/datadog-plugin-connect/test/integration-test/client.spec.js b/packages/datadog-plugin-connect/test/integration-test/client.spec.js index 541db6e2cc5..ba354dc9091 100644 --- a/packages/datadog-plugin-connect/test/integration-test/client.spec.js +++ b/packages/datadog-plugin-connect/test/integration-test/client.spec.js @@ -5,7 +5,8 @@ const { createSandbox, curlAndAssertMessage, checkSpansForServiceName, - spawnPluginIntegrationTestProc + spawnPluginIntegrationTestProc, + varySandbox } = require('../../../../integration-tests/helpers') const { withVersions } = require('../../../dd-trace/test/setup/mocha') const { assert } = require('chai') @@ -14,13 +15,18 @@ describe('esm', () => { let agent let proc let sandbox - + let variants // test against later versions because server.mjs uses newer package syntax - withVersions('connect', 'connect', '>=3', version => { + withVersions('connect', 'connect', version => { before(async function () { this.timeout(20000) sandbox = await createSandbox([`'connect@${version}'`], false, [ './packages/datadog-plugin-connect/test/integration-test/*']) + variants = varySandbox(sandbox, 'server.mjs', { + default: 'import connect from \'connect\'', + star: 'import * as starConnect from \'connect\'; const connect = starConnect.default;', + destructure: 'import { default as connect } from \'connect\';' + }) }) after(async () => { @@ -36,14 +42,16 @@ describe('esm', () => { await agent.stop() }) - it('is instrumented', async () => { - proc = await spawnPluginIntegrationTestProc(sandbox.folder, 'server.mjs', agent.port) - - return curlAndAssertMessage(agent, proc, ({ headers, payload }) => { - assert.propertyVal(headers, 'host', `127.0.0.1:${agent.port}`) - assert.isArray(payload) - assert.strictEqual(checkSpansForServiceName(payload, 'connect.request'), true) - }) - }).timeout(20000) + for (const variant of ['default', 'destructure', 'star']) { + it(`is instrumented (${variant})`, async () => { + proc = await spawnPluginIntegrationTestProc(sandbox.folder, variants[variant], agent.port) + + return curlAndAssertMessage(agent, proc, ({ headers, payload }) => { + assert.propertyVal(headers, 'host', `127.0.0.1:${agent.port}`) + assert.isArray(payload) + assert.strictEqual(checkSpansForServiceName(payload, 'connect.request'), true) + }) + }).timeout(20000) + } }) }) diff --git a/packages/datadog-plugin-dns/test/integration-test/client.spec.js b/packages/datadog-plugin-dns/test/integration-test/client.spec.js index 4a2f5113458..bb9112dfff0 100644 --- a/packages/datadog-plugin-dns/test/integration-test/client.spec.js +++ b/packages/datadog-plugin-dns/test/integration-test/client.spec.js @@ -4,7 +4,8 @@ const { FakeAgent, createSandbox, checkSpansForServiceName, - spawnPluginIntegrationTestProc + spawnPluginIntegrationTestProc, + varySandbox } = require('../../../../integration-tests/helpers') const { assert } = require('chai') @@ -12,11 +13,17 @@ describe('esm', () => { let agent let proc let sandbox + let variants before(async function () { this.timeout(20000) sandbox = await createSandbox([], false, [ './packages/datadog-plugin-dns/test/integration-test/*']) + variants = varySandbox(sandbox, 'server.mjs', { + default: `import dns from 'dns'`, + star: `import * as dns from 'dns'`, + destructure: `import { lookup } from 'dns'; const dns = { lookup }` + }) }) after(async () => { @@ -33,17 +40,19 @@ describe('esm', () => { }) context('dns', () => { - it('is instrumented', async () => { - const res = agent.assertMessageReceived(({ headers, payload }) => { - assert.propertyVal(headers, 'host', `127.0.0.1:${agent.port}`) - assert.isArray(payload) - assert.strictEqual(checkSpansForServiceName(payload, 'dns.lookup'), true) - assert.strictEqual(payload[0][0].resource, 'fakedomain.faketld') - }) - - proc = await spawnPluginIntegrationTestProc(sandbox.folder, 'server.mjs', agent.port) - - await res - }).timeout(20000) + for (const variant of ['default', 'star', 'destructure']) { + it(`is instrumented (${variant})`, async () => { + const res = agent.assertMessageReceived(({ headers, payload }) => { + assert.propertyVal(headers, 'host', `127.0.0.1:${agent.port}`) + assert.isArray(payload) + assert.strictEqual(checkSpansForServiceName(payload, 'dns.lookup'), true) + assert.strictEqual(payload[0][0].resource, 'fakedomain.faketld') + }) + + proc = await spawnPluginIntegrationTestProc(sandbox.folder, variants[variant], agent.port) + + await res + }).timeout(20000) + } }) }) diff --git a/packages/datadog-plugin-elasticsearch/test/integration-test/client.spec.js b/packages/datadog-plugin-elasticsearch/test/integration-test/client.spec.js index 2c2e6202635..b86d8c29d39 100644 --- a/packages/datadog-plugin-elasticsearch/test/integration-test/client.spec.js +++ b/packages/datadog-plugin-elasticsearch/test/integration-test/client.spec.js @@ -4,7 +4,8 @@ const { FakeAgent, createSandbox, checkSpansForServiceName, - spawnPluginIntegrationTestProc + spawnPluginIntegrationTestProc, + varySandbox } = require('../../../../integration-tests/helpers') const { withVersions } = require('../../../dd-trace/test/setup/mocha') const { assert } = require('chai') @@ -13,6 +14,7 @@ describe('esm', () => { let agent let proc let sandbox + let variants // excluding 8.16.0 for esm tests, because it is not working: https://github.com/elastic/elasticsearch-js/issues/2466 withVersions('elasticsearch', ['@elastic/elasticsearch'], '<8.16.0 || >8.16.0', version => { @@ -20,6 +22,11 @@ describe('esm', () => { this.timeout(20000) sandbox = await createSandbox([`'@elastic/elasticsearch@${version}'`], false, [ './packages/datadog-plugin-elasticsearch/test/integration-test/*']) + variants = varySandbox(sandbox, 'server.mjs', { + default: `import elasticsearch from '@elastic/elasticsearch'`, + star: `import * as elasticsearch from '@elastic/elasticsearch'`, + destructure: `import { Client } from '@elastic/elasticsearch'; const elasticsearch = { Client }` + }) }) after(async () => { @@ -34,17 +41,18 @@ describe('esm', () => { proc && proc.kill() await agent.stop() }) - - it('is instrumented', async () => { - const res = agent.assertMessageReceived(({ headers, payload }) => { - assert.propertyVal(headers, 'host', `127.0.0.1:${agent.port}`) - assert.isArray(payload) - assert.strictEqual(checkSpansForServiceName(payload, 'elasticsearch.query'), true) - }) - - proc = await spawnPluginIntegrationTestProc(sandbox.folder, 'server.mjs', agent.port) - - await res - }).timeout(20000) + for (const variant of ['default', 'destructure', 'star']) { + it(`is instrumented (${variant})`, async () => { + const res = agent.assertMessageReceived(({ headers, payload }) => { + assert.propertyVal(headers, 'host', `127.0.0.1:${agent.port}`) + assert.isArray(payload) + assert.strictEqual(checkSpansForServiceName(payload, 'elasticsearch.query'), true) + }) + + proc = await spawnPluginIntegrationTestProc(sandbox.folder, variants[variant], agent.port) + + await res + }).timeout(20000) + } }) }) diff --git a/packages/datadog-plugin-elasticsearch/test/integration-test/server.mjs b/packages/datadog-plugin-elasticsearch/test/integration-test/server.mjs index ff47d43b773..2bc6e1ce1e8 100644 --- a/packages/datadog-plugin-elasticsearch/test/integration-test/server.mjs +++ b/packages/datadog-plugin-elasticsearch/test/integration-test/server.mjs @@ -1,6 +1,6 @@ import 'dd-trace/init.js' -import { Client } from '@elastic/elasticsearch' +import elasticsearch from '@elastic/elasticsearch' -const client = new Client({ node: 'http://127.0.0.1:9200' }) +const client = new elasticsearch.Client({ node: 'http://127.0.0.1:9200' }) await client.ping() diff --git a/packages/datadog-plugin-http2/test/integration-test/client.spec.js b/packages/datadog-plugin-http2/test/integration-test/client.spec.js index 800dc1d0c6d..6dece07e67d 100644 --- a/packages/datadog-plugin-http2/test/integration-test/client.spec.js +++ b/packages/datadog-plugin-http2/test/integration-test/client.spec.js @@ -3,7 +3,8 @@ const { FakeAgent, createSandbox, - spawnPluginIntegrationTestProc + spawnPluginIntegrationTestProc, + varySandbox } = require('../../../../integration-tests/helpers') const { assert } = require('chai') const http2 = require('http2') @@ -12,11 +13,17 @@ describe('esm', () => { let agent let proc let sandbox + let variants before(async function () { this.timeout(50000) sandbox = await createSandbox(['http2'], false, [ './packages/datadog-plugin-http2/test/integration-test/*']) + variants = varySandbox(sandbox, 'server.mjs', { + default: `import http2 from 'http2'`, + star: `import * as http2 from 'http2'`, + destructure: `import { createServer } from 'http2'; const http2 = { createServer }` + }) }) after(async function () { @@ -34,20 +41,22 @@ describe('esm', () => { }) context('http2', () => { - it('is instrumented', async () => { - proc = await spawnPluginIntegrationTestProc(sandbox.folder, 'server.mjs', agent.port) - const resultPromise = agent.assertMessageReceived(({ headers, payload }) => { - assert.propertyVal(headers, 'host', `127.0.0.1:${agent.port}`) - assert.isArray(payload) - assert.strictEqual(payload.length, 1) - assert.isArray(payload[0]) - assert.strictEqual(payload[0].length, 1) - assert.propertyVal(payload[0][0], 'name', 'web.request') - assert.propertyVal(payload[0][0].meta, 'component', 'http2') - }) - await curl(proc) - return resultPromise - }).timeout(50000) + for (const variant of ['default', 'destructure', 'star']) { + it(`is instrumented (${variant})`, async () => { + proc = await spawnPluginIntegrationTestProc(sandbox.folder, variants[variant], agent.port) + const resultPromise = agent.assertMessageReceived(({ headers, payload }) => { + assert.propertyVal(headers, 'host', `127.0.0.1:${agent.port}`) + assert.isArray(payload) + assert.strictEqual(payload.length, 1) + assert.isArray(payload[0]) + assert.strictEqual(payload[0].length, 1) + assert.propertyVal(payload[0][0], 'name', 'web.request') + assert.propertyVal(payload[0][0].meta, 'component', 'http2') + }) + await curl(proc) + return resultPromise + }).timeout(50000) + } }) }) diff --git a/packages/datadog-plugin-ioredis/test/integration-test/client.spec.js b/packages/datadog-plugin-ioredis/test/integration-test/client.spec.js index ed52f073e36..9a1a7d52bce 100644 --- a/packages/datadog-plugin-ioredis/test/integration-test/client.spec.js +++ b/packages/datadog-plugin-ioredis/test/integration-test/client.spec.js @@ -4,7 +4,8 @@ const { FakeAgent, createSandbox, checkSpansForServiceName, - spawnPluginIntegrationTestProc + spawnPluginIntegrationTestProc, + varySandbox } = require('../../../../integration-tests/helpers') const { withVersions } = require('../../../dd-trace/test/setup/mocha') const { assert } = require('chai') @@ -13,11 +14,17 @@ describe('esm', () => { let agent let proc let sandbox + let variants withVersions('ioredis', 'ioredis', version => { before(async function () { this.timeout(20000) sandbox = await createSandbox([`'ioredis@${version}'`], false, [ './packages/datadog-plugin-ioredis/test/integration-test/*']) + variants = varySandbox(sandbox, 'server.mjs', { + default: `import Redis from 'ioredis'`, + star: `import * as modRedis from 'ioredis'; const { default: Redis } = modRedis`, + destructure: `import { default as Redis } from 'ioredis'` + }) }) after(async () => { @@ -33,16 +40,18 @@ describe('esm', () => { await agent.stop() }) - it('is instrumented', async () => { - const res = agent.assertMessageReceived(({ headers, payload }) => { - assert.propertyVal(headers, 'host', `127.0.0.1:${agent.port}`) - assert.isArray(payload) - assert.strictEqual(checkSpansForServiceName(payload, 'redis.command'), true) - }) + for (const variant of ['default', 'star', 'destructure']) { + it(`is instrumented (${variant})`, async () => { + const res = agent.assertMessageReceived(({ headers, payload }) => { + assert.propertyVal(headers, 'host', `127.0.0.1:${agent.port}`) + assert.isArray(payload) + assert.strictEqual(checkSpansForServiceName(payload, 'redis.command'), true) + }) - proc = await spawnPluginIntegrationTestProc(sandbox.folder, 'server.mjs', agent.port) + proc = await spawnPluginIntegrationTestProc(sandbox.folder, variants[variant], agent.port) - await res - }).timeout(20000) + await res + }).timeout(20000) + } }) }) diff --git a/packages/datadog-plugin-net/test/integration-test/client.spec.js b/packages/datadog-plugin-net/test/integration-test/client.spec.js index 53e5c988a73..97a27391a16 100644 --- a/packages/datadog-plugin-net/test/integration-test/client.spec.js +++ b/packages/datadog-plugin-net/test/integration-test/client.spec.js @@ -4,7 +4,8 @@ const { FakeAgent, createSandbox, checkSpansForServiceName, - spawnPluginIntegrationTestProc + spawnPluginIntegrationTestProc, + varySandbox } = require('../../../../integration-tests/helpers') const { assert } = require('chai') @@ -12,11 +13,17 @@ describe('esm', () => { let agent let proc let sandbox + let variants before(async function () { this.timeout(20000) sandbox = await createSandbox(['net'], false, [ './packages/datadog-plugin-net/test/integration-test/*']) + variants = varySandbox(sandbox, 'server.mjs', { + default: `import net from 'net'`, + star: `import * as net from 'net'`, + destructure: `import { createConnection } from 'net'; const net = { createConnection }` + }) }) after(async () => { @@ -33,18 +40,20 @@ describe('esm', () => { }) context('net', () => { - it('is instrumented', async () => { - const res = agent.assertMessageReceived(({ headers, payload }) => { - assert.propertyVal(headers, 'host', `127.0.0.1:${agent.port}`) - assert.isArray(payload) - assert.strictEqual(checkSpansForServiceName(payload, 'tcp.connect'), true) - const metaContainsNet = payload.some((span) => span.some((nestedSpan) => nestedSpan.meta.component === 'net')) - assert.strictEqual(metaContainsNet, true) - }) - - proc = await spawnPluginIntegrationTestProc(sandbox.folder, 'server.mjs', agent.port) - - await res - }).timeout(20000) + for (const variant of ['default', 'star', 'destructure']) { + it(`is instrumented (${variant})`, async () => { + const res = agent.assertMessageReceived(({ headers, payload }) => { + assert.propertyVal(headers, 'host', `127.0.0.1:${agent.port}`) + assert.isArray(payload) + assert.strictEqual(checkSpansForServiceName(payload, 'tcp.connect'), true) + const metaContainsNet = payload.some((span) => span.some((nestedSpan) => nestedSpan.meta.component === 'net')) + assert.strictEqual(metaContainsNet, true) + }) + + proc = await spawnPluginIntegrationTestProc(sandbox.folder, variants[variant], agent.port) + + await res + }).timeout(20000) + } }) }) diff --git a/packages/datadog-plugin-pino/test/integration-test/client.spec.js b/packages/datadog-plugin-pino/test/integration-test/client.spec.js index b97f0885ac8..abec92ce47a 100644 --- a/packages/datadog-plugin-pino/test/integration-test/client.spec.js +++ b/packages/datadog-plugin-pino/test/integration-test/client.spec.js @@ -3,7 +3,8 @@ const { FakeAgent, createSandbox, - spawnPluginIntegrationTestProc + spawnPluginIntegrationTestProc, + varySandbox } = require('../../../../integration-tests/helpers') const { withVersions } = require('../../../dd-trace/test/setup/mocha') const { expect } = require('chai') @@ -12,12 +13,18 @@ describe('esm', () => { let agent let proc let sandbox + let variants withVersions('pino', 'pino', version => { before(async function () { this.timeout(20000) sandbox = await createSandbox([`'pino@${version}'`], false, ['./packages/datadog-plugin-pino/test/integration-test/*']) + variants = varySandbox(sandbox, 'server.mjs', { + default: `import pino from 'pino'`, + star: `import * as modPino from 'pino'; const pino = (...a) => modPino.default(...a)`, + destructure: `import { default as pino } from 'pino'`, + }) }) after(async () => { @@ -33,16 +40,18 @@ describe('esm', () => { await agent.stop() }) - it('is instrumented', async () => { - proc = await spawnPluginIntegrationTestProc( - sandbox.folder, - 'server.mjs', - agent.port, - (data) => { - const jsonObject = JSON.parse(data.toString()) - expect(jsonObject).to.have.property('dd') - } - ) - }).timeout(20000) + for (const variant of ['default', 'star', 'destructure']) { + it(`is instrumented (${variant})`, async () => { + proc = await spawnPluginIntegrationTestProc( + sandbox.folder, + variants[variant], + agent.port, + (data) => { + const jsonObject = JSON.parse(data.toString()) + expect(jsonObject).to.have.property('dd') + } + ) + }).timeout(20000) + } }) })