diff --git a/test/integration/distributed-tracing/background.tap.js b/test/integration/distributed-tracing/background.test.js similarity index 57% rename from test/integration/distributed-tracing/background.tap.js rename to test/integration/distributed-tracing/background.test.js index 1b97302668..dbdde045bd 100644 --- a/test/integration/distributed-tracing/background.tap.js +++ b/test/integration/distributed-tracing/background.test.js @@ -5,14 +5,17 @@ 'use strict' -const tap = require('tap') +const test = require('node:test') +const tspl = require('@matteo.collina/tspl') + const helper = require('../../lib/agent_helper') const API = require('../../../api') let compareSampled = null -tap.test('background transactions should not blow up with DT', (t) => { - t.plan(24) +test('background transactions should not blow up with DT', async (t) => { + const plan = tspl(t, { plan: 24 }) + const config = { distributed_tracing: { enabled: true @@ -34,7 +37,7 @@ tap.test('background transactions should not blow up with DT', (t) => { const api = new API(agent) const server = http.createServer(function (req, res) { - t.ok(req.headers.newrelic, 'got incoming newrelic header') + plan.ok(req.headers.newrelic, 'got incoming newrelic header') req.resume() res.end() @@ -59,52 +62,60 @@ tap.test('background transactions should not blow up with DT', (t) => { const finishedHandlers = [ function web(trans, event) { - t.equal(trans.name, 'WebTransaction/NormalizedUri/*', 'got web trans first') + plan.equal(trans.name, 'WebTransaction/NormalizedUri/*', 'got web trans first') const intrinsic = event[0] - t.equal(intrinsic.name, 'WebTransaction/NormalizedUri/*', 'web event has name') - t.ok(intrinsic.guid, 'web should have a guid on event') - t.ok(intrinsic.traceId, 'web should have a traceId on event') - t.ok(intrinsic.priority, 'web should have a priority on event') - t.ok(intrinsic.sampled != null, 'web should have a sampled boolean on event') - t.ok(intrinsic.parentId, 'web should have parentId on event') - t.ok(intrinsic['parent.type'], 'web should have parent type on event') - t.ok(intrinsic['parent.app'], 'web should have parent app on event') - t.ok(intrinsic['parent.account'], 'web should have parent account on event') - t.ok(intrinsic['parent.transportType'], 'web should have parent transport type on event') - t.ok( + plan.equal(intrinsic.name, 'WebTransaction/NormalizedUri/*', 'web event has name') + plan.ok(intrinsic.guid, 'web should have a guid on event') + plan.ok(intrinsic.traceId, 'web should have a traceId on event') + plan.ok(intrinsic.priority, 'web should have a priority on event') + plan.ok(intrinsic.sampled != null, 'web should have a sampled boolean on event') + plan.ok(intrinsic.parentId, 'web should have parentId on event') + plan.ok(intrinsic['parent.type'], 'web should have parent type on event') + plan.ok(intrinsic['parent.app'], 'web should have parent app on event') + plan.ok(intrinsic['parent.account'], 'web should have parent account on event') + plan.ok(intrinsic['parent.transportType'], 'web should have parent transport type on event') + plan.ok( intrinsic['parent.transportDuration'], 'web should have parent transport duration on event' ) - t.notOk( + plan.equal( intrinsic['nr.alternatePathHashes'], + undefined, 'web should not have an nr.alternatePathHashes on event' ) - compareSampled = currySampled(t, { + compareSampled = currySampled(plan, { sampled: intrinsic.sampled, priority: intrinsic.priority }) }, function background(trans, event) { - t.equal(trans.name, 'OtherTransaction/Nodejs/myTx', 'got background trans second') + plan.equal(trans.name, 'OtherTransaction/Nodejs/myTx', 'got background trans second') const intrinsic = event[0] - t.ok(intrinsic.traceId, 'bg should have a traceId on event') - t.ok(intrinsic.priority, 'bg should have a priority on event') - t.ok(intrinsic.guid, 'bg should have a guid on event') - t.ok(intrinsic.sampled != null, 'bg should have a sampled boolean on event') - t.notOk( + plan.ok(intrinsic.traceId, 'bg should have a traceId on event') + plan.ok(intrinsic.priority, 'bg should have a priority on event') + plan.ok(intrinsic.guid, 'bg should have a guid on event') + plan.ok(intrinsic.sampled != null, 'bg should have a sampled boolean on event') + plan.equal( intrinsic['nr.referringPathHash'], + undefined, 'bg should not have an nr.referringPathHash on event' ) - t.notOk( + plan.equal( intrinsic['nr.referringTransactionGuid'], + undefined, 'bg should not have an nr.referringTransactionGuid on event' ) - t.notOk(intrinsic['nr.apdexPerfZone'], 'bg should have an nr.apdexPerfZone on event') - t.notOk( + plan.equal( + intrinsic['nr.apdexPerfZone'], + undefined, + 'bg should have an nr.apdexPerfZone on event' + ) + plan.equal( intrinsic['nr.alternatePathHashes'], + undefined, 'bg should have an nr.alternatePathHashes on event' ) @@ -122,12 +133,14 @@ tap.test('background transactions should not blow up with DT', (t) => { finishedHandlers[count](trans, event) count += 1 }) + + await plan.completed }) -function currySampled(t, a) { +function currySampled(plan, a) { return (b) => { b = b || a - t.ok( + plan.ok( a.sampled === b.sampled && a.priority === b.priority, 'sampled values and priority persist across transactions' ) diff --git a/test/integration/distributed-tracing/dt.tap.js b/test/integration/distributed-tracing/dt.test.js similarity index 62% rename from test/integration/distributed-tracing/dt.tap.js rename to test/integration/distributed-tracing/dt.test.js index 5d39427521..773efc0a0e 100644 --- a/test/integration/distributed-tracing/dt.tap.js +++ b/test/integration/distributed-tracing/dt.test.js @@ -5,10 +5,13 @@ 'use strict' +const test = require('node:test') +const assert = require('node:assert') +const url = require('node:url') +const tspl = require('@matteo.collina/tspl') + const API = require('../../../api') const helper = require('../../lib/agent_helper') -const tap = require('tap') -const url = require('url') const ACCOUNT_ID = '1337' const APP_ID = '7331' @@ -18,8 +21,9 @@ const symbols = require('../../../lib/symbols') let compareSampled = null -tap.test('distributed tracing full integration', (t) => { - t.plan(79) +test('distributed tracing full integration', async (t) => { + const plan = tspl(t, { plan: 79 }) + const config = { distributed_tracing: { enabled: true @@ -32,10 +36,6 @@ tap.test('distributed tracing full integration', (t) => { agent.config.account_id = ACCOUNT_ID agent.config.trusted_account_key = ACCOUNT_ID - t.teardown(() => { - helper.unloadAgent(agent) - }) - // require http after creating the agent const http = require('http') const api = new API(agent) @@ -74,7 +74,7 @@ tap.test('distributed tracing full integration', (t) => { const START_PORT = start.address().port const middle = generateServer(http, api, started, (req, res) => { - t.ok(req.headers.newrelic, 'middle received newrelic from start') + plan.ok(req.headers.newrelic, 'middle received newrelic from start') const tx = agent.tracer.getTransaction() tx.nameState.appendPath('foobar') @@ -91,13 +91,14 @@ tap.test('distributed tracing full integration', (t) => { MIDDLE_PORT = middle.address().port const end = generateServer(http, api, started, (req, res) => { - t.ok(req.headers.newrelic, 'end received newrelic from middle') + plan.ok(req.headers.newrelic, 'end received newrelic from middle') res.end() }) END_PORT = end.address().port - t.teardown(() => { + t.after(() => { + helper.unloadAgent(agent) start.close() middle.close() end.close() @@ -110,24 +111,24 @@ tap.test('distributed tracing full integration', (t) => { EXPECTED_DT_METRICS.forEach((name) => { const metric = `${name}/App/${ACCOUNT_ID}/${APP_ID}/HTTP/all` - t.ok(unscoped[metric], `end generated a ${name} metric`) - t.ok(unscoped[`${metric}Web`], `end generated a ${name} (Web) metric`) + plan.ok(unscoped[metric], `end generated a ${name} metric`) + plan.ok(unscoped[`${metric}Web`], `end generated a ${name} (Web) metric`) }) - t.equal(Object.keys(unscoped).length, 11, 'end should only have expected unscoped metrics') - t.equal(Object.keys(trans.metrics.scoped).length, 0, 'should have no scoped metrics') + plan.equal(Object.keys(unscoped).length, 11, 'end should only have expected unscoped metrics') + plan.equal(Object.keys(trans.metrics.scoped).length, 0, 'should have no scoped metrics') // check the intrinsic attributes - validateIntrinsics(t, trans.trace.intrinsics, 'end', 'trace') + validateIntrinsics(plan, trans.trace.intrinsics, 'end', 'trace') // check the insights event const intrinsic = event[0] - compareSampled = currySampled(t, { + compareSampled = currySampled(plan, { sampled: intrinsic.sampled, priority: intrinsic.priority }) - validateIntrinsics(t, intrinsic, 'end', 'event', secondExternalId) + validateIntrinsics(plan, intrinsic, 'end', 'event', secondExternalId) }, function middleTest(trans, event) { // check the unscoped metrics @@ -135,32 +136,36 @@ tap.test('distributed tracing full integration', (t) => { EXPECTED_DT_METRICS.forEach((name) => { const metric = `${name}/App/${ACCOUNT_ID}/${APP_ID}/HTTP/all` - t.ok(unscoped[metric], `middle generated a ${name} metric`) - t.ok(unscoped[`${metric}Web`], `middle generated a ${name} (Web) metric`) + plan.ok(unscoped[metric], `middle generated a ${name} metric`) + plan.ok(unscoped[`${metric}Web`], `middle generated a ${name} (Web) metric`) }) const external = `External/localhost:${END_PORT}/` EXTERNAL_METRIC_SUFFIXES.forEach((suf) => { - t.ok(unscoped[external + suf], `middle generated expected External metric (/${suf})`) + plan.ok(unscoped[external + suf], `middle generated expected External metric (/${suf})`) }) - t.equal(Object.keys(unscoped).length, 15, 'middle should only have expected unscoped metrics') + plan.equal( + Object.keys(unscoped).length, + 15, + 'middle should only have expected unscoped metrics' + ) // check the scoped metrics const scoped = trans.metrics.scoped const middleMetric = scoped['WebTransaction/Nodejs/GET//start/middle'] - t.ok(middleMetric, 'middle generated a scoped metric block') - t.ok(middleMetric[external + 'http'], 'middle generated an External scoped metric') + plan.ok(middleMetric, 'middle generated a scoped metric block') + plan.ok(middleMetric[external + 'http'], 'middle generated an External scoped metric') const scopedKeys = Object.keys(middleMetric) - t.equal(scopedKeys.length, 1, 'middle should only be the inbound and outbound request.') - t.same( + plan.equal(scopedKeys.length, 1, 'middle should only be the inbound and outbound request.') + plan.deepStrictEqual( scopedKeys, [`External/localhost:${END_PORT}/http`], 'should have expected scoped metric name' ) // check the intrinsic attributes - validateIntrinsics(t, trans.trace.intrinsics, 'middle', 'trace') + validateIntrinsics(plan, trans.trace.intrinsics, 'middle', 'trace') // check the insights event const intrinsic = event[0] @@ -170,36 +175,40 @@ tap.test('distributed tracing full integration', (t) => { priority: intrinsic.priority }) - validateIntrinsics(t, intrinsic, 'middle', 'event', firstExternalId) + validateIntrinsics(plan, intrinsic, 'middle', 'event', firstExternalId) }, function startTest(trans, event) { // check the unscoped metrics const unscoped = trans.metrics.unscoped const metric = 'DurationByCaller/Unknown/Unknown/Unknown/Unknown/all' - t.ok(unscoped[metric], 'start has expected DT unscoped metric') + plan.ok(unscoped[metric], 'start has expected DT unscoped metric') const external = `External/localhost:${MIDDLE_PORT}/` EXTERNAL_METRIC_SUFFIXES.forEach((suf) => { - t.ok(unscoped[external + suf], `start generated expected External metric (/${suf})`) + plan.ok(unscoped[external + suf], `start generated expected External metric (/${suf})`) }) - t.equal(Object.keys(unscoped).length, 13, 'start should only have expected unscoped metrics') + plan.equal( + Object.keys(unscoped).length, + 13, + 'start should only have expected unscoped metrics' + ) // check the scoped metrics const scoped = trans.metrics.scoped const startMetric = scoped['WebTransaction/Nodejs/GET//start'] - t.ok(startMetric, 'start generated a scoped metric block') - t.ok(startMetric[external + 'http'], 'start generated an External scoped metric') + plan.ok(startMetric, 'start generated a scoped metric block') + plan.ok(startMetric[external + 'http'], 'start generated an External scoped metric') const scopedKeys = Object.keys(startMetric) - t.equal(scopedKeys.length, 1, 'start should only be the inbound and outbound request.') - t.same( + plan.equal(scopedKeys.length, 1, 'start should only be the inbound and outbound request.') + plan.deepStrictEqual( scopedKeys, [`External/localhost:${MIDDLE_PORT}/http`], 'should have expected scoped metric name' ) // check the intrinsic attributes - validateIntrinsics(t, trans.trace.intrinsics, 'start', 'trace') + validateIntrinsics(plan, trans.trace.intrinsics, 'start', 'trace') // check the insights event const intrinsic = event[0] @@ -209,11 +218,12 @@ tap.test('distributed tracing full integration', (t) => { priority: intrinsic.priority }) - validateIntrinsics(t, intrinsic, 'start', 'event') - - t.end() + validateIntrinsics(plan, intrinsic, 'start', 'event') } ] + + await plan.completed + function runTest() { http.get(generateUrl(START_PORT, 'start'), (res) => { res.resume() @@ -230,7 +240,9 @@ tap.test('distributed tracing full integration', (t) => { })[0] testsToCheck.push(transInspector[txCount].bind(this, trans, event)) if (++txCount === 3) { - testsToCheck.forEach((test) => test()) + for (const testToCheck of testsToCheck) { + testToCheck() + } } }) } @@ -245,22 +257,12 @@ const createResponse = (req, res, body, bodyProperty) => { res.end() } -tap.test('distributed tracing', (t) => { - let agent = null - let start = null - let middle = null - let end = null - let START_PORT - let MIDDLE_PORT - let END_PORT - - t.autoend() - +test('distributed tracing', async (t) => { // simulation of the callback used by the async library, used by generateServer and close const cb = () => new Promise((resolve) => resolve()) - t.beforeEach(async () => { - agent = helper.instrumentMockedAgent({ + t.beforeEach(async (ctx) => { + const agent = helper.instrumentMockedAgent({ distributed_tracing: { enabled: true }, cross_application_tracer: { enabled: true } }) @@ -282,59 +284,65 @@ tap.test('distributed tracing', (t) => { }) } - start = generateServer(http, api, cb, (req, res) => { - return getNextUrl('start/middle', 'start', MIDDLE_PORT, req, res) + const end = generateServer(http, api, cb, (req, res) => { + return createResponse(req, res, {}, 'end') }) - - START_PORT = start.address().port - middle = generateServer(http, api, cb, (req, res) => { + const END_PORT = end.address().port + const middle = generateServer(http, api, cb, (req, res) => { return getNextUrl('middle/end', 'middle', END_PORT, req, res) }) - MIDDLE_PORT = middle.address().port - end = generateServer(http, api, cb, (req, res) => { - return createResponse(req, res, {}, 'end') + const MIDDLE_PORT = middle.address().port + const start = generateServer(http, api, cb, (req, res) => { + return getNextUrl('start/middle', 'start', MIDDLE_PORT, req, res) }) - END_PORT = end.address().port + const START_PORT = start.address().port + + ctx.nr = { agent, start, START_PORT, middle, MIDDLE_PORT, end, END_PORT } }) - t.afterEach(async () => { - helper.unloadAgent(agent) - await Promise.all([start.close(cb), middle.close(cb), end.close(cb)]) + t.afterEach(async (ctx) => { + helper.unloadAgent(ctx.nr.agent) + await Promise.all([ctx.nr.start.close(cb), ctx.nr.middle.close(cb), ctx.nr.end.close(cb)]) }) - t.test('should create tracing headers at each step', (t) => { + await t.test('should create tracing headers at each step', (t, end) => { + const { agent, START_PORT } = t.nr helper.runInTransaction(agent, (tx) => { get(generateUrl(START_PORT, 'start'), (err, { body }) => { - t.error(err) + assert.ifError(err) - t.ok(body.start.newrelic, 'should have DT headers from the start') - t.ok(body.middle.newrelic, 'should continue trace to through next state') - t.ok(tx.isDistributedTrace, 'should mark transaction as distributed') + assert.ok(body.start.newrelic, 'should have DT headers from the start') + assert.ok(body.middle.newrelic, 'should continue trace to through next state') + assert.ok(tx.isDistributedTrace, 'should mark transaction as distributed') - t.end() + end() }) }) }) - const headerValues = [symbols.disableDT, 'x-new-relic-disable-dt'] - headerValues.forEach((header) => { - t.test(`should be disabled by ${header.toString()}`, (t) => { + for (const header of [symbols.disableDT, 'x-new-relic-disable-dt']) { + await t.test(`should be disabled by ${header.toString()}`, (t, end) => { + const { agent, START_PORT } = t.nr helper.runInTransaction(agent, (tx) => { const OLD_HEADER = 'x-newrelic-transaction' const headers = { [header]: 'true' } get(generateUrl(START_PORT, 'start'), { headers }, (err, { body }) => { - t.error(err) - t.notOk(body.start.newrelic, 'should not add DT header when disabled') - t.notOk(body.start[OLD_HEADER], 'should not add old CAT header either') - t.ok(body.middle.newrelic, 'should not stop down-stream DT from working') - - t.notOk(tx.isDistributedTrace, 'should not mark transaction as distributed') - - t.end() + assert.ifError(err) + assert.equal(body.start.newrelic, undefined, 'should not add DT header when disabled') + assert.equal(body.start[OLD_HEADER], undefined, 'should not add old CAT header either') + assert.ok(body.middle.newrelic, undefined, 'should not stop down-stream DT from working') + + assert.equal( + tx.isDistributedTrace, + undefined, + 'should not mark transaction as distributed' + ) + + end() }) }) }) - }) + } }) function generateServer(http, api, started, responseHandler) { @@ -352,10 +360,10 @@ function generateUrl(port, endpoint) { return 'http://localhost:' + port + '/' + endpoint } -function currySampled(t, a) { +function currySampled(plan, a) { return (b) => { b = b || a - t.ok( + plan.ok( a.sampled === b.sampled && a.priority === b.priority, 'sampled values and priority persist across transactions' ) @@ -364,36 +372,36 @@ function currySampled(t, a) { } } -function validateIntrinsics(t, intrinsic, reqName, type, parentSpanId) { +function validateIntrinsics(plan, intrinsic, reqName, type, parentSpanId) { reqName = reqName || 'start' type = type || 'event' - t.ok(intrinsic.guid, `${reqName} should have a guid on ${type}`) - t.ok(intrinsic.traceId, `${reqName} should have a traceId on ${type}`) - t.ok(intrinsic.sampled != null, `${reqName} should have a sampled boolean on ${type}`) - t.ok(intrinsic.priority, `${reqName} should have a priority on ${type}`) + plan.ok(intrinsic.guid, `${reqName} should have a guid on ${type}`) + plan.ok(intrinsic.traceId, `${reqName} should have a traceId on ${type}`) + plan.ok(intrinsic.sampled != null, `${reqName} should have a sampled boolean on ${type}`) + plan.ok(intrinsic.priority, `${reqName} should have a priority on ${type}`) if (reqName === 'start') { - t.notOk(intrinsic.parentId, `${reqName} should not have a parentId on ${type}`) + plan.equal(intrinsic.parentId, undefined, `${reqName} should not have a parentId on ${type}`) return } if (type !== 'trace') { - t.ok(intrinsic.parentId, `${reqName} should have a parentId on ${type}`) - t.equal( + plan.ok(intrinsic.parentId, `${reqName} should have a parentId on ${type}`) + plan.equal( intrinsic.parentSpanId, parentSpanId, `${reqName} should have a parentSpanId of ${parentSpanId} on ${type}` ) } - t.ok(intrinsic['parent.app'], `${reqName} should have a parent app on ${type}`) - t.ok(intrinsic['parent.type'], `${reqName} should have a parent type on ${type}`) - t.ok(intrinsic['parent.account'], `${reqName} should have a parent account on ${type}`) - t.ok( + plan.ok(intrinsic['parent.app'], `${reqName} should have a parent app on ${type}`) + plan.ok(intrinsic['parent.type'], `${reqName} should have a parent type on ${type}`) + plan.ok(intrinsic['parent.account'], `${reqName} should have a parent account on ${type}`) + plan.ok( intrinsic['parent.transportType'], `${reqName} should have a parent transportType on ${type}` ) - t.ok( + plan.ok( intrinsic['parent.transportDuration'], `${reqName} should have a parent transportDuration on ${type}` ) diff --git a/test/integration/distributed-tracing/span-error-attributes.tap.js b/test/integration/distributed-tracing/span-error-attributes.tap.js index a6420959f8..cf102be9d2 100644 --- a/test/integration/distributed-tracing/span-error-attributes.tap.js +++ b/test/integration/distributed-tracing/span-error-attributes.tap.js @@ -5,309 +5,304 @@ 'use strict' -const tap = require('tap') +const test = require('node:test') +const assert = require('node:assert') +const tspl = require('@matteo.collina/tspl') + +const match = require('../../lib/custom-assertions/match') const helper = require('../../lib/agent_helper') const API = require('../../../api') -tap.test('span error attributes', (t) => { - t.test('core', (t) => { - const config = { - distributed_tracing: { enabled: true } - } - - const agent = helper.instrumentMockedAgent(config) - const api = new API(agent) +test('core', async (t) => { + const plan = tspl(t, { plan: 6 }) - const spanIds = [] - const numErrors = 3 + const agent = helper.instrumentMockedAgent({ + distributed_tracing: { enabled: true } + }) + const api = new API(agent) - agent.on('transactionFinished', () => { - const errorEvents = agent.errors.eventAggregator.getEvents() - const errorEventSpanIds = errorEvents.map((e) => e[2].spanId) + const spanIds = [] + const numErrors = 3 - t.same( - new Set(spanIds), - new Set(errorEventSpanIds), - 'Every TransactionError event should have a unique span ID' - ) + agent.on('transactionFinished', () => { + const errorEvents = agent.errors.eventAggregator.getEvents() + const errorEventSpanIds = errorEvents.map((e) => e[2].spanId) - t.equal(errorEvents.length, numErrors, 'Every error was reported') + plan.deepStrictEqual( + new Set(spanIds), + new Set(errorEventSpanIds), + 'Every TransactionError event should have a unique span ID' + ) - const spanEvents = agent.spanEventAggregator.getEvents() + plan.equal(errorEvents.length, numErrors, 'Every error was reported') - spanEvents.forEach((s) => { - const attrs = s.attributes - t.match(attrs['error.message'], /test[0-9]/, 'Error attributes are on the spans') + const spanEvents = agent.spanEventAggregator.getEvents() - t.match(attrs['error.class'], 'Error', 'Error attributes are on the spans') - }) + spanEvents.forEach((s) => { + const attrs = s.attributes + match(attrs['error.message'], /test[0-9]/, { assert: plan }) - t.equal(spanEvents.length, numErrors, 'Every span was reported') + match(attrs['error.class'], 'Error', { assert: plan }) }) - helper.runInTransaction(agent, (tx) => { - for (let i = 0; i < numErrors; i++) { - api.startSegment(`segment${i}`, true, () => { - const segment = api.shim.getSegment() - spanIds.push(segment.id) - api.noticeError(new Error(`test${i}`)) - }) - } - - tx.end() - }) + plan.equal(spanEvents.length, numErrors, 'Every span was reported') + }) - helper.unloadAgent(agent) + helper.runInTransaction(agent, (tx) => { + for (let i = 0; i < numErrors; i++) { + api.startSegment(`segment${i}`, true, () => { + const segment = api.shim.getSegment() + spanIds.push(segment.id) + api.noticeError(new Error(`test${i}`)) + }) + } - t.end() + tx.end() }) - t.test('should not add error attributes to spans when errors disabled', (t) => { - const agent = helper.instrumentMockedAgent({ - distributed_tracing: { - enabled: true - }, - error_collector: { - enabled: false - } - }) + t.after(() => helper.unloadAgent(agent)) - t.teardown(() => { - helper.unloadAgent(agent) - }) + await plan.completed +}) - const api = new API(agent) +test('should not add error attributes to spans when errors disabled', (t, end) => { + const agent = helper.instrumentMockedAgent({ + distributed_tracing: { + enabled: true + }, + error_collector: { + enabled: false + } + }) - let spanId = null + t.after(() => { + helper.unloadAgent(agent) + }) - agent.on('transactionFinished', () => { - const spanEvent = agent.spanEventAggregator.getEvents()[0] + const api = new API(agent) - t.equal(spanEvent.intrinsics.guid, spanId) + let spanId = null - const hasAttribute = Object.hasOwnProperty.bind(spanEvent.attributes) - t.notOk(hasAttribute('error.message')) + agent.on('transactionFinished', () => { + const spanEvent = agent.spanEventAggregator.getEvents()[0] - t.end() - }) + assert.equal(spanEvent.intrinsics.guid, spanId) - helper.runInTransaction(agent, (tx) => { - api.startSegment('segment', true, () => { - const segment = api.shim.getSegment() - spanId = segment.id - api.noticeError(new Error('test')) - }) + const hasAttribute = Object.hasOwnProperty.bind(spanEvent.attributes) + assert.equal(hasAttribute('error.message'), false) - tx.end() - }) + end() }) - t.test("Span error attributes aren't added with LASP/HSM", (t) => { - const config = { - distributed_tracing: { enabled: true }, - high_security: true - } + helper.runInTransaction(agent, (tx) => { + api.startSegment('segment', true, () => { + const segment = api.shim.getSegment() + spanId = segment.id + api.noticeError(new Error('test')) + }) - const agent = helper.instrumentMockedAgent(config) - const api = new API(agent) + tx.end() + }) +}) - let spanId +test("Span error attributes aren't added with LASP/HSM", (t, end) => { + const agent = helper.instrumentMockedAgent({ + distributed_tracing: { enabled: true }, + high_security: true + }) + const api = new API(agent) + + let spanId + + agent.on('transactionFinished', () => { + const spanEvent = agent.spanEventAggregator.getEvents()[0] + const attrs = spanEvent.attributes + assert.ok( + spanEvent.intrinsics.guid === spanId && !attrs['error.message'], + 'There should be no error message on the span' + ) + end() + }) - agent.on('transactionFinished', () => { - const spanEvent = agent.spanEventAggregator.getEvents()[0] - const attrs = spanEvent.attributes - t.ok( - spanEvent.intrinsics.guid === spanId && !attrs['error.message'], - 'There should be no error message on the span' - ) + helper.runInTransaction(agent, (tx) => { + api.startSegment('segment', true, () => { + const segment = api.shim.getSegment() + spanId = segment.id + api.noticeError(new Error('test')) }) - helper.runInTransaction(agent, (tx) => { - api.startSegment('segment', true, () => { - const segment = api.shim.getSegment() - spanId = segment.id - api.noticeError(new Error('test')) - }) - - tx.end() - }) + tx.end() + }) - helper.unloadAgent(agent) + t.after(() => helper.unloadAgent(agent)) +}) - t.end() +test("Span error attributes aren't added with ignored classes errors", (t, end) => { + const agent = helper.instrumentMockedAgent({ + distributed_tracing: { enabled: true }, + error_collector: { ignore_classes: ['CustomError'] } + }) + const api = new API(agent) + + let ignoredSpanId + let spanId + + agent.on('transactionFinished', () => { + const errorEvents = agent.errors.eventAggregator.getEvents() + const spanEvents = agent.spanEventAggregator.getEvents() + const ignoredSpanEvent = spanEvents.filter((s) => s.intrinsics.guid === ignoredSpanId)[0] + const spanEvent = spanEvents.filter((s) => s.intrinsics.guid === spanId)[0] + + assert.ok( + errorEvents.length === 1 && errorEvents[0][2].spanId === spanId, + 'There should only be the non-ignored error reported' + ) + + assert.ok( + spanEvent.attributes['error.message'] === 'not ignored', + 'The non-ignored error should be reported' + ) + + assert.equal( + ignoredSpanEvent.attributes['error.message'], + undefined, + 'The ignored error should not be reported' + ) + + end() }) - t.test("Span error attributes aren't added with ignored classes errors", (t) => { - const config = { - distributed_tracing: { enabled: true }, - error_collector: { ignore_classes: ['CustomError'] } + helper.runInTransaction(agent, (tx) => { + class CustomError extends Error { + constructor() { + super(...arguments) + this.name = 'CustomError' + } } - const agent = helper.instrumentMockedAgent(config) - const api = new API(agent) - - let ignoredSpanId - let spanId - - agent.on('transactionFinished', () => { - const errorEvents = agent.errors.eventAggregator.getEvents() - const spanEvents = agent.spanEventAggregator.getEvents() - const ignoredSpanEvent = spanEvents.filter((s) => s.intrinsics.guid === ignoredSpanId)[0] - const spanEvent = spanEvents.filter((s) => s.intrinsics.guid === spanId)[0] + api.startSegment('segment1', true, () => { + const segment = api.shim.getSegment() + ignoredSpanId = segment.id + agent.errors.add(tx, new CustomError('ignored')) + }) - t.ok( - errorEvents.length === 1 && errorEvents[0][2].spanId === spanId, - 'There should only be the non-ignored error reported' - ) + api.startSegment('segment2', true, () => { + const segment = api.shim.getSegment() + spanId = segment.id + agent.errors.add(tx, new Error('not ignored')) + }) - t.ok( - spanEvent.attributes['error.message'] === 'not ignored', - 'The non-ignored error should be reported' - ) + tx.end() + }) - t.notOk( - ignoredSpanEvent.attributes['error.message'], - 'The ignored error should not be reported' - ) - }) + t.after(() => helper.unloadAgent(agent)) +}) - helper.runInTransaction(agent, (tx) => { - class CustomError extends Error { - constructor() { - super(...arguments) - this.name = 'CustomError' - } - } +test("Span error attributes aren't added with ignored status errors", (t, end) => { + const agent = helper.instrumentMockedAgent({ + distributed_tracing: { enabled: true }, + error_collector: { ignore_status_codes: [404, 422] } + }) + const api = new API(agent) - api.startSegment('segment1', true, () => { - const segment = api.shim.getSegment() - ignoredSpanId = segment.id - agent.errors.add(tx, new CustomError('ignored')) - }) + let ignoredSpanId = null - api.startSegment('segment2', true, () => { - const segment = api.shim.getSegment() - spanId = segment.id - agent.errors.add(tx, new Error('not ignored')) - }) + agent.on('transactionFinished', () => { + const errorEvents = agent.errors.eventAggregator.getEvents() + const spanEvents = agent.spanEventAggregator.getEvents() + const ignoredSpanEvent = spanEvents.filter((s) => s.intrinsics.guid === ignoredSpanId)[0] - tx.end() - }) + assert.equal( + errorEvents.length, + 0, + 'There should not be any errors reported because of status code' + ) - helper.unloadAgent(agent) + assert.equal( + ignoredSpanEvent.attributes['error.message'], + undefined, + 'The ignored error should not be added to span.' + ) - t.end() + end() }) - t.test("Span error attributes aren't added with ignored status errors", (t) => { - const config = { - distributed_tracing: { enabled: true }, - error_collector: { ignore_status_codes: [404, 422] } + helper.runInTransaction(agent, (tx) => { + class CustomError extends Error { + constructor() { + super(...arguments) + this.name = 'CustomError' + } } - const agent = helper.instrumentMockedAgent(config) - const api = new API(agent) - - let ignoredSpanId = null - - agent.on('transactionFinished', () => { - const errorEvents = agent.errors.eventAggregator.getEvents() - const spanEvents = agent.spanEventAggregator.getEvents() - const ignoredSpanEvent = spanEvents.filter((s) => s.intrinsics.guid === ignoredSpanId)[0] - - t.equal( - errorEvents.length, - 0, - 'There should not be any errors reported because of status code' - ) - - t.notOk( - ignoredSpanEvent.attributes['error.message'], - 'The ignored error should not be added to span.' - ) + api.startSegment('segment1', true, () => { + const segment = api.shim.getSegment() + ignoredSpanId = segment.id + agent.errors.add(tx, new CustomError('ignored')) }) - helper.runInTransaction(agent, (tx) => { - class CustomError extends Error { - constructor() { - super(...arguments) - this.name = 'CustomError' - } - } + tx.statusCode = 422 + tx.end() + }) - api.startSegment('segment1', true, () => { - const segment = api.shim.getSegment() - ignoredSpanId = segment.id - agent.errors.add(tx, new CustomError('ignored')) - }) + t.after(() => helper.unloadAgent(agent)) +}) - tx.statusCode = 422 - tx.end() - }) +test('should propagate expected error attribute to span', (t, end) => { + const agent = helper.instrumentMockedAgent({ + distributed_tracing: { + enabled: true + }, + error_collector: { + expected_classes: ['CustomError'] + } + }) + t.after(() => { helper.unloadAgent(agent) - - t.end() }) - t.test('should propogate expected error attribute to span', (t) => { - const agent = helper.instrumentMockedAgent({ - distributed_tracing: { - enabled: true - }, - error_collector: { - expected_classes: ['CustomError'] - } - }) - - t.teardown(() => { - helper.unloadAgent(agent) - }) + const api = new API(agent) - const api = new API(agent) + let expectedSpanId + let notExpectedSpanId - let expectedSpanId - let notExpectedSpanId + agent.on('transactionFinished', () => { + const errorEvents = agent.errors.eventAggregator.getEvents() + const spanEvents = agent.spanEventAggregator.getEvents() + const expectedSpanEvent = spanEvents.filter((s) => s.intrinsics.guid === expectedSpanId)[0] + const spanEvent = spanEvents.filter((s) => s.intrinsics.guid === notExpectedSpanId)[0] - agent.on('transactionFinished', () => { - const errorEvents = agent.errors.eventAggregator.getEvents() - const spanEvents = agent.spanEventAggregator.getEvents() - const expectedSpanEvent = spanEvents.filter((s) => s.intrinsics.guid === expectedSpanId)[0] - const spanEvent = spanEvents.filter((s) => s.intrinsics.guid === notExpectedSpanId)[0] + assert.equal(errorEvents.length, 2) - t.equal(errorEvents.length, 2) + assert.equal(expectedSpanEvent.attributes['error.expected'], true) - t.equal(expectedSpanEvent.attributes['error.expected'], true) + const hasAttribute = Object.hasOwnProperty.bind(spanEvent.attributes) + assert.equal(hasAttribute('error.expected'), false) - const hasAttribute = Object.hasOwnProperty.bind(spanEvent.attributes) - t.equal(hasAttribute('error.expected'), false) - - t.end() - }) + end() + }) - helper.runInTransaction(agent, (tx) => { - class CustomError extends Error { - constructor() { - super(...arguments) - this.name = 'CustomError' - } + helper.runInTransaction(agent, (tx) => { + class CustomError extends Error { + constructor() { + super(...arguments) + this.name = 'CustomError' } + } - api.startSegment('segment1', true, () => { - const segment = api.shim.getSegment() - expectedSpanId = segment.id - agent.errors.add(tx, new CustomError('expected')) - }) - - api.startSegment('segment2', true, () => { - const segment = api.shim.getSegment() - notExpectedSpanId = segment.id - agent.errors.add(tx, new Error('not expected')) - }) + api.startSegment('segment1', true, () => { + const segment = api.shim.getSegment() + expectedSpanId = segment.id + agent.errors.add(tx, new CustomError('expected')) + }) - tx.end() + api.startSegment('segment2', true, () => { + const segment = api.shim.getSegment() + notExpectedSpanId = segment.id + agent.errors.add(tx, new Error('not expected')) }) - }) - t.end() + tx.end() + }) }) diff --git a/test/integration/distributed-tracing/trace-context-cross-agent.tap.js b/test/integration/distributed-tracing/trace-context-cross-agent.test.js similarity index 79% rename from test/integration/distributed-tracing/trace-context-cross-agent.tap.js rename to test/integration/distributed-tracing/trace-context-cross-agent.test.js index ddf7b078ea..d94c994ade 100644 --- a/test/integration/distributed-tracing/trace-context-cross-agent.tap.js +++ b/test/integration/distributed-tracing/trace-context-cross-agent.test.js @@ -1,13 +1,16 @@ /* - * Copyright 2020 New Relic Corporation. All rights reserved. + * Copyright 2024 New Relic Corporation. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ 'use strict' -const tap = require('tap') + +const test = require('node:test') +const assert = require('node:assert') + +const { TYPES } = require('../../../lib/transaction') const API = require('../../../api') const helper = require('../../lib/agent_helper') -const TYPES = require('../../../lib/transaction').TYPES const recorder = require('../../../lib/metrics/recorders/distributed-trace') const recordSupportability = require('../../../lib/agent').prototype.recordSupportability @@ -43,21 +46,10 @@ function hasNestedProperty(object, descendants) { return true } -const testExpectedFixtureKeys = function (t, thingWithKeys, expectedKeys) { - let actualKeys = thingWithKeys - if (!Array.isArray(actualKeys)) { - actualKeys = Object.keys(thingWithKeys) - } - for (const [i] of actualKeys.entries()) { - const key = actualKeys[i] - t.ok(expectedKeys.indexOf(key) !== -1, 'key [' + key + '] should be expected?') - } -} - -const testExact = function (t, object, fixture) { +const testExact = function (object, fixture) { for (const [descendants, fixtureValue] of Object.entries(fixture)) { const valueToTest = getDescendantValue(object, descendants) - t.same( + assert.deepEqual( valueToTest, fixtureValue, `Expected ${descendants} to be ${fixtureValue} but got ${valueToTest}` @@ -65,42 +57,42 @@ const testExact = function (t, object, fixture) { } } -const testNotEqual = function (t, object, fixture) { - for (const [descendants, fixtureValue] of Object.entries(fixture)) { - const valueToTest = getDescendantValue(object, descendants) - t.ok(valueToTest !== fixtureValue, 'is ' + descendants + ' not equal?') - } -} - -const testUnexpected = function (t, object, fixture) { +const testExpected = function (object, fixture) { for (const [key] of fixture.entries()) { const fixtureValue = fixture[key] const exists = hasNestedProperty(object, fixtureValue) - t.notOk(exists, 'is ' + fixtureValue + ' absent?') + assert.ok(exists, 'is ' + fixtureValue + ' set?') } } -const testExpected = function (t, object, fixture) { +const testUnexpected = function (object, fixture) { for (const [key] of fixture.entries()) { const fixtureValue = fixture[key] const exists = hasNestedProperty(object, fixtureValue) - t.ok(exists, 'is ' + fixtureValue + ' set?') + assert.equal(exists, false, 'is ' + fixtureValue + ' absent?') } } -const testVendor = function (t, object, vendors) { - t.same(object.tracestate.vendors, vendors, 'do vendors match?') +const testNotEqual = function (object, fixture) { + for (const [descendants, fixtureValue] of Object.entries(fixture)) { + const valueToTest = getDescendantValue(object, descendants) + assert.ok(valueToTest !== fixtureValue, 'is ' + descendants + ' not equal?') + } } -// tests a few of the helper functions we wrote for this test case -tap.test('helper functions', function (t) { +const testVendor = function (object, vendors) { + assert.deepStrictEqual(object.tracestate.vendors, vendors, 'do vendors match?') +} + +// Tests a few of the helper functions we wrote for this test suite. +test('helper functions', () => { const objectExact = { foo: { bar: 'baz' }, one: { two: 'three' } } - testExact(t, objectExact, { 'foo.bar': 'baz', 'one.two': 'three' }) + testExact(objectExact, { 'foo.bar': 'baz', 'one.two': 'three' }) const objectExpected = { foo: { bar: 'baz' }, @@ -108,7 +100,7 @@ tap.test('helper functions', function (t) { science: false, science2: NaN } - testExpected(t, objectExpected, ['foo.bar', 'one.two', 'science', 'science2']) + testExpected(objectExpected, ['foo.bar', 'one.two', 'science', 'science2']) const objectUnExpected = { foo: { bar: 'baz' }, @@ -116,17 +108,23 @@ tap.test('helper functions', function (t) { science: false, science2: NaN } - testUnexpected(t, objectUnExpected, ['apple', 'orange']) + testUnexpected(objectUnExpected, ['apple', 'orange']) const objectNotEqual = { foo: { bar: 'baz' }, one: { two: 'three' } } - testNotEqual(t, objectNotEqual, { 'foo.bar': 'bazz', 'one.two': 'threee' }) - t.end() + testNotEqual(objectNotEqual, { 'foo.bar': 'bazz', 'one.two': 'threee' }) +}) + +test('distributed tracing trace context', async (t) => { + const testCases = require('../../lib/cross_agent_tests/distributed_tracing/trace_context.json') + for (const [i] of testCases.entries()) { + await runTestCase(testCases[i], t) + } }) -const getEventsToCheck = function (eventType, agent) { +function getEventsToCheck(eventType, agent) { let toCheck switch (eventType) { case 'Transaction': @@ -144,7 +142,7 @@ const getEventsToCheck = function (eventType, agent) { return toCheck } -const getExactExpectedUnexpectedFromIntrinsics = function (testCase, eventType) { +function getExactExpectedUnexpectedFromIntrinsics(testCase, eventType) { const common = testCase.intrinsics.common const specific = testCase.intrinsics[eventType] || {} const exact = Object.assign(specific.exact || {}, common.exact || {}) @@ -158,66 +156,44 @@ const getExactExpectedUnexpectedFromIntrinsics = function (testCase, eventType) } } -const testSingleEvent = function (t, event, eventType, fixture) { +function testSingleEvent(event, eventType, fixture) { const { exact, expected, unexpected } = fixture const attributes = event[0] - t.ok(attributes, 'Should have attributes') + assert.ok(attributes, 'Should have attributes') const attributesHasOwnProperty = Object.hasOwnProperty.bind(attributes) expected.forEach((key) => { const hasAttribute = attributesHasOwnProperty(key) - t.ok(hasAttribute, `does ${eventType} have ${key}`) + assert.ok(hasAttribute, `does ${eventType} have ${key}`) }) unexpected.forEach((key) => { const hasAttribute = attributesHasOwnProperty(key) - t.notOk(hasAttribute, `${eventType} should not have ${key}`) + assert.equal(hasAttribute, false, `${eventType} should not have ${key}`) }) Object.keys(exact).forEach((key) => { const attributeValue = attributes[key] const expectedValue = exact[key] - t.equal(attributeValue, expectedValue, `${eventType} should have ${key}=${expectedValue}`) + assert.equal(attributeValue, expectedValue, `${eventType} should have ${key}=${expectedValue}`) }) } -const runTestCaseTargetEvents = function (t, testCase, agent) { - if (!testCase.intrinsics) { - return - } - for (const [key] of testCase.intrinsics.target_events.entries()) { - const eventType = testCase.intrinsics.target_events[key] - const toCheck = getEventsToCheck(eventType, agent) - t.ok(toCheck.length > 0, 'do we have an event ( ' + eventType + ' ) to test?') - const fixture = getExactExpectedUnexpectedFromIntrinsics(testCase, eventType) - - for (const [index] of toCheck.entries()) { - // Span events are not payload-formatted - // straight out of the aggregator. - const event = 'Span' === eventType ? toCheck[index].toJSON() : toCheck[index] - testSingleEvent(t, event, eventType, fixture) - } - } -} - -const runTestCaseMetrics = function (t, testCase, agent) { - if (!testCase.expected_metrics) { - return +const testExpectedFixtureKeys = function (thingWithKeys, expectedKeys) { + let actualKeys = thingWithKeys + if (!Array.isArray(actualKeys)) { + actualKeys = Object.keys(thingWithKeys) } - const metrics = agent.metrics - for (const [key] of testCase.expected_metrics.entries()) { - const metricPair = testCase.expected_metrics[key] - const metricName = metricPair[0] - const callCount = metrics.getOrCreateMetric(metricName).callCount - const metricCount = metricPair[1] - t.ok(callCount === metricCount, `${metricName} should have ${metricCount} samples`) + for (const [i] of actualKeys.entries()) { + const key = actualKeys[i] + assert.ok(expectedKeys.indexOf(key) !== -1, 'key [' + key + '] should be expected?') } } -const runTestCaseOutboundPayloads = function (t, testCase, context) { +function runTestCaseOutboundPayloads(testCase, context) { if (!testCase.outbound_payloads) { return } @@ -226,18 +202,18 @@ const runTestCaseOutboundPayloads = function (t, testCase, context) { for (const [assertType, fields] of Object.entries(testToRun)) { switch (assertType) { case 'exact': - testExact(t, context[key], fields) + testExact(context[key], fields) break case 'expected': - testExpected(t, context[key], fields) + testExpected(context[key], fields) break case 'unexpected': - testUnexpected(t, context[key], fields) + testUnexpected(context[key], fields) case 'notequal': - testNotEqual(t, context[key], fields) + testNotEqual(context[key], fields) break case 'vendors': - testVendor(t, context[key], fields) + testVendor(context[key], fields) break default: throw new Error("I don't know how to test a(n) " + assertType) @@ -246,12 +222,45 @@ const runTestCaseOutboundPayloads = function (t, testCase, context) { } } -const runTestCase = function (testCase, parentTest) { +function runTestCaseMetrics(testCase, agent) { + if (!testCase.expected_metrics) { + return + } + const metrics = agent.metrics + for (const [key] of testCase.expected_metrics.entries()) { + const metricPair = testCase.expected_metrics[key] + const metricName = metricPair[0] + const callCount = metrics.getOrCreateMetric(metricName).callCount + const metricCount = metricPair[1] + assert.ok(callCount === metricCount, `${metricName} should have ${metricCount} samples`) + } +} + +function runTestCaseTargetEvents(testCase, agent) { + if (!testCase.intrinsics) { + return + } + for (const [key] of testCase.intrinsics.target_events.entries()) { + const eventType = testCase.intrinsics.target_events[key] + const toCheck = getEventsToCheck(eventType, agent) + assert.ok(toCheck.length > 0, 'do we have an event ( ' + eventType + ' ) to test?') + const fixture = getExactExpectedUnexpectedFromIntrinsics(testCase, eventType) + + for (const [index] of toCheck.entries()) { + // Span events are not payload-formatted + // straight out of the aggregator. + const event = 'Span' === eventType ? toCheck[index].toJSON() : toCheck[index] + testSingleEvent(event, eventType, fixture) + } + } +} + +async function runTestCase(testCase, parentTest) { // validates the test case data has what we're looking for. Good for // catching any changes to the test format over time, as well as becoming // familiar with what we need to do to implement a test runner - parentTest.test('validate test: ' + testCase.test_name, function (t) { - testExpectedFixtureKeys(t, testCase, [ + await parentTest.test('validate test: ' + testCase.test_name, (t, end) => { + testExpectedFixtureKeys(testCase, [ 'account_id', 'expected_metrics', 'force_sampled_true', @@ -271,7 +280,7 @@ const runTestCase = function (testCase, parentTest) { if (testCase.outbound_payloads) { for (const [i] of testCase.outbound_payloads.entries()) { const outboundPayload = testCase.outbound_payloads[i] - testExpectedFixtureKeys(t, outboundPayload, [ + testExpectedFixtureKeys(outboundPayload, [ 'exact', 'expected', 'notequal', @@ -283,7 +292,7 @@ const runTestCase = function (testCase, parentTest) { if (testCase.intrinsics) { // top level intrinsics keys - testExpectedFixtureKeys(t, testCase.intrinsics, [ + testExpectedFixtureKeys(testCase.intrinsics, [ 'Transaction', 'Span', 'common', @@ -291,11 +300,11 @@ const runTestCase = function (testCase, parentTest) { 'TransactionError' ]) - testExpectedFixtureKeys(t, testCase.intrinsics.common, ['exact', 'unexpected', 'expected']) + testExpectedFixtureKeys(testCase.intrinsics.common, ['exact', 'unexpected', 'expected']) // test there are no unexpected event types in there const expectedEvents = ['Span', 'Transaction', 'TransactionError'] - testExpectedFixtureKeys(t, testCase.intrinsics.target_events, expectedEvents) + testExpectedFixtureKeys(testCase.intrinsics.target_events, expectedEvents) // test the top level keys of each event for (const [i] of testCase.intrinsics.target_events.entries()) { @@ -306,19 +315,19 @@ const runTestCase = function (testCase, parentTest) { if (!eventTestConfig) { continue } - testExpectedFixtureKeys(t, eventTestConfig, ['exact', 'unexpected', 'expected']) + testExpectedFixtureKeys(eventTestConfig, ['exact', 'unexpected', 'expected']) } } - t.end() + end() }) - parentTest.test('trace context: ' + testCase.test_name, function (t) { + await parentTest.test('trace context: ' + testCase.test_name, (t, end) => { if (testCase.comment && testCase.comment.length > 0) { const comment = Array.isArray(testCase.comment) ? testCase.comment.join('\n') : testCase.comment - t.comment(comment) + t.diagnostic(comment) } const agent = helper.instrumentMockedAgent({}) @@ -329,6 +338,7 @@ const runTestCase = function (testCase, parentTest) { agent.config.span_events.enabled = testCase.span_events_enabled agent.config.transaction_events.enabled = testCase.transaction_events_enabled agent.config.distributed_tracing.enabled = true + t.after(() => helper.unloadAgent(agent)) const agentApi = new API(agent) @@ -474,23 +484,14 @@ const runTestCase = function (testCase, parentTest) { payloadTest.exact['newrelic.d.pr'] = 1.1234321 } - runTestCaseOutboundPayloads(t, testCase, insertedTraceContextTraces) - runTestCaseTargetEvents(t, testCase, agent) - runTestCaseMetrics(t, testCase, agent) + runTestCaseOutboundPayloads(testCase, insertedTraceContextTraces) + runTestCaseTargetEvents(testCase, agent) + runTestCaseMetrics(testCase, agent) } - t.ok(transaction, 'we have a transaction') + assert.ok(transaction, 'we have a transaction') }) - t.end() - helper.unloadAgent(agent) + end() }) } - -tap.test('distributed tracing trace context', (t) => { - const testCases = require('../../lib/cross_agent_tests/distributed_tracing/trace_context.json') - for (const [i] of testCases.entries()) { - runTestCase(testCases[i], t) - } - t.end() -}) diff --git a/test/integration/distributed-tracing/transaction-span-attributes.tap.js b/test/integration/distributed-tracing/transaction-span-attributes.test.js similarity index 79% rename from test/integration/distributed-tracing/transaction-span-attributes.tap.js rename to test/integration/distributed-tracing/transaction-span-attributes.test.js index 439c291750..d19dce06b8 100644 --- a/test/integration/distributed-tracing/transaction-span-attributes.tap.js +++ b/test/integration/distributed-tracing/transaction-span-attributes.test.js @@ -5,18 +5,19 @@ 'use strict' -const tap = require('tap') +const test = require('node:test') +const assert = require('node:assert') const helper = require('../../lib/agent_helper') -tap.test('should apply transaction name as active span intrinsic on transaction end', (t) => { +test('should apply transaction name as active span intrinsic on transaction end', (t, end) => { const agent = helper.instrumentMockedAgent({ distributed_tracing: { enabled: true } }) - t.teardown(() => { + t.after(() => { helper.unloadAgent(agent) }) @@ -40,9 +41,9 @@ tap.test('should apply transaction name as active span intrinsic on transaction const [intrinsics] = serialized - t.equal(intrinsics['transaction.name'], transaction.name) + assert.equal(intrinsics['transaction.name'], transaction.name) - t.end() + end() }, 10) }) })