From d169546b7c51d83db0697f941343cd334f675e60 Mon Sep 17 00:00:00 2001 From: Amy Chisholm Date: Thu, 19 Sep 2024 07:43:54 -0700 Subject: [PATCH] test: Convert transaction* and urltils tests to `node:test` (#2585) --- .../unit/transaction-event-aggregator.test.js | 109 +- test/unit/transaction-logs.test.js | 45 +- test/unit/transaction-naming.test.js | 201 ++- test/unit/transaction.test.js | 1500 ++++++++--------- test/unit/urltils.test.js | 432 +++-- 5 files changed, 1134 insertions(+), 1153 deletions(-) diff --git a/test/unit/transaction-event-aggregator.test.js b/test/unit/transaction-event-aggregator.test.js index 46a78fd933..d3fb27dc13 100644 --- a/test/unit/transaction-event-aggregator.test.js +++ b/test/unit/transaction-event-aggregator.test.js @@ -4,7 +4,8 @@ */ 'use strict' -const tap = require('tap') +const test = require('node:test') +const assert = require('node:assert') const sinon = require('sinon') const TransactionEventAggregator = require('../../lib/transaction/transaction-event-aggregator') const Metrics = require('../../lib/metrics') @@ -14,11 +15,12 @@ const LIMIT = 5 const EXPECTED_METHOD = 'analytic_event_data' const SPLIT_THRESHOLD = 3 -function beforeEach(t) { +function beforeEach(ctx) { const fakeCollectorApi = { send: sinon.stub() } const fakeHarvester = { add: sinon.stub() } - t.context.eventAggregator = new TransactionEventAggregator( + ctx.nr = {} + ctx.nr.eventAggregator = new TransactionEventAggregator( { runId: RUN_ID, limit: LIMIT, @@ -30,23 +32,21 @@ function beforeEach(t) { metrics: new Metrics(5, {}, {}) } ) - t.context.fakeCollectorApi = fakeCollectorApi + ctx.nr.fakeCollectorApi = fakeCollectorApi } -tap.test('Transaction Event Aggregator', (t) => { - t.autoend() +test('Transaction Event Aggregator', async (t) => { t.beforeEach(beforeEach) - t.test('should set the correct default method', (t) => { - const { eventAggregator } = t.context + await t.test('should set the correct default method', (t) => { + const { eventAggregator } = t.nr const method = eventAggregator.method - t.equal(method, EXPECTED_METHOD) - t.end() + assert.equal(method, EXPECTED_METHOD) }) - t.test('toPayload() should return json format of data', (t) => { - const { eventAggregator } = t.context + await t.test('toPayload() should return json format of data', (t) => { + const { eventAggregator } = t.nr const expectedMetrics = { reservoir_size: LIMIT, events_seen: 1 @@ -57,30 +57,27 @@ tap.test('Transaction Event Aggregator', (t) => { eventAggregator.add(rawEvent) const payload = eventAggregator._toPayloadSync() - t.equal(payload.length, 3) + assert.equal(payload.length, 3) const [runId, eventMetrics, eventData] = payload - t.equal(runId, RUN_ID) - t.same(eventMetrics, expectedMetrics) - t.same(eventData, [rawEvent]) - t.end() + assert.equal(runId, RUN_ID) + assert.deepEqual(eventMetrics, expectedMetrics) + assert.deepEqual(eventData, [rawEvent]) }) - t.test('toPayload() should return nothing with no event data', (t) => { - const { eventAggregator } = t.context + await t.test('toPayload() should return nothing with no event data', (t) => { + const { eventAggregator } = t.nr const payload = eventAggregator._toPayloadSync() - t.notOk(payload) - t.end() + assert.equal(payload, null) }) }) -tap.test('Transaction Event Aggregator - when data over split threshold', (t) => { - t.autoend() +test('Transaction Event Aggregator - when data over split threshold', async (t) => { t.beforeEach((t) => { beforeEach(t) - const { eventAggregator } = t.context + const { eventAggregator } = t.nr eventAggregator.add([{ type: 'Transaction', error: false }, { num: 1 }]) eventAggregator.add([{ type: 'Transaction', error: false }, { num: 2 }]) eventAggregator.add([{ type: 'Transaction', error: false }, { num: 3 }]) @@ -88,25 +85,24 @@ tap.test('Transaction Event Aggregator - when data over split threshold', (t) => eventAggregator.add([{ type: 'Transaction', error: false }, { num: 5 }]) }) - t.test('should emit proper message with method for starting send', (t) => { - const { eventAggregator } = t.context + await t.test('should emit proper message with method for starting send', (t, end) => { + const { eventAggregator } = t.nr const expectedStartEmit = `starting_data_send-${EXPECTED_METHOD}` - eventAggregator.once(expectedStartEmit, t.end) + eventAggregator.once(expectedStartEmit, end) eventAggregator.send() }) - t.test('should clear existing data', (t) => { - const { eventAggregator } = t.context + await t.test('should clear existing data', (t) => { + const { eventAggregator } = t.nr eventAggregator.send() - t.equal(eventAggregator.events.length, 0) - t.end() + assert.equal(eventAggregator.events.length, 0) }) - t.test('should call transport for two payloads', (t) => { - const { eventAggregator, fakeCollectorApi } = t.context + await t.test('should call transport for two payloads', (t) => { + const { eventAggregator, fakeCollectorApi } = t.nr const payloads = [] fakeCollectorApi.send.callsFake((_method, payload, callback) => { @@ -118,30 +114,29 @@ tap.test('Transaction Event Aggregator - when data over split threshold', (t) => eventAggregator.send() - t.equal(payloads.length, 2) + assert.equal(payloads.length, 2) const [firstPayload, secondPayload] = payloads const [firstRunId, firstMetrics, firstEventData] = firstPayload - t.equal(firstRunId, RUN_ID) - t.same(firstMetrics, { + assert.equal(firstRunId, RUN_ID) + assert.deepEqual(firstMetrics, { reservoir_size: 2, events_seen: 2 }) - t.equal(firstEventData.length, 2) + assert.equal(firstEventData.length, 2) const [secondRunId, secondMetrics, secondEventData] = secondPayload - t.equal(secondRunId, RUN_ID) - t.same(secondMetrics, { + assert.equal(secondRunId, RUN_ID) + assert.deepEqual(secondMetrics, { reservoir_size: 3, events_seen: 3 }) - t.equal(secondEventData.length, 3) - t.end() + assert.equal(secondEventData.length, 3) }) - t.test('should call merge with original data when transport indicates retain', (t) => { - const { eventAggregator, fakeCollectorApi } = t.context + await t.test('should call merge with original data when transport indicates retain', (t) => { + const { eventAggregator, fakeCollectorApi } = t.nr const originalData = eventAggregator._getMergeData() fakeCollectorApi.send.callsFake((_method, _payload, callback) => { @@ -151,17 +146,16 @@ tap.test('Transaction Event Aggregator - when data over split threshold', (t) => eventAggregator.send() const currentData = eventAggregator._getMergeData() - t.equal(currentData.length, originalData.length) + assert.equal(currentData.length, originalData.length) const originalEvents = originalData.toArray().sort(sortEventsByNum) const currentEvents = currentData.toArray().sort(sortEventsByNum) - t.same(currentEvents, originalEvents) - t.end() + assert.deepEqual(currentEvents, originalEvents) }) - t.test('should not merge when transport indicates not to retain', (t) => { - const { eventAggregator, fakeCollectorApi } = t.context + await t.test('should not merge when transport indicates not to retain', (t) => { + const { eventAggregator, fakeCollectorApi } = t.nr fakeCollectorApi.send.callsFake((_method, _payload, callback) => { callback(null, { retainData: false }) }) @@ -170,12 +164,11 @@ tap.test('Transaction Event Aggregator - when data over split threshold', (t) => const currentData = eventAggregator._getMergeData() - t.equal(currentData.length, 0) - t.end() + assert.equal(currentData.length, 0) }) - t.test('should handle payload retain values individually', (t) => { - const { eventAggregator, fakeCollectorApi } = t.context + await t.test('should handle payload retain values individually', (t) => { + const { eventAggregator, fakeCollectorApi } = t.nr let payloadCount = 0 let payloadToRetain = null fakeCollectorApi.send.callsFake((_method, payload, callback) => { @@ -194,19 +187,17 @@ tap.test('Transaction Event Aggregator - when data over split threshold', (t) => const eventsToRetain = payloadToRetain[2].sort(sortEventsByNum) const currentData = eventAggregator._getMergeData() - t.equal(currentData.length, eventsToRetain.length) + assert.equal(currentData.length, eventsToRetain.length) const currentEvents = currentData.toArray().sort(sortEventsByNum) - - t.same(currentEvents, eventsToRetain) - t.end() + assert.deepEqual(currentEvents, eventsToRetain) }) - t.test('should emit proper message with method for finishing send', (t) => { - const { eventAggregator, fakeCollectorApi } = t.context + await t.test('should emit proper message with method for finishing send', (t, end) => { + const { eventAggregator, fakeCollectorApi } = t.nr const expectedEndEmit = `finished_data_send-${EXPECTED_METHOD}` - eventAggregator.once(expectedEndEmit, t.end) + eventAggregator.once(expectedEndEmit, end) fakeCollectorApi.send.callsFake((_method, _payload, callback) => { callback(null, { retainData: false }) diff --git a/test/unit/transaction-logs.test.js b/test/unit/transaction-logs.test.js index 711f112f18..2f87593d1e 100644 --- a/test/unit/transaction-logs.test.js +++ b/test/unit/transaction-logs.test.js @@ -4,15 +4,14 @@ */ 'use strict' +const test = require('node:test') +const assert = require('node:assert') const Logs = require('../../lib/transaction/logs') -const { test } = require('tap') const sinon = require('sinon') -test('Logs tests', (t) => { - t.autoend() - let logs - let agent - t.beforeEach(() => { +test('Logs tests', async (t) => { + t.beforeEach((ctx) => { + ctx.nr = {} const config = { event_harvest_config: { harvest_limits: { @@ -20,40 +19,40 @@ test('Logs tests', (t) => { } } } - agent = { + ctx.nr.agent = { logs: { addBatch: sinon.stub() }, config } - logs = new Logs(agent) + ctx.nr.logs = new Logs(ctx.nr.agent) }) - t.test('should initialize logs storage', (t) => { - t.same(logs.storage, [], 'should init storage to empty') - t.same(logs.aggregator, agent.logs, 'should create log aggregator') - t.equal(logs.maxLimit, 2, 'should set max limit accordingly') - t.end() + await t.test('should initialize logs storage', (t) => { + const { agent, logs } = t.nr + assert.deepEqual(logs.storage, [], 'should init storage to empty') + assert.deepEqual(logs.aggregator, agent.logs, 'should create log aggregator') + assert.equal(logs.maxLimit, 2, 'should set max limit accordingly') }) - t.test('it should add logs to storage', (t) => { + await t.test('it should add logs to storage', (t) => { + const { logs } = t.nr logs.add('line') - t.same(logs.storage, ['line']) - t.end() + assert.deepEqual(logs.storage, ['line']) }) - t.test('it should not add data to storage if max limit has been met', (t) => { + await t.test('it should not add data to storage if max limit has been met', (t) => { + const { logs } = t.nr logs.add('line1') logs.add('line2') logs.add('line3') logs.add('line4') - t.same(logs.storage, ['line1', 'line2']) - t.end() + assert.deepEqual(logs.storage, ['line1', 'line2']) }) - t.test('it should flush the batch', (t) => { + await t.test('it should flush the batch', (t) => { + const { logs } = t.nr logs.add('line') const priority = Math.random() + 1 logs.flush(priority) - t.ok(logs.aggregator.addBatch.callCount, 1, 'should call addBatch once') - t.same(logs.aggregator.addBatch.args[0], [['line'], priority]) - t.end() + assert.ok(logs.aggregator.addBatch.callCount, 1, 'should call addBatch once') + assert.deepEqual(logs.aggregator.addBatch.args[0], [['line'], priority]) }) }) diff --git a/test/unit/transaction-naming.test.js b/test/unit/transaction-naming.test.js index e4e986810a..511c6d41f7 100644 --- a/test/unit/transaction-naming.test.js +++ b/test/unit/transaction-naming.test.js @@ -5,166 +5,229 @@ 'use strict' +const test = require('node:test') +const assert = require('node:assert') const helper = require('../lib/agent_helper') const API = require('../../api') -const { test } = require('tap') -test('Transaction naming:', function (t) { - t.autoend() - let agent - - t.beforeEach(function () { - agent = helper.loadMockedAgent() +test('Transaction naming:', async function (t) { + t.beforeEach(function (ctx) { + ctx.nr = {} + ctx.nr.agent = helper.loadMockedAgent() }) - t.afterEach(function () { - helper.unloadAgent(agent) + t.afterEach(function (ctx) { + helper.unloadAgent(ctx.nr.agent) }) - t.test('Transaction should be named /* without any other naming source', function (t) { + await t.test('Transaction should be named /* without any other naming source', function (t, end) { + const { agent } = t.nr helper.runInTransaction(agent, function (transaction) { transaction.finalizeNameFromUri('http://test.test.com/', 200) - t.equal(transaction.name, 'WebTransaction/NormalizedUri/*') - t.equal(transaction.name, transaction.getFullName(), 'name should be equal to finalized name') - t.end() + assert.equal(transaction.name, 'WebTransaction/NormalizedUri/*') + assert.equal( + transaction.name, + transaction.getFullName(), + 'name should be equal to finalized name' + ) + end() }) }) - t.test('Transaction should not be normalized when 404', function (t) { + await t.test('Transaction should not be normalized when 404', function (t, end) { + const { agent } = t.nr helper.runInTransaction(agent, function (transaction) { transaction.nameState.setName('Expressjs', 'GET', '/', null) transaction.finalizeNameFromUri('http://test.test.com/', 404) - t.equal(transaction.name, 'WebTransaction/Expressjs/GET/(not found)') - t.equal(transaction.name, transaction.getFullName(), 'name should be equal to finalized name') - t.end() + assert.equal(transaction.name, 'WebTransaction/Expressjs/GET/(not found)') + assert.equal( + transaction.name, + transaction.getFullName(), + 'name should be equal to finalized name' + ) + end() }) }) - t.test('Instrumentation should trump default naming', function (t) { + await t.test('Instrumentation should trump default naming', function (t, end) { + const { agent } = t.nr helper.runInTransaction(agent, function (transaction) { simulateInstrumentation(transaction) transaction.finalizeNameFromUri('http://test.test.com/', 200) - t.equal(transaction.name, 'WebTransaction/Expressjs/GET//setByInstrumentation') - t.equal(transaction.name, transaction.getFullName(), 'name should be equal to finalized name') - t.end() + assert.equal(transaction.name, 'WebTransaction/Expressjs/GET//setByInstrumentation') + assert.equal( + transaction.name, + transaction.getFullName(), + 'name should be equal to finalized name' + ) + end() }) }) - t.test('API naming should trump default naming', function (t) { + await t.test('API naming should trump default naming', function (t, end) { + const { agent } = t.nr const api = new API(agent) helper.runInTransaction(agent, function (transaction) { api.setTransactionName('override') transaction.finalizeNameFromUri('http://test.test.com/', 200) - t.equal(transaction.name, 'WebTransaction/Custom/override') - t.equal(transaction.name, transaction.getFullName(), 'name should be equal to finalized name') - t.end() + assert.equal(transaction.name, 'WebTransaction/Custom/override') + assert.equal( + transaction.name, + transaction.getFullName(), + 'name should be equal to finalized name' + ) + end() }) }) - t.test('API naming should trump instrumentation naming', function (t) { + await t.test('API naming should trump instrumentation naming', function (t, end) { + const { agent } = t.nr const api = new API(agent) helper.runInTransaction(agent, function (transaction) { simulateInstrumentation(transaction) api.setTransactionName('override') transaction.finalizeNameFromUri('http://test.test.com/', 200) - t.equal(transaction.name, 'WebTransaction/Custom/override') - t.equal(transaction.name, transaction.getFullName(), 'name should be equal to finalized name') - t.end() + assert.equal(transaction.name, 'WebTransaction/Custom/override') + assert.equal( + transaction.name, + transaction.getFullName(), + 'name should be equal to finalized name' + ) + end() }) }) - t.test('API naming should trump instrumentation naming (order should not matter)', function (t) { - const api = new API(agent) - helper.runInTransaction(agent, function (transaction) { - api.setTransactionName('override') - simulateInstrumentation(transaction) - transaction.finalizeNameFromUri('http://test.test.com/', 200) - t.equal(transaction.name, 'WebTransaction/Custom/override') - t.equal(transaction.name, transaction.getFullName(), 'name should be equal to finalized name') - t.end() - }) - }) + await t.test( + 'API naming should trump instrumentation naming (order should not matter)', + function (t, end) { + const { agent } = t.nr + const api = new API(agent) + helper.runInTransaction(agent, function (transaction) { + api.setTransactionName('override') + simulateInstrumentation(transaction) + transaction.finalizeNameFromUri('http://test.test.com/', 200) + assert.equal(transaction.name, 'WebTransaction/Custom/override') + assert.equal( + transaction.name, + transaction.getFullName(), + 'name should be equal to finalized name' + ) + end() + }) + } + ) - t.test('API should trump 404', function (t) { + await t.test('API should trump 404', function (t, end) { + const { agent } = t.nr const api = new API(agent) helper.runInTransaction(agent, function (transaction) { api.setTransactionName('override') simulateInstrumentation(transaction) transaction.finalizeNameFromUri('http://test.test.com/', 404) - t.equal(transaction.name, 'WebTransaction/Custom/override') - t.equal(transaction.name, transaction.getFullName(), 'name should be equal to finalized name') - t.end() + assert.equal(transaction.name, 'WebTransaction/Custom/override') + assert.equal( + transaction.name, + transaction.getFullName(), + 'name should be equal to finalized name' + ) + end() }) }) - t.test('Custom naming rules should trump default naming', function (t) { + await t.test('Custom naming rules should trump default naming', function (t, end) { + const { agent } = t.nr agent.userNormalizer.addSimple(/\//, '/test-transaction') helper.runInTransaction(agent, function (transaction) { transaction.finalizeNameFromUri('http://test.test.com/', 200) - t.equal(transaction.name, 'WebTransaction/NormalizedUri/test-transaction') - t.equal(transaction.name, transaction.getFullName(), 'name should be equal to finalized name') - t.end() + assert.equal(transaction.name, 'WebTransaction/NormalizedUri/test-transaction') + assert.equal( + transaction.name, + transaction.getFullName(), + 'name should be equal to finalized name' + ) + end() }) }) - t.test( + await t.test( 'Server sent naming rules should be applied when user specified rules are set', - function (t) { + function (t, end) { + const { agent } = t.nr agent.urlNormalizer.addSimple(/\d+/, '*') agent.userNormalizer.addSimple(/123/, 'abc') helper.runInTransaction(agent, function (transaction) { transaction.finalizeNameFromUri('http://test.test.com/123/456', 200) - t.equal(transaction.name, 'WebTransaction/NormalizedUri/abc/*') - t.equal( + assert.equal(transaction.name, 'WebTransaction/NormalizedUri/abc/*') + assert.equal( transaction.name, transaction.getFullName(), 'name should be equal to finalized name' ) - t.end() + end() }) } ) - t.test('Custom naming rules should be cleaned up', function (t) { + await t.test('Custom naming rules should be cleaned up', function (t, end) { + const { agent } = t.nr agent.userNormalizer.addSimple(/\//, 'test-transaction') helper.runInTransaction(agent, function (transaction) { transaction.finalizeNameFromUri('http://test.test.com/', 200) - t.equal(transaction.name, 'WebTransaction/NormalizedUri/test-transaction') - t.equal(transaction.name, transaction.getFullName(), 'name should be equal to finalized name') - t.end() + assert.equal(transaction.name, 'WebTransaction/NormalizedUri/test-transaction') + assert.equal( + transaction.name, + transaction.getFullName(), + 'name should be equal to finalized name' + ) + end() }) }) - t.test('Custom naming rules should trump instrumentation naming', function (t) { + await t.test('Custom naming rules should trump instrumentation naming', function (t, end) { + const { agent } = t.nr agent.userNormalizer.addSimple(/\//, '/test-transaction') helper.runInTransaction(agent, function (transaction) { simulateInstrumentation(transaction) transaction.finalizeNameFromUri('http://test.test.com/', 200) - t.equal(transaction.name, 'WebTransaction/NormalizedUri/test-transaction') - t.equal(transaction.name, transaction.getFullName(), 'name should be equal to finalized name') - t.end() + assert.equal(transaction.name, 'WebTransaction/NormalizedUri/test-transaction') + assert.equal( + transaction.name, + transaction.getFullName(), + 'name should be equal to finalized name' + ) + end() }) }) - t.test('API calls should trump Custom naming rules', function (t) { + await t.test('API calls should trump Custom naming rules', function (t, end) { + const { agent } = t.nr agent.userNormalizer.addSimple(/\//, '/test-transaction') const api = new API(agent) helper.runInTransaction(agent, function (transaction) { api.setTransactionName('override') transaction.finalizeNameFromUri('http://test.test.com/', 200) - t.equal(transaction.name, 'WebTransaction/Custom/override') - t.equal(transaction.name, transaction.getFullName(), 'name should be equal to finalized name') - t.end() + assert.equal(transaction.name, 'WebTransaction/Custom/override') + assert.equal( + transaction.name, + transaction.getFullName(), + 'name should be equal to finalized name' + ) + end() }) }) - t.test('Custom naming rules should trump 404', function (t) { + await t.test('Custom naming rules should trump 404', function (t, end) { + const { agent } = t.nr agent.userNormalizer.addSimple(/\//, '/test-transaction') helper.runInTransaction(agent, function (transaction) { transaction.finalizeNameFromUri('http://test.test.com/', 404) - t.equal(transaction.name, 'WebTransaction/NormalizedUri/test-transaction') - t.equal(transaction.name, transaction.getFullName(), 'name should be equal to finalized name') - t.end() + assert.equal(transaction.name, 'WebTransaction/NormalizedUri/test-transaction') + assert.equal( + transaction.name, + transaction.getFullName(), + 'name should be equal to finalized name' + ) + end() }) }) }) diff --git a/test/unit/transaction.test.js b/test/unit/transaction.test.js index 0c623d8041..781451d24f 100644 --- a/test/unit/transaction.test.js +++ b/test/unit/transaction.test.js @@ -5,7 +5,8 @@ 'use strict' -const tap = require('tap') +const test = require('node:test') +const assert = require('node:assert') const helper = require('../lib/agent_helper') const API = require('../../api') const AttributeFilter = require('../../lib/config/attribute-filter') @@ -15,24 +16,22 @@ const Transaction = require('../../lib/transaction') const Segment = require('../../lib/transaction/trace/segment') const hashes = require('../../lib/util/hashes') const sinon = require('sinon') +const { match } = require('../lib/custom-assertions') -tap.test('Transaction unit tests', (t) => { - t.autoend() - - let agent = null - let txn = null - - t.beforeEach(function () { - agent = helper.loadMockedAgent() - txn = new Transaction(agent) +test('Transaction unit tests', async (t) => { + t.beforeEach(function (ctx) { + ctx.nr = {} + ctx.nr.agent = helper.loadMockedAgent() + ctx.nr.txn = new Transaction(ctx.nr.agent) }) - t.afterEach(() => { - helper.unloadAgent(agent) + t.afterEach((ctx) => { + helper.unloadAgent(ctx.nr.agent) }) - t.test('basic transaction tests', (t) => { - t.throws( + await t.test('basic transaction tests', (t, end) => { + const { agent, txn } = t.nr + assert.throws( () => { return new Transaction() }, @@ -41,26 +40,27 @@ tap.test('Transaction unit tests', (t) => { ) const trace = txn.trace - t.ok(trace instanceof Trace, 'should create a trace on demand') - t.notOk(trace instanceof Array, 'should have at most one associated trace') + assert.ok(trace instanceof Trace, 'should create a trace on demand') + assert.ok(!(trace instanceof Array), 'should have at most one associated trace') agent.on('transactionFinished', (inner) => { - t.equal( + assert.equal( inner.metrics, txn.metrics, 'should hand its metrics off to the agent upon finalization' ) - t.end() + end() }) txn.end() }) - t.test('with DT enabled, should produce span events when finalizing', (t) => { + await t.test('with DT enabled, should produce span events when finalizing', (t, end) => { + const { agent } = t.nr agent.config.distributed_tracing.enabled = true agent.once('transactionFinished', () => { - t.equal(agent.spanEventAggregator.length, 1, 'should have a span event') + assert.equal(agent.spanEventAggregator.length, 1, 'should have a span event') }) helper.runInTransaction(agent, function (inner) { const childSegment = inner.trace.add('child') @@ -68,14 +68,15 @@ tap.test('Transaction unit tests', (t) => { inner.end() }) - t.end() + end() }) - t.test('with DT enabled, should not produce span events when ignored', (t) => { + await t.test('with DT enabled, should not produce span events when ignored', (t, end) => { + const { agent } = t.nr agent.config.distributed_tracing.enabled = true agent.once('transactionFinished', () => { - t.equal(agent.spanEventAggregator.length, 0, 'should have no span events') + assert.equal(agent.spanEventAggregator.length, 0, 'should have no span events') }) helper.runInTransaction(agent, function (inner) { const childSegment = inner.trace.add('child') @@ -84,23 +85,25 @@ tap.test('Transaction unit tests', (t) => { inner.end() }) - t.end() + end() }) - t.test('handing itself off to the agent upon finalization', (t) => { + await t.test('handing itself off to the agent upon finalization', (t, end) => { + const { agent, txn } = t.nr agent.on('transactionFinished', (inner) => { - t.same(inner, txn, 'should have the same transaction') - t.end() + assert.deepEqual(inner, txn, 'should have the same transaction') + end() }) txn.end() }) - t.test('should flush logs on end', (t) => { + await t.test('should flush logs on end', (t, end) => { + const { agent, txn } = t.nr sinon.spy(txn.logs, 'flush') agent.on('transactionFinished', (inner) => { - t.equal(inner.logs.flush.callCount, 1, 'should call `flush` once') - t.end() + assert.equal(inner.logs.flush.callCount, 1, 'should call `flush` once') + end() }) txn.logs.add('log-line1') @@ -108,11 +111,12 @@ tap.test('Transaction unit tests', (t) => { txn.end() }) - t.test('should not flush logs when transaction is ignored', (t) => { + await t.test('should not flush logs when transaction is ignored', (t, end) => { + const { agent, txn } = t.nr sinon.spy(txn.logs, 'flush') agent.on('transactionFinished', (inner) => { - t.equal(inner.logs.flush.callCount, 0, 'should not call `flush`') - t.end() + assert.equal(inner.logs.flush.callCount, 0, 'should not call `flush`') + end() }) txn.logs.add('log-line1') @@ -121,45 +125,58 @@ tap.test('Transaction unit tests', (t) => { txn.end() }) - t.test('initial transaction attributes', (t) => { - t.ok(txn.id, 'should have an ID') - t.ok(txn.metrics, 'should have associated metrics') - t.ok(txn.timer.isActive(), 'should be timing its duration') - t.equal(txn.url, null, 'should have no associated URL (for hidden class)') - t.equal(txn.name, null, 'should have no name set (for hidden class)') - t.equal(txn.nameState.getName(), null, 'should have no PARTIAL name set (for hidden class)') - t.equal(txn.statusCode, null, 'should have no HTTP status code set (for hidden class)') - t.equal(txn.error, null, 'should have no error attached (for hidden class)') - t.equal(txn.verb, null, 'should have no HTTP method / verb set (for hidden class)') - t.notOk(txn.ignore, 'should not be ignored by default (for hidden class)') - t.equal(txn.sampled, null, 'should not have a sampled state set') - t.end() - }) - - t.test('with associated metrics', (t) => { - t.ok(txn.metrics instanceof Metrics, 'should have metrics') - t.not(txn.metrics, getMetrics(agent), 'should manage its own independent of the agent') - t.equal( + await t.test('initial transaction attributes', (t) => { + const { txn } = t.nr + assert.ok(txn.id, 'should have an ID') + assert.ok(txn.metrics, 'should have associated metrics') + assert.ok(txn.timer.isActive(), 'should be timing its duration') + assert.equal(txn.url, null, 'should have no associated URL (for hidden class)') + assert.equal(txn.name, null, 'should have no name set (for hidden class)') + assert.equal( + txn.nameState.getName(), + null, + 'should have no PARTIAL name set (for hidden class)' + ) + assert.equal(txn.statusCode, null, 'should have no HTTP status code set (for hidden class)') + assert.equal(txn.error, null, 'should have no error attached (for hidden class)') + assert.equal(txn.verb, null, 'should have no HTTP method / verb set (for hidden class)') + assert.ok(!txn.ignore, 'should not be ignored by default (for hidden class)') + assert.equal(txn.sampled, null, 'should not have a sampled state set') + }) + + await t.test('with associated metrics', (t) => { + const { agent, txn } = t.nr + assert.ok(txn.metrics instanceof Metrics, 'should have metrics') + assert.notEqual( + txn.metrics, + getMetrics(agent), + 'should manage its own independent of the agent' + ) + assert.equal( getMetrics(agent).apdexT, txn.metrics.apdexT, 'should have the same apdex threshold as the agent' ) - t.equal(agent.mapper, txn.metrics.mapper, 'should have the same metrics mapper as the agent') - t.end() + assert.equal( + agent.mapper, + txn.metrics.mapper, + 'should have the same metrics mapper as the agent' + ) }) - t.test('web transactions', (t) => { + await t.test('web transactions', (t) => { + const { txn } = t.nr txn.type = Transaction.TYPES.BG - t.notOk(txn.isWeb(), 'should know when it is not a web transaction') + assert.ok(!txn.isWeb(), 'should know when it is not a web transaction') txn.type = Transaction.TYPES.WEB - t.ok(txn.isWeb(), 'should know when it is a web transaction') - t.end() + assert.ok(txn.isWeb(), 'should know when it is a web transaction') }) - t.test('when dealing with individual metrics', (t) => { + await t.test('when dealing with individual metrics', (t, end) => { + const { agent } = t.nr let tt = new Transaction(agent) tt.measure('Custom/Test01') - t.ok(tt.metrics.getMetric('Custom/Test01'), 'should add metrics by name') + assert.ok(tt.metrics.getMetric('Custom/Test01'), 'should add metrics by name') tt.end() @@ -171,12 +188,15 @@ tap.test('Transaction unit tests', (t) => { tt.measure(TRACE_NAME, null, SLEEP_DURATION - 5) const statistics = tt.metrics.getMetric(TRACE_NAME) - t.equal( + assert.equal( statistics.callCount, 2, 'should allow multiple overlapping metric measurements for same name' ) - t.ok(statistics.max > (SLEEP_DURATION - 1) / 1000, 'should measure at least 42 milliseconds') + assert.ok( + statistics.max > (SLEEP_DURATION - 1) / 1000, + 'should measure at least 42 milliseconds' + ) tt.end() @@ -185,246 +205,247 @@ tap.test('Transaction unit tests', (t) => { tt.end() const metrics = tt.metrics.getMetric('Custom/Test16') - t.equal(metrics.total, 0.065, 'should allow manual setting of metric durations') + assert.equal(metrics.total, 0.065, 'should allow manual setting of metric durations') - t.end() + end() }) - t.test('when setting apdex for key transactions', (t) => { + await t.test('when setting apdex for key transactions', (t) => { + const { txn } = t.nr txn._setApdex('Apdex/TestController/key', 1200, 667) const metric = txn.metrics.getMetric('Apdex/TestController/key') - t.equal(metric.apdexT, 0.667, 'should set apdexT to the key transaction apdexT') - t.equal(metric.satisfying, 0, 'should not have satisfied') - t.equal(metric.tolerating, 1, 'should have been tolerated') - t.equal(metric.frustrating, 0, 'should not have frustrated') + assert.equal(metric.apdexT, 0.667, 'should set apdexT to the key transaction apdexT') + assert.equal(metric.satisfying, 0, 'should not have satisfied') + assert.equal(metric.tolerating, 1, 'should have been tolerated') + assert.equal(metric.frustrating, 0, 'should not have frustrated') txn._setApdex('Apdex/TestController/another', 1200) const another = txn.metrics.getMetric('Apdex/TestController/another') - t.equal(another.apdexT, 0.1, 'should not require a key transaction apdexT') - t.end() + assert.equal(another.apdexT, 0.1, 'should not require a key transaction apdexT') }) - t.test('should ignore calculating apdex when ignoreApdex is true', (t) => { + await t.test('should ignore calculating apdex when ignoreApdex is true', (t) => { + const { txn } = t.nr txn.ignoreApdex = true txn._setApdex('Apdex/TestController/key', 1200, 667) const metric = txn.metrics.getMetric('Apdex/TestController/key') - t.notOk(metric) - t.end() + assert.ok(!metric) }) }) -tap.test('Transaction naming tests', (t) => { - t.autoend() - let agent = null - let txn = null - function beforeEach() { - agent = helper.loadMockedAgent({ - attributes: { - enabled: true, - include: ['request.parameters.*'] - } +test('Transaction naming tests', async (t) => { + function bookends(t) { + t.beforeEach((ctx) => { + ctx.nr = {} + ctx.nr.agent = helper.loadMockedAgent({ + attributes: { + enabled: true, + include: ['request.parameters.*'] + } + }) + ctx.nr.agent.config.emit('attributes.include') + ctx.nr.txn = new Transaction(ctx.nr.agent) }) - agent.config.emit('attributes.include') - txn = new Transaction(agent) - } - t.afterEach(() => { - helper.unloadAgent(agent) - }) + t.afterEach((ctx) => { + helper.unloadAgent(ctx.nr.agent) + }) + } - t.test('getName', (t) => { - t.autoend() - t.beforeEach(beforeEach) + await t.test('getName', async (t) => { + bookends(t) - t.test('base test', (t) => { - t.equal(txn.getName(), null, 'should return `null` if there is no name, partialName, or url') - t.end() + await t.test('base test', (t) => { + const { txn } = t.nr + assert.equal( + txn.getName(), + null, + 'should return `null` if there is no name, partialName, or url' + ) }) - t.test('partial name should remain unset if it was not set before', (t) => { + await t.test('partial name should remain unset if it was not set before', (t) => { + const { txn } = t.nr txn.url = '/some/pathname' - t.equal(txn.nameState.getName(), null, 'should have no namestate') - t.equal(txn.getName(), 'NormalizedUri/*', 'should have a default partial name') - t.equal(txn.nameState.getName(), null, 'should still have no namestate') - t.end() + assert.equal(txn.nameState.getName(), null, 'should have no namestate') + assert.equal(txn.getName(), 'NormalizedUri/*', 'should have a default partial name') + assert.equal(txn.nameState.getName(), null, 'should still have no namestate') }) - t.test('should return the right name if partialName and url are set', (t) => { + await t.test('should return the right name if partialName and url are set', (t) => { + const { txn } = t.nr txn.nameState.setPrefix('Framework') txn.nameState.setVerb('verb') txn.nameState.appendPath('route') txn.url = '/route' - t.equal(txn.getName(), 'WebFrameworkUri/Framework/VERB/route', 'should have full name') - t.equal(txn.nameState.getName(), 'Framework/VERB/route', 'should have the partial name') - t.end() + assert.equal(txn.getName(), 'WebFrameworkUri/Framework/VERB/route', 'should have full name') + assert.equal(txn.nameState.getName(), 'Framework/VERB/route', 'should have the partial name') }) - t.test('should return the name if it has already been set', (t) => { + await t.test('should return the name if it has already been set', (t) => { + const { txn } = t.nr txn.setPartialName('foo/bar') - t.equal(txn.getName(), 'foo/bar', 'name should be as set') - t.end() + assert.equal(txn.getName(), 'foo/bar', 'name should be as set') }) }) - t.test('isIgnored', (t) => { - t.autoend() - t.beforeEach(beforeEach) + await t.test('isIgnored', async (t) => { + bookends(t) - t.test('should return true if a transaction is ignored by a rule', (t) => { + await t.test('should return true if a transaction is ignored by a rule', (t) => { + const { agent, txn } = t.nr const api = new API(agent) api.addIgnoringRule('^/test/') txn.finalizeNameFromUri('/test/string?do=thing&another=thing', 200) - t.ok(txn.isIgnored(), 'should ignore the transaction') - t.end() + assert.ok(txn.isIgnored(), 'should ignore the transaction') }) }) - t.test('getFullName', (t) => { - t.autoend() - t.beforeEach(beforeEach) + await t.test('getFullName', async (t) => { + bookends(t) - t.test('should return null if it does not have name, partialName, or url', (t) => { - t.equal(txn.getFullName(), null, 'should not have a full name') - t.end() + await t.test('should return null if it does not have name, partialName, or url', (t) => { + const { txn } = t.nr + assert.equal(txn.getFullName(), null, 'should not have a full name') }) - t.test('partial name should remain unset if it was not set before', (t) => { + await t.test('partial name should remain unset if it was not set before', (t) => { + const { txn } = t.nr txn.url = '/some/pathname' - t.equal(txn.nameState.getName(), null, 'should have no namestate') - t.equal( + assert.equal(txn.nameState.getName(), null, 'should have no namestate') + assert.equal( txn.getFullName(), 'WebTransaction/NormalizedUri/*', 'should have a default full name' ) - t.equal(txn.nameState.getName(), null, 'should still have no namestate') - t.end() + assert.equal(txn.nameState.getName(), null, 'should still have no namestate') }) - t.test('should return the right name if partialName and url are set', (t) => { + await t.test('should return the right name if partialName and url are set', (t) => { + const { txn } = t.nr txn.nameState.setPrefix('Framework') txn.nameState.setVerb('verb') txn.nameState.appendPath('route') txn.url = '/route' - t.equal( + assert.equal( txn.getFullName(), 'WebTransaction/WebFrameworkUri/Framework/VERB/route', 'should have full name' ) - t.equal(txn.nameState.getName(), 'Framework/VERB/route', 'should have full name') - t.end() + assert.equal(txn.nameState.getName(), 'Framework/VERB/route', 'should have full name') }) - t.test('should return the name if it has already been set', (t) => { + await t.test('should return the name if it has already been set', (t) => { + const { txn } = t.nr txn.name = 'OtherTransaction/foo/bar' - t.equal(txn.getFullName(), 'OtherTransaction/foo/bar') - t.end() + assert.equal(txn.getFullName(), 'OtherTransaction/foo/bar') }) - t.test('should return the forced name if set', (t) => { + await t.test('should return the forced name if set', (t) => { + const { txn } = t.nr txn.name = 'FullName' txn._partialName = 'PartialName' txn.forceName = 'ForcedName' - t.equal(txn.getFullName(), 'WebTransaction/ForcedName') - t.end() + assert.equal(txn.getFullName(), 'WebTransaction/ForcedName') }) }) - t.test('with no partial name set', (t) => { - t.autoend() - t.beforeEach(beforeEach) + await t.test('with no partial name set', async (t) => { + bookends(t) - t.test('produces a normalized (backstopped) name when status is 200', (t) => { + await t.test('produces a normalized (backstopped) name when status is 200', (t) => { + const { txn } = t.nr txn.finalizeNameFromUri('/test/string?do=thing&another=thing', 200) - t.equal(txn.name, 'WebTransaction/NormalizedUri/*') - t.end() + assert.equal(txn.name, 'WebTransaction/NormalizedUri/*') }) - t.test('produces a normalized partial name when status is 200', (t) => { + await t.test('produces a normalized partial name when status is 200', (t) => { + const { txn } = t.nr txn.finalizeNameFromUri('/test/string?do=thing&another=thing', 200) - t.equal(txn._partialName, 'NormalizedUri/*') - t.end() + assert.equal(txn._partialName, 'NormalizedUri/*') }) - t.test('passes through status code when status is 200', (t) => { + await t.test('passes through status code when status is 200', (t) => { + const { txn } = t.nr txn.finalizeNameFromUri('/test/string?do=thing&another=thing', 200) - t.equal(txn.statusCode, 200) - t.end() + assert.equal(txn.statusCode, 200) }) - t.test('produces a non-error name when status code is ignored', (t) => { + await t.test('produces a non-error name when status code is ignored', (t) => { + const { agent, txn } = t.nr agent.config.error_collector.ignore_status_codes = [404, 500] txn.finalizeNameFromUri('/test/string?do=thing&another=thing', 500) - t.equal(txn.name, 'WebTransaction/NormalizedUri/*') - t.end() + assert.equal(txn.name, 'WebTransaction/NormalizedUri/*') }) - t.test('produces a non-error partial name when status code is ignored', (t) => { + await t.test('produces a non-error partial name when status code is ignored', (t) => { + const { agent, txn } = t.nr agent.config.error_collector.ignore_status_codes = [404, 500] txn.finalizeNameFromUri('/test/string?do=thing&another=thing', 500) - t.equal(txn._partialName, 'NormalizedUri/*') - t.end() + assert.equal(txn._partialName, 'NormalizedUri/*') }) - t.test('passes through status code when status is 404', (t) => { + await t.test('passes through status code when status is 404', (t) => { + const { txn } = t.nr txn.finalizeNameFromUri('/test/string?do=thing&another=thing', 404) - t.equal(txn.statusCode, 404) - t.end() + assert.equal(txn.statusCode, 404) }) - t.test('produces a `not found` partial name when status is 404', (t) => { + await t.test('produces a `not found` partial name when status is 404', (t) => { + const { txn } = t.nr txn.nameState.setName('Expressjs', 'GET', '/') txn.finalizeNameFromUri('/test/string?do=thing&another=thing', 404) - t.equal(txn._partialName, 'Expressjs/GET/(not found)') - t.end() + assert.equal(txn._partialName, 'Expressjs/GET/(not found)') }) - t.test('produces a `not found` name when status is 404', (t) => { + await t.test('produces a `not found` name when status is 404', (t) => { + const { txn } = t.nr txn.nameState.setName('Expressjs', 'GET', '/') txn.finalizeNameFromUri('/test/string?do=thing&another=thing', 404) - t.equal(txn.name, 'WebTransaction/Expressjs/GET/(not found)') - t.end() + assert.equal(txn.name, 'WebTransaction/Expressjs/GET/(not found)') }) - t.test('passes through status code when status is 405', (t) => { + await t.test('passes through status code when status is 405', (t) => { + const { txn } = t.nr txn.finalizeNameFromUri('/test/string?do=thing&another=thing', 405) - t.equal(txn.statusCode, 405) - t.end() + assert.equal(txn.statusCode, 405) }) - t.test('produces a `method not allowed` partial name when status is 405', (t) => { + await t.test('produces a `method not allowed` partial name when status is 405', (t) => { + const { txn } = t.nr txn.nameState.setName('Expressjs', 'GET', '/') txn.finalizeNameFromUri('/test/string?do=thing&another=thing', 405) - t.equal(txn._partialName, 'Expressjs/GET/(method not allowed)') - t.end() + assert.equal(txn._partialName, 'Expressjs/GET/(method not allowed)') }) - t.test('produces a `method not allowed` name when status is 405', (t) => { + await t.test('produces a `method not allowed` name when status is 405', (t) => { + const { txn } = t.nr txn.nameState.setName('Expressjs', 'GET', '/') txn.finalizeNameFromUri('/test/string?do=thing&another=thing', 405) - t.equal(txn.name, 'WebTransaction/Expressjs/GET/(method not allowed)') - t.end() + assert.equal(txn.name, 'WebTransaction/Expressjs/GET/(method not allowed)') }) - t.test('produces a name based on 501 status code message', (t) => { + await t.test('produces a name based on 501 status code message', (t) => { + const { txn } = t.nr txn.finalizeNameFromUri('/test/string?do=thing&another=thing', 501) - t.equal(txn.name, 'WebTransaction/WebFrameworkUri/(not implemented)') - t.end() + assert.equal(txn.name, 'WebTransaction/WebFrameworkUri/(not implemented)') }) - t.test('produces a regular partial name based on 501 status code message', (t) => { + await t.test('produces a regular partial name based on 501 status code message', (t) => { + const { txn } = t.nr txn.finalizeNameFromUri('/test/string?do=thing&another=thing', 501) - t.equal(txn._partialName, 'WebFrameworkUri/(not implemented)') - t.end() + assert.equal(txn._partialName, 'WebFrameworkUri/(not implemented)') }) - t.test('passes through status code when status is 501', (t) => { + await t.test('passes through status code when status is 501', (t) => { + const { txn } = t.nr txn.finalizeNameFromUri('/test/string?do=thing&another=thing', 501) - t.equal(txn.statusCode, 501) - t.end() + assert.equal(txn.statusCode, 501) }) - t.test('should update value from segment normalizer rules', (t) => { + await t.test('should update value from segment normalizer rules', (t) => { + const { agent, txn } = t.nr const url = 'NormalizedUri/test/explicit/string/lyrics' txn.forceName = url txn.url = url @@ -432,112 +453,121 @@ tap.test('Transaction naming tests', (t) => { { prefix: 'WebTransaction/NormalizedUri', terms: ['test', 'string'] } ]) txn.finalizeNameFromUri(url, 200) - t.equal(txn.name, 'WebTransaction/NormalizedUri/test/*/string/*') - t.end() + assert.equal(txn.name, 'WebTransaction/NormalizedUri/test/*/string/*') }) - t.test('should not scope web transactions to their URL', (t) => { + await t.test('should not scope web transactions to their URL', (t) => { + const { txn } = t.nr txn.finalizeNameFromUri('/test/1337?action=edit', 200) - t.not(txn.name, '/test/1337?action=edit') - t.not(txn.name, 'WebTransaction/Uri/test/1337') - t.end() + assert.notEqual(txn.name, '/test/1337?action=edit') + assert.notEqual(txn.name, 'WebTransaction/Uri/test/1337') }) }) - t.test('with a custom partial name set', (t) => { - t.autoend() + await t.test('with a custom partial name set', async (t) => { + t.beforeEach((ctx) => { + ctx.nr = {} + ctx.nr.agent = helper.loadMockedAgent({ + attributes: { + enabled: true, + include: ['request.parameters.*'] + } + }) + ctx.nr.agent.config.emit('attributes.include') + ctx.nr.txn = new Transaction(ctx.nr.agent) + ctx.nr.txn.nameState.setPrefix('Custom') + ctx.nr.txn.nameState.appendPath('test') + ctx.nr.agent.transactionNameNormalizer.rules = [] + }) - t.beforeEach(() => { - beforeEach() - txn.nameState.setPrefix('Custom') - txn.nameState.appendPath('test') - agent.transactionNameNormalizer.rules = [] + t.afterEach((ctx) => { + helper.unloadAgent(ctx.nr.agent) }) - t.test('produces a custom name when status is 200', (t) => { + await t.test('produces a custom name when status is 200', (t) => { + const { txn } = t.nr txn.finalizeNameFromUri('/test/string?do=thing&another=thing', 200) - t.equal(txn.name, 'WebTransaction/Custom/test') - t.end() + assert.equal(txn.name, 'WebTransaction/Custom/test') }) - t.test('produces a partial name when status is 200', (t) => { + await t.test('produces a partial name when status is 200', (t) => { + const { txn } = t.nr txn.finalizeNameFromUri('/test/string?do=thing&another=thing', 200) - t.equal(txn.nameState.getName(), 'Custom/test') - t.end() + assert.equal(txn.nameState.getName(), 'Custom/test') }) - t.test('should rename a transaction when told to by a rule', (t) => { + await t.test('should rename a transaction when told to by a rule', (t) => { + const { agent, txn } = t.nr agent.transactionNameNormalizer.addSimple('^(WebTransaction/Custom)/test$', '$1/*') txn.finalizeNameFromUri('/test/string?do=thing&another=thing', 200) - t.equal(txn.name, 'WebTransaction/Custom/*') - t.end() + assert.equal(txn.name, 'WebTransaction/Custom/*') }) - t.test('passes through status code when status is 200', (t) => { + await t.test('passes through status code when status is 200', (t) => { + const { txn } = t.nr txn.finalizeNameFromUri('/test/string?do=thing&another=thing', 200) - t.equal(txn.statusCode, 200) - t.end() + assert.equal(txn.statusCode, 200) }) - t.test('keeps the custom name when error status is ignored', (t) => { + await t.test('keeps the custom name when error status is ignored', (t) => { + const { agent, txn } = t.nr agent.config.error_collector.ignore_status_codes = [404, 500] txn.finalizeNameFromUri('/test/string?do=thing&another=thing', 500) - t.equal(txn.name, 'WebTransaction/Custom/test') - t.end() + assert.equal(txn.name, 'WebTransaction/Custom/test') }) - t.test('keeps the custom partial name when error status is ignored', (t) => { + await t.test('keeps the custom partial name when error status is ignored', (t) => { + const { txn } = t.nr txn.finalizeNameFromUri('/test/string?do=thing&another=thing', 404) - t.equal(txn.nameState.getName(), 'Custom/test') - t.end() + assert.equal(txn.nameState.getName(), 'Custom/test') }) - t.test('passes through status code when status is 404', (t) => { + await t.test('passes through status code when status is 404', (t) => { + const { txn } = t.nr txn.finalizeNameFromUri('/test/string?do=thing&another=thing', 404) - t.equal(txn.statusCode, 404) - t.end() + assert.equal(txn.statusCode, 404) }) - t.test('produces the custom name even when status is 501', (t) => { + await t.test('produces the custom name even when status is 501', (t) => { + const { txn } = t.nr txn.finalizeNameFromUri('/test/string?do=thing&another=thing', 501) - t.equal(txn.name, 'WebTransaction/Custom/test') - t.end() + assert.equal(txn.name, 'WebTransaction/Custom/test') }) - t.test('produces the custom partial name even when status is 501', (t) => { + await t.test('produces the custom partial name even when status is 501', (t) => { + const { txn } = t.nr txn.finalizeNameFromUri('/test/string?do=thing&another=thing', 501) - t.equal(txn.nameState.getName(), 'Custom/test') - t.end() + assert.equal(txn.nameState.getName(), 'Custom/test') }) - t.test('passes through status code when status is 501', (t) => { + await t.test('passes through status code when status is 501', (t) => { + const { txn } = t.nr txn.finalizeNameFromUri('/test/string?do=thing&another=thing', 501) - t.equal(txn.statusCode, 501) - t.end() + assert.equal(txn.statusCode, 501) }) - t.test('should ignore a transaction when told to by a rule', (t) => { + await t.test('should ignore a transaction when told to by a rule', (t) => { + const { agent, txn } = t.nr agent.transactionNameNormalizer.addSimple('^WebTransaction/Custom/test$') txn.finalizeNameFromUri('/test/string?do=thing&another=thing', 200) - t.ok(txn.isIgnored()) - t.end() + assert.ok(txn.isIgnored()) }) }) - t.test('pathHashes', (t) => { - t.autoend() - t.beforeEach(beforeEach) + await t.test('pathHashes', async (t) => { + bookends(t) - t.test('should add up to 10 items to to pathHashes', (t) => { + await t.test('should add up to 10 items to to pathHashes', (t) => { + const { txn } = t.nr const toAdd = ['1', '2', '3', '4', '4', '5', '6', '7', '8', '9', '10', '11'] const expected = ['10', '9', '8', '7', '6', '5', '4', '3', '2', '1'] toAdd.forEach(txn.pushPathHash.bind(txn)) - t.same(txn.pathHashes, expected) - t.end() + assert.deepEqual(txn.pathHashes, expected) }) - t.test('should not include current pathHash in alternatePathHashes', (t) => { + await t.test('should not include current pathHash in alternatePathHashes', (t) => { + const { agent, txn } = t.nr txn.name = '/a/b/c' txn.referringPathHash = '/d/e/f' @@ -548,15 +578,15 @@ tap.test('Transaction naming tests', (t) => { ) txn.pathHashes = ['/a', curHash, '/a/b'] - t.equal(txn.alternatePathHashes(), '/a,/a/b') + assert.equal(txn.alternatePathHashes(), '/a,/a/b') txn.nameState.setPrefix(txn.name) txn.name = null txn.pathHashes = ['/a', '/a/b'] - t.equal(txn.alternatePathHashes(), '/a,/a/b') - t.end() + assert.equal(txn.alternatePathHashes(), '/a,/a/b') }) - t.test('should return null when no alternate pathHashes exist', (t) => { + await t.test('should return null when no alternate pathHashes exist', (t) => { + const { agent, txn } = t.nr txn.nameState.setPrefix('/a/b/c') txn.referringPathHash = '/d/e/f' @@ -567,71 +597,65 @@ tap.test('Transaction naming tests', (t) => { ) txn.pathHashes = [curHash] - t.equal(txn.alternatePathHashes(), null) + assert.equal(txn.alternatePathHashes(), null) txn.pathHashes = [] - t.equal(txn.alternatePathHashes(), null) - t.end() + assert.equal(txn.alternatePathHashes(), null) }) }) }) -tap.test('Transaction methods', (t) => { - t.autoend() - let txn = null - let agent = null - +test('Transaction methods', async (t) => { function bookends(t) { - t.beforeEach(() => { - agent = helper.loadMockedAgent() - txn = new Transaction(agent) + t.beforeEach((ctx) => { + ctx.nr = {} + ctx.nr.agent = helper.loadMockedAgent() + ctx.nr.txn = new Transaction(ctx.nr.agent) }) - t.afterEach(() => { - helper.unloadAgent(agent) + t.afterEach((ctx) => { + helper.unloadAgent(ctx.nr.agent) }) } - t.test('hasErrors', (t) => { - t.autoend() + await t.test('hasErrors', async (t) => { bookends(t) - t.test('should return true if exceptions property is not empty', (t) => { - t.notOk(txn.hasErrors()) + await t.test('should return true if exceptions property is not empty', (t) => { + const { txn } = t.nr + assert.ok(!txn.hasErrors()) txn.exceptions.push(new Error()) - t.ok(txn.hasErrors()) - t.end() + assert.ok(txn.hasErrors()) }) - t.test('should return true if statusCode is an error', (t) => { + await t.test('should return true if statusCode is an error', (t) => { + const { txn } = t.nr txn.statusCode = 500 - t.ok(txn.hasErrors()) - t.end() + assert.ok(txn.hasErrors()) }) }) - t.test('isSampled', (t) => { - t.autoend() + await t.test('isSampled', async (t) => { bookends(t) - t.test('should be true when the transaction is sampled', (t) => { + await t.test('should be true when the transaction is sampled', (t) => { + const { txn } = t.nr // the first 10 transactions are sampled so this should be true - t.ok(txn.isSampled()) - t.end() + assert.ok(txn.isSampled()) }) - t.test('should be false when the transaction is not sampled', (t) => { + await t.test('should be false when the transaction is not sampled', (t) => { + const { txn } = t.nr txn.priority = Infinity txn.sampled = false - t.notOk(txn.isSampled()) - t.end() + assert.ok(!txn.isSampled()) }) }) - t.test('getIntrinsicAttributes', (t) => { - t.autoend() + await t.test('getIntrinsicAttributes', async (t) => { bookends(t) - t.test('includes CAT attributes when enabled', (t) => { + await t.test('includes CAT attributes when enabled', (t) => { + const { txn } = t.nr txn.agent.config.cross_application_tracer.enabled = true txn.agent.config.distributed_tracing.enabled = false txn.tripId = '3456' @@ -639,14 +663,14 @@ tap.test('Transaction methods', (t) => { txn.incomingCatId = '2345' const attributes = txn.getIntrinsicAttributes() - t.equal(attributes.referring_transaction_guid, '1234') - t.equal(attributes.client_cross_process_id, '2345') - t.type(attributes.path_hash, 'string') - t.equal(attributes.trip_id, '3456') - t.end() + assert.equal(attributes.referring_transaction_guid, '1234') + assert.equal(attributes.client_cross_process_id, '2345') + assert.equal(typeof attributes.path_hash, 'string') + assert.equal(attributes.trip_id, '3456') }) - t.test('includes Synthetics attributes', (t) => { + await t.test('includes Synthetics attributes', (t) => { + const { txn } = t.nr txn.syntheticsData = { version: 1, accountId: 123, @@ -656,13 +680,13 @@ tap.test('Transaction methods', (t) => { } const attributes = txn.getIntrinsicAttributes() - t.equal(attributes.synthetics_resource_id, 'resId') - t.equal(attributes.synthetics_job_id, 'jobId') - t.equal(attributes.synthetics_monitor_id, 'monId') - t.end() + assert.equal(attributes.synthetics_resource_id, 'resId') + assert.equal(attributes.synthetics_job_id, 'jobId') + assert.equal(attributes.synthetics_monitor_id, 'monId') }) - t.test('includes Synthetics Info attributes', (t) => { + await t.test('includes Synthetics Info attributes', (t) => { + const { txn } = t.nr // spec states must be present too txn.syntheticsData = {} txn.syntheticsInfoData = { @@ -677,38 +701,35 @@ tap.test('Transaction methods', (t) => { } const attributes = txn.getIntrinsicAttributes() - t.equal(attributes.synthetics_type, 'unitTest') - t.equal(attributes.synthetics_initiator, 'cli') - t.equal(attributes.synthetics_attr_test, 'value') - t.equal(attributes.synthetics_attr_2_test, 'value1') - t.equal(attributes.synthetics_x_test_header, 'value2') - t.end() + assert.equal(attributes.synthetics_type, 'unitTest') + assert.equal(attributes.synthetics_initiator, 'cli') + assert.equal(attributes.synthetics_attr_test, 'value') + assert.equal(attributes.synthetics_attr_2_test, 'value1') + assert.equal(attributes.synthetics_x_test_header, 'value2') }) - t.test('returns different object every time', (t) => { - t.not(txn.getIntrinsicAttributes(), txn.getIntrinsicAttributes()) - t.end() + await t.test('returns different object every time', (t) => { + const { txn } = t.nr + assert.notEqual(txn.getIntrinsicAttributes(), txn.getIntrinsicAttributes()) }) - t.test('includes distributed trace attributes', (t) => { + await t.test('includes distributed trace attributes', (t) => { + const { txn } = t.nr const attributes = txn.getIntrinsicAttributes() - t.ok(txn.priority.toString().length <= 8) - t.has(attributes, { - guid: txn.id, - traceId: txn.traceId, - priority: txn.priority, - sampled: true - }) - t.end() + assert.ok(txn.priority.toString().length <= 8) + assert.equal(attributes.guid, txn.id) + assert.equal(attributes.traceId, txn.traceId) + assert.equal(attributes.priority, txn.priority) + assert.equal(attributes.sampled, true) }) }) - t.test('getResponseDurationInMillis', (t) => { - t.autoend() + await t.test('getResponseDurationInMillis', async (t) => { bookends(t) - t.test('for web transactions', (t) => { + await t.test('for web transactions', (t) => { + const { txn } = t.nr txn.url = 'someUrl' // add a segment that will end after the txn ends @@ -719,15 +740,15 @@ tap.test('Transaction methods', (t) => { childSegment.end() // response time should equal the transaction timer duration - t.equal( + assert.equal( txn.getResponseTimeInMillis(), txn.timer.getDurationInMillis(), 'should use the time until transaction.end() is called' ) - t.end() }) - t.test('for background transactions', (t) => { + await t.test('for background transactions', (t) => { + const { txn } = t.nr // add a segment that will end after the transaction ends txn.type = Transaction.TYPES.BG const bgTransactionSegment = txn.trace.add('backgroundWork') @@ -737,23 +758,19 @@ tap.test('Transaction methods', (t) => { bgTransactionSegment.end() // response time should equal the full duration of the trace - t.equal( + assert.equal( txn.getResponseTimeInMillis(), txn.trace.getDurationInMillis(), 'should report response time equal to trace duration' ) - t.end() }) }) }) -tap.test('_acceptDistributedTracePayload', (t) => { - t.autoend() - let txn = null - let agent = null - - t.beforeEach(function () { - agent = helper.loadMockedAgent({ +test('_acceptDistributedTracePayload', async (t) => { + t.beforeEach(function (ctx) { + ctx.nr = {} + const agent = helper.loadMockedAgent({ distributed_tracing: { enabled: true } }) agent.config.trusted_account_key = '1' @@ -763,53 +780,55 @@ tap.test('_acceptDistributedTracePayload', (t) => { agent.recordSupportability = sinon.spy() - txn = new Transaction(agent) + ctx.nr.agent = agent + ctx.nr.txn = new Transaction(ctx.nr.agent) }) - t.afterEach(function () { - helper.unloadAgent(agent) - agent = null + t.afterEach(function (ctx) { + helper.unloadAgent(ctx.nr.agent) + ctx.nr.agent = null }) - t.test('records supportability metric if no payload was passed', (t) => { + await t.test('records supportability metric if no payload was passed', (t) => { + const { txn } = t.nr txn._acceptDistributedTracePayload(null) - t.equal( + assert.equal( txn.agent.recordSupportability.args[0][0], 'DistributedTrace/AcceptPayload/Ignored/Null' ) - t.end() }) - t.test( + await t.test( 'when already marked as distributed trace, records `Multiple` supportability metric if parentId exists', (t) => { + const { txn } = t.nr txn.isDistributedTrace = true txn.parentId = 'exists' txn._acceptDistributedTracePayload({}) - t.equal( + assert.equal( txn.agent.recordSupportability.args[0][0], 'DistributedTrace/AcceptPayload/Ignored/Multiple' ) - t.end() } ) - t.test( + await t.test( 'when already marked as distributed trace, records `CreateBeforeAccept` metric if parentId does not exist', (t) => { + const { txn } = t.nr txn.isDistributedTrace = true txn._acceptDistributedTracePayload({}) - t.equal( + assert.equal( txn.agent.recordSupportability.args[0][0], 'DistributedTrace/AcceptPayload/Ignored/CreateBeforeAccept' ) - t.end() } ) - t.test('should not accept payload if no configured trusted key', (t) => { + await t.test('should not accept payload if no configured trusted key', (t) => { + const { txn } = t.nr txn.agent.config.trusted_account_key = null txn.agent.config.account_id = null @@ -824,12 +843,15 @@ tap.test('_acceptDistributedTracePayload', (t) => { txn._acceptDistributedTracePayload({ v: [0, 1], d: data }) - t.equal(txn.agent.recordSupportability.args[0][0], 'DistributedTrace/AcceptPayload/Exception') - t.notOk(txn.isDistributedTrace) - t.end() + assert.equal( + txn.agent.recordSupportability.args[0][0], + 'DistributedTrace/AcceptPayload/Exception' + ) + assert.ok(!txn.isDistributedTrace) }) - t.test('should not accept payload if DT disabled', (t) => { + await t.test('should not accept payload if DT disabled', (t) => { + const { txn } = t.nr txn.agent.config.distributed_tracing.enabled = false const data = { @@ -843,12 +865,15 @@ tap.test('_acceptDistributedTracePayload', (t) => { txn._acceptDistributedTracePayload({ v: [0, 1], d: data }) - t.equal(txn.agent.recordSupportability.args[0][0], 'DistributedTrace/AcceptPayload/Exception') - t.notOk(txn.isDistributedTrace) - t.end() + assert.equal( + txn.agent.recordSupportability.args[0][0], + 'DistributedTrace/AcceptPayload/Exception' + ) + assert.ok(!txn.isDistributedTrace) }) - t.test('should accept payload if config valid and CAT disabled', (t) => { + await t.test('should accept payload if config valid and CAT disabled', (t) => { + const { txn } = t.nr txn.agent.config.cross_application_tracer.enabled = false const data = { @@ -862,21 +887,21 @@ tap.test('_acceptDistributedTracePayload', (t) => { txn._acceptDistributedTracePayload({ v: [0, 1], d: data }) - t.ok(txn.isDistributedTrace) - t.end() + assert.ok(txn.isDistributedTrace) }) - t.test('fails if payload version is above agent-supported version', (t) => { + await t.test('fails if payload version is above agent-supported version', (t) => { + const { txn } = t.nr txn._acceptDistributedTracePayload({ v: [1, 0] }) - t.equal( + assert.equal( txn.agent.recordSupportability.args[0][0], 'DistributedTrace/AcceptPayload/ParseException' ) - t.notOk(txn.isDistributedTrace) - t.end() + assert.ok(!txn.isDistributedTrace) }) - t.test('fails if payload account id is not in trusted ids', (t) => { + await t.test('fails if payload account id is not in trusted ids', (t) => { + const { txn } = t.nr const data = { ac: 2, ty: 'App', @@ -890,30 +915,30 @@ tap.test('_acceptDistributedTracePayload', (t) => { v: [0, 1], d: data }) - t.equal( + assert.equal( txn.agent.recordSupportability.args[0][0], 'DistributedTrace/AcceptPayload/Ignored/UntrustedAccount' ) - t.notOk(txn.isDistributedTrace) - t.end() + assert.ok(!txn.isDistributedTrace) }) - t.test('fails if payload data is missing required keys', (t) => { + await t.test('fails if payload data is missing required keys', (t) => { + const { txn } = t.nr txn._acceptDistributedTracePayload({ v: [0, 1], d: { ac: 1 } }) - t.equal( + assert.equal( txn.agent.recordSupportability.args[0][0], 'DistributedTrace/AcceptPayload/ParseException' ) - t.notOk(txn.isDistributedTrace) - t.end() + assert.ok(!txn.isDistributedTrace) }) - t.test('takes the priority and sampled state from the incoming payload', (t) => { + await t.test('takes the priority and sampled state from the incoming payload', (t) => { + const { txn } = t.nr const data = { ac: '1', ty: 'App', @@ -926,14 +951,14 @@ tap.test('_acceptDistributedTracePayload', (t) => { } txn._acceptDistributedTracePayload({ v: [0, 1], d: data }) - t.ok(txn.sampled) - t.equal(txn.priority, data.pr) + assert.ok(txn.sampled) + assert.equal(txn.priority, data.pr) // Should not truncate accepted priority - t.equal(txn.priority.toString().length, 9) - t.end() + assert.equal(txn.priority.toString().length, 9) }) - t.test('does not take the distributed tracing data if priority is missing', (t) => { + await t.test('does not take the distributed tracing data if priority is missing', (t) => { + const { txn } = t.nr const data = { ac: 1, ty: 'App', @@ -945,12 +970,12 @@ tap.test('_acceptDistributedTracePayload', (t) => { } txn._acceptDistributedTracePayload({ v: [0, 1], d: data }) - t.equal(txn.priority, null) - t.equal(txn.sampled, null) - t.end() + assert.equal(txn.priority, null) + assert.equal(txn.sampled, null) }) - t.test('stores payload props on transaction', (t) => { + await t.test('stores payload props on transaction', (t) => { + const { txn } = t.nr const data = { ac: '1', ty: 'App', @@ -961,16 +986,19 @@ tap.test('_acceptDistributedTracePayload', (t) => { } txn._acceptDistributedTracePayload({ v: [0, 1], d: data }) - t.equal(txn.agent.recordSupportability.args[0][0], 'DistributedTrace/AcceptPayload/Success') - t.equal(txn.parentId, data.tx) - t.equal(txn.parentType, data.ty) - t.equal(txn.traceId, data.tr) - t.ok(txn.isDistributedTrace) - t.ok(txn.parentTransportDuration > 0) - t.end() + assert.equal( + txn.agent.recordSupportability.args[0][0], + 'DistributedTrace/AcceptPayload/Success' + ) + assert.equal(txn.parentId, data.tx) + assert.equal(txn.parentType, data.ty) + assert.equal(txn.traceId, data.tr) + assert.ok(txn.isDistributedTrace) + assert.ok(txn.parentTransportDuration > 0) }) - t.test('should 0 transport duration when receiving payloads from the future', (t) => { + await t.test('should 0 transport duration when receiving payloads from the future', (t) => { + const { txn } = t.nr const data = { ac: '1', ty: 'App', @@ -982,85 +1010,77 @@ tap.test('_acceptDistributedTracePayload', (t) => { } txn._acceptDistributedTracePayload({ v: [0, 1], d: data }) - t.equal(txn.agent.recordSupportability.args[0][0], 'DistributedTrace/AcceptPayload/Success') - t.equal(txn.parentId, data.tx) - t.equal(txn.parentSpanId, txn.trace.root.id) - t.equal(txn.parentType, data.ty) - t.equal(txn.traceId, data.tr) - t.ok(txn.isDistributedTrace) - t.equal(txn.parentTransportDuration, 0) - t.end() - }) - t.end() + assert.equal( + txn.agent.recordSupportability.args[0][0], + 'DistributedTrace/AcceptPayload/Success' + ) + assert.equal(txn.parentId, data.tx) + assert.equal(txn.parentSpanId, txn.trace.root.id) + assert.equal(txn.parentType, data.ty) + assert.equal(txn.traceId, data.tr) + assert.ok(txn.isDistributedTrace) + assert.equal(txn.parentTransportDuration, 0) + }) }) -tap.test('_getParsedPayload', (t) => { - t.autoend() - - let txn = null - let agent = null - let payload = null - - t.beforeEach(() => { - agent = helper.loadMockedAgent({ +test('_getParsedPayload', async (t) => { + t.beforeEach((ctx) => { + ctx.nr = {} + const agent = helper.loadMockedAgent({ distributed_tracing: { enabled: true } }) agent.recordSupportability = sinon.spy() - txn = new Transaction(agent) - payload = JSON.stringify({ + ctx.nr.agent = agent + ctx.nr.txn = new Transaction(agent) + ctx.nr.payload = JSON.stringify({ test: 'payload' }) }) - t.afterEach(() => { - helper.unloadAgent(agent) - agent = null + t.afterEach((ctx) => { + helper.unloadAgent(ctx.nr.agent) + ctx.nr.agent = null }) - t.test('returns parsed JSON object', (t) => { + await t.test('returns parsed JSON object', (t) => { + const { txn, payload } = t.nr const res = txn._getParsedPayload(payload) - t.same(res, { test: 'payload' }) - t.end() + assert.deepEqual(res, { test: 'payload' }) }) - t.test('returns parsed object from base64 string', (t) => { + await t.test('returns parsed object from base64 string', (t) => { + const { txn, payload } = t.nr txn.agent.config.encoding_key = 'test' const res = txn._getParsedPayload(payload.toString('base64')) - t.same(res, { test: 'payload' }) - t.end() + assert.deepEqual(res, { test: 'payload' }) }) - t.test('returns null if string is invalid JSON', (t) => { + await t.test('returns null if string is invalid JSON', (t) => { + const { txn } = t.nr const res = txn._getParsedPayload('{invalid JSON string}') - t.equal(res, null) - t.equal( + assert.equal(res, null) + assert.equal( txn.agent.recordSupportability.args[0][0], 'DistributedTrace/AcceptPayload/ParseException' ) - t.end() }) - t.test('returns null if decoding fails', (t) => { + await t.test('returns null if decoding fails', (t) => { + const { txn, payload } = t.nr txn.agent.config.encoding_key = 'test' - payload = hashes.obfuscateNameUsingKey(payload, 'some other key') + const newPayload = hashes.obfuscateNameUsingKey(payload, 'some other key') - const res = txn._getParsedPayload(payload) - t.equal(res, null) - t.end() + const res = txn._getParsedPayload(newPayload) + assert.equal(res, null) }) }) -tap.test('_createDistributedTracePayload', (t) => { - t.autoend() - - let txn = null - let agent = null - let contextManager = null - - t.beforeEach(() => { - agent = helper.loadMockedAgent({ +test('_createDistributedTracePayload', async (t) => { + t.beforeEach((ctx) => { + ctx.nr = {} + const agent = helper.loadMockedAgent({ distributed_tracing: { enabled: true } }) @@ -1073,104 +1093,104 @@ tap.test('_createDistributedTracePayload', (t) => { agent.config.cross_process_id = null agent.config.trusted_account_ids = null - contextManager = helper.getContextManager() - txn = new Transaction(agent) + ctx.nr.agent = agent + ctx.nr.contextManager = helper.getContextManager() + ctx.nr.txn = new Transaction(ctx.nr.agent) }) - t.afterEach(() => { - helper.unloadAgent(agent) - agent = null + t.afterEach((ctx) => { + helper.unloadAgent(ctx.nr.agent) }) - t.test('should not create payload when DT disabled', (t) => { + await t.test('should not create payload when DT disabled', (t) => { + const { txn } = t.nr txn.agent.config.distributed_tracing.enabled = false const payload = txn._createDistributedTracePayload().text() - t.equal(payload, '') - t.equal(txn.agent.recordSupportability.callCount, 0) - t.notOk(txn.isDistributedTrace) - t.end() + assert.equal(payload, '') + assert.equal(txn.agent.recordSupportability.callCount, 0) + assert.ok(!txn.isDistributedTrace) }) - t.test('should create payload when DT enabled and CAT disabled', (t) => { + await t.test('should create payload when DT enabled and CAT disabled', (t) => { + const { txn } = t.nr txn.agent.config.cross_application_tracer.enabled = false const payload = txn._createDistributedTracePayload().text() - t.not(payload, null) - t.not(payload, '') - t.end() + assert.notEqual(payload, null) + assert.notEqual(payload, '') }) - t.test('does not change existing priority', (t) => { + await t.test('does not change existing priority', (t) => { + const { txn } = t.nr txn.priority = 999 txn.sampled = false txn._createDistributedTracePayload() - t.equal(txn.priority, 999) - t.notOk(txn.sampled) - t.end() + assert.equal(txn.priority, 999) + assert.ok(!txn.sampled) }) - t.test('sets the transaction as sampled if the trace is chosen', (t) => { + await t.test('sets the transaction as sampled if the trace is chosen', (t) => { + const { txn } = t.nr const payload = JSON.parse(txn._createDistributedTracePayload().text()) - t.equal(payload.d.sa, txn.sampled) - t.equal(payload.d.pr, txn.priority) - t.end() + assert.equal(payload.d.sa, txn.sampled) + assert.equal(payload.d.pr, txn.priority) }) - t.test('adds the current span id as the parent span id', (t) => { + await t.test('adds the current span id as the parent span id', (t) => { + const { agent, txn, contextManager } = t.nr agent.config.span_events.enabled = true contextManager.setContext(txn.trace.root) txn.sampled = true const payload = JSON.parse(txn._createDistributedTracePayload().text()) - t.equal(payload.d.id, txn.trace.root.id) + assert.equal(payload.d.id, txn.trace.root.id) contextManager.setContext(null) agent.config.span_events.enabled = false - t.end() }) - t.test('does not add the span id if the transaction is not sampled', (t) => { + await t.test('does not add the span id if the transaction is not sampled', (t) => { + const { agent, txn, contextManager } = t.nr agent.config.span_events.enabled = true txn._calculatePriority() txn.sampled = false contextManager.setContext(txn.trace.root) const payload = JSON.parse(txn._createDistributedTracePayload().text()) - t.equal(payload.d.id, undefined) + assert.equal(payload.d.id, undefined) contextManager.setContext(null) agent.config.span_events.enabled = false - t.end() }) - t.test('returns stringified payload object', (t) => { + await t.test('returns stringified payload object', (t) => { + const { txn } = t.nr const payload = txn._createDistributedTracePayload().text() - t.type(payload, 'string') - t.equal(txn.agent.recordSupportability.args[0][0], 'DistributedTrace/CreatePayload/Success') - t.ok(txn.isDistributedTrace) - t.end() + assert.equal(typeof payload, 'string') + assert.equal( + txn.agent.recordSupportability.args[0][0], + 'DistributedTrace/CreatePayload/Success' + ) + assert.ok(txn.isDistributedTrace) }) }) -tap.test('acceptDistributedTraceHeaders', (t) => { - t.autoend() - - let agent = null - - t.beforeEach(() => { - agent = helper.loadMockedAgent({ +test('acceptDistributedTraceHeaders', async (t) => { + t.beforeEach((ctx) => { + ctx.nr = {} + ctx.nr.agent = helper.loadMockedAgent({ distributed_tracing: { enabled: true }, span_events: { enabled: true } }) - agent.config.trusted_account_key = '1' + ctx.nr.agent.config.trusted_account_key = '1' }) - t.afterEach(() => { - helper.unloadAgent(agent) - agent = null + t.afterEach((ctx) => { + helper.unloadAgent(ctx.nr.agent) }) - t.test('should accept a valid trace context traceparent header', (t) => { + await t.test('should accept a valid trace context traceparent header', (t, end) => { + const { agent } = t.nr const goodParent = '00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00' const headers = { @@ -1183,15 +1203,16 @@ tap.test('acceptDistributedTraceHeaders', (t) => { txn.acceptDistributedTraceHeaders('HTTP', headers) - t.equal(txn.traceId, '4bf92f3577b34da6a3ce929d0e0e4736') - t.equal(txn.parentSpanId, '00f067aa0ba902b7') + assert.equal(txn.traceId, '4bf92f3577b34da6a3ce929d0e0e4736') + assert.equal(txn.parentSpanId, '00f067aa0ba902b7') txn.end() - t.end() + end() }) }) - t.test('should not accept invalid trace context traceparent header', (t) => { + await t.test('should not accept invalid trace context traceparent header', (t, end) => { + const { agent } = t.nr helper.runInTransaction(agent, function (txn) { const childSegment = txn.trace.add('child') childSegment.start() @@ -1211,13 +1232,14 @@ tap.test('acceptDistributedTraceHeaders', (t) => { const secondHeaders = createHeadersAndInsertTrace(txn) - t.equal(secondHeaders.traceparent, origTraceparent) + assert.equal(secondHeaders.traceparent, origTraceparent) txn.end() - t.end() + end() }) }) - t.test('should use newrelic format when no traceparent', (t) => { + await t.test('should use newrelic format when no traceparent', (t, end) => { + const { agent } = t.nr const trustedAccountKey = '123' agent.config.trusted_account_key = trustedAccountKey @@ -1249,20 +1271,21 @@ tap.test('acceptDistributedTraceHeaders', (t) => { txn.acceptDistributedTraceHeaders('HTTP', headers) - t.ok(txn.isDistributedTrace) - t.ok(txn.acceptedDistributedTrace) + assert.ok(txn.isDistributedTrace) + assert.ok(txn.acceptedDistributedTrace) const outboundHeaders = createHeadersAndInsertTrace(txn) const splitData = outboundHeaders.traceparent.split('-') const [, traceId] = splitData - t.equal(traceId, expectedTraceId) + assert.equal(traceId, expectedTraceId) txn.end() - t.end() + end() }) }) - t.test('should not throw error when headers is a string', (t) => { + await t.test('should not throw error when headers is a string', (t, end) => { + const { agent } = t.nr const trustedAccountKey = '123' agent.config.trusted_account_key = trustedAccountKey @@ -1272,19 +1295,20 @@ tap.test('acceptDistributedTraceHeaders', (t) => { const headers = 'JUST A STRING' - t.doesNotThrow(function () { + assert.doesNotThrow(function () { txn.acceptDistributedTraceHeaders('HTTP', headers) }) - t.equal(txn.isDistributedTrace, null) - t.equal(txn.acceptedDistributedTrace, null) + assert.equal(txn.isDistributedTrace, null) + assert.equal(txn.acceptedDistributedTrace, null) txn.end() - t.end() + end() }) }) - t.test('should only accept the first tracecontext', (t) => { + await t.test('should only accept the first tracecontext', (t, end) => { + const { agent } = t.nr const expectedTraceId = 'da8bc8cc6d062849b0efcf3c169afb5a' const expectedParentSpanId = '7d3efb1b173fecfa' const expectedAppId = '2827902' @@ -1306,16 +1330,17 @@ tap.test('acceptDistributedTraceHeaders', (t) => { txn.acceptDistributedTraceHeaders('HTTP', firstTraceContext) txn.acceptDistributedTraceHeaders('HTTP', secondTraceContext) - t.equal(txn.traceId, expectedTraceId) - t.equal(txn.parentSpanId, expectedParentSpanId) - t.equal(txn.parentApp, '2827902') + assert.equal(txn.traceId, expectedTraceId) + assert.equal(txn.parentSpanId, expectedParentSpanId) + assert.equal(txn.parentApp, '2827902') txn.end() - t.end() + end() }) }) - t.test('should not accept tracecontext after sending a trace', (t) => { + await t.test('should not accept tracecontext after sending a trace', (t, end) => { + const { agent } = t.nr const unexpectedTraceId = 'da8bc8cc6d062849b0efcf3c169afb5a' const unexpectedParentSpanId = '7d3efb1b173fecfa' const unexpectedAppId = '2827902' @@ -1334,39 +1359,36 @@ tap.test('acceptDistributedTraceHeaders', (t) => { txn.acceptDistributedTraceHeaders('HTTP', firstTraceContext) - t.not(txn.traceId, unexpectedTraceId) - t.not(txn.parentSpanId, unexpectedParentSpanId) - t.not(txn.parentApp, '2827902') + assert.notEqual(txn.traceId, unexpectedTraceId) + assert.notEqual(txn.parentSpanId, unexpectedParentSpanId) + assert.notEqual(txn.parentApp, '2827902') const traceparentParts = outboundHeaders.traceparent.split('-') const [, expectedTraceId] = traceparentParts - t.equal(txn.traceId, expectedTraceId) + assert.equal(txn.traceId, expectedTraceId) txn.end() - t.end() + end() }) }) }) -tap.test('insertDistributedTraceHeaders', (t) => { - t.autoend() - - let agent = null - let contextManager = null - - t.beforeEach(function () { - agent = helper.loadMockedAgent() - contextManager = helper.getContextManager() +test('insertDistributedTraceHeaders', async (t) => { + t.beforeEach(function (ctx) { + ctx.nr = {} + ctx.nr.agent = helper.loadMockedAgent() + ctx.nr.contextManager = helper.getContextManager() }) - t.afterEach(() => { - helper.unloadAgent(agent) + t.afterEach((ctx) => { + helper.unloadAgent(ctx.nr.agent) }) - t.test( - 'should lowercase traceId for tracecontext when recieved upper from newrelic format', - (t) => { + await t.test( + 'should lowercase traceId for tracecontext when received upper from newrelic format', + (t, end) => { + const { agent } = t.nr const trustedAccountKey = '123' agent.config.account_id = 'AccountId1' @@ -1403,8 +1425,8 @@ tap.test('insertDistributedTraceHeaders', (t) => { txn.acceptDistributedTraceHeaders('HTTP', headers) - t.ok(txn.isDistributedTrace) - t.ok(txn.acceptedDistributedTrace) + assert.ok(txn.isDistributedTrace) + assert.ok(txn.acceptedDistributedTrace) const insertedHeaders = {} txn.insertDistributedTraceHeaders(insertedHeaders) @@ -1412,24 +1434,25 @@ tap.test('insertDistributedTraceHeaders', (t) => { const splitData = insertedHeaders.traceparent.split('-') const [, traceId] = splitData - t.equal(traceId, expectedTraceContextTraceId) + assert.equal(traceId, expectedTraceContextTraceId) const rawPayload = Buffer.from(insertedHeaders.newrelic, 'base64').toString('utf-8') const payload = JSON.parse(rawPayload) // newrelic header should have traceId untouched - t.equal(payload.d.tr, incomingTraceId) + assert.equal(payload.d.tr, incomingTraceId) // traceId used for metrics shoudl go untouched - t.equal(txn.traceId, incomingTraceId) + assert.equal(txn.traceId, incomingTraceId) txn.end() - t.end() + end() }) } ) - t.test('should generate a valid new trace context traceparent header', (t) => { + await t.test('should generate a valid new trace context traceparent header', (t) => { + const { agent, contextManager } = t.nr agent.config.distributed_tracing.enabled = true agent.config.trusted_account_key = '1' agent.config.span_events.enabled = true @@ -1444,19 +1467,18 @@ tap.test('insertDistributedTraceHeaders', (t) => { const lowercaseHexRegex = /^[a-f0-9]+/ - t.equal(traceparentParts.length, 4) - t.equal(traceparentParts[0], '00', 'version matches') - t.equal(traceparentParts[1].length, 32, 'traceId of length 32') - t.equal(traceparentParts[2].length, 16, 'parentId of length 16') - t.equal(traceparentParts[3], '01', 'flags match') - - t.match(traceparentParts[1], lowercaseHexRegex, 'traceId is lowercase hex') - t.match(traceparentParts[2], lowercaseHexRegex, 'parentId is lowercase hex') + assert.equal(traceparentParts.length, 4) + assert.equal(traceparentParts[0], '00', 'version matches') + assert.equal(traceparentParts[1].length, 32, 'traceId of length 32') + assert.equal(traceparentParts[2].length, 16, 'parentId of length 16') + assert.equal(traceparentParts[3], '01', 'flags match') - t.end() + match(traceparentParts[1], lowercaseHexRegex, 'traceId is lowercase hex') + match(traceparentParts[2], lowercaseHexRegex, 'parentId is lowercase hex') }) - t.test('should generate new parentId when spans_events disabled', (t) => { + await t.test('should generate new parentId when spans_events disabled', (t) => { + const { agent, contextManager } = t.nr agent.config.distributed_tracing.enabled = true agent.config.trusted_account_key = '1' agent.config.span_events.enabled = false @@ -1470,13 +1492,13 @@ tap.test('insertDistributedTraceHeaders', (t) => { const traceparent = outboundHeaders.traceparent const traceparentParts = traceparent.split('-') - t.equal(traceparentParts[2].length, 16, 'parentId has length 16') + assert.equal(traceparentParts[2].length, 16, 'parentId has length 16') - t.match(traceparentParts[2], lowercaseHexRegex, 'parentId is lowercase hex') - t.end() + match(traceparentParts[2], lowercaseHexRegex, 'parentId is lowercase hex') }) - t.test('should set traceparent sample part to 01 for sampled transaction', (t) => { + await t.test('should set traceparent sample part to 01 for sampled transaction', (t) => { + const { agent, contextManager } = t.nr agent.config.distributed_tracing.enabled = true agent.config.trusted_account_key = '1' agent.config.span_events.enabled = true @@ -1490,12 +1512,11 @@ tap.test('insertDistributedTraceHeaders', (t) => { const traceparent = outboundHeaders.traceparent const traceparentParts = traceparent.split('-') - t.equal(traceparentParts[3], '01', 'flags match') - - t.end() + assert.equal(traceparentParts[3], '01', 'flags match') }) - t.test('should set traceparent traceid if traceparent exists on transaction', (t) => { + await t.test('should set traceparent traceid if traceparent exists on transaction', (t) => { + const { agent, contextManager } = t.nr agent.config.distributed_tracing.enabled = true agent.config.trusted_account_key = '1' agent.config.span_events.enabled = true @@ -1511,39 +1532,35 @@ tap.test('insertDistributedTraceHeaders', (t) => { const outboundHeaders = createHeadersAndInsertTrace(txn) const traceparentParts = outboundHeaders.traceparent.split('-') - t.equal(traceparentParts[1], '4bf92f3577b34da6a3ce929d0e0e4736', 'traceId matches') - - t.end() + assert.equal(traceparentParts[1], '4bf92f3577b34da6a3ce929d0e0e4736', 'traceId matches') }) - t.test('generates a priority for entry-point transactions', (t) => { + await t.test('generates a priority for entry-point transactions', (t) => { + const { agent } = t.nr const txn = new Transaction(agent) - t.equal(txn.priority, null) - t.equal(txn.sampled, null) + assert.equal(txn.priority, null) + assert.equal(txn.sampled, null) txn.insertDistributedTraceHeaders({}) - t.type(txn.priority, 'number') - t.type(txn.sampled, 'boolean') - t.end() + assert.equal(typeof txn.priority, 'number') + assert.equal(typeof txn.sampled, 'boolean') }) }) -tap.test('acceptTraceContextPayload', (t) => { - t.autoend() - - let agent = null - - t.beforeEach(function () { - agent = helper.loadMockedAgent() +test('acceptTraceContextPayload', async (t) => { + t.beforeEach(function (ctx) { + ctx.nr = {} + ctx.nr.agent = helper.loadMockedAgent() }) - t.afterEach(() => { - helper.unloadAgent(agent) + t.afterEach((ctx) => { + helper.unloadAgent(ctx.nr.agent) }) - t.test('should accept a valid trace context traceparent header', (t) => { + await t.test('should accept a valid trace context traceparent header', (t, end) => { + const { agent } = t.nr agent.config.distributed_tracing.enabled = true agent.config.trusted_account_key = '1' agent.config.span_events.enabled = true @@ -1556,15 +1573,16 @@ tap.test('acceptTraceContextPayload', (t) => { txn.acceptTraceContextPayload(goodParent, 'stuff') - t.equal(txn.traceId, '4bf92f3577b34da6a3ce929d0e0e4736') - t.equal(txn.parentSpanId, '00f067aa0ba902b7') + assert.equal(txn.traceId, '4bf92f3577b34da6a3ce929d0e0e4736') + assert.equal(txn.parentSpanId, '00f067aa0ba902b7') txn.end() - t.end() + end() }) }) - t.test('should not accept invalid trace context traceparent header', (t) => { + await t.test('should not accept invalid trace context traceparent header', (t, end) => { + const { agent } = t.nr agent.config.distributed_tracing.enabled = true agent.config.trusted_account_key = '1' agent.config.span_events.enabled = true @@ -1582,13 +1600,14 @@ tap.test('acceptTraceContextPayload', (t) => { const secondHeaders = createHeadersAndInsertTrace(txn) - t.equal(secondHeaders.traceparent, origTraceparent) + assert.equal(secondHeaders.traceparent, origTraceparent) txn.end() - t.end() + end() }) }) - t.test('should not accept tracestate when trusted_account_key missing', (t) => { + await t.test('should not accept tracestate when trusted_account_key missing', (t, end) => { + const { agent } = t.nr agent.config.trusted_account_key = null agent.config.distributed_tracing.enabled = true agent.config.span_events.enabled = true @@ -1605,21 +1624,22 @@ tap.test('acceptTraceContextPayload', (t) => { txn.acceptTraceContextPayload(incomingTraceparent, incomingNullKeyedTracestate) // traceparent - t.equal(txn.traceId, '4bf92f3577b34da6a3ce929d0e0e4736') - t.equal(txn.parentSpanId, '00f067aa0ba902b7') + assert.equal(txn.traceId, '4bf92f3577b34da6a3ce929d0e0e4736') + assert.equal(txn.parentSpanId, '00f067aa0ba902b7') // tracestate - t.equal(txn.parentType, null) - t.equal(txn.accountId, undefined) - t.equal(txn.parentApp, null) - t.equal(txn.parentId, null) + assert.equal(txn.parentType, null) + assert.equal(txn.accountId, undefined) + assert.equal(txn.parentApp, null) + assert.equal(txn.parentId, null) txn.end() - t.end() + end() }) }) - t.test('should accept tracestate when trusted_account_key matches', (t) => { + await t.test('should accept tracestate when trusted_account_key matches', (t, end) => { + const { agent } = t.nr agent.config.trusted_account_key = '33' agent.config.distributed_tracing.enabled = true agent.config.span_events.enabled = true @@ -1636,52 +1656,48 @@ tap.test('acceptTraceContextPayload', (t) => { txn.acceptTraceContextPayload(incomingTraceparent, incomingNullKeyedTracestate) // traceparent - t.equal(txn.traceId, '4bf92f3577b34da6a3ce929d0e0e4736') - t.equal(txn.parentSpanId, '00f067aa0ba902b7') + assert.equal(txn.traceId, '4bf92f3577b34da6a3ce929d0e0e4736') + assert.equal(txn.parentSpanId, '00f067aa0ba902b7') // tracestate - t.equal(txn.parentType, 'App') - t.equal(txn.parentAcct, '33') - t.equal(txn.parentApp, '2827902') - t.equal(txn.parentId, 'e8b91a159289ff74') + assert.equal(txn.parentType, 'App') + assert.equal(txn.parentAcct, '33') + assert.equal(txn.parentApp, '2827902') + assert.equal(txn.parentId, 'e8b91a159289ff74') txn.end() - t.end() + end() }) }) }) -tap.test('addDistributedTraceIntrinsics', (t) => { - t.autoend() - - let txn = null - let attributes = null - let agent = null - - t.beforeEach(() => { - agent = helper.loadMockedAgent({ +test('addDistributedTraceIntrinsics', async (t) => { + t.beforeEach((ctx) => { + ctx.nr = {} + ctx.nr.agent = helper.loadMockedAgent({ attributes: { enabled: true } }) - attributes = {} - txn = new Transaction(agent) + ctx.nr.attributes = {} + ctx.nr.txn = new Transaction(ctx.nr.agent) }) - t.afterEach(() => { - helper.unloadAgent(agent) + t.afterEach((ctx) => { + helper.unloadAgent(ctx.nr.agent) }) - t.test('does not change existing priority', (t) => { + await t.test('does not change existing priority', (t) => { + const { txn, attributes } = t.nr txn.priority = 999 txn.sampled = false txn.addDistributedTraceIntrinsics(attributes) - t.equal(txn.priority, 999) - t.notOk(txn.sampled) - t.end() + assert.equal(txn.priority, 999) + assert.ok(!txn.sampled) }) - t.test('adds expected attributes if no payload was received', (t) => { + await t.test('adds expected attributes if no payload was received', (t) => { + const { txn, attributes } = t.nr txn.isDistributedTrace = false txn.addDistributedTraceIntrinsics(attributes) @@ -1692,11 +1708,11 @@ tap.test('addDistributedTraceIntrinsics', (t) => { priority: txn.priority, sampled: true } - t.has(attributes, expected) - t.end() + assert.deepEqual(attributes, expected) }) - t.test('adds DT attributes if payload was accepted', (t) => { + await t.test('adds DT attributes if payload was accepted', (t) => { + const { txn, attributes } = t.nr txn.agent.config.account_id = '5678' txn.agent.config.primary_application_id = '1234' txn.agent.config.trusted_account_key = '5678' @@ -1705,7 +1721,6 @@ tap.test('addDistributedTraceIntrinsics', (t) => { const payload = txn._createDistributedTracePayload().text() txn.isDistributedTrace = false txn._acceptDistributedTracePayload(payload, 'AMQP') - txn.addDistributedTraceIntrinsics(attributes) const expected = { @@ -1714,20 +1729,19 @@ tap.test('addDistributedTraceIntrinsics', (t) => { 'parent.account': '5678', 'parent.transportType': 'AMQP' } - t.has(attributes, expected) - t.hasProp(attributes, 'parent.transportDuration') - t.end() + + assert.equal(attributes['parent.type'], expected['parent.type']) + assert.equal(attributes['parent.app'], expected['parent.app']) + assert.equal(attributes['parent.account'], expected['parent.account']) + assert.equal(attributes['parent.transportType'], expected['parent.transportType']) + assert.notEqual(attributes['parent.transportDuration'], null) }) }) -tap.test('transaction end', (t) => { - t.autoend() - - let agent = null - let transaction = null - - t.beforeEach(() => { - agent = helper.loadMockedAgent({ +test('transaction end', async (t) => { + t.beforeEach((ctx) => { + ctx.nr = {} + ctx.nr.agent = helper.loadMockedAgent({ attributes: { enabled: true, include: ['request.parameters.*'] @@ -1737,52 +1751,44 @@ tap.test('transaction end', (t) => { } }) - transaction = new Transaction(agent) + ctx.nr.txn = new Transaction(ctx.nr.agent) }) - t.afterEach(() => { - helper.unloadAgent(agent) - - agent = null - transaction = null + t.afterEach((ctx) => { + helper.unloadAgent(ctx.nr.agent) }) - t.test('should clear errors', (t) => { - transaction.userErrors.push(new Error('user sadness')) - transaction.exceptions.push(new Error('things went bad')) - - transaction.end() + await t.test('should clear errors', (t) => { + const { txn } = t.nr + txn.userErrors.push(new Error('user sadness')) + txn.exceptions.push(new Error('things went bad')) - t.equal(transaction.userErrors, null) - t.equal(transaction.exceptions, null) + txn.end() - t.end() + assert.equal(txn.userErrors, null) + assert.equal(txn.exceptions, null) }) - t.test('should not clear errors until after transactionFinished event', (t) => { - transaction.userErrors.push(new Error('user sadness')) - transaction.exceptions.push(new Error('things went bad')) + await t.test('should not clear errors until after transactionFinished event', (t, end) => { + const { agent, txn } = t.nr + txn.userErrors.push(new Error('user sadness')) + txn.exceptions.push(new Error('things went bad')) agent.on('transactionFinished', (endedTransaction) => { - t.equal(endedTransaction.userErrors.length, 1) - t.equal(endedTransaction.exceptions.length, 1) + assert.equal(endedTransaction.userErrors.length, 1) + assert.equal(endedTransaction.exceptions.length, 1) - t.end() + end() }) - transaction.end() + txn.end() }) }) -tap.test('when being named with finalizeNameFromUri', (t) => { - t.autoend() - - let agent = null - let contextManager = null - let transaction = null - - t.beforeEach(() => { - agent = helper.loadMockedAgent({ +test('when being named with finalizeNameFromUri', async (t) => { + t.beforeEach((ctx) => { + ctx.nr = {} + ctx.nr.agent = helper.loadMockedAgent({ attributes: { enabled: true, include: ['request.parameters.*'] @@ -1791,152 +1797,133 @@ tap.test('when being named with finalizeNameFromUri', (t) => { enabled: true } }) - contextManager = helper.getContextManager() - - transaction = new Transaction(agent) + ctx.nr.contextManager = helper.getContextManager() + ctx.nr.txn = new Transaction(ctx.nr.agent) }) - t.afterEach(() => { - helper.unloadAgent(agent) - - agent = null - transaction = null + t.afterEach((ctx) => { + helper.unloadAgent(ctx.nr.agent) }) - t.test('should throw when called with no parameters', (t) => { - t.throws(() => transaction.finalizeNameFromUri()) - - t.end() + await t.test('should throw when called with no parameters', (t) => { + const { txn } = t.nr + assert.throws(() => txn.finalizeNameFromUri()) }) - t.test('should ignore a request path when told to by a rule', (t) => { + await t.test('should ignore a request path when told to by a rule', (t) => { + const { agent, txn } = t.nr const api = new API(agent) api.addIgnoringRule('^/test/') - transaction.finalizeNameFromUri('/test/string?do=thing&another=thing', 200) + txn.finalizeNameFromUri('/test/string?do=thing&another=thing', 200) - t.equal(transaction.isIgnored(), true) - - t.end() + assert.equal(txn.isIgnored(), true) }) - t.test('should ignore a transaction when told to by a rule', (t) => { + await t.test('should ignore a transaction when told to by a rule', (t) => { + const { agent, txn } = t.nr agent.transactionNameNormalizer.addSimple('^WebTransaction/NormalizedUri') - transaction.finalizeNameFromUri('/test/string?do=thing&another=thing', 200) - - t.equal(transaction.isIgnored(), true) + txn.finalizeNameFromUri('/test/string?do=thing&another=thing', 200) - t.end() + assert.equal(txn.isIgnored(), true) }) - t.test('should pass through a name when told to by a rule', (t) => { + await t.test('should pass through a name when told to by a rule', (t) => { + const { agent, txn } = t.nr agent.userNormalizer.addSimple('^/config', '/foobar') - transaction.finalizeNameFromUri('/config', 200) - - t.equal(transaction.name, 'WebTransaction/NormalizedUri/foobar') + txn.finalizeNameFromUri('/config', 200) - t.end() + assert.equal(txn.name, 'WebTransaction/NormalizedUri/foobar') }) - t.test('should add finalized via rule transaction name to active span intrinsics', (t) => { + await t.test('should add finalized via rule transaction name to active span intrinsics', (t) => { + const { agent, txn, contextManager } = t.nr agent.userNormalizer.addSimple('^/config', '/foobar') - addSegmentInContext(contextManager, transaction, 'test segment') + addSegmentInContext(contextManager, txn, 'test segment') - transaction.finalizeNameFromUri('/config', 200) + txn.finalizeNameFromUri('/config', 200) const spanContext = agent.tracer.getSpanContext() const intrinsics = spanContext.intrinsicAttributes - t.ok(intrinsics) - t.equal(intrinsics['transaction.name'], 'WebTransaction/NormalizedUri/foobar') - - t.end() + assert.ok(intrinsics) + assert.equal(intrinsics['transaction.name'], 'WebTransaction/NormalizedUri/foobar') }) - t.test('when namestate populated should use name stack', (t) => { - setupNameState(transaction) - - transaction.finalizeNameFromUri('/some/random/path', 200) + await t.test('when namestate populated should use name stack', (t) => { + const { txn } = t.nr + setupNameState(txn) - t.equal(transaction.name, 'WebTransaction/Restify/COOL//foo/:foo/bar/:bar') + txn.finalizeNameFromUri('/some/random/path', 200) - t.end() + assert.equal(txn.name, 'WebTransaction/Restify/COOL//foo/:foo/bar/:bar') }) - t.test('when namestate populated should copy parameters from the name stack', (t) => { - setupNameState(transaction) + await t.test('when namestate populated should copy parameters from the name stack', (t) => { + const { txn } = t.nr + setupNameState(txn) - transaction.finalizeNameFromUri('/some/random/path', 200) + txn.finalizeNameFromUri('/some/random/path', 200) - const attrs = transaction.trace.attributes.get(AttributeFilter.DESTINATIONS.TRANS_TRACE) + const attrs = txn.trace.attributes.get(AttributeFilter.DESTINATIONS.TRANS_TRACE) - t.match(attrs, { + match(attrs, { 'request.parameters.foo': 'biz', 'request.parameters.bar': 'bang' }) - - t.end() }) - t.test( + await t.test( 'when namestate populated, ' + 'should add finalized via rule transaction name to active span intrinsics', (t) => { - setupNameState(transaction) - addSegmentInContext(contextManager, transaction, 'test segment') + const { agent, txn, contextManager } = t.nr + setupNameState(txn) + addSegmentInContext(contextManager, txn, 'test segment') - transaction.finalizeNameFromUri('/some/random/path', 200) + txn.finalizeNameFromUri('/some/random/path', 200) const spanContext = agent.tracer.getSpanContext() const intrinsics = spanContext.intrinsicAttributes - t.ok(intrinsics) - t.equal(intrinsics['transaction.name'], 'WebTransaction/Restify/COOL//foo/:foo/bar/:bar') - - t.end() + assert.ok(intrinsics) + assert.equal(intrinsics['transaction.name'], 'WebTransaction/Restify/COOL//foo/:foo/bar/:bar') } ) - t.test('when namestate populated and high_security enabled, should use name stack', (t) => { - setupNameState(transaction) + await t.test('when namestate populated and high_security enabled, should use name stack', (t) => { + const { agent, txn } = t.nr + setupNameState(txn) setupHighSecurity(agent) - transaction.finalizeNameFromUri('/some/random/path', 200) - - t.equal(transaction.name, 'WebTransaction/Restify/COOL//foo/:foo/bar/:bar') + txn.finalizeNameFromUri('/some/random/path', 200) - t.end() + assert.equal(txn.name, 'WebTransaction/Restify/COOL//foo/:foo/bar/:bar') }) - t.test( + await t.test( 'when namestate populated and high_security enabled, ' + 'should not copy parameters from the name stack', (t) => { - setupNameState(transaction) + const { agent, txn } = t.nr + setupNameState(txn) setupHighSecurity(agent) - transaction.finalizeNameFromUri('/some/random/path', 200) - - const attrs = transaction.trace.attributes.get(AttributeFilter.DESTINATIONS.TRANS_TRACE) - t.same(attrs, {}) + txn.finalizeNameFromUri('/some/random/path', 200) - t.end() + const attrs = txn.trace.attributes.get(AttributeFilter.DESTINATIONS.TRANS_TRACE) + assert.deepEqual(attrs, {}) } ) }) -tap.test('requestd', (t) => { - t.autoend() - - let agent = null - let contextManager = null - let transaction = null - - t.beforeEach(() => { - agent = helper.loadMockedAgent({ +test('requestd', async (t) => { + t.beforeEach((ctx) => { + ctx.nr = {} + ctx.nr.agent = helper.loadMockedAgent({ span_events: { enabled: true, attributes: { @@ -1948,45 +1935,35 @@ tap.test('requestd', (t) => { } }) - contextManager = helper.getContextManager() - - transaction = new Transaction(agent) + ctx.nr.contextManager = helper.getContextManager() + ctx.nr.txn = new Transaction(ctx.nr.agent) }) - t.afterEach(() => { - helper.unloadAgent(agent) - - agent = null - transaction = null + t.afterEach((ctx) => { + helper.unloadAgent(ctx.nr.agent) }) - t.test('when namestate populated should copy parameters from the name stack', (t) => { - setupNameState(transaction) + await t.test('when namestate populated should copy parameters from the name stack', (t) => { + const { txn, contextManager } = t.nr + setupNameState(txn) - addSegmentInContext(contextManager, transaction, 'test segment') + addSegmentInContext(contextManager, txn, 'test segment') - transaction.finalizeNameFromUri('/some/random/path', 200) + txn.finalizeNameFromUri('/some/random/path', 200) const segment = contextManager.getContext() - t.match(segment.attributes.get(AttributeFilter.DESTINATIONS.SPAN_EVENT), { + match(segment.attributes.get(AttributeFilter.DESTINATIONS.SPAN_EVENT), { 'request.parameters.foo': 'biz', 'request.parameters.bar': 'bang' }) - - t.end() }) }) -tap.test('when being named with finalizeName', (t) => { - t.autoend() - - let agent = null - let contextManager = null - let transaction = null - - t.beforeEach(() => { - agent = helper.loadMockedAgent({ +test('when being named with finalizeName', async (t) => { + t.beforeEach((ctx) => { + ctx.nr = {} + ctx.nr.agent = helper.loadMockedAgent({ attributes: { enabled: true, include: ['request.parameters.*'] @@ -1996,64 +1973,57 @@ tap.test('when being named with finalizeName', (t) => { } }) - contextManager = helper.getContextManager() - transaction = new Transaction(agent) + ctx.nr.contextManager = helper.getContextManager() + ctx.nr.txn = new Transaction(ctx.nr.agent) }) - t.afterEach(() => { - helper.unloadAgent(agent) - - agent = null - transaction = null + t.afterEach((ctx) => { + helper.unloadAgent(ctx.nr.agent) }) - t.test('should call finalizeNameFromUri if no name is given for a web txn', (t) => { + await t.test('should call finalizeNameFromUri if no name is given for a web txn', (t) => { + const { txn } = t.nr let called = false - transaction.finalizeNameFromUri = () => { + txn.finalizeNameFromUri = () => { called = true } - transaction.type = 'web' - transaction.url = '/foo/bar' - transaction.finalizeName() - - t.ok(called) + txn.type = 'web' + txn.url = '/foo/bar' + txn.finalizeName() - t.end() + assert.ok(called) }) - t.test('should apply ignore rules', (t) => { + await t.test('should apply ignore rules', (t) => { + const { agent, txn } = t.nr agent.transactionNameNormalizer.addSimple('foo') // Ignore foo - transaction.finalizeName('foo') + txn.finalizeName('foo') - t.equal(transaction.isIgnored(), true) - - t.end() + assert.equal(txn.isIgnored(), true) }) - t.test('should not apply user naming rules', (t) => { + await t.test('should not apply user naming rules', (t) => { + const { agent, txn } = t.nr agent.userNormalizer.addSimple('^/config', '/foobar') - transaction.finalizeName('/config') - - t.equal(transaction.getFullName(), 'WebTransaction//config') + txn.finalizeName('/config') - t.end() + assert.equal(txn.getFullName(), 'WebTransaction//config') }) - t.test('should add finalized transaction name to active span intrinsics', (t) => { - addSegmentInContext(contextManager, transaction, 'test segment') + await t.test('should add finalized transaction name to active span intrinsics', (t) => { + const { agent, txn, contextManager } = t.nr + addSegmentInContext(contextManager, txn, 'test segment') - transaction.finalizeName('/config') + txn.finalizeName('/config') const spanContext = agent.tracer.getSpanContext() const intrinsics = spanContext.intrinsicAttributes - t.ok(intrinsics) - t.equal(intrinsics['transaction.name'], 'WebTransaction//config') - - t.end() + assert.ok(intrinsics) + assert.equal(intrinsics['transaction.name'], 'WebTransaction//config') }) }) diff --git a/test/unit/urltils.test.js b/test/unit/urltils.test.js index f4376a0378..915fd50447 100644 --- a/test/unit/urltils.test.js +++ b/test/unit/urltils.test.js @@ -4,322 +4,283 @@ */ 'use strict' -const tap = require('tap') +const test = require('node:test') +const assert = require('node:assert') const sinon = require('sinon') const proxyquire = require('proxyquire') const url = require('url') -tap.test('NR URL utilities', function (t) { - t.autoend() - t.beforeEach(function () { +test('NR URL utilities', async function (t) { + t.beforeEach(function (ctx) { + ctx.nr = {} const loggerStub = { warn: sinon.stub() } - t.context.urltils = proxyquire('../../lib/util/urltils', { + ctx.nr.urltils = proxyquire('../../lib/util/urltils', { '../logger': { child: sinon.stub().returns(loggerStub) } }) - t.context.loggerStub = loggerStub + ctx.nr.loggerStub = loggerStub }) - t.test('scrubbing URLs should return "/" if there\'s no leading slash on the path', function (t) { - const { urltils } = t.context - t.equal(urltils.scrub('?t_u=http://some.com/o/p'), '/') - t.end() - }) + await t.test( + 'scrubbing URLs should return "/" if there\'s no leading slash on the path', + function (t) { + const { urltils } = t.nr + assert.equal(urltils.scrub('?t_u=http://some.com/o/p'), '/') + } + ) - t.test('parsing parameters', function (t) { - t.autoend() - t.test('should find empty object of params in url lacking query', function (t) { - const { urltils } = t.context - t.same(urltils.parseParameters('/favicon.ico'), {}) - t.end() + await t.test('parsing parameters', async function (t) { + await t.test('should find empty object of params in url lacking query', function (t) { + const { urltils } = t.nr + assert.deepEqual(urltils.parseParameters('/favicon.ico'), {}) }) - t.test('should find v param in url containing ?v with no value', function (t) { - const { urltils } = t.context - t.same(urltils.parseParameters('/status?v'), { v: true }) - t.end() + await t.test('should find v param in url containing ?v with no value', function (t) { + const { urltils } = t.nr + assert.deepEqual(urltils.parseParameters('/status?v'), { v: true }) }) - t.test('should find v param with value in url containing ?v=1', function (t) { - const { urltils } = t.context - t.same(urltils.parseParameters('/status?v=1'), { v: '1' }) - t.end() + await t.test('should find v param with value in url containing ?v=1', function (t) { + const { urltils } = t.nr + assert.deepEqual(urltils.parseParameters('/status?v=1'), { v: '1' }) }) - t.test('should find v param when passing in an object', function (t) { - const { urltils } = t.context - t.same(urltils.parseParameters(url.parse('/status?v=1', true)), { v: '1' }) - t.end() + await t.test('should find v param when passing in an object', function (t) { + const { urltils } = t.nr + assert.deepEqual(urltils.parseParameters(url.parse('/status?v=1', true)), { v: '1' }) }) }) - t.test('determining whether an HTTP status code is an error', function (t) { - t.autoend() + await t.test('determining whether an HTTP status code is an error', async function (t) { let config = { error_collector: { ignore_status_codes: [] } } - t.test('should not throw when called with no params', function (t) { - const { urltils } = t.context - t.doesNotThrow(function () { + await t.test('should not throw when called with no params', function (t) { + const { urltils } = t.nr + assert.doesNotThrow(function () { urltils.isError() }) - t.end() }) - t.test('should not throw when called with no code', function (t) { - const { urltils } = t.context - t.doesNotThrow(function () { + await t.test('should not throw when called with no code', function (t) { + const { urltils } = t.nr + assert.doesNotThrow(function () { urltils.isError(config) }) - t.end() }) - t.test('should not throw when config is missing', function (t) { - const { urltils } = t.context - t.doesNotThrow(function () { + await t.test('should not throw when config is missing', function (t) { + const { urltils } = t.nr + assert.doesNotThrow(function () { urltils.isError(null, 200) }) - t.end() }) - t.test('should NOT mark an OK request as an error', function (t) { - const { urltils } = t.context - t.equal(urltils.isError(config, 200), false) - t.end() + await t.test('should NOT mark an OK request as an error', function (t) { + const { urltils } = t.nr + assert.equal(urltils.isError(config, 200), false) }) - t.test('should NOT mark a permanent redirect as an error', function (t) { - const { urltils } = t.context - t.equal(urltils.isError(config, 301), false) - t.end() + await t.test('should NOT mark a permanent redirect as an error', function (t) { + const { urltils } = t.nr + assert.equal(urltils.isError(config, 301), false) }) - t.test('should NOT mark a temporary redirect as an error', function (t) { - const { urltils } = t.context - t.equal(urltils.isError(config, 303), false) - t.end() + await t.test('should NOT mark a temporary redirect as an error', function (t) { + const { urltils } = t.nr + assert.equal(urltils.isError(config, 303), false) }) - t.test('should mark a bad request as an error', function (t) { - const { urltils } = t.context - t.equal(urltils.isError(config, 400), true) - t.end() + await t.test('should mark a bad request as an error', function (t) { + const { urltils } = t.nr + assert.equal(urltils.isError(config, 400), true) }) - t.test('should mark an unauthorized request as an error', function (t) { - const { urltils } = t.context - t.equal(urltils.isError(config, 401), true) - t.end() + await t.test('should mark an unauthorized request as an error', function (t) { + const { urltils } = t.nr + assert.equal(urltils.isError(config, 401), true) }) - t.test('should mark a "payment required" request as an error', function (t) { - const { urltils } = t.context - t.equal(urltils.isError(config, 402), true) - t.end() + await t.test('should mark a "payment required" request as an error', function (t) { + const { urltils } = t.nr + assert.equal(urltils.isError(config, 402), true) }) - t.test('should mark a forbidden request as an error', function (t) { - const { urltils } = t.context - t.equal(urltils.isError(config, 403), true) - t.end() + await t.test('should mark a forbidden request as an error', function (t) { + const { urltils } = t.nr + assert.equal(urltils.isError(config, 403), true) }) - t.test('should mark a not found request as an error', function (t) { - const { urltils } = t.context - t.equal(urltils.isError(config, 404), true) - t.end() + await t.test('should mark a not found request as an error', function (t) { + const { urltils } = t.nr + assert.equal(urltils.isError(config, 404), true) }) - t.test('should mark a request with too long a URI as an error', function (t) { - const { urltils } = t.context - t.equal(urltils.isError(config, 414), true) - t.end() + await t.test('should mark a request with too long a URI as an error', function (t) { + const { urltils } = t.nr + assert.equal(urltils.isError(config, 414), true) }) - t.test('should mark a method not allowed request as an error', function (t) { - const { urltils } = t.context - t.equal(urltils.isError(config, 405), true) - t.end() + await t.test('should mark a method not allowed request as an error', function (t) { + const { urltils } = t.nr + assert.equal(urltils.isError(config, 405), true) }) - t.test('should mark a request with unacceptable types as an error', function (t) { - const { urltils } = t.context - t.equal(urltils.isError(config, 406), true) - t.end() + await t.test('should mark a request with unacceptable types as an error', function (t) { + const { urltils } = t.nr + assert.equal(urltils.isError(config, 406), true) }) - t.test('should mark a request requiring proxy auth as an error', function (t) { - const { urltils } = t.context - t.equal(urltils.isError(config, 407), true) - t.end() + await t.test('should mark a request requiring proxy auth as an error', function (t) { + const { urltils } = t.nr + assert.equal(urltils.isError(config, 407), true) }) - t.test('should mark a timed out request as an error', function (t) { - const { urltils } = t.context - t.equal(urltils.isError(config, 408), true) - t.end() + await t.test('should mark a timed out request as an error', function (t) { + const { urltils } = t.nr + assert.equal(urltils.isError(config, 408), true) }) - t.test('should mark a conflicted request as an error', function (t) { - const { urltils } = t.context - t.equal(urltils.isError(config, 409), true) - t.end() + await t.test('should mark a conflicted request as an error', function (t) { + const { urltils } = t.nr + assert.equal(urltils.isError(config, 409), true) }) - t.test('should mark a request for a disappeared resource as an error', function (t) { - const { urltils } = t.context - t.equal(urltils.isError(config, 410), true) - t.end() + await t.test('should mark a request for a disappeared resource as an error', function (t) { + const { urltils } = t.nr + assert.equal(urltils.isError(config, 410), true) }) - t.test('should mark a request with a missing length as an error', function (t) { - const { urltils } = t.context - t.equal(urltils.isError(config, 411), true) - t.end() + await t.test('should mark a request with a missing length as an error', function (t) { + const { urltils } = t.nr + assert.equal(urltils.isError(config, 411), true) }) - t.test('should mark a request with a failed precondition as an error', function (t) { - const { urltils } = t.context - t.equal(urltils.isError(config, 412), true) - t.end() + await t.test('should mark a request with a failed precondition as an error', function (t) { + const { urltils } = t.nr + assert.equal(urltils.isError(config, 412), true) }) - t.test('should mark a too-large request as an error', function (t) { - const { urltils } = t.context - t.equal(urltils.isError(config, 413), true) - t.end() + await t.test('should mark a too-large request as an error', function (t) { + const { urltils } = t.nr + assert.equal(urltils.isError(config, 413), true) }) - t.test('should mark a request for an unsupported media type as an error', function (t) { - const { urltils } = t.context - t.equal(urltils.isError(config, 415), true) - t.end() + await t.test('should mark a request for an unsupported media type as an error', function (t) { + const { urltils } = t.nr + assert.equal(urltils.isError(config, 415), true) }) - t.test('should mark a request for an unsatisfiable range as an error', function (t) { - const { urltils } = t.context - t.equal(urltils.isError(config, 416), true) - t.end() + await t.test('should mark a request for an unsatisfiable range as an error', function (t) { + const { urltils } = t.nr + assert.equal(urltils.isError(config, 416), true) }) - t.test('should mark a request with a failed expectation as an error', function (t) { - const { urltils } = t.context - t.equal(urltils.isError(config, 417), true) - t.end() + await t.test('should mark a request with a failed expectation as an error', function (t) { + const { urltils } = t.nr + assert.equal(urltils.isError(config, 417), true) }) - t.test('should mark a request asserting teapotness as an error', function (t) { - const { urltils } = t.context - t.equal(urltils.isError(config, 418), true) - t.end() + await t.test('should mark a request asserting teapotness as an error', function (t) { + const { urltils } = t.nr + assert.equal(urltils.isError(config, 418), true) }) - t.test('should mark a request with timed-out auth as an error', function (t) { - const { urltils } = t.context - t.equal(urltils.isError(config, 419), true) - t.end() + await t.test('should mark a request with timed-out auth as an error', function (t) { + const { urltils } = t.nr + assert.equal(urltils.isError(config, 419), true) }) - t.test('should mark a request for enhanced calm (brah) as an error', function (t) { - const { urltils } = t.context - t.equal(urltils.isError(config, 420), true) - t.end() + await t.test('should mark a request for enhanced calm (brah) as an error', function (t) { + const { urltils } = t.nr + assert.equal(urltils.isError(config, 420), true) }) - t.test('should work with strings', function (t) { - const { urltils } = t.context + await t.test('should work with strings', function (t) { + const { urltils } = t.nr config = { error_collector: { ignore_status_codes: [403] } } - t.equal(urltils.isError(config, '200'), false) - t.equal(urltils.isError(config, '403'), false) - t.equal(urltils.isError(config, '404'), true) - t.end() + assert.equal(urltils.isError(config, '200'), false) + assert.equal(urltils.isError(config, '403'), false) + assert.equal(urltils.isError(config, '404'), true) }) }) - t.test('isIgnoredError', function (t) { - t.autoend() + await t.test('isIgnoredError', async function (t) { const config = { error_collector: { ignore_status_codes: [] } } - t.test('returns true if the status code is an HTTP error in the ignored list', (t) => { - const { urltils } = t.context + await t.test('returns true if the status code is an HTTP error in the ignored list', (t) => { + const { urltils } = t.nr const errorCodes = [ 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 500, 503 ] errorCodes.forEach((code) => { - t.equal(urltils.isIgnoredError(config, code), false) + assert.equal(urltils.isIgnoredError(config, code), false) config.error_collector.ignore_status_codes = [code] - t.equal(urltils.isIgnoredError(config, code), true) + assert.equal(urltils.isIgnoredError(config, code), true) }) - t.end() }) - t.test('returns false if the status code is NOT an HTTP error', function (t) { - const { urltils } = t.context + await t.test('returns false if the status code is NOT an HTTP error', function (t) { + const { urltils } = t.nr const statusCodes = [200] statusCodes.forEach((code) => { - t.equal(urltils.isIgnoredError(config, code), false) + assert.equal(urltils.isIgnoredError(config, code), false) config.error_collector.ignore_status_codes = [code] - t.equal(urltils.isIgnoredError(config, code), false) + assert.equal(urltils.isIgnoredError(config, code), false) }) - t.end() }) }) - t.test('copying parameters from a query hash', function (t) { - t.autoend() - t.beforeEach(function (t) { - t.context.source = {} - t.context.dest = {} + await t.test('copying parameters from a query hash', async function (t) { + t.beforeEach(function (ctx) { + ctx.nr.source = {} + ctx.nr.dest = {} }) - t.test("shouldn't not throw on missing configuration", function (t) { - const { urltils, source, dest } = t.context - t.doesNotThrow(function () { + await t.test("shouldn't not throw on missing configuration", function (t) { + const { urltils, source, dest } = t.nr + assert.doesNotThrow(function () { urltils.copyParameters(null, source, dest) }) - t.end() }) - t.test('should not throw on missing source', function (t) { - const { urltils, dest } = t.context - t.doesNotThrow(function () { + await t.test('should not throw on missing source', function (t) { + const { urltils, dest } = t.nr + assert.doesNotThrow(function () { urltils.copyParameters(null, dest) }) - t.end() }) - t.test('should not throw on missing destination', function (t) { - const { urltils, source } = t.context - t.doesNotThrow(function () { + await t.test('should not throw on missing destination', function (t) { + const { urltils, source } = t.nr + assert.doesNotThrow(function () { urltils.copyParameters(source, null) }) - t.end() }) - t.test('should copy parameters from source to destination', function (t) { - const { urltils, source, dest } = t.context + await t.test('should copy parameters from source to destination', function (t) { + const { urltils, source, dest } = t.nr dest.existing = 'here' source.firstNew = 'present' source.secondNew = 'accounted for' - t.doesNotThrow(function () { + assert.doesNotThrow(function () { urltils.copyParameters(source, dest) }) - t.same(dest, { + assert.deepEqual(dest, { existing: 'here', firstNew: 'present', secondNew: 'accounted for' }) - t.end() }) - t.test('should not overwrite existing parameters in destination', function (t) { - const { urltils, source, dest } = t.context + await t.test('should not overwrite existing parameters in destination', function (t) { + const { urltils, source, dest } = t.nr dest.existing = 'here' dest.firstNew = 'already around' source.firstNew = 'present' @@ -327,49 +288,45 @@ tap.test('NR URL utilities', function (t) { urltils.copyParameters(source, dest) - t.same(dest, { + assert.deepEqual(dest, { existing: 'here', firstNew: 'already around', secondNew: 'accounted for' }) - t.end() }) - t.test('should not overwrite null parameters in destination', function (t) { - const { urltils, source, dest } = t.context + await t.test('should not overwrite null parameters in destination', function (t) { + const { urltils, source, dest } = t.nr dest.existing = 'here' dest.firstNew = null source.firstNew = 'present' urltils.copyParameters(source, dest) - t.same(dest, { + assert.deepEqual(dest, { existing: 'here', firstNew: null }) - t.end() }) - t.test('should not overwrite undefined parameters in destination', function (t) { - const { urltils, source, dest } = t.context + await t.test('should not overwrite undefined parameters in destination', function (t) { + const { urltils, source, dest } = t.nr dest.existing = 'here' dest.firstNew = undefined source.firstNew = 'present' urltils.copyParameters(source, dest) - t.same(dest, { + assert.deepEqual(dest, { existing: 'here', firstNew: undefined }) - t.end() }) }) - t.test('obfuscates path by regex', function (t) { - t.autoend() - t.beforeEach((t) => { - t.context.config = { + await t.test('obfuscates path by regex', async function (t) { + t.beforeEach((ctx) => { + ctx.nr.config = { url_obfuscation: { enabled: false, regex: { @@ -379,83 +336,84 @@ tap.test('NR URL utilities', function (t) { } } } - t.context.path = '/foo/123/bar/456/baz/789' + ctx.nr.path = '/foo/123/bar/456/baz/789' }) - t.test('should not obfuscate path by default', function (t) { - const { urltils, config, path } = t.context - t.equal(urltils.obfuscatePath(config, path), path) - t.end() + await t.test('should not obfuscate path by default', function (t) { + const { urltils, config, path } = t.nr + assert.equal(urltils.obfuscatePath(config, path), path) }) - t.test('should not obfuscate if obfuscation is enabled but pattern is not set', function (t) { - const { urltils, config, path } = t.context - config.url_obfuscation.enabled = true - t.equal(urltils.obfuscatePath(config, path), path) - t.end() - }) + await t.test( + 'should not obfuscate if obfuscation is enabled but pattern is not set', + function (t) { + const { urltils, config, path } = t.nr + config.url_obfuscation.enabled = true + assert.equal(urltils.obfuscatePath(config, path), path) + } + ) - t.test('should not obfuscate if obfuscation is enabled but pattern is invalid', function (t) { - const { urltils, config, path } = t.context - config.url_obfuscation.enabled = true - config.url_obfuscation.regex.pattern = '/foo/bar/baz/[0-9]+' - t.equal(urltils.obfuscatePath(config, path), path) - t.end() - }) + await t.test( + 'should not obfuscate if obfuscation is enabled but pattern is invalid', + function (t) { + const { urltils, config, path } = t.nr + config.url_obfuscation.enabled = true + config.url_obfuscation.regex.pattern = '/foo/bar/baz/[0-9]+' + assert.equal(urltils.obfuscatePath(config, path), path) + } + ) - t.test( + await t.test( 'should obfuscate with empty string `` if replacement is not set and pattern is set', function (t) { - const { urltils, config, path } = t.context + const { urltils, config, path } = t.nr config.url_obfuscation.enabled = true config.url_obfuscation.regex.pattern = '/foo/[0-9]+/bar/[0-9]+/baz/[0-9]+' - t.equal(urltils.obfuscatePath(config, path), '') - t.end() + assert.equal(urltils.obfuscatePath(config, path), '') } ) - t.test( + await t.test( 'should obfuscate with replacement if replacement is set and pattern is set', function (t) { - const { urltils, config, path } = t.context + const { urltils, config, path } = t.nr config.url_obfuscation.enabled = true config.url_obfuscation.regex.pattern = '/foo/[0-9]+/bar/[0-9]+/baz/[0-9]+' config.url_obfuscation.regex.replacement = '/***' - t.equal(urltils.obfuscatePath(config, path), '/***') - t.end() + assert.equal(urltils.obfuscatePath(config, path), '/***') } ) - t.test('should obfuscate as expected with capture groups pattern over strings', function (t) { - const { urltils, config, path } = t.context - config.url_obfuscation.enabled = true - config.url_obfuscation.regex.pattern = '(/foo/)(.*)(/bar/)(.*)(/baz/)(.*)' - config.url_obfuscation.regex.replacement = '$1***$3***$5***' - t.equal(urltils.obfuscatePath(config, path), '/foo/***/bar/***/baz/***') - t.end() - }) + await t.test( + 'should obfuscate as expected with capture groups pattern over strings', + function (t) { + const { urltils, config, path } = t.nr + config.url_obfuscation.enabled = true + config.url_obfuscation.regex.pattern = '(/foo/)(.*)(/bar/)(.*)(/baz/)(.*)' + config.url_obfuscation.regex.replacement = '$1***$3***$5***' + assert.equal(urltils.obfuscatePath(config, path), '/foo/***/bar/***/baz/***') + } + ) - t.test('should obfuscate as expected with regex patterns and flags', function (t) { - const { urltils, config, path } = t.context + await t.test('should obfuscate as expected with regex patterns and flags', function (t) { + const { urltils, config, path } = t.nr config.url_obfuscation.enabled = true config.url_obfuscation.regex.pattern = '[0-9]+' config.url_obfuscation.regex.flags = 'g' config.url_obfuscation.regex.replacement = '***' - t.equal(urltils.obfuscatePath(config, path), '/foo/***/bar/***/baz/***') - t.end() + assert.equal(urltils.obfuscatePath(config, path), '/foo/***/bar/***/baz/***') }) - t.test( + await t.test( 'should call logger warn if obfuscation is enabled but pattern is invalid', function (t) { - const { urltils, config, path } = t.context + const { urltils, config, path } = t.nr config.url_obfuscation.enabled = true config.url_obfuscation.regex.pattern = '[0-9+' urltils.obfuscatePath(config, path) - t.equal(t.context.loggerStub.warn.calledOnce, true) - t.end() + assert.equal(t.nr.loggerStub.warn.calledOnce, true) } ) })