From 86231b7dec5bc5807ae26a88a7b8f2ff1535d9c4 Mon Sep 17 00:00:00 2001 From: Bob Evans Date: Wed, 2 Oct 2024 09:15:48 -0400 Subject: [PATCH] test: Migrated unit tests to `node:test` (#2623) --- test/unit/rum.test.js | 170 +++++---- test/unit/sampler.test.js | 188 +++++----- test/unit/shimmer.test.js | 639 ++++++++++++++++------------------ test/unit/stats.test.js | 113 +++--- test/unit/synthetics.test.js | 117 +++---- test/unit/system-info.test.js | 236 ++++++------- 6 files changed, 679 insertions(+), 784 deletions(-) diff --git a/test/unit/rum.test.js b/test/unit/rum.test.js index d45f84fd6d..5816fcba76 100644 --- a/test/unit/rum.test.js +++ b/test/unit/rum.test.js @@ -4,15 +4,16 @@ */ 'use strict' -const tap = require('tap') +const assert = require('node:assert') +const test = require('node:test') const helper = require('../lib/agent_helper') const API = require('../../api') const hashes = require('../../lib/util/hashes') -tap.test('the RUM API', function (t) { - t.autoend() - t.beforeEach(function (t) { +test('the RUM API', async function (t) { + t.beforeEach(function (ctx) { + ctx.nr = {} const agent = helper.loadMockedAgent({ license_key: 'license key here', browser_monitoring: { @@ -27,213 +28,208 @@ tap.test('the RUM API', function (t) { agent.config.application_id = 12345 agent.config.browser_monitoring.browser_key = 1234 agent.config.browser_monitoring.js_agent_loader = 'function() {}' - t.context.api = new API(agent) - t.context.agent = agent + ctx.nr.api = new API(agent) + ctx.nr.agent = agent }) - t.afterEach(function (t) { - helper.unloadAgent(t.context.agent) + t.afterEach(function (ctx) { + helper.unloadAgent(ctx.nr.agent) }) - t.test('should not generate header when disabled', function (t) { - const { agent, api } = t.context + await t.test('should not generate header when disabled', function (t) { + const { agent, api } = t.nr agent.config.browser_monitoring.enable = false - t.equal(api.getBrowserTimingHeader(), '') - t.end() + assert.equal(api.getBrowserTimingHeader(), '') }) - t.test('should issue a warning outside a transaction by default', function (t) { - const { api } = t.context - t.equal(api.getBrowserTimingHeader(), '') - t.end() + await t.test('should issue a warning outside a transaction by default', function (t) { + const { api } = t.nr + assert.equal(api.getBrowserTimingHeader(), '') }) - t.test( + await t.test( 'should issue a warning outside a transaction and allowTransactionlessInjection is false', function (t) { - const { api } = t.context - t.equal( + const { api } = t.nr + assert.equal( api.getBrowserTimingHeader({ allowTransactionlessInjection: false }), '' ) - t.end() } ) - t.test('should issue a warning if the transaction was ignored', function (t) { - const { agent, api } = t.context + await t.test('should issue a warning if the transaction was ignored', function (t, end) { + const { agent, api } = t.nr helper.runInTransaction(agent, function (tx) { tx.ignore = true - t.equal(api.getBrowserTimingHeader(), '') - t.end() + assert.equal(api.getBrowserTimingHeader(), '') + end() }) }) - t.test('should not generate header config is missing', function (t) { - const { agent, api } = t.context + await t.test('should not generate header config is missing', function (t) { + const { agent, api } = t.nr agent.config.browser_monitoring = undefined - t.equal(api.getBrowserTimingHeader(), '') - t.end() + assert.equal(api.getBrowserTimingHeader(), '') }) - t.test('should issue a warning if transaction has no name', function (t) { - const { agent, api } = t.context + await t.test('should issue a warning if transaction has no name', function (t, end) { + const { agent, api } = t.nr helper.runInTransaction(agent, function () { - t.equal(api.getBrowserTimingHeader(), '') - t.end() + assert.equal(api.getBrowserTimingHeader(), '') + end() }) }) - t.test('should issue a warning without an application_id', function (t) { - const { agent, api } = t.context + await t.test('should issue a warning without an application_id', function (t, end) { + const { agent, api } = t.nr agent.config.application_id = undefined helper.runInTransaction(agent, function (tx) { tx.finalizeNameFromUri('hello') - t.equal(api.getBrowserTimingHeader(), '') - t.end() + assert.equal(api.getBrowserTimingHeader(), '') + end() }) }) - t.test('should return the rum headers when in a named transaction', function (t) { - const { agent, api } = t.context + await t.test('should return the rum headers when in a named transaction', function (t, end) { + const { agent, api } = t.nr helper.runInTransaction(agent, function (tx) { tx.finalizeNameFromUri('hello') - t.equal(api.getBrowserTimingHeader().indexOf(' 5) - t.end() + assert.ok(api.getBrowserTimingHeader().split('\n').length > 5) + end() }) }) - t.test('should be compact when not debugging', function (t) { - const { agent, api } = t.context + await t.test('should be compact when not debugging', function (t, end) { + const { agent, api } = t.nr helper.runInTransaction(agent, function (tx) { tx.finalizeNameFromUri('hello') const l = api.getBrowserTimingHeader().split('\n').length - t.equal(l, 1) - t.end() + assert.equal(l, 1) + end() }) }) - t.test('should return empty headers when missing browser_key', function (t) { - const { agent, api } = t.context + await t.test('should return empty headers when missing browser_key', function (t, end) { + const { agent, api } = t.nr agent.config.browser_monitoring.browser_key = undefined helper.runInTransaction(agent, function (tx) { tx.finalizeNameFromUri('hello') - t.equal(api.getBrowserTimingHeader(), '') - t.end() + assert.equal(api.getBrowserTimingHeader(), '') + end() }) }) - t.test('should return empty headers when missing js_agent_loader', function (t) { - const { agent, api } = t.context + await t.test('should return empty headers when missing js_agent_loader', function (t, end) { + const { agent, api } = t.nr agent.config.browser_monitoring.js_agent_loader = '' helper.runInTransaction(agent, function (tx) { tx.finalizeNameFromUri('hello') - t.equal(api.getBrowserTimingHeader(), '') - t.end() + assert.equal(api.getBrowserTimingHeader(), '') + end() }) }) - t.test('should be empty headers when loader is none', function (t) { - const { agent, api } = t.context + await t.test('should be empty headers when loader is none', function (t, end) { + const { agent, api } = t.nr agent.config.browser_monitoring.loader = 'none' helper.runInTransaction(agent, function (tx) { tx.finalizeNameFromUri('hello') - t.equal(api.getBrowserTimingHeader(), '') - t.end() + assert.equal(api.getBrowserTimingHeader(), '') + end() }) }) - t.test('should get browser agent script with wrapping tag', function (t) { - const { agent, api } = t.context + await t.test('should get browser agent script with wrapping tag', function (t, end) { + const { agent, api } = t.nr helper.runInTransaction(agent, function (tx) { tx.finalizeNameFromUri('hello') const timingHeader = api.getBrowserTimingHeader() - t.ok( + assert.ok( timingHeader.startsWith( ``)) - t.end() + assert.ok(timingHeader.endsWith(`}; function() {}`)) + end() }) }) - t.test( + await t.test( 'should get the browser agent script when outside a transaction and allowTransactionlessInjection is true', function (t) { - const { api } = t.context + const { api } = t.nr const timingHeader = api.getBrowserTimingHeader({ allowTransactionlessInjection: true }) - t.ok( + assert.ok( timingHeader.startsWith( ``)) - t.end() + assert.ok(timingHeader.endsWith(`}; function() {}`)) } ) - t.test( + await t.test( 'should get browser agent script with wrapping tag and add nonce attribute to script if passed in options', - function (t) { - const { agent, api } = t.context + function (t, end) { + const { agent, api } = t.nr helper.runInTransaction(agent, function (tx) { tx.finalizeNameFromUri('hello') const timingHeader = api.getBrowserTimingHeader({ nonce: '12345' }) - t.ok( + assert.ok( timingHeader.startsWith( ``)) - t.end() + assert.ok(timingHeader.endsWith(`}; function() {}`)) + end() }) } ) - t.test( + await t.test( 'should get browser agent script without wrapping tag if hasToRemoveScriptWrapper passed in options', - function (t) { - const { agent, api } = t.context + function (t, end) { + const { agent, api } = t.nr helper.runInTransaction(agent, function (tx) { tx.finalizeNameFromUri('hello') const timingHeader = api.getBrowserTimingHeader({ hasToRemoveScriptWrapper: true }) - t.ok( + assert.ok( timingHeader.startsWith( 'window.NREUM||(NREUM={});NREUM.info = {"licenseKey":1234,"applicationID":12345,' ) ) - t.ok(timingHeader.endsWith(`}; function() {}`)) - t.end() + assert.ok(timingHeader.endsWith(`}; function() {}`)) + end() }) } ) - t.test('should add custom attributes', function (t) { - const { agent, api } = t.context + await t.test('should add custom attributes', function (t, end) { + const { agent, api } = t.nr helper.runInTransaction(agent, function (tx) { api.addCustomAttribute('hello', 1) tx.finalizeNameFromUri('hello') const payload = /"atts":"(.*)"/.exec(api.getBrowserTimingHeader()) - t.ok(payload) + assert.ok(payload) const deobf = hashes.deobfuscateNameUsingKey( payload[1], agent.config.license_key.substring(0, 13) ) - t.equal(JSON.parse(deobf).u.hello, 1) - t.end() + assert.equal(JSON.parse(deobf).u.hello, 1) + end() }) }) }) diff --git a/test/unit/sampler.test.js b/test/unit/sampler.test.js index e5a3dbe263..704b3c1ab9 100644 --- a/test/unit/sampler.test.js +++ b/test/unit/sampler.test.js @@ -4,44 +4,42 @@ */ 'use strict' -const tap = require('tap') +const assert = require('node:assert') +const test = require('node:test') const Agent = require('../../lib/agent') const configurator = require('../../lib/config') const sampler = require('../../lib/sampler') const sinon = require('sinon') - +const numCpus = require('os').cpus().length const NAMES = require('../../lib/metrics/names') -tap.test('environmental sampler', function (t) { - t.autoend() - const numCpus = require('os').cpus().length - - t.beforeEach(function (t) { +test('environmental sampler', async function (t) { + t.beforeEach(function (ctx) { + ctx.nr = {} const sandbox = sinon.createSandbox() - t.context.sandbox = sandbox + ctx.nr.sandbox = sandbox // process.cpuUsage return values in cpu microseconds (1^-6) sandbox .stub(process, 'cpuUsage') .callsFake(() => ({ user: 1e6 * numCpus, system: 1e6 * numCpus })) // process.uptime returns values in seconds sandbox.stub(process, 'uptime').callsFake(() => 1) - t.context.agent = new Agent(configurator.initialize()) + ctx.nr.agent = new Agent(configurator.initialize()) }) - t.afterEach(function (t) { + t.afterEach(function (ctx) { sampler.stop() - t.context.sandbox.restore() + ctx.nr.sandbox.restore() }) - t.test('should have the native-metrics package available', function (t) { - t.doesNotThrow(function () { + await t.test('should have the native-metrics package available', function () { + assert.doesNotThrow(function () { require('@newrelic/native-metrics') }) - t.end() }) - t.test('should still gather native metrics when bound and unbound', function (t) { - const { agent } = t.context + await t.test('should still gather native metrics when bound and unbound', function (t, end) { + const { agent } = t.nr sampler.start(agent) sampler.stop() sampler.start(agent) @@ -55,10 +53,10 @@ tap.test('environmental sampler', function (t) { sampler.sampleGc(agent, sampler.nativeMetrics)() const loop = agent.metrics.getOrCreateMetric(NAMES.LOOP.USAGE) - t.ok(loop.callCount > 1) - t.ok(loop.max > 0) - t.ok(loop.min <= loop.max) - t.ok(loop.total >= loop.max) + assert.ok(loop.callCount > 1) + assert.ok(loop.max > 0) + assert.ok(loop.min <= loop.max) + assert.ok(loop.total >= loop.max) // Find at least one typed GC metric. const type = [ @@ -68,109 +66,101 @@ tap.test('environmental sampler', function (t) { 'ProcessWeakCallbacks', 'All' ].find((t) => agent.metrics.getOrCreateMetric(NAMES.GC.PREFIX + t).callCount) - t.ok(type) + assert.ok(type) const gc = agent.metrics.getOrCreateMetric(NAMES.GC.PREFIX + type) - t.ok(gc.callCount >= 1) - t.ok(gc.total >= 0.001) // At least 1 ms of GC + assert.ok(gc.callCount >= 1) + assert.ok(gc.total >= 0.001) // At least 1 ms of GC const pause = agent.metrics.getOrCreateMetric(NAMES.GC.PAUSE_TIME) - t.ok(pause.callCount >= gc.callCount) - t.ok(pause.total >= gc.total) - t.end() + assert.ok(pause.callCount >= gc.callCount) + assert.ok(pause.total >= gc.total) + end() }) }) - t.test('should gather loop metrics', function (t) { - const { agent } = t.context + await t.test('should gather loop metrics', function (t, end) { + const { agent } = t.nr sampler.start(agent) sampler.nativeMetrics.getLoopMetrics() spinLoop(function runLoop() { sampler.sampleLoop(agent, sampler.nativeMetrics)() const stats = agent.metrics.getOrCreateMetric(NAMES.LOOP.USAGE) - t.ok(stats.callCount > 1) - t.ok(stats.max > 0) - t.ok(stats.min <= stats.max) - t.ok(stats.total >= stats.max) - t.end() + assert.ok(stats.callCount > 1) + assert.ok(stats.max > 0) + assert.ok(stats.min <= stats.max) + assert.ok(stats.total >= stats.max) + end() }) }) - t.test('should depend on Agent to provide the current metrics summary', function (t) { - const { agent } = t.context - t.doesNotThrow(function () { + await t.test('should depend on Agent to provide the current metrics summary', function (t) { + const { agent } = t.nr + assert.doesNotThrow(function () { sampler.start(agent) }) - t.doesNotThrow(function () { + assert.doesNotThrow(function () { sampler.stop(agent) }) - t.end() }) - t.test('should default to a state of stopped', function (t) { - t.equal(sampler.state, 'stopped') - t.end() + await t.test('should default to a state of stopped', function () { + assert.equal(sampler.state, 'stopped') }) - t.test('should say it is running after start', function (t) { - const { agent } = t.context + await t.test('should say it is running after start', function (t) { + const { agent } = t.nr sampler.start(agent) - t.equal(sampler.state, 'running') - t.end() + assert.equal(sampler.state, 'running') }) - t.test('should say it is stopped after stop', function (t) { - const { agent } = t.context + await t.test('should say it is stopped after stop', function (t) { + const { agent } = t.nr sampler.start(agent) - t.equal(sampler.state, 'running') + assert.equal(sampler.state, 'running') sampler.stop(agent) - t.equal(sampler.state, 'stopped') - t.end() + assert.equal(sampler.state, 'stopped') }) - t.test('should gather CPU user utilization metric', function (t) { - const { agent } = t.context + await t.test('should gather CPU user utilization metric', function (t) { + const { agent } = t.nr sampler.sampleCpu(agent)() const stats = agent.metrics.getOrCreateMetric(NAMES.CPU.USER_UTILIZATION) - t.equal(stats.callCount, 1) - t.equal(stats.total, 1) - t.end() + assert.equal(stats.callCount, 1) + assert.equal(stats.total, 1) }) - t.test('should gather CPU system utilization metric', function (t) { - const { agent } = t.context + await t.test('should gather CPU system utilization metric', function (t) { + const { agent } = t.nr sampler.sampleCpu(agent)() const stats = agent.metrics.getOrCreateMetric(NAMES.CPU.SYSTEM_UTILIZATION) - t.equal(stats.callCount, 1) - t.equal(stats.total, 1) - t.end() + assert.equal(stats.callCount, 1) + assert.equal(stats.total, 1) }) - t.test('should gather CPU user time metric', function (t) { - const { agent } = t.context + await t.test('should gather CPU user time metric', function (t) { + const { agent } = t.nr sampler.sampleCpu(agent)() const stats = agent.metrics.getOrCreateMetric(NAMES.CPU.USER_TIME) - t.equal(stats.callCount, 1) - t.equal(stats.total, numCpus) - t.end() + assert.equal(stats.callCount, 1) + assert.equal(stats.total, numCpus) }) - t.test('should gather CPU sytem time metric', function (t) { - const { agent } = t.context + await t.test('should gather CPU sytem time metric', function (t) { + const { agent } = t.nr sampler.sampleCpu(agent)() const stats = agent.metrics.getOrCreateMetric(NAMES.CPU.SYSTEM_TIME) - t.equal(stats.callCount, 1) - t.equal(stats.total, numCpus) - t.end() + assert.equal(stats.callCount, 1) + assert.equal(stats.total, numCpus) }) - t.test('should gather GC metrics', function (t) { - const { agent } = t.context + await t.test('should gather GC metrics', function (t, end) { + const { agent } = t.nr sampler.start(agent) // Clear up the current state of the metrics. @@ -187,69 +177,65 @@ tap.test('environmental sampler', function (t) { 'ProcessWeakCallbacks', 'All' ].find((t) => agent.metrics.getOrCreateMetric(NAMES.GC.PREFIX + t).callCount) - t.ok(type) + assert.ok(type) const gc = agent.metrics.getOrCreateMetric(NAMES.GC.PREFIX + type) - t.ok(gc.callCount >= 1) + assert.ok(gc.callCount >= 1) // Assuming GC to take some amount of time. // With Node 12, the minimum for this work often seems to be // around 0.0008 on the servers. - t.ok(gc.total >= 0.0004) + assert.ok(gc.total >= 0.0004) const pause = agent.metrics.getOrCreateMetric(NAMES.GC.PAUSE_TIME) - t.ok(pause.callCount >= gc.callCount) - t.ok(pause.total >= gc.total) - t.end() + assert.ok(pause.callCount >= gc.callCount) + assert.ok(pause.total >= gc.total) + end() }) }) - t.test('should not gather GC metrics if disabled', function (t) { - const { agent } = t.context + await t.test('should not gather GC metrics if disabled', function (t) { + const { agent } = t.nr agent.config.plugins.native_metrics.enabled = false sampler.start(agent) - t.not(sampler.nativeMetrics) - t.end() + assert.ok(!sampler.nativeMetrics) }) - t.test('should catch if process.cpuUsage throws an error', function (t) { - const { agent } = t.context + await t.test('should catch if process.cpuUsage throws an error', function (t) { + const { agent } = t.nr const err = new Error('ohhhhhh boyyyyyy') process.cpuUsage.throws(err) sampler.sampleCpu(agent)() const stats = agent.metrics.getOrCreateMetric('CPU/User/Utilization') - t.equal(stats.callCount, 0) - t.end() + assert.equal(stats.callCount, 0) }) - t.test('should collect all specified memory statistics', function (t) { - const { agent } = t.context + await t.test('should collect all specified memory statistics', function (t) { + const { agent } = t.nr sampler.sampleMemory(agent)() Object.keys(NAMES.MEMORY).forEach(function testStat(memoryStat) { const metricName = NAMES.MEMORY[memoryStat] const stats = agent.metrics.getOrCreateMetric(metricName) - t.equal(stats.callCount, 1, `${metricName} callCount`) - t.ok(stats.max > 1, `${metricName} max`) + assert.equal(stats.callCount, 1, `${metricName} callCount`) + assert.ok(stats.max > 1, `${metricName} max`) }) - t.end() }) - t.test('should catch if process.memoryUsage throws an error', function (t) { - const { agent, sandbox } = t.context + await t.test('should catch if process.memoryUsage throws an error', function (t) { + const { agent, sandbox } = t.nr sandbox.stub(process, 'memoryUsage').callsFake(() => { throw new Error('your computer is on fire') }) sampler.sampleMemory(agent)() const stats = agent.metrics.getOrCreateMetric('Memory/Physical') - t.equal(stats.callCount, 0) - t.end() + assert.equal(stats.callCount, 0) }) - t.test('should have some rough idea of how deep the event queue is', function (t) { - const { agent } = t.context + await t.test('should have some rough idea of how deep the event queue is', function (t, end) { + const { agent } = t.nr sampler.checkEvents(agent)() /* sampler.checkEvents works by creating a timer and using @@ -264,18 +250,18 @@ tap.test('environmental sampler', function (t) { */ setTimeout(function () { const stats = agent.metrics.getOrCreateMetric('Events/wait') - t.equal(stats.callCount, 1) + assert.equal(stats.callCount, 1) /* process.hrtime will notice the passage of time, but this * happens too fast to measure any meaningful latency in versions * of Node that don't have process.hrtime available, so just make * sure we're not getting back undefined or null here. */ - t.ok(typeof stats.total === 'number') + assert.ok(typeof stats.total === 'number') if (process.hrtime) { - t.ok(stats.total > 0) + assert.ok(stats.total > 0) } - t.end() + end() }, 0) }) }) diff --git a/test/unit/shimmer.test.js b/test/unit/shimmer.test.js index 6c9b7fcb64..ec1600628b 100644 --- a/test/unit/shimmer.test.js +++ b/test/unit/shimmer.test.js @@ -4,13 +4,13 @@ */ 'use strict' - -const tap = require('tap') +const assert = require('node:assert') +const test = require('node:test') const oldInstrumentations = require('../../lib/instrumentations') const insPath = require.resolve('../../lib/instrumentations') const proxyquire = require('proxyquire') const sinon = require('sinon') - +const { tspl } = require('@matteo.collina/tspl') const helper = require('../lib/agent_helper') const logger = require('../../lib/logger').child({ component: 'TEST' }) const shimmer = require('../../lib/shimmer') @@ -23,121 +23,112 @@ const TEST_MODULE_RELATIVE_PATH = `../helpers/node_modules/${TEST_MODULE_PATH}` const TEST_MODULE = 'sinon' const TEST_PATH_WITHIN = `${TEST_MODULE}/lib/sinon/spy` -function makeModuleTests({ moduleName, relativePath, throwsError }, t) { - t.autoend() - t.beforeEach(function (t) { - t.context.counter = 0 - t.context.errorThrown = 0 - t.context.agent = helper.instrumentMockedAgent() +async function makeModuleTests({ moduleName, relativePath, throwsError }, t) { + t.beforeEach(function (ctx) { + ctx.nr = {} + ctx.nr.counter = 0 + ctx.nr.errorThrown = 0 + ctx.nr.agent = helper.instrumentMockedAgent() const instrumentationOpts = { moduleName: moduleName, onRequire: function (shim, module) { - t.context.instrumentedModule = module - ++t.context.counter - t.context.onRequireArgs = arguments + ctx.nr.instrumentedModule = module + ++ctx.nr.counter + ctx.nr.onRequireArgs = arguments if (throwsError) { - t.context.expectedErr = 'This threw an error! Oh no!' - throw new Error(t.context.expectedErr) + ctx.nr.expectedErr = 'This threw an error! Oh no!' + throw new Error(ctx.nr.expectedErr) } }, onError: function (err) { - if (err.message === t.context.expectedErr) { - t.context.errorThrown += 1 + if (err.message === ctx.nr.expectedErr) { + ctx.nr.errorThrown += 1 } } } shimmer.registerInstrumentation(instrumentationOpts) }) - t.afterEach(function (t) { - t.context.onRequireArgs = null + t.afterEach(function (ctx) { + ctx.nr.onRequireArgs = null clearCachedModules([relativePath]) - helper.unloadAgent(t.context.agent) + helper.unloadAgent(ctx.nr.agent) }) - t.test('should be sent a shim and the loaded module', function (t) { + await t.test('should be sent a shim and the loaded module', function (t) { const mod = require(relativePath) - const { onRequireArgs } = t.context - t.equal(onRequireArgs.length, 3) - t.ok(onRequireArgs[0] instanceof shims.Shim) - t.equal(onRequireArgs[1], mod) - t.equal(onRequireArgs[2], moduleName) - t.end() + const { onRequireArgs } = t.nr + assert.equal(onRequireArgs.length, 3) + assert.ok(onRequireArgs[0] instanceof shims.Shim) + assert.equal(onRequireArgs[1], mod) + assert.equal(onRequireArgs[2], moduleName) }) - t.test('should construct a DatastoreShim if the type is "datastore"', function (t) { + await t.test('should construct a DatastoreShim if the type is "datastore"', function (t) { shimmer.registeredInstrumentations.getAllByName(moduleName)[0].instrumentation.type = 'datastore' require(relativePath) - const { onRequireArgs } = t.context - t.ok(onRequireArgs[0] instanceof shims.DatastoreShim) - t.end() + const { onRequireArgs } = t.nr + assert.ok(onRequireArgs[0] instanceof shims.DatastoreShim) }) - t.test('should receive the correct module (' + moduleName + ')', function (t) { + await t.test('should receive the correct module (' + moduleName + ')', function (t) { const mod = require(relativePath) - t.equal(mod, t.context.instrumentedModule) - t.end() + assert.equal(mod, t.nr.instrumentedModule) }) - t.test('should only run the instrumentation once', function (t) { - t.equal(t.context.counter, 0) + await t.test('should only run the instrumentation once', function (t) { + assert.equal(t.nr.counter, 0) require(relativePath) - t.equal(t.context.counter, 1) + assert.equal(t.nr.counter, 1) require(relativePath) require(relativePath) require(relativePath) require(relativePath) - t.equal(t.context.counter, 1) - t.end() + assert.equal(t.nr.counter, 1) }) - t.test('should have some NR properties after instrumented', (t) => { + await t.test('should have some NR properties after instrumented', () => { const mod = require(relativePath) const nrKeys = getNRSymbols(mod) const message = `Expected to have Symbol(shim) but found ${nrKeys}.` - t.ok(nrKeys.includes('Symbol(shim)'), message) - t.end() + assert.ok(nrKeys.includes('Symbol(shim)'), message) }) - t.test('should clean up NR added properties', (t) => { + await t.test('should clean up NR added properties', () => { const mod = require(relativePath) shimmer.unwrapAll() const nrKeys = getNRSymbols(mod) const message = `Expected keys to be equal but found: ${JSON.stringify(nrKeys)}` - t.equal(nrKeys.length, 0, message) - t.end() + assert.equal(nrKeys.length, 0, message) }) if (throwsError) { - t.test('should send error to onError handler', (t) => { + await t.test('should send error to onError handler', (t) => { require(relativePath) - t.equal(t.context.errorThrown, 1) - t.end() + assert.equal(t.nr.errorThrown, 1) }) } } -tap.test('shimmer', function (t) { - t.autoend() - t.test('custom instrumentation', function (t) { - t.autoend() - t.test( +test('shimmer', async function (t) { + await t.test('custom instrumentation', async function (t) { + await t.test( 'of relative modules', makeModuleTests.bind(this, { moduleName: TEST_MODULE_PATH, relativePath: TEST_MODULE_RELATIVE_PATH }) ) - t.test( + await t.test( 'of modules', makeModuleTests.bind(this, { moduleName: TEST_MODULE, relativePath: TEST_MODULE }) ) - t.test( + await t.test( 'of modules, where instrumentation fails', makeModuleTests.bind(this, { moduleName: TEST_MODULE, @@ -145,16 +136,16 @@ tap.test('shimmer', function (t) { throwsError: true }) ) - t.test( + await t.test( 'of deep modules', makeModuleTests.bind(this, { moduleName: TEST_PATH_WITHIN, relativePath: TEST_PATH_WITHIN }) ) }) - t.test('wrapping exports', function (t) { - t.autoend() - t.beforeEach(function (t) { - t.context.agent = helper.instrumentMockedAgent() + await t.test('wrapping exports', async function (t) { + t.beforeEach(function (ctx) { + ctx.nr = {} + ctx.nr.agent = helper.instrumentMockedAgent() shimmer.registerInstrumentation({ moduleName: TEST_MODULE_PATH, onRequire: function (shim, nodule) { @@ -164,28 +155,26 @@ tap.test('shimmer', function (t) { shim.wrapExport(original, function () { return wrapper }) - t.context.wrapper = wrapper - t.context.original = original + ctx.nr.wrapper = wrapper + ctx.nr.original = original } }) }) - t.afterEach(function (t) { - helper.unloadAgent(t.context.agent) + t.afterEach(function (ctx) { + helper.unloadAgent(ctx.nr.agent) clearCachedModules([TEST_MODULE_RELATIVE_PATH]) }) - t.test('should replace the return value from require', function (t) { + await t.test('should replace the return value from require', function (t) { const obj = require(TEST_MODULE_RELATIVE_PATH) - const { wrapper, original } = t.context - t.equal(obj, wrapper) - t.not(obj, original) - t.end() + const { wrapper, original } = t.nr + assert.equal(obj, wrapper) + assert.notDeepEqual(obj, original) }) }) - t.test('the instrumentation injector', function (t) { - t.autoend() + await t.test('the instrumentation injector', async function (t) { const nodule = { c: 2, ham: 'ham', @@ -203,15 +192,14 @@ tap.test('shimmer', function (t) { } } - t.test('should not wrap anything without enough information', (t) => { + await t.test('should not wrap anything without enough information', () => { shimmer.wrapMethod(nodule, 'nodule') - t.equal(shimmer.isWrapped(nodule.doubler), false) + assert.equal(shimmer.isWrapped(nodule.doubler), false) shimmer.wrapMethod(nodule, 'nodule', 'doubler') - t.equal(shimmer.isWrapped(nodule.doubler), false) - t.end() + assert.equal(shimmer.isWrapped(nodule.doubler), false) }) - t.test('should wrap a method', function (t) { + await t.test('should wrap a method', function () { let doubled = 0 let before = false let after = false @@ -224,20 +212,19 @@ tap.test('shimmer', function (t) { } }) - t.equal(shimmer.isWrapped(nodule.doubler), true) - t.ok(typeof nodule.doubler[symbols.unwrap] === 'function') + assert.equal(shimmer.isWrapped(nodule.doubler), true) + assert.ok(typeof nodule.doubler[symbols.unwrap] === 'function') nodule.doubler(7, function (z) { doubled = z }) - t.equal(doubled, 16) - t.equal(before, true) - t.equal(after, true) - t.end() + assert.equal(doubled, 16) + assert.equal(before, true) + assert.equal(after, true) }) - t.test('should preserve properties on wrapped methods', (t) => { + await t.test('should preserve properties on wrapped methods', () => { let quadrupled = 0 let before = false let after = false @@ -252,21 +239,20 @@ tap.test('shimmer', function (t) { } }) - t.ok(typeof nodule.quadrupler[symbols.unwrap] === 'function') - t.ok(typeof nodule.quadrupler.test === 'function') + assert.ok(typeof nodule.quadrupler[symbols.unwrap] === 'function') + assert.ok(typeof nodule.quadrupler.test === 'function') nodule.quadrupler(7, function (z) { quadrupled = z }) - t.equal(quadrupled, 30) - t.equal(before, true) - t.equal(after, true) - t.end() + assert.equal(quadrupled, 30) + assert.equal(before, true) + assert.equal(after, true) }) - t.test('should not error out on external instrumentations that fail', function (t) { - t.teardown(() => { + await t.test('should not error out on external instrumentations that fail', function (t) { + t.after(() => { require.cache[insPath].exports = oldInstrumentations }) @@ -278,63 +264,56 @@ tap.test('shimmer', function (t) { } return ret } - t.doesNotThrow(function () { + assert.doesNotThrow(function () { require('../lib/broken_instrumentation_module') }) - t.end() }) - t.test('with accessor replacement', function (t) { - t.autoend() - - t.beforeEach(function (t) { - t.context.simple = { target: true } + await t.test('with accessor replacement', async function (t) { + t.beforeEach(function (ctx) { + ctx.nr = {} + ctx.nr.simple = { target: true } }) - t.test("shouldn't throw if called with no params", function (t) { - t.doesNotThrow(function () { + await t.test("shouldn't throw if called with no params", function () { + assert.doesNotThrow(function () { shimmer.wrapDeprecated() }) - t.end() }) - t.test("shouldn't throw if called with only the original object", function (t) { - const { simple } = t.context - t.doesNotThrow(function () { + await t.test("shouldn't throw if called with only the original object", function (t) { + const { simple } = t.nr + assert.doesNotThrow(function () { shimmer.wrapDeprecated(simple) }) - t.end() }) - t.test("shouldn't throw if property to be replaced is omitted", function (t) { - const { simple } = t.context - t.doesNotThrow(function () { + await t.test("shouldn't throw if property to be replaced is omitted", function (t) { + const { simple } = t.nr + assert.doesNotThrow(function () { shimmer.wrapDeprecated(simple, 'nodule', null, { get: function () {}, set: function () {} }) }) - t.end() }) - t.test("shouldn't throw if getter is omitted", function (t) { - const { simple } = t.context - t.doesNotThrow(function () { + await t.test("shouldn't throw if getter is omitted", function (t) { + const { simple } = t.nr + assert.doesNotThrow(function () { shimmer.wrapDeprecated(simple, 'nodule', 'target', { set: function () {} }) }) - t.end() }) - t.test("shouldn't throw if setter is omitted", function (t) { - const { simple } = t.context - t.doesNotThrow(function () { + await t.test("shouldn't throw if setter is omitted", function (t) { + const { simple } = t.nr + assert.doesNotThrow(function () { shimmer.wrapDeprecated(simple, 'nodule', 'target', { get: function () {} }) }) - t.end() }) - t.test('should replace a property with an accessor', function (t) { - const { simple } = t.context + await t.test('should replace a property with an accessor', function (t) { + const { simple } = t.nr shimmer.debug = true // test internal debug code const original = shimmer.wrapDeprecated(simple, 'nodule', 'target', { get: function () { @@ -342,33 +321,32 @@ tap.test('shimmer', function (t) { return false } }) - t.equal(original, true) + assert.equal(original, true) - t.equal(simple.target, false) + assert.equal(simple.target, false) // internal debug code should unwrap - t.doesNotThrow(shimmer.unwrapAll) - t.end() + assert.doesNotThrow(shimmer.unwrapAll) }) - t.test('should invoke the setter when the accessor is used', function (t) { - const { simple } = t.context + await t.test('should invoke the setter when the accessor is used', function (t, end) { + const { simple } = t.nr const test = 'ham' const original = shimmer.wrapDeprecated(simple, 'nodule', 'target', { get: function () { return test }, set: function (value) { - t.equal(value, 'eggs') - t.end() + assert.equal(value, 'eggs') + end() } }) - t.equal(original, true) - t.equal(simple.target, 'ham') + assert.equal(original, true) + assert.equal(simple.target, 'ham') simple.target = 'eggs' }) }) - t.test('should wrap, then unwrap a method', function (t) { + await t.test('should wrap, then unwrap a method', function () { let tripled = 0 let before = false let after = false @@ -385,9 +363,9 @@ tap.test('shimmer', function (t) { tripled = z }) - t.equal(tripled, 23) - t.equal(before, true) - t.equal(after, true) + assert.equal(tripled, 23) + assert.equal(before, true) + assert.equal(after, true) before = false after = false @@ -398,58 +376,59 @@ tap.test('shimmer', function (t) { tripled = j }) - t.equal(tripled, 29) - t.equal(before, false) - t.equal(after, false) - t.end() + assert.equal(tripled, 29) + assert.equal(before, false) + assert.equal(after, false) }) - t.test("shouldn't break anything when an NR-wrapped method is wrapped again", function (t) { - let hamceptacle = '' - let before = false - let after = false - let hammed = false + await t.test( + "shouldn't break anything when an NR-wrapped method is wrapped again", + function () { + let hamceptacle = '' + let before = false + let after = false + let hammed = false + + shimmer.wrapMethod(nodule, 'nodule', 'hammer', function (original) { + return function () { + before = true + original.apply(this, arguments) + after = true + } + }) - shimmer.wrapMethod(nodule, 'nodule', 'hammer', function (original) { - return function () { - before = true - original.apply(this, arguments) - after = true + // monkey-patching the old-fashioned way + const hammer = nodule.hammer + nodule.hammer = function () { + hammer.apply(this, arguments) + hammed = true } - }) - - // monkey-patching the old-fashioned way - const hammer = nodule.hammer - nodule.hammer = function () { - hammer.apply(this, arguments) - hammed = true - } - - nodule.hammer('Burt', function (k) { - hamceptacle = k - }) - t.equal(hamceptacle, 'hamBurt') - t.equal(before, true) - t.equal(after, true) - t.equal(hammed, true) - t.end() - }) + nodule.hammer('Burt', function (k) { + hamceptacle = k + }) - t.test('with full instrumentation running', function (t) { - t.autoend() + assert.equal(hamceptacle, 'hamBurt') + assert.equal(before, true) + assert.equal(after, true) + assert.equal(hammed, true) + } + ) - t.beforeEach(function (t) { - t.context.agent = helper.loadMockedAgent() + await t.test('with full instrumentation running', async function (t) { + t.beforeEach(function (ctx) { + ctx.nr = {} + ctx.nr.agent = helper.loadMockedAgent() }) - t.afterEach(function (t) { - helper.unloadAgent(t.context.agent) + t.afterEach(function (ctx) { + helper.unloadAgent(ctx.nr.agent) }) - t.test('should push transactions through process.nextTick', function (t) { - const { agent } = t.context - t.equal(agent.getTransaction(), null) + await t.test('should push transactions through process.nextTick', async function (t) { + const plan = tspl(t, { plan: 31 }) + const { agent } = t.nr + plan.equal(agent.getTransaction(), null) const synchronizer = new EventEmitter() const transactions = [] @@ -464,7 +443,7 @@ tap.test('shimmer', function (t) { process.nextTick( agent.tracer.bindFunction(function bindFunctionCb() { const lookup = agent.getTransaction() - t.equal(lookup, current) + plan.equal(lookup, current) synchronizer.emit('inner', lookup, i) }) @@ -473,27 +452,22 @@ tap.test('shimmer', function (t) { wrapped() } - let doneCount = 0 synchronizer.on('inner', function (trans, j) { - doneCount += 1 - t.equal(trans, transactions[j]) - t.equal(trans.id, ids[j]) - + plan.equal(trans, transactions[j]) + plan.equal(trans.id, ids[j]) trans.end() - - if (doneCount === 10) { - t.end() - } }) for (let i = 0; i < 10; i += 1) { process.nextTick(spamTransaction.bind(this, i)) } + await plan.completed }) - t.test('should push transactions through setTimeout', function (t) { - const { agent } = t.context - t.equal(agent.getTransaction(), null) + await t.test('should push transactions through setTimeout', async function (t) { + const plan = tspl(t, { plan: 31 }) + const { agent } = t.nr + plan.equal(agent.getTransaction(), null) const synchronizer = new EventEmitter() const transactions = [] @@ -508,7 +482,7 @@ tap.test('shimmer', function (t) { setTimeout( agent.tracer.bindFunction(function bindFunctionCb() { const lookup = agent.getTransaction() - t.equal(lookup, current) + plan.equal(lookup, current) synchronizer.emit('inner', lookup, i) }), @@ -518,17 +492,10 @@ tap.test('shimmer', function (t) { wrapped() } - let doneCount = 0 synchronizer.on('inner', function (trans, j) { - doneCount += 1 - t.equal(trans, transactions[j]) - t.equal(trans.id, ids[j]) - + plan.equal(trans, transactions[j]) + plan.equal(trans.id, ids[j]) trans.end() - - if (doneCount === 10) { - t.end() - } }) for (let i = 0; i < 10; i += 1) { @@ -536,11 +503,13 @@ tap.test('shimmer', function (t) { const timeout = Math.floor(Math.random() * 20) setTimeout(spamTransaction.bind(this, i), timeout) } + await plan.completed }) - t.test('should push transactions through EventEmitters', function (t) { - const { agent } = t.context - t.equal(agent.getTransaction(), null) + await t.test('should push transactions through EventEmitters', async function (t) { + const plan = tspl(t, { plan: 41 }) + const { agent } = t.nr + plan.equal(agent.getTransaction(), null) const eventer = new EventEmitter() const transactions = [] @@ -559,8 +528,8 @@ tap.test('shimmer', function (t) { name, agent.tracer.bindFunction(function bindFunctionCb() { const lookup = agent.getTransaction() - t.equal(lookup, current) - t.equal(lookup.id, id) + plan.equal(lookup, current) + plan.equal(lookup.id, id) eventer.emit('inner', lookup, j) }) @@ -571,107 +540,100 @@ tap.test('shimmer', function (t) { wrapped() } - let doneCount = 0 eventer.on('inner', function (trans, j) { - doneCount += 1 - t.equal(trans, transactions[j]) - t.equal(trans.id, ids[j]) + plan.equal(trans, transactions[j]) + plan.equal(trans.id, ids[j]) trans.end() - - if (doneCount === 10) { - t.end() - } }) for (let i = 0; i < 10; i += 1) { eventTransaction(i) } + await plan.completed }) - t.test('should handle whatever ridiculous nonsense you throw at it', function (t) { - const { agent } = t.context - t.equal(agent.getTransaction(), null) - - const synchronizer = new EventEmitter() - const eventer = new EventEmitter() - const transactions = [] - const ids = [] - let doneCount = 0 - - const verify = function (i, phase, passed) { - const lookup = agent.getTransaction() - logger.trace( - '%d %s %d %d', - i, - phase, - lookup ? lookup.id : 'missing', - passed ? passed.id : 'missing' - ) - - t.equal(lookup, passed) - t.equal(lookup, transactions[i]) - t.equal(lookup.id, ids[i]) - } - - eventer.on('rntest', function (trans, j) { - verify(j, 'eventer', trans) - synchronizer.emit('inner', trans, j) - }) - - const createTimer = function (trans, j) { - const wrapped = agent.tracer.wrapFunctionFirst('createTimer', null, process.nextTick) + await t.test( + 'should handle whatever ridiculous nonsense you throw at it', + async function (t) { + const plan = tspl(t, { plan: 171 }) + const { agent } = t.nr + plan.equal(agent.getTransaction(), null) + + const synchronizer = new EventEmitter() + const eventer = new EventEmitter() + const transactions = [] + const ids = [] + + const verify = function (i, phase, passed) { + const lookup = agent.getTransaction() + logger.trace( + '%d %s %d %d', + i, + phase, + lookup ? lookup.id : 'missing', + passed ? passed.id : 'missing' + ) - wrapped(function () { - const current = agent.getTransaction() + plan.equal(lookup, passed) + plan.equal(lookup, transactions[i]) + plan.equal(lookup.id, ids[i]) + } - verify(j, 'createTimer', current) - eventer.emit('rntest', current, j) + eventer.on('rntest', function (trans, j) { + verify(j, 'eventer', trans) + synchronizer.emit('inner', trans, j) }) - } - const createTicker = function (j) { - return agent.tracer.transactionProxy(function transactionProxyCb() { - const current = agent.getTransaction() - transactions[j] = current - ids[j] = current.id + const createTimer = function (trans, j) { + const wrapped = agent.tracer.wrapFunctionFirst('createTimer', null, process.nextTick) - verify(j, 'createTicker', current) + wrapped(function () { + const current = agent.getTransaction() - process.nextTick( - agent.tracer.bindFunction(function bindFunctionCb() { - verify(j, 'nextTick', current) - createTimer(current, j) - }) - ) - }) - } + verify(j, 'createTimer', current) + eventer.emit('rntest', current, j) + }) + } - synchronizer.on('inner', function (trans, j) { - verify(j, 'synchronizer', trans) - doneCount += 1 - t.equal(trans, transactions[j]) - t.equal(trans.id, ids[j]) + const createTicker = function (j) { + return agent.tracer.transactionProxy(function transactionProxyCb() { + const current = agent.getTransaction() + transactions[j] = current + ids[j] = current.id + + verify(j, 'createTicker', current) + + process.nextTick( + agent.tracer.bindFunction(function bindFunctionCb() { + verify(j, 'nextTick', current) + createTimer(current, j) + }) + ) + }) + } - trans.end() + synchronizer.on('inner', function (trans, j) { + verify(j, 'synchronizer', trans) + plan.equal(trans, transactions[j]) + plan.equal(trans.id, ids[j]) + trans.end() + }) - if (doneCount === 10) { - t.end() + for (let i = 0; i < 10; i++) { + process.nextTick(createTicker(i)) } - }) - - for (let i = 0; i < 10; i++) { - process.nextTick(createTicker(i)) + await plan.completed } - }) + ) }) }) }) -tap.test('Should not augment module when no instrumentation hooks provided', (t) => { +test('Should not augment module when no instrumentation hooks provided', async (t) => { const agent = helper.instrumentMockedAgent() - t.teardown(() => { + t.after(() => { helper.unloadAgent(agent) }) @@ -683,44 +645,42 @@ tap.test('Should not augment module when no instrumentation hooks provided', (t) const loadedModule = require(TEST_MODULE_RELATIVE_PATH) - t.equal(loadedModule.foo, 'bar') + assert.equal(loadedModule.foo, 'bar') // Future proofing to catch any added symbols. If test module modified to add own symbol // will have to filter out here. const nrSymbols = Object.getOwnPropertySymbols(loadedModule) - t.equal(nrSymbols.length, 0, `should not have NR symbols but found: ${JSON.stringify(nrSymbols)}`) - - t.end() + assert.equal( + nrSymbols.length, + 0, + `should not have NR symbols but found: ${JSON.stringify(nrSymbols)}` + ) }) -tap.test('Should not crash on empty instrumentation registration', (t) => { +test('Should not crash on empty instrumentation registration', async (t) => { const agent = helper.instrumentMockedAgent() - t.teardown(() => { + t.after(() => { helper.unloadAgent(agent) }) - t.doesNotThrow(shimmer.registerInstrumentation) - - t.end() + assert.doesNotThrow(shimmer.registerInstrumentation) }) -tap.test('Should not register instrumentation with no name provided', (t) => { +test('Should not register instrumentation with no name provided', async (t) => { const agent = helper.instrumentMockedAgent() - t.teardown(() => { + t.after(() => { helper.unloadAgent(agent) }) shimmer.registerInstrumentation({}) - t.notOk(shimmer.registeredInstrumentations.undefined) - - t.end() + assert.ok(!shimmer.registeredInstrumentations.undefined) }) -tap.test('Should not register when no hooks provided', (t) => { +test('Should not register when no hooks provided', async (t) => { const agent = helper.instrumentMockedAgent() - t.teardown(() => { + t.after(() => { helper.unloadAgent(agent) }) @@ -729,64 +689,53 @@ tap.test('Should not register when no hooks provided', (t) => { moduleName: moduleName }) - t.notOk(shimmer.registeredInstrumentations[moduleName]) - - t.end() + assert.ok(!shimmer.registeredInstrumentations[moduleName]) }) -tap.test('should register hooks for ritm and iitm', (t) => { +test('should register hooks for ritm and iitm', async () => { const fakeAgent = {} shimmer.registerHooks(fakeAgent) - t.ok(shimmer._ritm, 'should have ritm instance') - t.ok(shimmer._iitm, 'should have iitm instance') - t.end() + assert.ok(shimmer._ritm, 'should have ritm instance') + assert.ok(shimmer._iitm, 'should have iitm instance') }) -tap.test('should unhook ritm and iitm when calling removeHooks', (t) => { +test('should unhook ritm and iitm when calling removeHooks', async () => { const fakeAgent = {} shimmer.registerHooks(fakeAgent) - t.ok(shimmer._ritm, 'should have ritm instance') - t.ok(shimmer._iitm, 'should have iitm instance') + assert.ok(shimmer._ritm, 'should have ritm instance') + assert.ok(shimmer._iitm, 'should have iitm instance') shimmer.removeHooks() - t.notOk(shimmer._iitm, 'should unhook iitm') - t.notOk(shimmer._ritm, 'should unhook ritm') - t.end() + assert.ok(!shimmer._iitm, 'should unhook iitm') + assert.ok(!shimmer._ritm, 'should unhook ritm') }) -tap.test('should not throw if you call removeHooks before creating ritm and iitm hooks', (t) => { - t.doesNotThrow(() => { +test('should not throw if you call removeHooks before creating ritm and iitm hooks', async () => { + assert.doesNotThrow(() => { shimmer.removeHooks() }) - t.end() }) -tap.test('Shimmer with logger mock', (t) => { - t.autoend() - let loggerMock - let shimmer - let sandbox - let agent - t.before(() => { - sandbox = sinon.createSandbox() - loggerMock = require('./mocks/logger')(sandbox) - shimmer = proxyquire('../../lib/shimmer', { - './logger': { - child: sandbox.stub().callsFake(() => loggerMock) - } - }) +test('Shimmer with logger mock', async (t) => { + const sandbox = sinon.createSandbox() + const loggerMock = require('./mocks/logger')(sandbox) + const shimmer = proxyquire('../../lib/shimmer', { + './logger': { + child: sandbox.stub().callsFake(() => loggerMock) + } }) - t.beforeEach(() => { - agent = helper.instrumentMockedAgent({}, true, shimmer) + t.beforeEach((ctx) => { + ctx.nr = {} + ctx.nr.agent = helper.instrumentMockedAgent({}, true, shimmer) }) - t.afterEach(() => { + t.afterEach((ctx) => { sandbox.resetHistory() clearCachedModules([TEST_MODULE_RELATIVE_PATH]) - helper.unloadAgent(agent, shimmer) + helper.unloadAgent(ctx.nr.agent, shimmer) }) - t.test('should log warning when onError hook throws', (t) => { + await t.test('should log warning when onError hook throws', () => { const origError = new Error('failed to instrument') const instFail = new Error('Failed to handle instrumentation error') shimmer.registerInstrumentation({ @@ -800,16 +749,15 @@ tap.test('Shimmer with logger mock', (t) => { }) require(TEST_MODULE_RELATIVE_PATH) - t.same(loggerMock.warn.args[0], [ + assert.deepEqual(loggerMock.warn.args[0], [ instFail, origError, 'Custom instrumentation for %s failed, then the onError handler threw an error', TEST_MODULE_PATH ]) - t.end() }) - t.test('should log warning when instrumentation fails and no onError handler', (t) => { + await t.test('should log warning when instrumentation fails and no onError handler', () => { const origError = new Error('failed to instrument') shimmer.registerInstrumentation({ moduleName: TEST_MODULE_PATH, @@ -819,17 +767,16 @@ tap.test('Shimmer with logger mock', (t) => { }) require(TEST_MODULE_RELATIVE_PATH) - t.same(loggerMock.warn.args[0], [ + assert.deepEqual(loggerMock.warn.args[0], [ origError, 'Custom instrumentation for %s failed. Please report this to the maintainers of the custom instrumentation.', TEST_MODULE_PATH ]) - t.end() }) - t.test( + await t.test( 'should skip instrumentation if hooks for the same package version have already run', - (t) => { + () => { const opts = { moduleName: TEST_MODULE_PATH, onRequire: () => {} @@ -839,16 +786,15 @@ tap.test('Shimmer with logger mock', (t) => { require(TEST_MODULE_RELATIVE_PATH) clearCachedModules([TEST_MODULE_RELATIVE_PATH]) require(TEST_MODULE_RELATIVE_PATH) - t.same(loggerMock.trace.args[2], [ + assert.deepEqual(loggerMock.trace.args[2], [ 'Already instrumented test-mod/module@0.0.1, skipping registering instrumentation' ]) - t.end() } ) - t.test( + await t.test( 'should skip instrumentation if hooks for the same package version have already errored', - (t) => { + () => { const opts = { moduleName: TEST_MODULE_PATH, onRequire: () => { @@ -860,14 +806,13 @@ tap.test('Shimmer with logger mock', (t) => { require(TEST_MODULE_RELATIVE_PATH) clearCachedModules([TEST_MODULE_RELATIVE_PATH]) require(TEST_MODULE_RELATIVE_PATH) - t.same(loggerMock.trace.args[2], [ + assert.deepEqual(loggerMock.trace.args[2], [ 'Failed to instrument test-mod/module@0.0.1, skipping registering instrumentation' ]) - t.end() } ) - t.test('should return package version from package.json', (t) => { + await t.test('should return package version from package.json', () => { shimmer.registerInstrumentation({ moduleName: TEST_MODULE_PATH, onRequire: () => {} @@ -875,22 +820,20 @@ tap.test('Shimmer with logger mock', (t) => { require(TEST_MODULE_RELATIVE_PATH) const version = shimmer.getPackageVersion(TEST_MODULE_PATH) - t.not(loggerMock.debug.callCount) - t.equal(version, '0.0.1', 'should get package version from package.json') - t.end() + assert.ok(!loggerMock.debug.callCount) + assert.equal(version, '0.0.1', 'should get package version from package.json') }) - t.test( + await t.test( 'should return Node.js version when it cannot obtain package version from package.json', - (t) => { + () => { const version = shimmer.getPackageVersion('bogus') - t.equal(version, process.version) - t.same(loggerMock.debug.args[0], [ + assert.equal(version, process.version) + assert.deepEqual(loggerMock.debug.args[0], [ 'Failed to get version for `%s`, reason: %s', 'bogus', `no tracked items for module 'bogus'` ]) - t.end() } ) }) diff --git a/test/unit/stats.test.js b/test/unit/stats.test.js index 27636c0822..80a4eba692 100644 --- a/test/unit/stats.test.js +++ b/test/unit/stats.test.js @@ -4,29 +4,27 @@ */ 'use strict' -const tap = require('tap') +const assert = require('node:assert') +const test = require('node:test') const Stats = require('../../lib/stats') function verifyStats(actualStats, expectedStats) { - this.equal(actualStats.callCount, expectedStats.callCount) - this.equal(actualStats.total, expectedStats.totalTime) - this.equal(actualStats.totalExclusive, expectedStats.totalExclusive) - this.equal(actualStats.min, expectedStats.min) - this.equal(actualStats.max, expectedStats.max) - this.equal(actualStats.sumOfSquares, expectedStats.sumOfSquares) + assert.equal(actualStats.callCount, expectedStats.callCount) + assert.equal(actualStats.total, expectedStats.totalTime) + assert.equal(actualStats.totalExclusive, expectedStats.totalExclusive) + assert.equal(actualStats.min, expectedStats.min) + assert.equal(actualStats.max, expectedStats.max) + assert.equal(actualStats.sumOfSquares, expectedStats.sumOfSquares) } -tap.Test.prototype.addAssert('verifyStats', 2, verifyStats) - -tap.test('Stats', function (t) { - t.autoend() - - t.beforeEach(function (t) { - t.context.statistics = new Stats() +test('Stats', async function (t) { + t.beforeEach(function (ctx) { + ctx.nr = {} + ctx.nr.statistics = new Stats() }) - t.test('should correctly summarize a sample set of statistics', function (t) { - const { statistics } = t.context + await t.test('should correctly summarize a sample set of statistics', function (t) { + const { statistics } = t.nr const expectedStats = { callCount: 3, totalTime: 0.306, @@ -40,12 +38,11 @@ tap.test('Stats', function (t) { statistics.recordValueInMillis(123, 34) statistics.recordValueInMillis(123, 34) - t.verifyStats(statistics, expectedStats) - t.end() + verifyStats(statistics, expectedStats) }) - t.test('should correctly summarize another simple set of statistics', function (t) { - const { statistics } = t.context + await t.test('should correctly summarize another simple set of statistics', function (t) { + const { statistics } = t.nr const expectedStats = { callCount: 2, totalTime: 0.24, @@ -58,14 +55,12 @@ tap.test('Stats', function (t) { statistics.recordValueInMillis(120, 0) statistics.recordValueInMillis(120, 0) - t.verifyStats(statistics, expectedStats) - t.end() + verifyStats(statistics, expectedStats) }) - t.test('incrementCallCount', function (t) { - t.autoend() - t.test('should increment by 1 by default', function (t) { - const { statistics } = t.context + await t.test('incrementCallCount', async function (t) { + await t.test('should increment by 1 by default', function (t) { + const { statistics } = t.nr const expectedStats = { callCount: 1, totalTime: 0, @@ -76,12 +71,11 @@ tap.test('Stats', function (t) { } statistics.incrementCallCount() - t.verifyStats(statistics, expectedStats) - t.end() + verifyStats(statistics, expectedStats) }) - t.test('should increment by the provided value', function (t) { - const { statistics } = t.context + await t.test('should increment by the provided value', function (t) { + const { statistics } = t.nr const expectedStats = { callCount: 23, totalTime: 0, @@ -92,12 +86,11 @@ tap.test('Stats', function (t) { } statistics.incrementCallCount(23) - t.verifyStats(statistics, expectedStats) - t.end() + verifyStats(statistics, expectedStats) }) - t.test("shouldn't increment when the provided value is 0", function (t) { - const { statistics } = t.context + await t.test("shouldn't increment when the provided value is 0", function (t) { + const { statistics } = t.nr const expectedStats = { callCount: 0, totalTime: 0, @@ -108,13 +101,12 @@ tap.test('Stats', function (t) { } statistics.incrementCallCount(0) - t.verifyStats(statistics, expectedStats) - t.end() + verifyStats(statistics, expectedStats) }) }) - t.test('should correctly merge summaries', function (t) { - const { statistics } = t.context + await t.test('should correctly merge summaries', function (t) { + const { statistics } = t.nr const expectedStats = { callCount: 3, totalTime: 0.306, @@ -128,7 +120,7 @@ tap.test('Stats', function (t) { statistics.recordValueInMillis(123, 34) statistics.recordValueInMillis(123, 34) - t.verifyStats(statistics, expectedStats) + verifyStats(statistics, expectedStats) const expectedStatsOther = { callCount: 2, @@ -143,7 +135,7 @@ tap.test('Stats', function (t) { other.recordValueInMillis(123, 0) other.recordValueInMillis(123, 0) - t.verifyStats(other, expectedStatsOther) + verifyStats(other, expectedStatsOther) const expectedStatsMerged = { callCount: 5, @@ -155,41 +147,38 @@ tap.test('Stats', function (t) { } statistics.merge(other) - t.verifyStats(statistics, expectedStatsMerged) - t.end() + verifyStats(statistics, expectedStatsMerged) }) - t.test('when handling quantities', { todo: true }, function (t) { - t.test('should store bytes as bytes, rescaling only at serialization', { todo: true }) - t.test('should store time as nanoseconds, rescaling only at serialization', { todo: true }) + await t.test('when handling quantities', { todo: true }, async function (t) { + await t.test('should store bytes as bytes, rescaling only at serialization', { todo: true }) + await t.test('should store time as nanoseconds, rescaling only at serialization', { + todo: true + }) }) - t.test('recordValueInBytes', function (t) { - t.autoend() + await t.test('recordValueInBytes', async function (t) { const MEGABYTE = 1024 ** 2 - t.test('should measure bytes as megabytes', function (t) { - const { statistics } = t.context + await t.test('should measure bytes as megabytes', function (t) { + const { statistics } = t.nr statistics.recordValueInBytes(MEGABYTE) - t.equal(statistics.total, 1) - t.equal(statistics.totalExclusive, 1) - t.end() + assert.equal(statistics.total, 1) + assert.equal(statistics.totalExclusive, 1) }) - t.test('should measure exclusive bytes ok', function (t) { - const { statistics } = t.context + await t.test('should measure exclusive bytes ok', function (t) { + const { statistics } = t.nr statistics.recordValueInBytes(MEGABYTE * 2, MEGABYTE) - t.equal(statistics.total, 2) - t.equal(statistics.totalExclusive, 1) - t.end() + assert.equal(statistics.total, 2) + assert.equal(statistics.totalExclusive, 1) }) - t.test('should optionally not convert bytes to megabytes', function (t) { - const { statistics } = t.context + await t.test('should optionally not convert bytes to megabytes', function (t) { + const { statistics } = t.nr statistics.recordValueInBytes(MEGABYTE * 2, MEGABYTE, true) - t.equal(statistics.total, MEGABYTE * 2) - t.equal(statistics.totalExclusive, MEGABYTE) - t.end() + assert.equal(statistics.total, MEGABYTE * 2) + assert.equal(statistics.totalExclusive, MEGABYTE) }) }) }) diff --git a/test/unit/synthetics.test.js b/test/unit/synthetics.test.js index 77b26b52b9..c655bedff5 100644 --- a/test/unit/synthetics.test.js +++ b/test/unit/synthetics.test.js @@ -4,8 +4,8 @@ */ 'use strict' - -const tap = require('tap') +const assert = require('node:assert') +const test = require('node:test') const proxyquire = require('proxyquire') const sinon = require('sinon') @@ -18,32 +18,25 @@ const { ENCODING_KEY, SYNTHETICS_DATA_ARRAY } = require('../helpers/synthetics') +const sandbox = sinon.createSandbox() +const loggerMock = require('./mocks/logger')(sandbox) +const synthetics = proxyquire('../../lib/synthetics', { + './logger': { + child: sandbox.stub().callsFake(() => loggerMock) + } +}) // Other files test more functionality // See: // * test/unit/analytics_events.test.js // * test/unit/instrumentation/http/synthetics.test.js // * test/unit/transaction.test.js -tap.test('synthetics helpers', (t) => { - let sandbox - let synthetics - let loggerMock - t.autoend() - t.before(() => { - sandbox = sinon.createSandbox() - loggerMock = require('./mocks/logger')(sandbox) - synthetics = proxyquire('../../lib/synthetics', { - './logger': { - child: sandbox.stub().callsFake(() => loggerMock) - } - }) - }) - +test('synthetics helpers', async (t) => { t.afterEach(() => { sandbox.resetHistory() }) - t.test('should assign synthetics and synthetics info header to transaction', (t) => { + await t.test('should assign synthetics and synthetics info header to transaction', () => { const tx = {} const headers = { 'x-newrelic-synthetics': SYNTHETICS_HEADER, @@ -54,15 +47,20 @@ tap.test('synthetics helpers', (t) => { tx, headers ) - t.same(loggerMock.trace.args[0], ['Parsed synthetics header: %s', SYNTHETICS_DATA_ARRAY]) - t.same(loggerMock.trace.args[1], ['Parsed synthetics info header: %s', SYNTHETICS_INFO]) - t.same(tx.syntheticsData, SYNTHETICS_DATA) - t.equal(tx.syntheticsHeader, SYNTHETICS_HEADER) - t.same(tx.syntheticsInfoData, SYNTHETICS_INFO) - t.equal(tx.syntheticsInfoHeader, SYNTHETICS_INFO_HEADER) - t.end() + assert.deepEqual(loggerMock.trace.args[0], [ + 'Parsed synthetics header: %s', + SYNTHETICS_DATA_ARRAY + ]) + assert.deepEqual(loggerMock.trace.args[1], [ + 'Parsed synthetics info header: %s', + SYNTHETICS_INFO + ]) + assert.deepEqual(tx.syntheticsData, SYNTHETICS_DATA) + assert.equal(tx.syntheticsHeader, SYNTHETICS_HEADER) + assert.deepEqual(tx.syntheticsInfoData, SYNTHETICS_INFO) + assert.equal(tx.syntheticsInfoHeader, SYNTHETICS_INFO_HEADER) }) - t.test('should not assign header if unable to decode header', (t) => { + await t.test('should not assign header if unable to decode header', () => { const tx = {} const headers = { 'x-newrelic-synthetics': 'bogus' @@ -72,12 +70,11 @@ tap.test('synthetics helpers', (t) => { tx, headers ) - t.equal(loggerMock.trace.args[0][1], 'Cannot parse synthetics header: %s') - t.equal(loggerMock.trace.args[0][2], 'bogus') - t.same(tx, {}) - t.end() + assert.equal(loggerMock.trace.args[0][1], 'Cannot parse synthetics header: %s') + assert.equal(loggerMock.trace.args[0][2], 'bogus') + assert.deepEqual(tx, {}) }) - t.test('should not assign synthetics header if not an array', (t) => { + await t.test('should not assign synthetics header if not an array', () => { const header = hashes.obfuscateNameUsingKey(JSON.stringify({ key: 'value' }), ENCODING_KEY) const tx = {} const headers = { @@ -88,12 +85,11 @@ tap.test('synthetics helpers', (t) => { tx, headers ) - t.equal(loggerMock.trace.args[1][0], 'Synthetics data is not an array.') - t.same(tx, {}) - t.end() + assert.equal(loggerMock.trace.args[1][0], 'Synthetics data is not an array.') + assert.deepEqual(tx, {}) }) - t.test('should log trace warning if not all values synthetics header are in array', (t) => { + await t.test('should log trace warning if not all values synthetics header are in array', () => { const data = [...SYNTHETICS_DATA_ARRAY] data.pop() data.pop() @@ -108,19 +104,22 @@ tap.test('synthetics helpers', (t) => { tx, headers ) - t.same(loggerMock.trace.args[1], ['Synthetics header length is %s, expected at least %s', 3, 5]) - t.equal(tx.syntheticsHeader, header) - t.same(tx.syntheticsData, { + assert.deepEqual(loggerMock.trace.args[1], [ + 'Synthetics header length is %s, expected at least %s', + 3, + 5 + ]) + assert.equal(tx.syntheticsHeader, header) + assert.deepEqual(tx.syntheticsData, { version: 1, accountId: 567, resourceId: 'resource', jobId: undefined, monitorId: undefined }) - t.end() }) - t.test('should not assign synthetics header if version is not 1', (t) => { + await t.test('should not assign synthetics header if version is not 1', () => { const data = [...SYNTHETICS_DATA_ARRAY] data[0] = 2 const header = hashes.obfuscateNameUsingKey(JSON.stringify(data), ENCODING_KEY) @@ -133,12 +132,11 @@ tap.test('synthetics helpers', (t) => { tx, headers ) - t.same(loggerMock.trace.args[1], ['Synthetics header version is not 1, got: %s', 2]) - t.same(tx, {}) - t.end() + assert.deepEqual(loggerMock.trace.args[1], ['Synthetics header version is not 1, got: %s', 2]) + assert.deepEqual(tx, {}) }) - t.test('should not assign synthetics header if account id is not in trusted ids', (t) => { + await t.test('should not assign synthetics header if account id is not in trusted ids', () => { const data = [...SYNTHETICS_DATA_ARRAY] data[1] = 999 const header = hashes.obfuscateNameUsingKey(JSON.stringify(data), ENCODING_KEY) @@ -151,16 +149,15 @@ tap.test('synthetics helpers', (t) => { tx, headers ) - t.same(loggerMock.trace.args[1], [ + assert.deepEqual(loggerMock.trace.args[1], [ 'Synthetics header account ID is not in trusted account IDs: %s (%s)', 999, '567,243' ]) - t.same(tx, {}) - t.end() + assert.deepEqual(tx, {}) }) - t.test('should not assign info header if unable to decode header', (t) => { + await t.test('should not assign info header if unable to decode header', () => { const tx = {} const headers = { 'x-newrelic-synthetics-info': 'bogus' @@ -170,12 +167,11 @@ tap.test('synthetics helpers', (t) => { tx, headers ) - t.equal(loggerMock.trace.args[0][1], 'Cannot parse synthetics info header: %s') - t.equal(loggerMock.trace.args[0][2], 'bogus') - t.same(tx, {}) - t.end() + assert.equal(loggerMock.trace.args[0][1], 'Cannot parse synthetics info header: %s') + assert.equal(loggerMock.trace.args[0][2], 'bogus') + assert.deepEqual(tx, {}) }) - t.test('should not assign info header if object is empty', (t) => { + await t.test('should not assign info header if object is empty', () => { const header = hashes.obfuscateNameUsingKey(JSON.stringify([1]), ENCODING_KEY) const tx = {} const headers = { @@ -186,12 +182,11 @@ tap.test('synthetics helpers', (t) => { tx, headers ) - t.equal(loggerMock.trace.args[1][0], 'Synthetics info data is not an object.') - t.same(tx, {}) - t.end() + assert.equal(loggerMock.trace.args[1][0], 'Synthetics info data is not an object.') + assert.deepEqual(tx, {}) }) - t.test('should not assign info header if version is not 1', (t) => { + await t.test('should not assign info header if version is not 1', () => { const data = { ...SYNTHETICS_INFO } data.version = 2 const header = hashes.obfuscateNameUsingKey(JSON.stringify(data), ENCODING_KEY) @@ -204,8 +199,10 @@ tap.test('synthetics helpers', (t) => { tx, headers ) - t.same(loggerMock.trace.args[1], ['Synthetics info header version is not 1, got: %s', 2]) - t.same(tx, {}) - t.end() + assert.deepEqual(loggerMock.trace.args[1], [ + 'Synthetics info header version is not 1, got: %s', + 2 + ]) + assert.deepEqual(tx, {}) }) }) diff --git a/test/unit/system-info.test.js b/test/unit/system-info.test.js index 12c270278d..242f6c2f05 100644 --- a/test/unit/system-info.test.js +++ b/test/unit/system-info.test.js @@ -4,23 +4,18 @@ */ 'use strict' -const tap = require('tap') +const assert = require('node:assert') +const test = require('node:test') const os = require('os') const proxyquire = require('proxyquire').noPreserveCache() const sinon = require('sinon') -tap.test('getProcessorStats - darwin', (t) => { - t.autoend() - - let platformFunction - let execFunction - let systemInfo - - t.beforeEach(() => { - platformFunction = sinon.stub().returns('darwin') - execFunction = sinon.stub() - - systemInfo = proxyquire('../../lib/system-info', { +test('getProcessorStats - darwin', async (t) => { + t.beforeEach((ctx) => { + ctx.nr = {} + const platformFunction = sinon.stub().returns('darwin') + const execFunction = sinon.stub() + ctx.nr.systemInfo = proxyquire('../../lib/system-info', { os: { platform: platformFunction }, @@ -28,9 +23,11 @@ tap.test('getProcessorStats - darwin', (t) => { execFile: execFunction } }) + ctx.nr.execFunction = execFunction }) - t.test('should return default data when all lookups error', async (t) => { + await t.test('should return default data when all lookups error', async (t) => { + const { execFunction, systemInfo } = t.nr execFunction.yields(new Error('whoops'), { stderr: null, stdout: null }) const results = await systemInfo._getProcessorStats() @@ -39,10 +36,11 @@ tap.test('getProcessorStats - darwin', (t) => { cores: null, packages: null } - t.same(results, expected, 'should return the expected results') + assert.deepEqual(results, expected, 'should return the expected results') }) - t.test('should return default data when all lookups return no data', async (t) => { + await t.test('should return default data when all lookups return no data', async (t) => { + const { execFunction, systemInfo } = t.nr execFunction.yields(null, { stderr: null, stdout: null }) const results = await systemInfo._getProcessorStats() @@ -51,10 +49,11 @@ tap.test('getProcessorStats - darwin', (t) => { cores: null, packages: null } - t.same(results, expected, 'should return the expected results') + assert.deepEqual(results, expected, 'should return the expected results') }) - t.test('should return default data when all lookups return errors', async (t) => { + await t.test('should return default data when all lookups return errors', async (t) => { + const { execFunction, systemInfo } = t.nr execFunction.yields(null, { stderr: new Error('oops'), stdout: null }) const results = await systemInfo._getProcessorStats() @@ -63,10 +62,11 @@ tap.test('getProcessorStats - darwin', (t) => { cores: null, packages: null } - t.same(results, expected, 'should return the expected results') + assert.deepEqual(results, expected, 'should return the expected results') }) - t.test('should return default data when all lookups return unexpected data', async (t) => { + await t.test('should return default data when all lookups return unexpected data', async (t) => { + const { execFunction, systemInfo } = t.nr execFunction.yields(null, { stderr: null, stdout: 'foo' }) const results = await systemInfo._getProcessorStats() @@ -75,10 +75,11 @@ tap.test('getProcessorStats - darwin', (t) => { cores: null, packages: null } - t.same(results, expected, 'should return the expected results') + assert.deepEqual(results, expected, 'should return the expected results') }) - t.test('should return data when all lookups succeed', async (t) => { + await t.test('should return data when all lookups succeed', async (t) => { + const { execFunction, systemInfo } = t.nr execFunction.yields(null, { stderr: null, stdout: 123 }) const results = await systemInfo._getProcessorStats() @@ -87,10 +88,11 @@ tap.test('getProcessorStats - darwin', (t) => { cores: 123, packages: 123 } - t.same(results, expected, 'should return the expected results') + assert.deepEqual(results, expected, 'should return the expected results') }) - t.test('should return data when all lookups eventually succeed', async (t) => { + await t.test('should return data when all lookups eventually succeed', async (t) => { + const { execFunction, systemInfo } = t.nr execFunction .onCall(0) .yields(null, { stderr: null, stdout: 789 }) @@ -111,22 +113,17 @@ tap.test('getProcessorStats - darwin', (t) => { cores: 456, packages: 789 } - t.same(results, expected, 'should return the expected results') + assert.deepEqual(results, expected, 'should return the expected results') }) }) -tap.test('getProcessorStats - bsd', (t) => { - t.autoend() - - let platformFunction - let execFunction - let systemInfo +test('getProcessorStats - bsd', async (t) => { + t.beforeEach((ctx) => { + ctx.nr = {} + const platformFunction = sinon.stub().returns('bsd') + const execFunction = sinon.stub() - t.beforeEach(() => { - platformFunction = sinon.stub().returns('bsd') - execFunction = sinon.stub() - - systemInfo = proxyquire('../../lib/system-info', { + ctx.nr.systemInfo = proxyquire('../../lib/system-info', { os: { platform: platformFunction }, @@ -134,9 +131,11 @@ tap.test('getProcessorStats - bsd', (t) => { execFile: execFunction } }) + ctx.nr.execFunction = execFunction }) - t.test('should return data', async (t) => { + await t.test('should return data', async (t) => { + const { execFunction, systemInfo } = t.nr execFunction.yields(null, { stderr: null, stdout: 123 }) const results = await systemInfo._getProcessorStats() @@ -145,22 +144,17 @@ tap.test('getProcessorStats - bsd', (t) => { cores: null, packages: null } - t.same(results, expected, 'should return the expected results') + assert.deepEqual(results, expected, 'should return the expected results') }) }) -tap.test('getProcessorStats - linux', (t) => { - t.autoend() - - let platformFunction - let readProcFunction - let systemInfo +test('getProcessorStats - linux', async (t) => { + t.beforeEach((ctx) => { + ctx.nr = {} + const platformFunction = sinon.stub().returns('linux') + const readProcFunction = sinon.stub() - t.beforeEach(() => { - platformFunction = sinon.stub().returns('linux') - readProcFunction = sinon.stub() - - systemInfo = proxyquire('../../lib/system-info', { + ctx.nr.systemInfo = proxyquire('../../lib/system-info', { './utilization/common': { readProc: readProcFunction }, @@ -168,9 +162,11 @@ tap.test('getProcessorStats - linux', (t) => { platform: platformFunction } }) + ctx.nr.readProcFunction = readProcFunction }) - t.test('should return data', async (t) => { + await t.test('should return data', async (t) => { + const { readProcFunction, systemInfo } = t.nr const exampleProcfile = `processor : 0 vendor_id : GenuineIntel cpu family : 6 @@ -205,10 +201,11 @@ tap.test('getProcessorStats - linux', (t) => { cores: 8, packages: 1 } - t.same(results, expected, 'should return the expected results') + assert.deepEqual(results, expected, 'should return the expected results') }) - t.test('should return null if readProc fails', async (t) => { + await t.test('should return null if readProc fails', async (t) => { + const { readProcFunction, systemInfo } = t.nr readProcFunction.yields(new Error('oops')) const results = await systemInfo._getProcessorStats() @@ -217,48 +214,41 @@ tap.test('getProcessorStats - linux', (t) => { cores: null, packages: null } - t.same(results, expected, 'should return the expected results') + assert.deepEqual(results, expected, 'should return the expected results') }) }) -tap.test('getProcessorStats - unknown', (t) => { - t.autoend() - - let platformFunction - let systemInfo +test('getProcessorStats - unknown', async (t) => { + t.beforeEach((ctx) => { + ctx.nr = {} + const platformFunction = sinon.stub().returns('something weird') - t.beforeEach(() => { - platformFunction = sinon.stub().returns('something weird') - - systemInfo = proxyquire('../../lib/system-info', { + ctx.nr.systemInfo = proxyquire('../../lib/system-info', { os: { platform: platformFunction } }) }) - t.test('should return default data', async (t) => { + await t.test('should return default data', async (t) => { + const { systemInfo } = t.nr const results = await systemInfo._getProcessorStats() const expected = { logical: null, cores: null, packages: null } - t.same(results, expected, 'should return the expected results') + assert.deepEqual(results, expected, 'should return the expected results') }) }) -tap.test('getMemoryStats - darwin', (t) => { - t.autoend() - let platformFunction - let execFunction - let systemInfo - - t.beforeEach(() => { - platformFunction = sinon.stub().returns('darwin') - execFunction = sinon.stub() +test('getMemoryStats - darwin', async (t) => { + t.beforeEach((ctx) => { + ctx.nr = {} + const platformFunction = sinon.stub().returns('darwin') + const execFunction = sinon.stub() - systemInfo = proxyquire('../../lib/system-info', { + ctx.nr.systemInfo = proxyquire('../../lib/system-info', { os: { platform: platformFunction }, @@ -266,26 +256,24 @@ tap.test('getMemoryStats - darwin', (t) => { execFile: execFunction } }) + ctx.nr.execFunction = execFunction }) - t.test('should return data', async (t) => { + await t.test('should return data', async (t) => { + const { execFunction, systemInfo } = t.nr execFunction.yields(null, { stderr: null, stdout: 1024 * 1024 }) const results = await systemInfo._getMemoryStats() - t.equal(results, 1) + assert.equal(results, 1) }) }) -tap.test('getMemoryStats - bsd', (t) => { - t.autoend() - let platformFunction - let execFunction - let systemInfo +test('getMemoryStats - bsd', async (t) => { + t.beforeEach((ctx) => { + ctx.nr = {} + const platformFunction = sinon.stub().returns('bsd') + const execFunction = sinon.stub() - t.beforeEach(() => { - platformFunction = sinon.stub().returns('bsd') - execFunction = sinon.stub() - - systemInfo = proxyquire('../../lib/system-info', { + ctx.nr.systemInfo = proxyquire('../../lib/system-info', { os: { platform: platformFunction }, @@ -293,26 +281,24 @@ tap.test('getMemoryStats - bsd', (t) => { execFile: execFunction } }) + ctx.nr.execFunction = execFunction }) - t.test('should return data', async (t) => { + await t.test('should return data', async (t) => { + const { execFunction, systemInfo } = t.nr execFunction.yields(null, { stderr: null, stdout: 1024 * 1024 }) const results = await systemInfo._getMemoryStats() - t.equal(results, 1) + assert.equal(results, 1) }) }) -tap.test('getMemoryStats - linux', (t) => { - t.autoend() - let platformFunction - let readProcFunction - let systemInfo - - t.beforeEach(() => { - platformFunction = sinon.stub().returns('linux') - readProcFunction = sinon.stub() +test('getMemoryStats - linux', async (t) => { + t.beforeEach((ctx) => { + ctx.nr = {} + const platformFunction = sinon.stub().returns('linux') + const readProcFunction = sinon.stub() - systemInfo = proxyquire('../../lib/system-info', { + ctx.nr.systemInfo = proxyquire('../../lib/system-info', { './utilization/common': { readProc: readProcFunction }, @@ -320,9 +306,11 @@ tap.test('getMemoryStats - linux', (t) => { platform: platformFunction } }) + ctx.nr.readProcFunction = readProcFunction }) - t.test('should return data', async (t) => { + await t.test('should return data', async (t) => { + const { readProcFunction, systemInfo } = t.nr const exampleProcfile = `MemTotal: 1882064 kB MemFree: 1376380 kB MemAvailable: 1535676 kB @@ -369,42 +357,38 @@ tap.test('getMemoryStats - linux', (t) => { readProcFunction.yields(null, exampleProcfile) const results = await systemInfo._getMemoryStats() - t.equal(results, 1837.953125) + assert.equal(results, 1837.953125) }) - t.test('should return null if readProc fails', async (t) => { + await t.test('should return null if readProc fails', async (t) => { + const { readProcFunction, systemInfo } = t.nr readProcFunction.yields(new Error('oops')) const results = await systemInfo._getMemoryStats() - t.equal(results, null) + assert.equal(results, null) }) }) -tap.test('getProcessorStats - unknown', (t) => { - t.autoend() +test('getProcessorStats - unknown', async (t) => { + t.beforeEach((ctx) => { + ctx.nr = {} + const platformFunction = sinon.stub().returns('something weird') - let platformFunction - let systemInfo - - t.beforeEach(() => { - platformFunction = sinon.stub().returns('something weird') - - systemInfo = proxyquire('../../lib/system-info', { + ctx.nr.systemInfo = proxyquire('../../lib/system-info', { os: { platform: platformFunction } }) }) - t.test('should return default data', async (t) => { + await t.test('should return default data', async (t) => { + const { systemInfo } = t.nr const results = await systemInfo._getMemoryStats() - t.equal(results, null) + assert.equal(results, null) }) }) -tap.test('systemInfo edge cases', (t) => { - t.autoend() - +test('systemInfo edge cases', async (t) => { const systemInfo = proxyquire('../../lib/system-info', { './utilization/docker-info': { getBootId: (agent, callback) => callback(null) @@ -429,9 +413,9 @@ tap.test('systemInfo edge cases', (t) => { }) } - t.test( + await t.test( 'should set logical_processors, total_ram_mib, and hostname if in configuration', - async (t) => { + async () => { const mockConfig = { logical_processors: '2', total_ram_mib: '2048', @@ -443,27 +427,27 @@ tap.test('systemInfo edge cases', (t) => { hostname: 'bob_test' } const config = await callSystemInfo(mockConfig) - t.same(config, { processorArch: os.arch(), config: parsedConfig }) + assert.deepEqual(config, { processorArch: os.arch(), config: parsedConfig }) } ) - t.test( + await t.test( 'should not try to set system info config if it does not exist in configuration', - async (t) => { + async () => { const config = await callSystemInfo(null) - t.same(config, { processorArch: os.arch() }) + assert.deepEqual(config, { processorArch: os.arch() }) } ) - t.test('should log error if utilization.logical_processor is a NaN', async (t) => { + await t.test('should log error if utilization.logical_processor is a NaN', async () => { const mockConfig = { logical_processors: 'bogus' } const config = await callSystemInfo(mockConfig) - t.same(config, { processorArch: os.arch() }) + assert.deepEqual(config, { processorArch: os.arch() }) }) - t.test('should log error if utilization.total_ram_mib is a NaN', async (t) => { + await t.test('should log error if utilization.total_ram_mib is a NaN', async () => { const mockConfig = { total_ram_mib: 'bogus' } const config = await callSystemInfo(mockConfig) - t.same(config, { processorArch: os.arch() }) + assert.deepEqual(config, { processorArch: os.arch() }) }) })