diff --git a/test/versioned/connect/package.json b/test/versioned/connect/package.json index 7a1ed5cc33..da7490ca47 100644 --- a/test/versioned/connect/package.json +++ b/test/versioned/connect/package.json @@ -9,7 +9,7 @@ "node": ">=18" }, "dependencies": { - "connect": ">=2.0.0" + "connect": ">=3.0.0" }, "files": [ "error-intercept.tap.js", diff --git a/test/versioned/elastic/package.json b/test/versioned/elastic/package.json index 5009991bc0..876c188bc8 100644 --- a/test/versioned/elastic/package.json +++ b/test/versioned/elastic/package.json @@ -20,18 +20,6 @@ "elasticsearchNoop.tap.js" ] }, - { - "engines": { - "node": "16" - }, - "dependencies": { - "@elastic/elasticsearch": ">=7.16.0 <=8.13.1", - "@elastic/transport": "8.4.1" - }, - "files": [ - "elasticsearch.tap.js" - ] - }, { "engines": { "node": ">=18" diff --git a/test/versioned/generic-pool/basic-v2.tap.js b/test/versioned/generic-pool/basic-v2.tap.js deleted file mode 100644 index 01b29b908f..0000000000 --- a/test/versioned/generic-pool/basic-v2.tap.js +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright 2020 New Relic Corporation. All rights reserved. - * SPDX-License-Identifier: Apache-2.0 - */ - -'use strict' - -const helper = require('../../lib/agent_helper') -const tap = require('tap') - -tap.test('generic-pool', function (t) { - t.autoend() - - let agent = null - let pool = null - const PoolClass = require('generic-pool').Pool - - t.beforeEach(function () { - agent = helper.instrumentMockedAgent() - pool = require('generic-pool') - }) - - t.afterEach(function () { - helper.unloadAgent(agent) - pool = null - }) - - const tasks = [] - const decontextInterval = setInterval(function () { - if (tasks.length > 0) { - const fn = tasks.pop() - fn() - } - }, 10) - - t.teardown(function () { - clearInterval(decontextInterval) - }) - - function addTask(cb, args) { - // in versions 2.5.2 and below - // destroy tasks do not pass a callback - // so let's not add a task if cb is undefined - if (!cb) { - return - } - tasks.push(function () { - return cb.apply(null, args || []) - }) - } - - function id(tx) { - return tx && tx.id - } - - t.test('instantiation', function (t) { - t.plan(4) - - t.doesNotThrow(function () { - // eslint-disable-next-line new-cap - const p = pool.Pool({ - create: function (cb) { - addTask(cb, [null, {}]) - }, - destroy: function (o, cb) { - addTask(cb) - } - }) - t.type(p, PoolClass, 'should create a Pool') - }, 'should be able to instantiate without new') - - t.doesNotThrow(function () { - const p = new pool.Pool({ - create: function (cb) { - addTask(cb, [null, {}]) - }, - destroy: function (o, cb) { - addTask(cb) - } - }) - t.type(p, PoolClass, 'should create a Pool') - }, 'should be able to instantiate with new') - }) - - t.test('context maintenance', function (t) { - const p = new pool.Pool({ - max: 2, - min: 0, - create: function (cb) { - addTask(cb, [null, {}]) - }, - destroy: function (o, cb) { - addTask(cb) - } - }) - - Array.from({ length: 6 }, async (_, i) => { - await run(i) - }) - - drain() - - async function run(n) { - return helper.runInTransaction(agent, async (tx) => { - return new Promise((resolve, reject) => { - p.acquire((err, conn) => { - if (err) { - reject(err) - } - - t.equal(id(agent.getTransaction()), id(tx), n + ': should maintain tx state') - addTask(() => { - p.release(conn) - resolve() - }) - }) - }) - }) - } - - function drain() { - run('drain') - - helper.runInTransaction(agent, function (tx) { - p.drain(function () { - t.equal(id(agent.getTransaction()), id(tx), 'should have context through drain') - - p.destroyAllNow(function () { - t.equal(id(agent.getTransaction()), id(tx), 'should have context through destroy') - t.end() - }) - }) - }) - } - }) -}) diff --git a/test/versioned/generic-pool/package.json b/test/versioned/generic-pool/package.json index dc7b20f31e..535852d8ab 100644 --- a/test/versioned/generic-pool/package.json +++ b/test/versioned/generic-pool/package.json @@ -14,17 +14,6 @@ "files": [ "basic.tap.js" ] - }, - { - "engines": { - "node": ">=18" - }, - "dependencies": { - "generic-pool": ">=2.4 <3" - }, - "files": [ - "basic-v2.tap.js" - ] } ], "dependencies": {} diff --git a/test/versioned/ioredis/ioredis-3.tap.js b/test/versioned/ioredis/ioredis-3.tap.js deleted file mode 100644 index 825effdc66..0000000000 --- a/test/versioned/ioredis/ioredis-3.tap.js +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright 2020 New Relic Corporation. All rights reserved. - * SPDX-License-Identifier: Apache-2.0 - */ - -'use strict' - -const tap = require('tap') -const helper = require('../../lib/agent_helper') -const { removeMatchedModules } = require('../../lib/cache-buster') -require('../../lib/metrics_helper') -const params = require('../../lib/params') -const urltils = require('../../../lib/util/urltils') - -// Indicates unique database in Redis. 0-15 supported. -const DB_INDEX = 4 - -tap.test('ioredis instrumentation', function (t) { - let agent - let redisClient - let METRIC_HOST_NAME - let HOST_ID - - t.beforeEach(async function () { - const result = await setup(t) - agent = result.agent - redisClient = result.client - METRIC_HOST_NAME = urltils.isLocalhost(params.redis_host) - ? agent.config.getHostnameSafe() - : params.redis_host - HOST_ID = METRIC_HOST_NAME + '/' + params.redis_port - }) - - t.afterEach(function () { - agent && helper.unloadAgent(agent) - redisClient && redisClient.disconnect() - }) - - t.test('creates expected metrics', { timeout: 5000 }, function (t) { - const onError = function (error) { - return t.fail(error) - } - - agent.on('transactionFinished', function (tx) { - const expected = [ - [{ name: 'Datastore/all' }], - [{ name: 'Datastore/Redis/all' }], - [{ name: 'Datastore/operation/Redis/set' }] - ] - expected['Datastore/instance/Redis/' + HOST_ID] = 2 - t.assertMetrics(tx.metrics, expected, false, false) - t.end() - }) - - helper.runInTransaction(agent, function transactionInScope(transaction) { - redisClient - .set('testkey', 'testvalue') - .then(function () { - transaction.end() - }, onError) - .catch(onError) - }) - }) - - t.test('creates expected segments', { timeout: 5000 }, function (t) { - const onError = function (error) { - return t.fail(error) - } - - agent.on('transactionFinished', function (tx) { - const root = tx.trace.root - t.equal(root.children.length, 2, 'root has two children') - - const setSegment = root.children[0] - t.equal(setSegment.name, 'Datastore/operation/Redis/set') - - // ioredis operations return promise, any 'then' callbacks will be sibling segments - // of the original redis call - const getSegment = root.children[1] - t.equal(getSegment.name, 'Datastore/operation/Redis/get') - t.equal(getSegment.children.length, 0, 'should not contain any segments') - - t.end() - }) - - helper.runInTransaction(agent, function transactionInScope(transaction) { - redisClient - .set('testkey', 'testvalue') - .then(function () { - return redisClient.get('testkey') - }) - .then(function () { - transaction.end() - }) - .catch(onError) - }) - }) - - // NODE-1524 regression - t.test('does not crash when ending out of transaction', function (t) { - helper.runInTransaction(agent, function transactionInScope(transaction) { - t.ok(agent.getTransaction(), 'transaction should be in progress') - redisClient.set('testkey', 'testvalue').then(function () { - t.notOk(agent.getTransaction(), 'transaction should have ended') - t.end() - }) - transaction.end() - }) - }) - - t.autoend() -}) - -async function setup(t) { - const agent = helper.instrumentMockedAgent() - - // remove from cache, so that the bluebird library that ioredis uses gets - // re-instrumented - clearLoadedModules(t) - - const Redis = require('ioredis') - - const client = new Redis(params.redis_port, params.redis_host) - await helper.flushRedisDb(client, DB_INDEX) - - return new Promise(async (resolve, reject) => { - client.select(DB_INDEX, (err) => { - if (err) { - return reject(err) - } - - resolve({ agent, client }) - }) - }) -} - -function clearLoadedModules(t) { - const deletedCount = removeMatchedModules(/ioredis\/node_modules\/ioredis/) - t.comment(`Cleared ${deletedCount} modules matching '*/ioredis/node_modules/ioredis/*'`) -} diff --git a/test/versioned/ioredis/package.json b/test/versioned/ioredis/package.json index eb84df4dbd..7513fa3e48 100644 --- a/test/versioned/ioredis/package.json +++ b/test/versioned/ioredis/package.json @@ -4,17 +4,6 @@ "version": "0.0.0", "private": true, "tests": [ - { - "engines": { - "node": ">=18" - }, - "dependencies": { - "ioredis": "3.x" - }, - "files": [ - "ioredis-3.tap.js" - ] - }, { "engines": { "node": ">=18" diff --git a/test/versioned/koa/package.json b/test/versioned/koa/package.json index 674e4cc25d..50a1775d0f 100644 --- a/test/versioned/koa/package.json +++ b/test/versioned/koa/package.json @@ -34,7 +34,7 @@ "samples": 5 }, "koa-router": { - "versions": ">=7.1.0", + "versions": ">=11.0.2", "samples": 5 } }, @@ -53,7 +53,7 @@ "samples": 5 }, "@koa/router": { - "versions": ">=8.0.0", + "versions": ">=11.0.2", "samples": 5 } }, diff --git a/test/versioned/nestjs/package.json b/test/versioned/nestjs/package.json index c7290539b7..eaa43edd18 100644 --- a/test/versioned/nestjs/package.json +++ b/test/versioned/nestjs/package.json @@ -9,7 +9,7 @@ "node": ">=18" }, "dependencies": { - "@nestjs/cli": ">=8.0.0" + "@nestjs/cli": ">=9.0.0" }, "files": [ "nest.tap.js" diff --git a/test/versioned/pg/package.json b/test/versioned/pg/package.json index bdfc18edb0..0b28021e6d 100644 --- a/test/versioned/pg/package.json +++ b/test/versioned/pg/package.json @@ -9,21 +9,7 @@ "node": ">=18" }, "dependencies": { - "pg": ">=8.2.0 <8.8.0", - "pg-native": ">=2.0.0" - }, - "files": [ - "force-native.tap.js", - "native.tap.js", - "pg.tap.js" - ] - }, - { - "engines": { - "node": ">=18" - }, - "dependencies": { - "pg": ">=8.8.0", + "pg": ">=8.2.0", "pg-native": ">=3.0.0" }, "files": [ diff --git a/test/versioned/redis/package.json b/test/versioned/redis/package.json index 14e585f574..589c9943fc 100644 --- a/test/versioned/redis/package.json +++ b/test/versioned/redis/package.json @@ -9,40 +9,7 @@ "node": ">=18" }, "dependencies": { - "redis": ">=2.0.0 < 2.3.0" - }, - "files": [ - "redis.tap.js" - ] - }, - { - "engines": { - "node": ">=18" - }, - "dependencies": { - "redis": ">=2.3.0 < 2.4.0" - }, - "files": [ - "redis.tap.js" - ] - }, - { - "engines": { - "node": ">=18" - }, - "dependencies": { - "redis": ">=2.4.0 < 2.6.0" - }, - "files": [ - "redis.tap.js" - ] - }, - { - "engines": { - "node": ">=18" - }, - "dependencies": { - "redis": ">=2.6.0 < 4.0.0" + "redis": ">=3.1.0 < 4.0.0" }, "files": [ "redis.tap.js" diff --git a/test/versioned/restify/package.json b/test/versioned/restify/package.json index 0b093e34ba..33a50e31fa 100644 --- a/test/versioned/restify/package.json +++ b/test/versioned/restify/package.json @@ -9,25 +9,7 @@ "node": ">=18" }, "dependencies": { - "restify": ">=5.0.0 <7", - "express": "4.16", - "restify-errors": "6.1" - }, - "files": [ - "pre-7/capture-params.tap.js", - "pre-7/ignoring.tap.js", - "pre-7/restify.tap.js", - "pre-7/router.tap.js", - "pre-7/rum.tap.js", - "pre-7/transaction-naming.tap.js" - ] - }, - { - "engines": { - "node": ">=18" - }, - "dependencies": { - "restify": ">=10.0.0", + "restify": ">=11.0.0", "express": "4.16", "restify-errors": "6.1" }, diff --git a/test/versioned/restify/pre-7/capture-params.tap.js b/test/versioned/restify/pre-7/capture-params.tap.js deleted file mode 100644 index 0ba875b9db..0000000000 --- a/test/versioned/restify/pre-7/capture-params.tap.js +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright 2020 New Relic Corporation. All rights reserved. - * SPDX-License-Identifier: Apache-2.0 - */ - -'use strict' - -const DESTINATIONS = require('../../../../lib/config/attribute-filter').DESTINATIONS -const test = require('tap').test -const helper = require('../../../lib/agent_helper') -const HTTP_ATTS = require('../../../lib/fixtures').httpAttributes - -test('Restify capture params introspection', function (t) { - t.autoend() - - let agent = null - - t.beforeEach(function () { - agent = helper.instrumentMockedAgent({ - allow_all_headers: false, - attributes: { - enabled: true, - include: ['request.parameters.*'] - } - }) - }) - - t.afterEach(function () { - helper.unloadAgent(agent) - }) - - t.test('simple case with no params', function (t) { - const server = require('restify').createServer() - let port = null - - t.teardown(function () { - server.close() - }) - - agent.on('transactionFinished', function (transaction) { - t.ok(transaction.trace, 'transaction has a trace.') - // on older versions of node response messages aren't included - const attributes = transaction.trace.attributes.get(DESTINATIONS.TRANS_TRACE) - HTTP_ATTS.forEach(function (key) { - t.ok(attributes[key], 'Trace contains expected HTTP attribute: ' + key) - }) - if (attributes.httpResponseMessage) { - t.equal(attributes.httpResponseMessage, 'OK', 'Trace contains httpResponseMessage') - } - }) - - server.get('/test', function (req, res, next) { - t.ok(agent.getTransaction(), 'transaction is available') - - res.send({ status: 'ok' }) - next() - }) - - server.listen(0, function () { - port = server.address().port - helper.makeGetRequest('http://localhost:' + port + '/test', function (error, res, body) { - t.equal(res.statusCode, 200, 'nothing exploded') - t.same(body, { status: 'ok' }, 'got expected respose') - t.end() - }) - }) - }) - - t.test('case with route params', function (t) { - const server = require('restify').createServer() - let port = null - - t.teardown(function () { - server.close() - }) - - agent.on('transactionFinished', function (transaction) { - t.ok(transaction.trace, 'transaction has a trace.') - // on older versions of node response messages aren't included - const attributes = transaction.trace.attributes.get(DESTINATIONS.TRANS_TRACE) - t.equal( - attributes['request.parameters.route.id'], - '1337', - 'Trace attributes include `id` route param' - ) - }) - - server.get('/test/:id', function (req, res, next) { - t.ok(agent.getTransaction(), 'transaction is available') - - res.send({ status: 'ok' }) - next() - }) - - server.listen(0, function () { - port = server.address().port - helper.makeGetRequest('http://localhost:' + port + '/test/1337', function (error, res, body) { - t.equal(res.statusCode, 200, 'nothing exploded') - t.same(body, { status: 'ok' }, 'got expected respose') - t.end() - }) - }) - }) - - t.test('case with query params', function (t) { - const server = require('restify').createServer() - let port = null - - t.teardown(function () { - server.close() - }) - - agent.on('transactionFinished', function (transaction) { - t.ok(transaction.trace, 'transaction has a trace.') - // on older versions of node response messages aren't included - const attributes = transaction.trace.attributes.get(DESTINATIONS.TRANS_TRACE) - t.equal( - attributes['request.parameters.name'], - 'restify', - 'Trace attributes include `name` query param' - ) - }) - - server.get('/test', function (req, res, next) { - t.ok(agent.getTransaction(), 'transaction is available') - - res.send({ status: 'ok' }) - next() - }) - - server.listen(0, function () { - port = server.address().port - const url = 'http://localhost:' + port + '/test?name=restify' - helper.makeGetRequest(url, function (error, res, body) { - t.equal(res.statusCode, 200, 'nothing exploded') - t.same(body, { status: 'ok' }, 'got expected respose') - t.end() - }) - }) - }) - - t.test('case with both route and query params', function (t) { - const server = require('restify').createServer() - let port = null - - t.teardown(function () { - server.close() - }) - - agent.on('transactionFinished', function (transaction) { - t.ok(transaction.trace, 'transaction has a trace.') - // on older versions of node response messages aren't included - const attributes = transaction.trace.attributes.get(DESTINATIONS.TRANS_TRACE) - t.equal( - attributes['request.parameters.route.id'], - '1337', - 'Trace attributes include `id` route param' - ) - t.equal( - attributes['request.parameters.name'], - 'restify', - 'Trace attributes include `name` query param' - ) - }) - - server.get('/test/:id', function (req, res, next) { - t.ok(agent.getTransaction(), 'transaction is available') - - res.send({ status: 'ok' }) - next() - }) - - server.listen(0, function () { - port = server.address().port - const url = 'http://localhost:' + port + '/test/1337?name=restify' - helper.makeGetRequest(url, function (error, res, body) { - t.equal(res.statusCode, 200, 'nothing exploded') - t.same(body, { status: 'ok' }, 'got expected respose') - t.end() - }) - }) - }) -}) diff --git a/test/versioned/restify/pre-7/ignoring.tap.js b/test/versioned/restify/pre-7/ignoring.tap.js deleted file mode 100644 index 6d383e5438..0000000000 --- a/test/versioned/restify/pre-7/ignoring.tap.js +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2020 New Relic Corporation. All rights reserved. - * SPDX-License-Identifier: Apache-2.0 - */ - -'use strict' - -const test = require('tap').test -const helper = require('../../../lib/agent_helper') -const API = require('../../../../api') - -test('Restify router introspection', function (t) { - t.plan(7) - - const agent = helper.instrumentMockedAgent() - const api = new API(agent) - const server = require('restify').createServer() - - t.teardown(function () { - server.close(function () { - helper.unloadAgent(agent) - }) - }) - - agent.on('transactionFinished', function (transaction) { - t.equal( - transaction.name, - 'WebTransaction/Restify/GET//polling/:id', - 'transaction has expected name even on error' - ) - - t.ok(transaction.ignore, 'transaction is ignored') - - t.notOk(agent.traces.trace, 'should have no transaction trace') - - const metrics = agent.metrics._metrics.unscoped - // loading k2 adds instrumentation metrics for things it registers - // this also differs between major versions of restify. 6+ also loads - // k2 child_process instrumentation, fun fun fun - const expectedMetrics = helper.isSecurityAgentEnabled(agent) ? 15 : 7 - t.equal( - Object.keys(metrics).length, - expectedMetrics, - 'only supportability metrics added to agent collection' - ) - - const errors = agent.errors.traceAggregator.errors - t.equal(errors.length, 0, 'no errors noticed') - }) - - server.get('/polling/:id', function (req, res, next) { - api.addIgnoringRule(/poll/) - res.send(400, { status: 'pollpollpoll' }) - next() - }) - - server.listen(0, function () { - const port = server.address().port - const url = 'http://localhost:' + port + '/polling/31337' - helper.makeGetRequest(url, function (error, res, body) { - t.equal(res.statusCode, 400, 'got expected error') - t.same(body, { status: 'pollpollpoll' }, 'got expected response') - }) - }) -}) diff --git a/test/versioned/restify/pre-7/newrelic.js b/test/versioned/restify/pre-7/newrelic.js deleted file mode 100644 index 5bfe53711f..0000000000 --- a/test/versioned/restify/pre-7/newrelic.js +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2020 New Relic Corporation. All rights reserved. - * SPDX-License-Identifier: Apache-2.0 - */ - -'use strict' - -exports.config = { - app_name: ['My Application'], - license_key: 'license key here', - logging: { - level: 'trace', - filepath: '../../../newrelic_agent.log' - }, - utilization: { - detect_aws: false, - detect_pcf: false, - detect_azure: false, - detect_gcp: false, - detect_docker: false - }, - transaction_tracer: { - enabled: true - } -} diff --git a/test/versioned/restify/pre-7/restify.tap.js b/test/versioned/restify/pre-7/restify.tap.js deleted file mode 100644 index 607786210a..0000000000 --- a/test/versioned/restify/pre-7/restify.tap.js +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright 2020 New Relic Corporation. All rights reserved. - * SPDX-License-Identifier: Apache-2.0 - */ - -'use strict' - -const tap = require('tap') -const helper = require('../../../lib/agent_helper') -require('../../../lib/metrics_helper') - -const METRIC = 'WebTransaction/Restify/GET//hello/:name' - -tap.test('Restify', (t) => { - t.autoend() - - let agent = null - let restify = null - t.beforeEach(() => { - agent = helper.instrumentMockedAgent() - - restify = require('restify') - }) - - t.afterEach(() => { - helper.unloadAgent(agent) - }) - - t.test('should not crash when handling a connection', function (t) { - t.plan(7) - - const server = restify.createServer() - t.teardown(() => server.close()) - - server.get('/hello/:name', function sayHello(req, res) { - t.ok(agent.getTransaction(), 'transaction should be available in handler') - res.send('hello ' + req.params.name) - }) - - server.listen(0, function () { - const port = server.address().port - t.notOk(agent.getTransaction(), 'transaction should not leak into server') - - const url = `http://localhost:${port}/hello/friend` - helper.makeGetRequest(url, function (error, response, body) { - if (error) { - return t.fail(error) - } - t.notOk(agent.getTransaction(), 'transaction should not leak into external request') - - const metric = agent.metrics.getMetric(METRIC) - t.ok(metric, 'request metrics should have been gathered') - t.equal(metric.callCount, 1, 'handler should have been called') - t.equal(body, 'hello friend', 'should return expected data') - - const isFramework = agent.environment.get('Framework').indexOf('Restify') > -1 - t.ok(isFramework, 'should indicate that restify is a framework') - }) - }) - }) - - t.test('should still be instrumented when run with SSL', function (t) { - t.plan(7) - - helper - .withSSL() - .then(([key, certificate, ca]) => { - const server = restify.createServer({ key: key, certificate: certificate }) - t.teardown(() => server.close()) - - server.get('/hello/:name', function sayHello(req, res) { - t.ok(agent.getTransaction(), 'transaction should be available in handler') - res.send('hello ' + req.params.name) - }) - - server.listen(0, function () { - const port = server.address().port - t.notOk(agent.getTransaction(), 'transaction should not leak into server') - - const url = `https://${helper.SSL_HOST}:${port}/hello/friend` - helper.makeGetRequest(url, { ca }, function (error, response, body) { - if (error) { - t.fail(error) - return t.end() - } - - t.notOk(agent.getTransaction(), 'transaction should not leak into external request') - - const metric = agent.metrics.getMetric(METRIC) - t.ok(metric, 'request metrics should have been gathered') - t.equal(metric.callCount, 1, 'handler should have been called') - t.equal(body, 'hello friend', 'should return expected data') - - const isFramework = agent.environment.get('Framework').indexOf('Restify') > -1 - t.ok(isFramework, 'should indicate that restify is a framework') - }) - }) - }) - .catch((error) => { - t.fail('unable to set up SSL: ' + error) - t.end() - }) - }) - - t.test('should generate middleware metrics', (t) => { - // Metrics for this transaction with the right name. - const expectedMiddlewareMetrics = [ - [{ name: 'WebTransaction/Restify/GET//foo/:bar' }], - [{ name: 'WebTransactionTotalTime/Restify/GET//foo/:bar' }], - [{ name: 'Apdex/Restify/GET//foo/:bar' }], - - // Unscoped middleware metrics. - [{ name: 'Nodejs/Middleware/Restify/middleware//' }], - [{ name: 'Nodejs/Middleware/Restify/middleware2//' }], - [{ name: 'Nodejs/Middleware/Restify/handler//foo/:bar' }], - - // Scoped middleware metrics. - [ - { - name: 'Nodejs/Middleware/Restify/middleware//', - scope: 'WebTransaction/Restify/GET//foo/:bar' - } - ], - [ - { - name: 'Nodejs/Middleware/Restify/middleware2//', - scope: 'WebTransaction/Restify/GET//foo/:bar' - } - ], - [ - { - name: 'Nodejs/Middleware/Restify/handler//foo/:bar', - scope: 'WebTransaction/Restify/GET//foo/:bar' - } - ] - ] - - const server = restify.createServer() - t.teardown(() => server.close()) - - server.use(function middleware(req, res, next) { - t.ok(agent.getTransaction(), 'should be in transaction context') - next() - }) - - server.use(function middleware2(req, res, next) { - t.ok(agent.getTransaction(), 'should be in transaction context') - next() - }) - - server.get('/foo/:bar', function handler(req, res, next) { - t.ok(agent.getTransaction(), 'should be in transaction context') - res.send({ message: 'done' }) - next() - }) - - server.listen(0, function () { - const port = server.address().port - const url = `http://localhost:${port}/foo/bar` - - helper.makeGetRequest(url, function (error) { - t.error(error) - - t.assertMetrics(agent.metrics, expectedMiddlewareMetrics, false, false) - t.end() - }) - }) - }) -}) diff --git a/test/versioned/restify/pre-7/router.tap.js b/test/versioned/restify/pre-7/router.tap.js deleted file mode 100644 index 2fef181b31..0000000000 --- a/test/versioned/restify/pre-7/router.tap.js +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright 2020 New Relic Corporation. All rights reserved. - * SPDX-License-Identifier: Apache-2.0 - */ - -'use strict' - -const tap = require('tap') - -const helper = require('../../../lib/agent_helper') - -tap.test('Restify router', function (t) { - t.autoend() - - let agent = null - let server = null - - t.beforeEach(function () { - agent = helper.instrumentMockedAgent({ - attributes: { - enabled: true, - include: ['request.parameters.*'] - } - }) - - server = require('restify').createServer() - }) - - t.afterEach(function () { - return new Promise((resolve) => { - server.close(function () { - helper.unloadAgent(agent) - resolve() - }) - }) - }) - - t.test('introspection', function (t) { - t.plan(12) - - // need to capture attributes - agent.config.attributes.enabled = true - - agent.on('transactionFinished', function (transaction) { - t.equal( - transaction.name, - 'WebTransaction/Restify/GET//test/:id', - 'transaction has expected name' - ) - t.equal(transaction.url, '/test/31337', 'URL is left alone') - t.equal(transaction.statusCode, 200, 'status code is OK') - t.equal(transaction.verb, 'GET', 'HTTP method is GET') - t.ok(transaction.trace, 'transaction has trace') - - const web = transaction.trace.root.children[0] - t.ok(web, 'trace has web segment') - t.equal(web.name, transaction.name, 'segment name and transaction name match') - t.equal(web.partialName, 'Restify/GET//test/:id', 'should have partial name for apdex') - t.equal( - web.getAttributes()['request.parameters.route.id'], - '31337', - 'namer gets parameters out of route' - ) - }) - - server.get('/test/:id', function (req, res, next) { - t.ok(agent.getTransaction(), 'transaction should be available') - - res.send({ status: 'ok' }) - next() - }) - - _listenAndRequest(t, '/test/31337') - }) - - t.test('next(true): continue processing', function (t) { - t.plan(6) - - server.get( - '/test/:id', - function first(req, res, next) { - t.ok(agent.getTransaction(), 'transaction should be available') - next(true) - }, - function second(req, res, next) { - t.ok(agent.getTransaction(), 'transaction should be available') - next(true) - }, - function final(req, res, next) { - t.ok(agent.getTransaction(), 'transaction should be available') - res.send({ status: 'ok' }) - next() - } - ) - - agent.on('transactionFinished', function (tx) { - t.equal(tx.name, 'WebTransaction/Restify/GET//test/:id', 'should have correct name') - }) - - _listenAndRequest(t, '/test/foobar') - }) - - t.test('next(false): stop processing', function (t) { - t.plan(4) - - server.get( - '/test/:id', - function first(req, res, next) { - t.ok(agent.getTransaction(), 'transaction should be available') - res.send({ status: 'ok' }) - next(false) - }, - function final(req, res, next) { - t.fail('should not enter this final middleware') - res.send({ status: 'ok' }) - next() - } - ) - - agent.on('transactionFinished', function (tx) { - t.equal(tx.name, 'WebTransaction/Restify/GET//test/:id', 'should have correct name') - }) - - _listenAndRequest(t, '/test/foobar') - }) - - t.test('next("other_route"): jump processing', function (t) { - t.plan(5) - - server.get({ name: 'first', path: '/test/:id' }, function final(req, res, next) { - t.ok(agent.getTransaction(), 'transaction should be available') - next('second') - }) - - server.get({ name: 'second', path: '/other' }, function final(req, res, next) { - t.ok(agent.getTransaction(), 'transaction should be available') - res.send({ status: 'ok' }) - next() - }) - - agent.on('transactionFinished', function (tx) { - t.equal(tx.name, 'WebTransaction/Restify/GET//other', 'should have correct name') - }) - - _listenAndRequest(t, '/test/foobar') - }) - - function _listenAndRequest(t, route) { - server.listen(0, function () { - const port = server.address().port - const url = 'http://localhost:' + port + route - helper.makeGetRequest(url, function (error, res, body) { - t.equal(res.statusCode, 200, 'nothing exploded') - t.same(body, { status: 'ok' }, 'got expected respose') - }) - }) - } -}) diff --git a/test/versioned/restify/pre-7/rum.tap.js b/test/versioned/restify/pre-7/rum.tap.js deleted file mode 100644 index 0df9dcfe69..0000000000 --- a/test/versioned/restify/pre-7/rum.tap.js +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2020 New Relic Corporation. All rights reserved. - * SPDX-License-Identifier: Apache-2.0 - */ - -'use strict' - -const tap = require('tap') - -const helper = require('../../../lib/agent_helper') -const API = require('../../../../api') - -tap.test('Restify router introspection', function (t) { - t.plan(3) - - const agent = helper.instrumentMockedAgent() - const server = require('restify').createServer() - const api = new API(agent) - - agent.config.application_id = '12345' - agent.config.browser_monitoring.browser_key = '12345' - agent.config.browser_monitoring.js_agent_loader = 'function(){}' - - t.teardown(() => { - server.close(() => { - helper.unloadAgent(agent) - }) - }) - - server.get('/test/:id', function (req, res, next) { - const rum = api.getBrowserTimingHeader() - t.equal(rum.substring(0, 7), ' { - t.autoend() - - let agent = null - let restify = null - let restifyPkg = null - let server = null - - t.beforeEach(() => { - agent = helper.instrumentMockedAgent() - - restify = require('restify') - restifyPkg = require('restify/package.json') - server = restify.createServer() - }) - - t.afterEach(() => { - return new Promise((resolve) => { - helper.unloadAgent(agent) - if (server) { - server.close(resolve) - } else { - resolve() - } - }) - }) - - t.test('transaction name with single route', (t) => { - t.plan(1) - - server.get('/path1', (req, res, next) => { - res.send() - next() - }) - - runTest({ t, endpoint: '/path1', expectedName: 'GET//path1' }) - }) - - t.test('transaction name with async response middleware', (t) => { - t.plan(1) - - // restify v5 added the plugins object - if (restify.plugins && restify.plugins.gzipResponse) { - server.use(restify.plugins.gzipResponse()) - } else { - server.use(restify.gzipResponse()) - } - - server.get('/path1', (req, res, next) => { - res.send({ - patientId: 5, - entries: ['hi', 'bye', 'example'], - total: 3 - }) - next() - }) - - runTest({ - t, - endpoint: '/path1', - expectedName: 'GET//path1', - requestOpts: { headers: { 'Accept-Encoding': 'gzip' } } - }) - }) - - t.test('transaction name with async response middleware (res.json)', (t) => { - t.plan(1) - - // restify v5 added the plugins object - if (restify.plugins && restify.plugins.gzipResponse) { - server.use(restify.plugins.gzipResponse()) - } else { - server.use(restify.gzipResponse()) - } - - server.get('/path1', (req, res, next) => { - res.json({ - patientId: 5, - entries: ['hi', 'bye', 'example'], - total: 3 - }) - next() - }) - - runTest({ - t, - endpoint: '/path1', - expectedName: 'GET//path1', - requestOpts: { headers: { 'Accept-Encoding': 'gzip' } } - }) - }) - - if (semver.satisfies(restifyPkg.version, '>=5')) { - t.test('transaction name with async response middleware (res.sendRaw)', (t) => { - t.plan(1) - - // restify v5 added the plugins object - if (restify.plugins && restify.plugins.gzipResponse) { - server.use(restify.plugins.gzipResponse()) - } else { - server.use(restify.gzipResponse()) - } - - server.get('/path1', (req, res, next) => { - res.sendRaw( - JSON.stringify({ - patientId: 5, - entries: ['hi', 'bye', 'example'], - total: 3 - }) - ) - next() - }) - - runTest({ - t, - endpoint: '/path1', - expectedName: 'GET//path1', - requestOpts: { headers: { 'Accept-Encoding': 'gzip' } } - }) - }) - } - - t.test('transaction name with async response middleware (res.redirect)', (t) => { - t.plan(1) - - // restify v5 added the plugins object - if (restify.plugins && restify.plugins.gzipResponse) { - server.use(restify.plugins.gzipResponse()) - } else { - server.use(restify.gzipResponse()) - } - - server.get('/path1', (req, res, next) => { - res.redirect('http://google.com', next) - }) - - runTest({ - t, - endpoint: '/path1', - expectedName: 'GET//path1', - requestOpts: { headers: { 'Accept-Encoding': 'gzip' } } - }) - }) - - t.test('transaction name with no matched routes', (t) => { - t.plan(1) - - server.get('/path1', (req, res, next) => { - t.fail('should not enter different endpoint') - res.send() - next() - }) - - runTest({ t, endpoint: '/foobar', prefix: 'Nodejs', expectedName: 'GET/(not found)' }) - }) - - t.test('transaction name with route that has multiple handlers', (t) => { - t.plan(3) - - server.get( - '/path1', - (req, res, next) => { - t.pass('should enter first middleware') - next() - }, - (req, res, next) => { - t.pass('should enter second middleware') - res.send() - next() - } - ) - - runTest({ t, endpoint: '/path1', expectedName: 'GET//path1' }) - }) - - t.test('transaction name with middleware', (t) => { - t.plan(3) - - server.use((req, res, next) => { - t.pass('should enter `use` middleware') - next() - }) - server.get('/path1', (req, res, next) => { - t.pass('should enter route handler') - res.send() - next() - }) - - runTest({ t, endpoint: '/path1', expectedName: 'GET//path1' }) - }) - - t.test('multiple route handlers with the same name do not duplicate', (t) => { - t.plan(3) - - server.get({ name: 'first', path: '/path1' }, (req, res, next) => { - t.pass('should execute first handler') - next('second') - }) - - server.get({ name: 'second', path: '/path1' }, (req, res, next) => { - t.pass('should execute second handler') - res.send() - next() - }) - - runTest({ t, endpoint: '/path1', expectedName: 'GET//path1' }) - }) - - t.test('responding from middleware', (t) => { - t.plan(2) - - server.use((req, res, next) => { - res.send() - next() - }) - - server.get('/path1', (req, res, next) => { - t.pass('should enter route middleware') - next() - }) - - runTest({ t, endpoint: '/path1', expectedName: 'GET//' }) - }) - - t.test('with error', (t) => { - t.plan(1) - - const errors = require('restify-errors') - - server.get('/path1', (req, res, next) => { - next(new errors.InternalServerError('foobar')) - }) - - runTest({ t, endpoint: '/path1', expectedName: 'GET//path1' }) - }) - - t.test('with error while out of context', (t) => { - t.plan(1) - - const errors = require('restify-errors') - - server.get('/path1', (req, res, next) => { - helper.runOutOfContext(() => { - next(new errors.InternalServerError('foobar')) - }) - }) - - runTest({ t, endpoint: '/path1', expectedName: 'GET//path1' }) - }) - - t.test('when using a route variable', (t) => { - t.plan(2) - - server.get('/foo/:bar', (req, res, next) => { - t.equal(req.params.bar, 'fizz', 'should pass through params') - res.send() - next() - }) - - runTest({ t, endpoint: '/foo/fizz', expectedName: 'GET//foo/:bar' }) - }) - - t.test('when using a regular expression in path', (t) => { - t.plan(2) - - server.get(/^\/foo\/(.*)/, (req, res, next) => { - t.equal(req.params[0], 'bar', 'should pass through captured param') - res.send() - next() - }) - - runTest({ t, endpoint: '/foo/bar', expectedName: 'GET//^\\/foo\\/(.*)/' }) - }) - - t.test('when next is called after transaction state loss', (t) => { - t.plan(5) - - server.use((req, res, next) => { - t.ok(agent.getTransaction(), 'should have transaction at start') - req.testTx = agent.getTransaction() - - helper.runOutOfContext(() => { - t.notOk(agent.getTransaction(), 'should lose transaction before next') - next() - }) - }) - - server.get('/path1', (req, res, next) => { - const tx = agent.getTransaction() - t.ok(tx, 'should re-instate transaction in next middleware') - t.equal(tx && tx.id, req.testTx.id, 'should reinstate correct transaction') - res.send() - next() - }) - - runTest({ t, endpoint: '/path1', expectedName: 'GET//path1' }) - }) - - t.test('responding after transaction state loss', (t) => { - t.plan(2) - - server.get('/path1', (req, res, next) => { - helper.runOutOfContext(() => { - t.notOk(agent.getTransaction(), 'should have no transaction') - res.send() - next() - }) - }) - - runTest({ t, endpoint: '/path1', expectedName: 'GET//path1' }) - }) - - t.test('responding with just a status code', (t) => { - t.plan(1) - - server.get('/path1', (req, res, next) => { - res.send(299) - next() - }) - - runTest({ t, endpoint: '/path1', expectedName: 'GET//path1' }) - }) - - t.test('responding with just a status code after state loss', (t) => { - t.plan(1) - - server.get('/path1', (req, res, next) => { - helper.runOutOfContext(() => { - res.send(299) - next() - }) - }) - - runTest({ t, endpoint: '/path1', expectedName: 'GET//path1' }) - }) - - /** - * @param {Object} cfg - * @property {Object} cfg.t - * @property {string} cfg.endpoint - * @property {string} [cfg.prefix='Restify'] - * @property {string} cfg.expectedName - * @property {Function} [cfg.cb=t.end] - * @property {Object} [cfg.requestOpts=null] - */ - function runTest(cfg) { - const t = cfg.t - const endpoint = cfg.endpoint - const prefix = cfg.prefix || 'Restify' - const expectedName = `WebTransaction/${prefix}/${cfg.expectedName}` - - agent.on('transactionFinished', (tx) => { - t.equal(tx.name, expectedName, 'should have correct name') - ;(cfg.cb && cfg.cb()) || t.end() - }) - - server.listen(() => { - const port = server.address().port - helper.makeGetRequest(`http://localhost:${port}${endpoint}`, cfg.requestOpts || null) - }) - } -}) diff --git a/test/versioned/superagent/package.json b/test/versioned/superagent/package.json index b4ff4cd429..7645b61d0e 100644 --- a/test/versioned/superagent/package.json +++ b/test/versioned/superagent/package.json @@ -9,7 +9,7 @@ }, "dependencies": { "superagent": { - "versions": ">=2 <7.1.0 || >=7.1.1", + "versions": ">=3 <7.1.0 || >=7.1.1", "samples": 5 } }, diff --git a/test/versioned/undici/package.json b/test/versioned/undici/package.json index ad73f760e6..d4bcc523ed 100644 --- a/test/versioned/undici/package.json +++ b/test/versioned/undici/package.json @@ -4,23 +4,12 @@ "version": "0.0.0", "private": true, "tests": [ - { - "engines": { - "node": "16" - }, - "dependencies": { - "undici": ">=4.7.0 <6.0.0" - }, - "files": [ - "requests.tap.js" - ] - }, { "engines": { "node": ">=18" }, "dependencies": { - "undici": ">=4.7.0" + "undici": ">=5.0.0" }, "files": [ "requests.tap.js"