From 0b07be8f7f29e67630326c73b96faa5e20527a0b Mon Sep 17 00:00:00 2001 From: Bob Evans Date: Mon, 9 Sep 2024 10:42:38 -0400 Subject: [PATCH] test: Migrated `test/unit/util` to use `node:test` (#2546) --- test/unit/util/application-logging.test.js | 158 ++++--- test/unit/util/async-each-limit.test.js | 22 +- test/unit/util/byte-limit.test.js | 72 ++-- test/unit/util/camel-case.test.js | 9 +- test/unit/util/code-level-metrics.test.js | 174 ++++---- test/unit/util/codec.test.js | 57 ++- test/unit/util/hashes.test.js | 48 +-- test/unit/util/label-parser.test.js | 18 +- test/unit/util/llm-utils.test.js | 53 ++- test/unit/util/logger.test.js | 467 ++++++++++++--------- test/unit/util/obfuscate-sql.test.js | 53 ++- test/unit/util/objects.test.js | 37 +- test/unit/util/snake-case.test.js | 22 +- 13 files changed, 594 insertions(+), 596 deletions(-) diff --git a/test/unit/util/application-logging.test.js b/test/unit/util/application-logging.test.js index 54926db100..2cdc84ad6a 100644 --- a/test/unit/util/application-logging.test.js +++ b/test/unit/util/application-logging.test.js @@ -4,15 +4,14 @@ */ 'use strict' - -const tap = require('tap') +const assert = require('node:assert') +const test = require('node:test') const sinon = require('sinon') const loggingUtils = require('../../../lib/util/application-logging') const { LOGGING } = require('../../../lib/metrics/names') -tap.test('truncate', (t) => { - t.autoend() - t.test('Should truncate string > 1024 chars', (t) => { +test('truncate', async (t) => { + await t.test('Should truncate string > 1024 chars', () => { const longString = '1111111111111111111111111111111111111111111111111111111111111111' + '1111111111111111111111111111111111111111111111111111111111111111' + @@ -35,19 +34,16 @@ tap.test('truncate', (t) => { const processedStr = loggingUtils.truncate(longString) - t.equal(processedStr.length, 1024) - t.equal(processedStr.substring(processedStr.length - 3), '...') - - t.end() + assert.equal(processedStr.length, 1024) + assert.equal(processedStr.substring(processedStr.length - 3), '...') }) - t.test('Should return non-truncated string when <= 1024 chars', (t) => { + await t.test('Should return non-truncated string when <= 1024 chars', () => { const str = 'kenny loggins' const processedStr = loggingUtils.truncate(str) - t.equal(processedStr, str) - t.end() + assert.equal(processedStr, str) }) const negativeTests = [ @@ -58,27 +54,25 @@ tap.test('truncate', (t) => { { value: [], type: 'array' }, { value: function () {}, type: 'function' } ] - negativeTests.forEach(({ value, type }) => { - t.test(`should not truncate ${type}`, (t) => { + for (const negativeTest of negativeTests) { + const { value, type } = negativeTest + await t.test(`should not truncate ${type}`, () => { const newValue = loggingUtils.truncate(value) - t.same(value, newValue) - t.end() + assert.deepEqual(value, newValue) }) - }) + } }) -tap.test('Application Logging Config Tests', (t) => { - t.autoend() +test('Application Logging Config Tests', async (t) => { const features = [ { feature: 'metrics', method: 'isMetricsEnabled' }, { feature: 'forwarding', method: 'isLogForwardingEnabled' }, { feature: 'local_decorating', method: 'isLocalDecoratingEnabled' } ] - let config = {} - - t.beforeEach(() => { - config = { + t.beforeEach((ctx) => { + ctx.nr = {} + ctx.nr.config = { application_logging: { enabled: true, metrics: { @@ -94,88 +88,90 @@ tap.test('Application Logging Config Tests', (t) => { } }) - features.forEach(({ feature, method }) => { - t.test( - `isApplicationLoggingEnabled should be true when application_logging and ${feature} is truthy`, - (t) => { - config.application_logging[feature].enabled = true - t.equal(loggingUtils.isApplicationLoggingEnabled(config), true) - t.end() - } - ) + await Promise.all( + features.map(async ({ feature, method }) => { + await t.test( + `isApplicationLoggingEnabled should be true when application_logging and ${feature} is truthy`, + (t) => { + const { config } = t.nr + config.application_logging[feature].enabled = true + assert.equal(loggingUtils.isApplicationLoggingEnabled(config), true) + } + ) - t.test(`${method} should be true when application_logging and ${feature} are truthy`, (t) => { - config.application_logging[feature].enabled = true - if (feature === 'forwarding') { - t.equal(loggingUtils[method](config, { logs: true }), true) - } else { - t.equal(loggingUtils[method](config), true) - } - t.end() + await t.test( + `${method} should be true when application_logging and ${feature} are truthy`, + (t) => { + const { config } = t.nr + config.application_logging[feature].enabled = true + if (feature === 'forwarding') { + assert.equal(loggingUtils[method](config, { logs: true }), true) + } else { + assert.equal(loggingUtils[method](config), true) + } + } + ) }) - }) + ) - t.test('should be false when application_logging is false', (t) => { + await t.test('should be false when application_logging is false', (t) => { + const { config } = t.nr config.application_logging.enabled = false - t.equal(loggingUtils.isApplicationLoggingEnabled(config), false) - t.end() + assert.equal(loggingUtils.isApplicationLoggingEnabled(config), false) }) - t.test('should be false when all features are false', (t) => { - t.equal(loggingUtils.isApplicationLoggingEnabled(config), false) - t.end() + await t.test('should be false when all features are false', (t) => { + const { config } = t.nr + assert.equal(loggingUtils.isApplicationLoggingEnabled(config), false) }) }) -tap.test('incrementLoggingLinesMetrics', (t) => { - t.autoend() - let callCountStub = null - let metricsStub = null - t.beforeEach(() => { - callCountStub = { incrementCallCount: sinon.stub() } - metricsStub = { +test('incrementLoggingLinesMetrics', async (t) => { + t.beforeEach((ctx) => { + console.log('before test') + ctx.nr = {} + const callCountStub = { incrementCallCount: sinon.stub() } + ctx.nr.metricsStub = { getOrCreateMetric: sinon.stub().returns(callCountStub) } - }) - - t.afterEach(() => { - callCountStub = null - metricsStub = null + ctx.nr.callCountStub = callCountStub }) const levels = Object.keys(LOGGING.LEVELS) - levels.forEach((level) => { - const levelLowercase = level.toLowerCase() - t.test(`should increment logging lines metrics for level: ${levelLowercase}`, (t) => { - loggingUtils.incrementLoggingLinesMetrics(levelLowercase, metricsStub) - t.equal( - metricsStub.getOrCreateMetric.args[0][0], - LOGGING.LINES, - `should create ${LOGGING.LINES} metric` - ) - t.equal( - metricsStub.getOrCreateMetric.args[1][0], - LOGGING.LEVELS[level], - `should create ${LOGGING.LEVELS[level]} metric` - ) - t.equal(callCountStub.incrementCallCount.callCount, 2, 'should increment each metric') - t.end() + await Promise.all( + levels.map(async (level) => { + const levelLowercase = level.toLowerCase() + await t.test(`should increment logging lines metrics for level: ${levelLowercase}`, (t) => { + const { metricsStub, callCountStub } = t.nr + loggingUtils.incrementLoggingLinesMetrics(levelLowercase, metricsStub) + assert.equal( + metricsStub.getOrCreateMetric.args[0][0], + LOGGING.LINES, + `should create ${LOGGING.LINES} metric` + ) + assert.equal( + metricsStub.getOrCreateMetric.args[1][0], + LOGGING.LEVELS[level], + `should create ${LOGGING.LEVELS[level]} metric` + ) + assert.equal(callCountStub.incrementCallCount.callCount, 2, 'should increment each metric') + }) }) - }) + ) - t.test('should default to unknown when level is undefined', (t) => { + await t.test('should default to unknown when level is undefined', (t) => { + const { metricsStub, callCountStub } = t.nr loggingUtils.incrementLoggingLinesMetrics(undefined, metricsStub) - t.equal( + assert.equal( metricsStub.getOrCreateMetric.args[0][0], LOGGING.LINES, `should create ${LOGGING.LINES} metric` ) - t.equal( + assert.equal( metricsStub.getOrCreateMetric.args[1][0], LOGGING.LEVELS.UNKNOWN, `should create ${LOGGING.LEVELS.UNKNOWN} metric` ) - t.equal(callCountStub.incrementCallCount.callCount, 2, 'should increment each metric') - t.end() + assert.equal(callCountStub.incrementCallCount.callCount, 2, 'should increment each metric') }) }) diff --git a/test/unit/util/async-each-limit.test.js b/test/unit/util/async-each-limit.test.js index 9d62065fe5..884b140b77 100644 --- a/test/unit/util/async-each-limit.test.js +++ b/test/unit/util/async-each-limit.test.js @@ -4,12 +4,12 @@ */ 'use strict' - -const { test } = require('tap') +const assert = require('node:assert') +const test = require('node:test') const sinon = require('sinon') const eachLimit = require('../../../lib/util/async-each-limit') -test('eachLimit should limit concurrent async executions', async (t) => { +test('eachLimit should limit concurrent async executions', async () => { let firstPromiseResolve let secondPromiseResolve let thirdPromiseResolve @@ -47,20 +47,20 @@ test('eachLimit should limit concurrent async executions', async (t) => { const promise = eachLimit(items, mapper, 2) - t.equal(access.callCount, 2, 'should have called two promises') - t.ok(access.calledWith('foo.json'), 'should have called the first promise') - t.ok(access.calledWith('bar.json'), 'should have called the second promise') - t.notOk(access.calledWith('baz.json'), 'should not have called the third promise yet') + assert.equal(access.callCount, 2, 'should have called two promises') + assert.ok(access.calledWith('foo.json'), 'should have called the first promise') + assert.ok(access.calledWith('bar.json'), 'should have called the second promise') + assert.ok(!access.calledWith('baz.json'), 'should not have called the third promise yet') firstPromiseResolve() - t.notOk(access.calledWith('baz.json'), 'should still not have called the third promise') + assert.ok(!access.calledWith('baz.json'), 'should still not have called the third promise') secondPromiseResolve() thirdPromiseResolve() const results = await promise - t.equal(access.callCount, 3, 'should have called three promises') - t.ok(access.calledWith('baz.json'), 'should have called the third promise') - t.same(results, [true, true, true], 'should return the correct results') + assert.equal(access.callCount, 3, 'should have called three promises') + assert.ok(access.calledWith('baz.json'), 'should have called the third promise') + assert.deepEqual(results, [true, true, true], 'should return the correct results') }) diff --git a/test/unit/util/byte-limit.test.js b/test/unit/util/byte-limit.test.js index 5a443ac805..3a7c6365cb 100644 --- a/test/unit/util/byte-limit.test.js +++ b/test/unit/util/byte-limit.test.js @@ -4,79 +4,65 @@ */ 'use strict' - -const { test } = require('tap') +const assert = require('node:assert') +const test = require('node:test') const byteUtils = require('../../../lib/util/byte-limit') -test('byte-limit', (t) => { - t.autoend() - - t.test('#isValidLength', (t) => { - t.autoend() - t.test('returns false when the string is larger than the limit', (t) => { - t.notOk(byteUtils.isValidLength('12345', 4)) - t.end() +test('byte-limit', async (t) => { + await t.test('#isValidLength', async (t) => { + await t.test('returns false when the string is larger than the limit', () => { + assert.ok(!byteUtils.isValidLength('12345', 4)) }) - t.test('returns true when the string is equal to the limit', (t) => { - t.ok(byteUtils.isValidLength('12345', 5)) - t.end() + await t.test('returns true when the string is equal to the limit', () => { + assert.ok(byteUtils.isValidLength('12345', 5)) }) - t.test('returns true when the string is smaller than the limit', (t) => { - t.ok(byteUtils.isValidLength('12345', 6)) - t.end() + await t.test('returns true when the string is smaller than the limit', () => { + assert.ok(byteUtils.isValidLength('12345', 6)) }) }) - t.test('#compareLength', (t) => { - t.autoend() - t.test('returns -1 when the string is smaller than the limit', (t) => { + + await t.test('#compareLength', async (t) => { + await t.test('returns -1 when the string is smaller than the limit', () => { const str = '123456789' const cmpVal = byteUtils.compareLength(str, 255) - t.ok(cmpVal < 0) - t.end() + assert.ok(cmpVal < 0) }) - t.test('returns 0 when the string is equal than the limit', (t) => { + await t.test('returns 0 when the string is equal than the limit', () => { const str = '123456789' const cmpVal = byteUtils.compareLength(str, 9) - t.equal(cmpVal, 0) - t.end() + assert.equal(cmpVal, 0) }) - t.test('returns 1 when the string is larger than the limit', (t) => { + await t.test('returns 1 when the string is larger than the limit', () => { const str = '123456789' const cmpVal = byteUtils.compareLength(str, 2) - t.ok(cmpVal > 0) - t.end() + assert.ok(cmpVal > 0) }) }) - t.test('#truncate', (t) => { - t.autoend() - t.test('truncates string value to given limit', (t) => { + await t.test('#truncate', async (t) => { + await t.test('truncates string value to given limit', () => { let str = '123456789' str = byteUtils.truncate(str, 5) - t.equal(str, '12345') - t.end() + assert.equal(str, '12345') }) - t.test('returns original string if within limit', (t) => { + await t.test('returns original string if within limit', () => { let str = '123456789' str = byteUtils.truncate(str, 10) - t.equal(str, '123456789') - t.end() + assert.equal(str, '123456789') }) - t.test('respects multibyte characters', (t) => { + await t.test('respects multibyte characters', () => { let str = '\uD87E\uDC04\uD87E\uDC04' - t.equal(Buffer.byteLength(str, 'utf8'), 8) + assert.equal(Buffer.byteLength(str, 'utf8'), 8) str = byteUtils.truncate(str, 3) - t.equal(str, '\uD87E') - t.end() + assert.equal(str, '\uD87E') }) - t.test('should strings with split unicode characters properly', (t) => { + await t.test('should strings with split unicode characters properly', () => { let str = '\uD87E\uDC04\uD87E\uDC04' - t.equal(Buffer.byteLength(str, 'utf8'), 8) + assert.equal(Buffer.byteLength(str, 'utf8'), 8) str = byteUtils.truncate(str, 2) - t.equal(str, '') - t.end() + assert.equal(str, '') }) }) }) diff --git a/test/unit/util/camel-case.test.js b/test/unit/util/camel-case.test.js index 48af2a3bb3..6ee1c40986 100644 --- a/test/unit/util/camel-case.test.js +++ b/test/unit/util/camel-case.test.js @@ -4,18 +4,17 @@ */ 'use strict' - -const tap = require('tap') +const assert = require('node:assert') +const test = require('node:test') const toCamelCase = require('../../../lib/util/camel-case') -tap.test('toCamelCase', (t) => { +test('toCamelCase', () => { ;[ { str: 'snake_case', expected: 'snakeCase' }, { str: 'myTestString', expected: 'myTestString' }, { str: '123AttrKey', expected: '123AttrKey' }, { str: 'X-Foo-Bar', expected: 'xFooBar' } ].forEach(({ str, expected }) => { - t.equal(toCamelCase(str), expected, `should convert ${str} to ${expected}`) + assert.equal(toCamelCase(str), expected, `should convert ${str} to ${expected}`) }) - t.end() }) diff --git a/test/unit/util/code-level-metrics.test.js b/test/unit/util/code-level-metrics.test.js index b311553985..73dc491954 100644 --- a/test/unit/util/code-level-metrics.test.js +++ b/test/unit/util/code-level-metrics.test.js @@ -4,15 +4,15 @@ */ 'use strict' - -const tap = require('tap') +const assert = require('node:assert') +const test = require('node:test') const { addCLMAttributes } = require('../../../lib/util/code-level-metrics') const { anon, arrow, named } = require('../../lib/clm-helper') const path = require('path') const helperPath = path.resolve(`${__dirname}/../../lib/clm-helper.js`) const sinon = require('sinon') const symbols = require('../../../lib/symbols') -require('../../lib/custom-tap-assertions') +const { assertExactClmAttrs } = require('../../lib/custom-assertions') /** * Helper to generate a long string @@ -25,151 +25,155 @@ function longString(len) { return Array(len + 1).join('a') } -tap.test('CLM Meta', (t) => { - t.autoend() - let segmentStub - - t.beforeEach(() => { - segmentStub = { +test('CLM Meta', async (t) => { + t.beforeEach((ctx) => { + ctx.nr = {} + ctx.nr.segmentStub = { addAttribute: sinon.stub() } }) - t.test('should return function name as code.function from function reference', (t) => { + await t.test('should return function name as code.function from function reference', (t) => { + const { segmentStub } = t.nr function testFunction() {} testFunction[symbols.clm] = true addCLMAttributes(testFunction, segmentStub) - t.exactClmAttrs(segmentStub, { + assertExactClmAttrs(segmentStub, { 'code.filepath': __filename, 'code.function': 'testFunction', - 'code.lineno': 39, + 'code.lineno': 38, 'code.column': 26 }) - t.end() }) - t.test('should return variable name as code.function from function reference', (t) => { + await t.test('should return variable name as code.function from function reference', (t) => { + const { segmentStub } = t.nr const testFunction = function () {} testFunction[symbols.clm] = true addCLMAttributes(testFunction, segmentStub) - t.exactClmAttrs(segmentStub, { + assertExactClmAttrs(segmentStub, { 'code.filepath': __filename, 'code.function': 'testFunction', - 'code.lineno': 52, + 'code.lineno': 51, 'code.column': 35 }) - t.end() }) - t.test( + await t.test( 'should return function name not variable name as code.function from function reference', (t) => { + const { segmentStub } = t.nr named[symbols.clm] = true addCLMAttributes(named, segmentStub) - t.exactClmAttrs(segmentStub, { + assertExactClmAttrs(segmentStub, { 'code.filepath': helperPath, 'code.function': 'testFunction', 'code.lineno': 11, 'code.column': 40 }) - t.end() } ) - t.test('should return (anonymous) as code.function from (anonymous) function reference', (t) => { - anon[symbols.clm] = true - addCLMAttributes(anon, segmentStub) - t.exactClmAttrs(segmentStub, { - 'code.filepath': helperPath, - 'code.function': '(anonymous)', - 'code.lineno': 9, - 'code.column': 27 - }) - t.end() - }) + await t.test( + 'should return (anonymous) as code.function from (anonymous) function reference', + (t) => { + const { segmentStub } = t.nr + anon[symbols.clm] = true + addCLMAttributes(anon, segmentStub) + assertExactClmAttrs(segmentStub, { + 'code.filepath': helperPath, + 'code.function': '(anonymous)', + 'code.lineno': 9, + 'code.column': 27 + }) + } + ) - t.test('should return (anonymous) as code.function from arrow function reference', (t) => { + await t.test('should return (anonymous) as code.function from arrow function reference', (t) => { + const { segmentStub } = t.nr arrow[symbols.clm] = true addCLMAttributes(arrow, segmentStub) - t.exactClmAttrs(segmentStub, { + assertExactClmAttrs(segmentStub, { 'code.filepath': helperPath, 'code.function': '(anonymous)', 'code.lineno': 10, 'code.column': 19 }) - t.end() }) - t.test('should not add CLM attrs when filePath is null', (t) => { + await t.test('should not add CLM attrs when filePath is null', (t) => { + const { segmentStub } = t.nr function fn() {} - t.comment( + t.diagnostic( 'This is testing Express router.route which binds a function thus breaking any function metadata' ) const boundFn = fn.bind(null) boundFn[symbols.clm] = true addCLMAttributes(boundFn, segmentStub) - t.notOk(segmentStub.addAttribute.callCount) - t.end() + assert.ok(!segmentStub.addAttribute.callCount) }) - t.test('should not return code attributes if function name > 255', (t) => { + await t.test('should not return code attributes if function name > 255', (t) => { + const { segmentStub } = t.nr const fnName = longString(256) const fn = new Function(`return function ${fnName}() {}`)() fn[symbols.clm] = true addCLMAttributes(fn, segmentStub) - t.notOk(segmentStub.addAttribute.callCount) - t.end() + assert.ok(!segmentStub.addAttribute.callCount) }) +}) - t.test('failure cases', (t) => { - t.autoend() +test('failure cases', async (t) => { + t.beforeEach((ctx) => { + ctx.nr = {} + ctx.nr.segmentStub = { + addAttribute: sinon.stub() + } const fnInspector = require('@contrast/fn-inspect') + sinon.stub(fnInspector, 'funcInfo') + ctx.nr.fnInspector = fnInspector + }) - t.beforeEach(() => { - sinon.stub(fnInspector, 'funcInfo') - }) - - t.afterEach(() => { - fnInspector.funcInfo.restore() - }) + t.afterEach((ctx) => { + ctx.nr.fnInspector.funcInfo.restore() + }) - t.test('should not try to get function metadata if clm symbol does not exist', (t) => { - addCLMAttributes(() => {}, segmentStub) - t.notOk(fnInspector.funcInfo.callCount, 'should not call funcInfo') - t.notOk(segmentStub.addAttribute.callCount, 'should not call segment.addAttribute') - t.end() - }) + await t.test('should not try to get function metadata if clm symbol does not exist', (t) => { + const { fnInspector, segmentStub } = t.nr + addCLMAttributes(() => {}, segmentStub) + assert.ok(!fnInspector.funcInfo.callCount, 'should not call funcInfo') + assert.ok(!segmentStub.addAttribute.callCount, 'should not call segment.addAttribute') + }) - t.test('should not return code attributes if filepath > 255', (t) => { - const longPath = longString(300) - fnInspector.funcInfo.returns({ lineNumber: 1, method: 'unitTest', file: longPath }) - const fn = () => {} - fn[symbols.clm] = true - addCLMAttributes(fn, segmentStub) - t.notOk(segmentStub.addAttribute.callCount) - t.end() - }) + await t.test('should not return code attributes if filepath > 255', (t) => { + const { fnInspector, segmentStub } = t.nr + const longPath = longString(300) + fnInspector.funcInfo.returns({ lineNumber: 1, method: 'unitTest', file: longPath }) + const fn = () => {} + fn[symbols.clm] = true + addCLMAttributes(fn, segmentStub) + assert.ok(!segmentStub.addAttribute.callCount) + }) - t.test('should only return code.function if retrieving function metadata fails', (t) => { - const err = new Error('failed to get function meta') - fnInspector.funcInfo.throws(err) - function test() {} - test[symbols.clm] = true - addCLMAttributes(test, segmentStub) - t.equal(segmentStub.addAttribute.callCount, 1) - t.same(segmentStub.addAttribute.args[0], ['code.function', 'test']) - t.end() - }) + await t.test('should only return code.function if retrieving function metadata fails', (t) => { + const { fnInspector, segmentStub } = t.nr + const err = new Error('failed to get function meta') + fnInspector.funcInfo.throws(err) + function testFn() {} + testFn[symbols.clm] = true + addCLMAttributes(testFn, segmentStub) + assert.equal(segmentStub.addAttribute.callCount, 1) + assert.deepEqual(segmentStub.addAttribute.args[0], ['code.function', 'testFn']) + }) - t.test('should not return code attributes if function name is > 255', (t) => { - const fnName = longString(256) - const fn = new Function(`return function ${fnName}() {}`)() - fn[symbols.clm] = true - const err = new Error('oh noes, not again') - fnInspector.funcInfo.throws(err) - addCLMAttributes(fn, segmentStub) - t.notOk(segmentStub.addAttribute.callCount) - t.end() - }) + await t.test('should not return code attributes if function name is > 255', (t) => { + const { fnInspector, segmentStub } = t.nr + const fnName = longString(256) + const fn = new Function(`return function ${fnName}() {}`)() + fn[symbols.clm] = true + const err = new Error('oh noes, not again') + fnInspector.funcInfo.throws(err) + addCLMAttributes(fn, segmentStub) + assert.ok(!segmentStub.addAttribute.callCount) }) }) diff --git a/test/unit/util/codec.test.js b/test/unit/util/codec.test.js index a06e565151..cedaf65487 100644 --- a/test/unit/util/codec.test.js +++ b/test/unit/util/codec.test.js @@ -4,55 +4,50 @@ */ 'use strict' -const { test } = require('tap') +const assert = require('node:assert') +const test = require('node:test') const zlib = require('zlib') const codec = require('../../../lib/util/codec') const DATA = { foo: 'bar' } const ENCODED = 'eJyrVkrLz1eyUkpKLFKqBQAdegQ0' -test('codec', function (t) { - t.autoend() - t.test('.encode', function (t) { - t.autoend() - t.test('should zip and base-64 encode the data', function (t) { - codec.encode(DATA, function (err, encoded) { - t.error(err) - t.equal(encoded, ENCODED) - t.end() - }) +test('codec', async function (t) { + await t.test('.encode should zip and base-64 encode the data', function (t, end) { + codec.encode(DATA, function (err, encoded) { + assert.equal(err, null) + assert.equal(encoded, ENCODED) + end() }) + }) - t.test('should not error for circular payloads', function (t) { - const val = '{"foo":"bar","obj":"[Circular ~]"}' - const obj = { foo: 'bar' } - obj.obj = obj + await t.test('.encode should not error for circular payloads', function (t, end) { + const val = '{"foo":"bar","obj":"[Circular ~]"}' + const obj = { foo: 'bar' } + obj.obj = obj - codec.encode(obj, function (err, encoded) { - t.error(err) - const decoded = zlib.inflateSync(Buffer.from(encoded, 'base64')).toString() - t.equal(decoded, val) - t.end() - }) + codec.encode(obj, function (err, encoded) { + assert.equal(err, null) + const decoded = zlib.inflateSync(Buffer.from(encoded, 'base64')).toString() + assert.equal(decoded, val) + end() }) }) - t.test('.decode should parse the encoded payload', function (t) { + await t.test('.decode should parse the encoded payload', function (t, end) { codec.decode(ENCODED, function (err, data) { - t.error(err) - t.same(data, DATA) - t.end() + assert.equal(err, null) + assert.deepEqual(data, DATA) + end() }) }) - t.test('.encodeSync should zip and base-64 encode the data', function (t) { + await t.test('.encodeSync should zip and base-64 encode the data', function () { const encoded = codec.encodeSync(DATA) - t.equal(encoded, ENCODED) - t.end() + assert.equal(encoded, ENCODED) }) - t.test('.decodeSync should parse the encoded payload', function (t) { + await t.test('.decodeSync should parse the encoded payload', function () { const data = codec.decodeSync(ENCODED) - t.same(data, DATA) - t.end() + assert.deepEqual(data, DATA) }) }) diff --git a/test/unit/util/hashes.test.js b/test/unit/util/hashes.test.js index c83432813b..fec849b74c 100644 --- a/test/unit/util/hashes.test.js +++ b/test/unit/util/hashes.test.js @@ -4,39 +4,33 @@ */ 'use strict' - -const tap = require('tap') +const assert = require('node:assert') +const test = require('node:test') const hashes = require('../../../lib/util/hashes') -tap.test('hashes', (t) => { - t.test('#makeId', (t) => { - t.test('always returns the correct length', (t) => { - for (let length = 4; length < 64; length++) { - for (let attempts = 0; attempts < 500; attempts++) { - const id = hashes.makeId(length) - t.equal(id.length, length) - } +test('hashes', async (t) => { + await t.test('#makeId always returns the correct length', () => { + for (let length = 4; length < 64; length++) { + for (let attempts = 0; attempts < 500; attempts++) { + const id = hashes.makeId(length) + assert.equal(id.length, length) } - t.end() - }) + } + }) - t.test('always unique', (t) => { - const ids = {} - for (let length = 16; length < 64; length++) { - for (let attempts = 0; attempts < 500; attempts++) { - const id = hashes.makeId(length) + await t.test('#makeId always unique', () => { + const ids = {} + for (let length = 16; length < 64; length++) { + for (let attempts = 0; attempts < 500; attempts++) { + const id = hashes.makeId(length) - // Should be unique - t.equal(ids[id], undefined) - ids[id] = true + // Should be unique + assert.equal(ids[id], undefined) + ids[id] = true - // and the correct length - t.equal(id.length, length) - } + // and the correct length + assert.equal(id.length, length) } - t.end() - }) - t.end() + } }) - t.end() }) diff --git a/test/unit/util/label-parser.test.js b/test/unit/util/label-parser.test.js index abe26b6947..16b1b368e3 100644 --- a/test/unit/util/label-parser.test.js +++ b/test/unit/util/label-parser.test.js @@ -4,21 +4,17 @@ */ 'use strict' - -const tap = require('tap') +const assert = require('node:assert') +const test = require('node:test') const testData = require('../../lib/cross_agent_tests/labels.json') const parse = require('../../../lib/util/label-parser').fromString -tap.test('label praser', (t) => { - t.test('should pass cross-agent tests', (t) => { - testData.forEach((example) => { - const result = parse(example.labelString) - t.same(result.labels.sort(byType), example.expected.sort(byType)) - t.same(!!result.warnings.length, example.warning) - }) - t.end() +test('label parser should pass cross-agent tests', () => { + testData.forEach((example) => { + const result = parse(example.labelString) + assert.deepEqual(result.labels.sort(byType), example.expected.sort(byType)) + assert.equal(!!result.warnings.length, example.warning) }) - t.end() }) function byType(a, b) { diff --git a/test/unit/util/llm-utils.test.js b/test/unit/util/llm-utils.test.js index 666a42e3f2..624eaa47ea 100644 --- a/test/unit/util/llm-utils.test.js +++ b/test/unit/util/llm-utils.test.js @@ -4,12 +4,12 @@ */ 'use strict' - -const tap = require('tap') +const assert = require('node:assert') +const test = require('node:test') const { extractLlmAttributes, extractLlmContext } = require('../../../lib/util/llm-utils') const { AsyncLocalStorage } = require('async_hooks') -tap.test('extractLlmAttributes', (t) => { +test('extractLlmAttributes', () => { const context = { 'skip': 1, 'llm.get': 2, @@ -17,58 +17,57 @@ tap.test('extractLlmAttributes', (t) => { } const llmContext = extractLlmAttributes(context) - t.notOk(llmContext.skip) - t.notOk(llmContext['fllm.skip']) - t.equal(llmContext['llm.get'], 2) - t.end() + assert.ok(!llmContext.skip) + assert.ok(!llmContext['fllm.skip']) + assert.equal(llmContext['llm.get'], 2) }) -tap.test('extractLlmContext', (t) => { - t.beforeEach((t) => { +test('extractLlmContext', async (t) => { + t.beforeEach((ctx) => { + ctx.nr = {} const tx = { _llmContextManager: new AsyncLocalStorage() } - t.context.agent = { + ctx.nr.agent = { tracer: { getTransaction: () => { return tx } } } - t.context.tx = tx + ctx.nr.tx = tx }) - t.test('handle empty context', (t) => { - const { tx, agent } = t.context + await t.test('handle empty context', (t, end) => { + const { tx, agent } = t.nr tx._llmContextManager.run(null, () => { const llmContext = extractLlmContext(agent) - t.equal(typeof llmContext, 'object') - t.equal(Object.entries(llmContext).length, 0) - t.end() + assert.equal(typeof llmContext, 'object') + assert.equal(Object.entries(llmContext).length, 0) + end() }) }) - t.test('extract LLM context', (t) => { - const { tx, agent } = t.context + await t.test('extract LLM context', (t, end) => { + const { tx, agent } = t.nr tx._llmContextManager.run({ 'llm.test': 1, 'skip': 2 }, () => { const llmContext = extractLlmContext(agent) - t.equal(llmContext['llm.test'], 1) - t.notOk(llmContext.skip) - t.end() + assert.equal(llmContext['llm.test'], 1) + assert.ok(!llmContext.skip) + end() }) }) - t.test('no transaction', (t) => { - const { tx, agent } = t.context + await t.test('no transaction', (t, end) => { + const { tx, agent } = t.nr agent.tracer.getTransaction = () => { return null } tx._llmContextManager.run(null, () => { const llmContext = extractLlmContext(agent) - t.equal(typeof llmContext, 'object') - t.equal(Object.entries(llmContext).length, 0) - t.end() + assert.equal(typeof llmContext, 'object') + assert.equal(Object.entries(llmContext).length, 0) + end() }) }) - t.end() }) diff --git a/test/unit/util/logger.test.js b/test/unit/util/logger.test.js index bf75677821..52b617b69e 100644 --- a/test/unit/util/logger.test.js +++ b/test/unit/util/logger.test.js @@ -4,91 +4,98 @@ */ 'use strict' -const tap = require('tap') +const assert = require('node:assert') +const test = require('node:test') const Logger = require('../../../lib/util/logger') const { Transform } = require('stream') const DEFAULT_KEYS = ['hostname', 'level', 'msg', 'name', 'pid', 'time', 'v'] -tap.Test.prototype.addAssert('expectEntry', 4, function expectEntry(entry, msg, level, keys) { - this.equal(entry.hostname, 'my-host') - this.equal(entry.name, 'my-logger') - this.equal(entry.pid, process.pid) - this.equal(entry.v, 0) - this.equal(entry.level, level) - this.equal(entry.msg, msg) - this.same(Object.keys(entry).sort(), keys || DEFAULT_KEYS) -}) - -tap.test('logger', function (t) { - t.autoend() - let results - let logger - - t.beforeEach(function () { - results = [] - logger = new Logger({ +function expectEntry(entry, msg, level, keys) { + assert.equal(entry.hostname, 'my-host') + assert.equal(entry.name, 'my-logger') + assert.equal(entry.pid, process.pid) + assert.equal(entry.v, 0) + assert.equal(entry.level, level) + assert.equal(entry.msg, msg) + assert.deepEqual(Object.keys(entry).sort(), keys || DEFAULT_KEYS) +} + +function addResult(ctx, data, encoding, done) { + ctx.nr.results = ctx.nr.results.concat( + data.toString().split('\n').filter(Boolean).map(JSON.parse) + ) + done() +} + +test('logger', async function (t) { + t.beforeEach(function (ctx) { + ctx.nr = {} + ctx.nr.results = [] + ctx.nr.logger = new Logger({ name: 'my-logger', level: 'info', hostname: 'my-host', stream: new Transform({ - transform: addResult + transform: addResult.bind(this, ctx) }) }) }) - function addResult(data, encoding, done) { - results = results.concat(data.toString().split('\n').filter(Boolean).map(JSON.parse)) - done() - } - - t.test('should interpolate values', function (t) { + await t.test('should interpolate values', function (t, end) { + const { logger } = t.nr logger.info('%d: %s', 1, 'a') logger.info('123', 4, '5') process.nextTick(function () { - t.equal(results.length, 2) - t.expectEntry(results[0], '1: a', 30) - t.expectEntry(results[1], '123 4 5', 30) - t.end() + const { results } = t.nr + assert.equal(results.length, 2) + expectEntry(results[0], '1: a', 30) + expectEntry(results[1], '123 4 5', 30) + end() }) }) - t.test('should default to error level logging', function (t) { + await t.test('should default to error level logging', function (t) { + const { logger } = t.nr logger.level('donkey kong') - t.equal(logger.options._level, 50) - t.end() + assert.equal(logger.options._level, 50) }) - t.test('should support prepended extras', function (t) { + await t.test('should support prepended extras', function (t, end) { + const { logger } = t.nr logger.info({ a: 1, b: 2 }, '%d: %s', 1, 'a') logger.info({ a: 1, b: 2 }, '123', 4, '5') process.nextTick(function () { + const { results } = t.nr const keys = ['a', 'b'].concat(DEFAULT_KEYS) - t.equal(results.length, 2) - t.expectEntry(results[0], '1: a', 30, keys) - t.equal(results[0].a, 1) - t.equal(results[0].b, 2) - t.expectEntry(results[1], '123 4 5', 30, keys) - t.equal(results[1].a, 1) - t.equal(results[1].b, 2) - t.end() + assert.equal(results.length, 2) + expectEntry(results[0], '1: a', 30, keys) + assert.equal(results[0].a, 1) + assert.equal(results[0].b, 2) + expectEntry(results[1], '123 4 5', 30, keys) + assert.equal(results[1].a, 1) + assert.equal(results[1].b, 2) + end() }) }) - t.test('should support prepended extras from Error objects', function (t) { + await t.test('should support prepended extras from Error objects', function (t, end) { + const { logger } = t.nr const error = new Error('error1') - t.ok(error.message) - t.ok(error.stack) + assert.ok(error.message) + assert.ok(error.stack) logger.info(error, 'log message') process.nextTick(function () { + const { results } = t.nr const [log1] = results - t.equal(log1.message, error.message) - t.equal(log1.stack, error.stack) - t.end() + assert.equal(log1.message, error.message) + assert.equal(log1.stack, error.stack) + end() }) }) - t.test('should only log expected levels', function (t) { + await t.test('should only log expected levels', function (t, end) { + const { logger } = t.nr logger.trace('trace') logger.debug('debug') logger.info('info') @@ -96,23 +103,26 @@ tap.test('logger', function (t) { logger.error('error') logger.fatal('fatal') process.nextTick(function () { - t.equal(results.length, 4) - t.expectEntry(results[0], 'info', 30) - t.expectEntry(results[1], 'warn', 40) - t.expectEntry(results[2], 'error', 50) - t.expectEntry(results[3], 'fatal', 60) + let { results } = t.nr + assert.equal(results.length, 4) + expectEntry(results[0], 'info', 30) + expectEntry(results[1], 'warn', 40) + expectEntry(results[2], 'error', 50) + expectEntry(results[3], 'fatal', 60) logger.level('trace') logger.trace('trace') logger.debug('debug') - t.equal(results.length, 6) - t.expectEntry(results[4], 'trace', 10) - t.expectEntry(results[5], 'debug', 20) - t.end() + ;({ results } = t.nr) + assert.equal(results.length, 6) + expectEntry(results[4], 'trace', 10) + expectEntry(results[5], 'debug', 20) + end() }) }) - t.test('and its children should only log expected levels', function (t) { + await t.test('and its children should only log expected levels', function (t, end) { + const { logger } = t.nr const child = logger.child({ aChild: true }) const grandchild = child.child({ aGrandchild: true }) @@ -129,27 +139,30 @@ tap.test('logger', function (t) { grandchild.error('error') grandchild.fatal('fatal') process.nextTick(function () { - t.equal(results.length, 8) - t.expectEntry(results[0], 'info', 30, ['aChild'].concat(DEFAULT_KEYS)) - t.expectEntry(results[1], 'warn', 40, ['aChild'].concat(DEFAULT_KEYS)) - t.expectEntry(results[2], 'error', 50, ['aChild'].concat(DEFAULT_KEYS)) - t.expectEntry(results[3], 'fatal', 60, ['aChild'].concat(DEFAULT_KEYS)) - t.expectEntry(results[4], 'info', 30, ['aChild', 'aGrandchild'].concat(DEFAULT_KEYS)) - t.expectEntry(results[5], 'warn', 40, ['aChild', 'aGrandchild'].concat(DEFAULT_KEYS)) - t.expectEntry(results[6], 'error', 50, ['aChild', 'aGrandchild'].concat(DEFAULT_KEYS)) - t.expectEntry(results[7], 'fatal', 60, ['aChild', 'aGrandchild'].concat(DEFAULT_KEYS)) + let { results } = t.nr + assert.equal(results.length, 8) + expectEntry(results[0], 'info', 30, ['aChild'].concat(DEFAULT_KEYS)) + expectEntry(results[1], 'warn', 40, ['aChild'].concat(DEFAULT_KEYS)) + expectEntry(results[2], 'error', 50, ['aChild'].concat(DEFAULT_KEYS)) + expectEntry(results[3], 'fatal', 60, ['aChild'].concat(DEFAULT_KEYS)) + expectEntry(results[4], 'info', 30, ['aChild', 'aGrandchild'].concat(DEFAULT_KEYS)) + expectEntry(results[5], 'warn', 40, ['aChild', 'aGrandchild'].concat(DEFAULT_KEYS)) + expectEntry(results[6], 'error', 50, ['aChild', 'aGrandchild'].concat(DEFAULT_KEYS)) + expectEntry(results[7], 'fatal', 60, ['aChild', 'aGrandchild'].concat(DEFAULT_KEYS)) logger.level('trace') child.trace('trace') grandchild.debug('debug') - t.equal(results.length, 10) - t.expectEntry(results[8], 'trace', 10, ['aChild'].concat(DEFAULT_KEYS)) - t.expectEntry(results[9], 'debug', 20, ['aChild', 'aGrandchild'].concat(DEFAULT_KEYS)) - t.end() + ;({ results } = t.nr) + assert.equal(results.length, 10) + expectEntry(results[8], 'trace', 10, ['aChild'].concat(DEFAULT_KEYS)) + expectEntry(results[9], 'debug', 20, ['aChild', 'aGrandchild'].concat(DEFAULT_KEYS)) + end() }) }) - t.test('and its children should be togglable', function (t) { + await t.test('and its children should be togglable', function (t, end) { + const { logger } = t.nr const child = logger.child({ aChild: true }) const grandchild = child.child({ aGrandchild: true }) @@ -158,16 +171,19 @@ tap.test('logger', function (t) { grandchild.info('on') logger.setEnabled(false) process.nextTick(function () { - t.equal(results.length, 3) + let { results } = t.nr + assert.equal(results.length, 3) logger.info('off') child.info('off') grandchild.info('off') - t.equal(results.length, 3) - t.end() + ;({ results } = t.nr) + assert.equal(results.length, 3) + end() }) }) - t.test('state should be synced between parent and child', function (t) { + await t.test('state should be synced between parent and child', function (t, end) { + const { logger } = t.nr const child = logger.child({ aChild: true }) const grandchild = child.child({ aGrandchild: true }) @@ -176,16 +192,19 @@ tap.test('logger', function (t) { grandchild.info('on') child.setEnabled(false) process.nextTick(function () { - t.equal(results.length, 3) + let { results } = t.nr + assert.equal(results.length, 3) logger.info('off') child.info('off') grandchild.info('off') - t.equal(results.length, 3) - t.end() + ;({ results } = t.nr) + assert.equal(results.length, 3) + end() }) }) - t.test('state should work on arbitrarily deep child loggers', function (t) { + await t.test('state should work on arbitrarily deep child loggers', function (t, end) { + const { logger } = t.nr const child = logger.child({ aChild: true }) const grandchild = child.child({ aGrandchild: true }) @@ -194,16 +213,19 @@ tap.test('logger', function (t) { grandchild.info('on') grandchild.setEnabled(false) process.nextTick(function () { - t.equal(results.length, 3) + let { results } = t.nr + assert.equal(results.length, 3) logger.info('off') child.info('off') grandchild.info('off') - t.equal(results.length, 3) - t.end() + ;({ results } = t.nr) + assert.equal(results.length, 3) + end() }) }) - t.test('should support child loggers', function (t) { + await t.test('should support child loggers', function (t, end) { + const { logger } = t.nr const childA = logger.child({ a: 1 }) const childB = logger.child({ b: 2, c: 3 }) const childC = childB.child({ c: 6 }) @@ -212,155 +234,182 @@ tap.test('logger', function (t) { childC.info({ a: 10 }, 'hello c') process.nextTick(function () { - t.equal(results.length, 3) - t.equal(results[0].a, 1) - t.expectEntry(results[1], 'hello b', 30, ['b', 'c'].concat(DEFAULT_KEYS)) - t.equal(results[1].b, 5) - t.equal(results[1].c, 3) - - t.expectEntry(results[2], 'hello c', 30, ['a', 'b', 'c'].concat(DEFAULT_KEYS)) - t.equal(results[2].a, 10) - t.equal(results[2].b, 2) - t.equal(results[2].c, 6) - t.end() + const { results } = t.nr + assert.equal(results.length, 3) + assert.equal(results[0].a, 1) + expectEntry(results[1], 'hello b', 30, ['b', 'c'].concat(DEFAULT_KEYS)) + assert.equal(results[1].b, 5) + assert.equal(results[1].c, 3) + + expectEntry(results[2], 'hello c', 30, ['a', 'b', 'c'].concat(DEFAULT_KEYS)) + assert.equal(results[2].a, 10) + assert.equal(results[2].b, 2) + assert.equal(results[2].c, 6) + end() }) }) - t.test('should support child loggers with prepended extras from Error objects', function (t) { - const error = new Error('error1') - t.ok(error.message) - t.ok(error.stack) + await t.test( + 'should support child loggers with prepended extras from Error objects', + function (t, end) { + const { logger } = t.nr + const error = new Error('error1') + assert.ok(error.message) + assert.ok(error.stack) - const child = logger.child({ a: 1 }) - child.info(error, 'log message') + const child = logger.child({ a: 1 }) + child.info(error, 'log message') - process.nextTick(function () { - const [log1] = results - t.equal(log1.message, error.message) - t.equal(log1.stack, error.stack) - t.end() - }) - }) + process.nextTick(function () { + const { results } = t.nr + const [log1] = results + assert.equal(log1.message, error.message) + assert.equal(log1.stack, error.stack) + end() + }) + } + ) - t.test('should have once methods that respect log levels', function (t) { + await t.test('should have once methods that respect log levels', function (t, end) { + const { logger } = t.nr logger.level('info') logger.traceOnce('test', 'value') process.nextTick(function () { - t.equal(results.length, 0) + let { results } = t.nr + assert.equal(results.length, 0) logger.infoOnce('test', 'value') process.nextTick(function () { - t.equal(results.length, 1) - t.expectEntry(results[0], 'value', 30, DEFAULT_KEYS) - t.end() + ;({ results } = t.nr) + assert.equal(results.length, 1) + expectEntry(results[0], 'value', 30, DEFAULT_KEYS) + end() }) }) }) - t.test('should have once methods that log things once', function (t) { + await t.test('should have once methods that log things once', function (t, end) { + const { logger } = t.nr logger.infoOnce('testkey', 'info') logger.infoOnce('testkey', 'info') logger.infoOnce('anothertestkey', 'another') process.nextTick(function () { - t.equal(results.length, 2) - t.expectEntry(results[0], 'info', 30, DEFAULT_KEYS) - t.expectEntry(results[1], 'another', 30, DEFAULT_KEYS) - t.end() + const { results } = t.nr + assert.equal(results.length, 2) + expectEntry(results[0], 'info', 30, DEFAULT_KEYS) + expectEntry(results[1], 'another', 30, DEFAULT_KEYS) + end() }) }) - t.test('should have once methods that can handle objects', function (t) { + await t.test('should have once methods that can handle objects', function (t, end) { + const { logger } = t.nr logger.infoOnce('a', { a: 2 }, 'hello a') logger.infoOnce('a', { a: 2 }, 'hello c') process.nextTick(function () { - t.equal(results.length, 1) - t.equal(results[0].a, 2) - t.expectEntry(results[0], 'hello a', 30, ['a'].concat(DEFAULT_KEYS)) - t.end() + const { results } = t.nr + assert.equal(results.length, 1) + assert.equal(results[0].a, 2) + expectEntry(results[0], 'hello a', 30, ['a'].concat(DEFAULT_KEYS)) + end() }) }) - t.test('should have oncePer methods that respect log levels', function (t) { + await t.test('should have oncePer methods that respect log levels', function (t, end) { + const { logger } = t.nr logger.level('info') logger.traceOncePer('test', 30, 'value') process.nextTick(function () { - t.equal(results.length, 0) + let { results } = t.nr + assert.equal(results.length, 0) logger.infoOncePer('test', 30, 'value') process.nextTick(function () { - t.equal(results.length, 1) - t.expectEntry(results[0], 'value', 30, DEFAULT_KEYS) - t.end() + ;({ results } = t.nr) + assert.equal(results.length, 1) + expectEntry(results[0], 'value', 30, DEFAULT_KEYS) + end() }) }) }) - t.test('should have oncePer methods that log things at most once in an interval', function (t) { - logger.infoOncePer('key', 50, 'value') - logger.infoOncePer('key', 50, 'value') - setTimeout(function () { + await t.test( + 'should have oncePer methods that log things at most once in an interval', + function (t, end) { + const { logger } = t.nr logger.infoOncePer('key', 50, 'value') - process.nextTick(function () { - t.equal(results.length, 2) - t.expectEntry(results[0], 'value', 30, DEFAULT_KEYS) - t.expectEntry(results[1], 'value', 30, DEFAULT_KEYS) - t.end() - }) - }, 100) - }) - t.test('should have oncePer methods that can handle objects', function (t) { + logger.infoOncePer('key', 50, 'value') + setTimeout(function () { + logger.infoOncePer('key', 50, 'value') + process.nextTick(function () { + const { results } = t.nr + assert.equal(results.length, 2) + expectEntry(results[0], 'value', 30, DEFAULT_KEYS) + expectEntry(results[1], 'value', 30, DEFAULT_KEYS) + end() + }) + }, 100) + } + ) + + await t.test('should have oncePer methods that can handle objects', function (t, end) { + const { logger } = t.nr logger.infoOncePer('a', 10, { a: 2 }, 'hello a') process.nextTick(function () { - t.equal(results.length, 1) - t.equal(results[0].a, 2) - t.expectEntry(results[0], 'hello a', 30, ['a'].concat(DEFAULT_KEYS)) - t.end() + const { results } = t.nr + assert.equal(results.length, 1) + assert.equal(results[0].a, 2) + expectEntry(results[0], 'hello a', 30, ['a'].concat(DEFAULT_KEYS)) + end() }) }) - t.test('should have enabled methods that respect log levels', function (t) { + await t.test('should have enabled methods that respect log levels', function (t) { + const { logger } = t.nr logger.level('info') - t.notOk(logger.traceEnabled()) - t.notOk(logger.debugEnabled()) - t.ok(logger.infoEnabled()) - t.ok(logger.warnEnabled()) - t.ok(logger.errorEnabled()) - t.ok(logger.fatalEnabled()) - t.end() + assert.ok(!logger.traceEnabled()) + assert.ok(!logger.debugEnabled()) + assert.ok(logger.infoEnabled()) + assert.ok(logger.warnEnabled()) + assert.ok(logger.errorEnabled()) + assert.ok(logger.fatalEnabled()) }) - t.test('should have enabled methods that change with the log level', function (t) { + await t.test('should have enabled methods that change with the log level', function (t) { + const { logger } = t.nr logger.level('fatal') - t.notOk(logger.traceEnabled()) - t.notOk(logger.debugEnabled()) - t.notOk(logger.infoEnabled()) - t.notOk(logger.warnEnabled()) - t.notOk(logger.errorEnabled()) - t.ok(logger.fatalEnabled()) + assert.ok(!logger.traceEnabled()) + assert.ok(!logger.debugEnabled()) + assert.ok(!logger.infoEnabled()) + assert.ok(!logger.warnEnabled()) + assert.ok(!logger.errorEnabled()) + assert.ok(logger.fatalEnabled()) logger.level('trace') - t.ok(logger.traceEnabled()) - t.ok(logger.debugEnabled()) - t.ok(logger.infoEnabled()) - t.ok(logger.warnEnabled()) - t.ok(logger.errorEnabled()) - t.ok(logger.fatalEnabled()) - t.end() + assert.ok(logger.traceEnabled()) + assert.ok(logger.debugEnabled()) + assert.ok(logger.infoEnabled()) + assert.ok(logger.warnEnabled()) + assert.ok(logger.errorEnabled()) + assert.ok(logger.fatalEnabled()) }) - t.test('should stringify objects', function (t) { + await t.test('should stringify objects', function (t, end) { + const { logger } = t.nr const obj = { a: 1, b: 2 } obj.self = obj logger.info('JSON: %s', obj) process.nextTick(function () { - t.equal(results.length, 1) - t.expectEntry(results[0], 'JSON: {"a":1,"b":2,"self":"[Circular ~]"}', 30) - t.end() + const { results } = t.nr + assert.equal(results.length, 1) + expectEntry(results[0], 'JSON: {"a":1,"b":2,"self":"[Circular ~]"}', 30) + end() }) }) - t.test('fail gracefully on unstringifiable objects', function (t) { + await t.test('fail gracefully on unstringifiable objects', function (t, end) { + const { logger } = t.nr const badObj = { get testData() { throw new Error() @@ -368,53 +417,51 @@ tap.test('logger', function (t) { } logger.info('JSON: %s', badObj) process.nextTick(function () { - t.equal(results.length, 1) - t.expectEntry(results[0], 'JSON: [UNPARSABLE OBJECT]', 30) - t.end() + const { results } = t.nr + assert.equal(results.length, 1) + expectEntry(results[0], 'JSON: [UNPARSABLE OBJECT]', 30) + end() }) }) }) -tap.test('logger write queue', function (t) { - t.autoend() - t.test('should buffer writes', function (t) { - const bigString = new Array(16 * 1024).join('a') +test('logger write queue should buffer writes', function (t, end) { + const bigString = new Array(16 * 1024).join('a') - const logger = new Logger({ - name: 'my-logger', - level: 'info', - hostname: 'my-host' - }) + const logger = new Logger({ + name: 'my-logger', + level: 'info', + hostname: 'my-host' + }) - logger.once('readable', function () { - logger.push = function (str) { - const pushed = Logger.prototype.push.call(this, str) - if (pushed) { - const parts = str - .split('\n') - .filter(Boolean) - .map(function (a) { - return a.toString() - }) - .map(JSON.parse) - t.expectEntry(parts[0], 'b', 30) - t.expectEntry(parts[1], 'c', 30) - t.expectEntry(parts[2], 'd', 30) - } - - return pushed + logger.once('readable', function () { + logger.push = function (str) { + const pushed = Logger.prototype.push.call(this, str) + if (pushed) { + const parts = str + .split('\n') + .filter(Boolean) + .map(function (a) { + return a.toString() + }) + .map(JSON.parse) + expectEntry(parts[0], 'b', 30) + expectEntry(parts[1], 'c', 30) + expectEntry(parts[2], 'd', 30) } - logger.info('b') - logger.info('c') - logger.info('d') + return pushed + } - logger.read() + logger.info('b') + logger.info('c') + logger.info('d') - process.nextTick(function () { - t.end() - }) + logger.read() + + process.nextTick(function () { + end() }) - logger.info(bigString) }) + logger.info(bigString) }) diff --git a/test/unit/util/obfuscate-sql.test.js b/test/unit/util/obfuscate-sql.test.js index daf3e1b14c..c2942e1bd6 100644 --- a/test/unit/util/obfuscate-sql.test.js +++ b/test/unit/util/obfuscate-sql.test.js @@ -4,46 +4,43 @@ */ 'use strict' - -const tap = require('tap') +const assert = require('node:assert') +const test = require('node:test') const tests = require('../../lib/cross_agent_tests/sql_obfuscation/sql_obfuscation') const obfuscate = require('../../../lib/util/sql/obfuscate') -tap.test('sql obfuscation', (t) => { - tests.forEach((test) => { - t.test(test.name, (t) => { - for (let i = 0; i < test.dialects.length; ++i) { - runTest(t, test, test.dialects[i]) - } - t.end() - }) - }) - - function runTest(t, test, dialect) { - t.comment(dialect) - const obfuscated = obfuscate(test.sql, dialect) - if (test.obfuscated.length === 1) { - t.equal(obfuscated, test.obfuscated[0]) - } else { - t.ok(test.obfuscated.includes(obfuscated)) - } +function runTest(t, testCase, dialect) { + t.diagnostic(dialect) + const obfuscated = obfuscate(testCase.sql, dialect) + if (testCase.obfuscated.length === 1) { + assert.equal(obfuscated, testCase.obfuscated[0]) + } else { + assert.ok(testCase.obfuscated.includes(obfuscated)) } +} - t.test('should handle line endings', (t) => { +test('sql obfuscation', async (t) => { + await Promise.all( + tests.map(async (tc) => { + await t.test(tc.name, (t) => { + for (let i = 0; i < tc.dialects.length; ++i) { + runTest(t, tc, tc.dialects[i]) + } + }) + }) + ) + + await t.test('should handle line endings', () => { const result = obfuscate('select * from foo where --abc\r\nbar=5', 'mysql') - t.equal(result, 'select * from foo where ?\r\nbar=?') - t.end() + assert.equal(result, 'select * from foo where ?\r\nbar=?') }) - t.test('should handle large JSON inserts', (t) => { + await t.test('should handle large JSON inserts', () => { const JSONData = '{"data": "' + new Array(8400000).fill('a').join('') + '"}' const result = obfuscate( 'INSERT INTO "Documents" ("data") VALUES (\'' + JSONData + "')", 'postgres' ) - t.equal(result, 'INSERT INTO "Documents" ("data") VALUES (?)') - t.end() + assert.equal(result, 'INSERT INTO "Documents" ("data") VALUES (?)') }) - - t.end() }) diff --git a/test/unit/util/objects.test.js b/test/unit/util/objects.test.js index 6c0cc64207..847cad1f2f 100644 --- a/test/unit/util/objects.test.js +++ b/test/unit/util/objects.test.js @@ -4,8 +4,8 @@ */ 'use strict' - -const tap = require('tap') +const assert = require('node:assert') +const test = require('node:test') const { isSimpleObject, isNotEmpty } = require('../../../lib/util/objects') const fixtures = [ { name: 'populated object', value: { a: 1, b: 2, c: 3 }, simple: true, nonEmpty: true }, @@ -25,31 +25,16 @@ const fixtures = [ { name: 'function with false return', value: () => false, simple: false, nonEmpty: false } ] -tap.test('isSimpleObject', (t) => { - t.test('should distinguish objects from non-objects', (t) => { - fixtures.forEach((f) => { - try { - const testValue = isSimpleObject(f.value) - t.equal(testValue, f.simple, `should be able to test ${f.name} correctly`) - } catch (e) { - t.notOk(e, `should be able to handle ${f.name} without error`) - } - }) - t.end() +test('isSimpleObject should distinguish objects from non-objects', () => { + fixtures.forEach((f) => { + const testValue = isSimpleObject(f.value) + assert.equal(testValue, f.simple, `should be able to test ${f.name} correctly`) }) - t.end() }) -tap.test('isNotEmpty', (t) => { - t.test('should discern non-empty objects from empty objects and other entities', (t) => { - fixtures.forEach((f) => { - try { - const testValue = isNotEmpty(f.value) - t.equal(testValue, f.nonEmpty, `should be able to test ${f.name} correctly`) - } catch (e) { - t.notOk(e, `should be able to handle ${f.name} without error`) - } - }) - t.end() + +test('isNotEmpty should discern non-empty objects from empty objects and other entities', () => { + fixtures.forEach((f) => { + const testValue = isNotEmpty(f.value) + assert.equal(testValue, f.nonEmpty, `should be able to test ${f.name} correctly`) }) - t.end() }) diff --git a/test/unit/util/snake-case.test.js b/test/unit/util/snake-case.test.js index 7c17582163..97524566dc 100644 --- a/test/unit/util/snake-case.test.js +++ b/test/unit/util/snake-case.test.js @@ -4,18 +4,18 @@ */ 'use strict' - -const tap = require('tap') +const assert = require('assert') +const test = require('node:test') const toSnakeCase = require('../../../lib/util/snake-case') +const fixtures = [ + { str: 'already_snake', expected: 'already_snake' }, + { str: 'myTestString', expected: 'my_test_string' }, + { str: '123AttrKey', expected: '123_attr_key' }, + { str: 'Foo-Bar', expected: 'foo_bar' } +] -tap.test('toSnakeCase', (t) => { - ;[ - { str: 'already_snake', expected: 'already_snake' }, - { str: 'myTestString', expected: 'my_test_string' }, - { str: '123AttrKey', expected: '123_attr_key' }, - { str: 'Foo-Bar', expected: 'foo_bar' } - ].forEach(({ str, expected }) => { - t.equal(toSnakeCase(str), expected, `should convert ${str} to ${expected}`) +test('toSnakeCase', () => { + fixtures.forEach(({ str, expected }) => { + assert.equal(toSnakeCase(str), expected, `should convert ${str} to ${expected}`) }) - t.end() })