From 1194b87286e0aa82c9079e1c2c897ec40a2544cb Mon Sep 17 00:00:00 2001 From: James Sumners Date: Mon, 9 Sep 2024 10:05:15 -0400 Subject: [PATCH 1/3] chore: Updated serverless unit tests to node:test --- THIRD_PARTY_NOTICES.md | 62 +++++----- package.json | 2 +- test/unit/serverless/api-gateway-v2.test.js | 128 ++++++++++---------- third_party_manifest.json | 60 ++++----- 4 files changed, 129 insertions(+), 123 deletions(-) diff --git a/THIRD_PARTY_NOTICES.md b/THIRD_PARTY_NOTICES.md index b4327dc219..f55b88ce93 100644 --- a/THIRD_PARTY_NOTICES.md +++ b/THIRD_PARTY_NOTICES.md @@ -34,6 +34,7 @@ code, the source code can be found at [https://github.com/newrelic/node-newrelic * [@aws-sdk/client-s3](#aws-sdkclient-s3) * [@aws-sdk/s3-request-presigner](#aws-sdks3-request-presigner) * [@koa/router](#koarouter) +* [@matteo.collina/tspl](#matteocollinatspl) * [@newrelic/eslint-config](#newreliceslint-config) * [@newrelic/newrelic-oss-cli](#newrelicnewrelic-oss-cli) * [@newrelic/test-utilities](#newrelictest-utilities) @@ -69,7 +70,6 @@ code, the source code can be found at [https://github.com/newrelic/node-newrelic * [nock](#nock) * [proxy](#proxy) * [proxyquire](#proxyquire) -* [rfdc](#rfdc) * [rimraf](#rimraf) * [self-cert](#self-cert) * [should](#should) @@ -1076,7 +1076,7 @@ SOFTWARE. ### @aws-sdk/client-s3 -This product includes source derived from [@aws-sdk/client-s3](https://github.com/aws/aws-sdk-js-v3) ([v3.637.0](https://github.com/aws/aws-sdk-js-v3/tree/v3.637.0)), distributed under the [Apache-2.0 License](https://github.com/aws/aws-sdk-js-v3/blob/v3.637.0/LICENSE): +This product includes source derived from [@aws-sdk/client-s3](https://github.com/aws/aws-sdk-js-v3) ([v3.632.0](https://github.com/aws/aws-sdk-js-v3/tree/v3.632.0)), distributed under the [Apache-2.0 License](https://github.com/aws/aws-sdk-js-v3/blob/v3.632.0/LICENSE): ``` Apache License @@ -1285,7 +1285,7 @@ This product includes source derived from [@aws-sdk/client-s3](https://github.co ### @aws-sdk/s3-request-presigner -This product includes source derived from [@aws-sdk/s3-request-presigner](https://github.com/aws/aws-sdk-js-v3) ([v3.637.0](https://github.com/aws/aws-sdk-js-v3/tree/v3.637.0)), distributed under the [Apache-2.0 License](https://github.com/aws/aws-sdk-js-v3/blob/v3.637.0/LICENSE): +This product includes source derived from [@aws-sdk/s3-request-presigner](https://github.com/aws/aws-sdk-js-v3) ([v3.632.0](https://github.com/aws/aws-sdk-js-v3/tree/v3.632.0)), distributed under the [Apache-2.0 License](https://github.com/aws/aws-sdk-js-v3/blob/v3.632.0/LICENSE): ``` Apache License @@ -1521,6 +1521,35 @@ THE SOFTWARE. ``` +### @matteo.collina/tspl + +This product includes source derived from [@matteo.collina/tspl](https://github.com/mcollina/tspl) ([v0.1.1](https://github.com/mcollina/tspl/tree/v0.1.1)), distributed under the [MIT License](https://github.com/mcollina/tspl/blob/v0.1.1/LICENSE): + +``` +MIT License + +Copyright (c) 2023 Matteo Collina + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +``` + ### @newrelic/eslint-config This product includes source derived from [@newrelic/eslint-config](https://github.com/newrelic/eslint-config-newrelic) ([v0.3.0](https://github.com/newrelic/eslint-config-newrelic/tree/v0.3.0)), distributed under the [Apache-2.0 License](https://github.com/newrelic/eslint-config-newrelic/blob/v0.3.0/LICENSE): @@ -2656,7 +2685,7 @@ SOFTWARE. ### async -This product includes source derived from [async](https://github.com/caolan/async) ([v3.2.6](https://github.com/caolan/async/tree/v3.2.6)), distributed under the [MIT License](https://github.com/caolan/async/blob/v3.2.6/LICENSE): +This product includes source derived from [async](https://github.com/caolan/async) ([v3.2.5](https://github.com/caolan/async/tree/v3.2.5)), distributed under the [MIT License](https://github.com/caolan/async/blob/v3.2.5/LICENSE): ``` Copyright (c) 2010-2018 Caolan McMahon @@ -2683,7 +2712,7 @@ THE SOFTWARE. ### aws-sdk -This product includes source derived from [aws-sdk](https://github.com/aws/aws-sdk-js) ([v2.1687.0](https://github.com/aws/aws-sdk-js/tree/v2.1687.0)), distributed under the [Apache-2.0 License](https://github.com/aws/aws-sdk-js/blob/v2.1687.0/LICENSE.txt): +This product includes source derived from [aws-sdk](https://github.com/aws/aws-sdk-js) ([v2.1677.0](https://github.com/aws/aws-sdk-js/tree/v2.1677.0)), distributed under the [Apache-2.0 License](https://github.com/aws/aws-sdk-js/blob/v2.1677.0/LICENSE.txt): ``` @@ -3978,29 +4007,6 @@ OTHER DEALINGS IN THE SOFTWARE. ``` -### rfdc - -This product includes source derived from [rfdc](https://github.com/davidmarkclements/rfdc) ([v1.4.1](https://github.com/davidmarkclements/rfdc/tree/v1.4.1)), distributed under the [MIT License](https://github.com/davidmarkclements/rfdc/blob/v1.4.1/LICENSE): - -``` -Copyright 2019 "David Mark Clements " - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and -to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions -of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF -CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -IN THE SOFTWARE. - -``` - ### rimraf This product includes source derived from [rimraf](https://github.com/isaacs/rimraf) ([v2.7.1](https://github.com/isaacs/rimraf/tree/v2.7.1)), distributed under the [ISC License](https://github.com/isaacs/rimraf/blob/v2.7.1/LICENSE): diff --git a/package.json b/package.json index 377d8ff3df..567ecdb3b7 100644 --- a/package.json +++ b/package.json @@ -219,6 +219,7 @@ "@aws-sdk/client-s3": "^3.556.0", "@aws-sdk/s3-request-presigner": "^3.556.0", "@koa/router": "^12.0.1", + "@matteo.collina/tspl": "^0.1.1", "@newrelic/eslint-config": "^0.3.0", "@newrelic/newrelic-oss-cli": "^0.1.2", "@newrelic/test-utilities": "^9.1.0", @@ -254,7 +255,6 @@ "nock": "11.8.0", "proxy": "^2.1.1", "proxyquire": "^1.8.0", - "rfdc": "^1.3.1", "rimraf": "^2.6.3", "self-cert": "^2.0.0", "should": "*", diff --git a/test/unit/serverless/api-gateway-v2.test.js b/test/unit/serverless/api-gateway-v2.test.js index 12d6e69bf2..e07a6562ba 100644 --- a/test/unit/serverless/api-gateway-v2.test.js +++ b/test/unit/serverless/api-gateway-v2.test.js @@ -5,33 +5,35 @@ 'use strict' -const tap = require('tap') -const os = require('os') -const rfdc = require('rfdc')() +const test = require('node:test') +const assert = require('node:assert') +const os = require('node:os') + +const { tspl } = require('@matteo.collina/tspl') +const { match } = require('../../lib/custom-assertions') const helper = require('../../lib/agent_helper') const AwsLambda = require('../../../lib/serverless/aws-lambda') -const ATTR_DEST = require('../../../lib/config/attribute-filter').DESTINATIONS - +const { DESTINATIONS: ATTR_DEST } = require('../../../lib/config/attribute-filter') const { httpApiGatewayV2Event: v2Event } = require('./fixtures') -tap.beforeEach((t) => { +test.beforeEach((ctx) => { // This env var suppresses console output we don't need to inspect. process.env.NEWRELIC_PIPE_PATH = os.devNull - t.context.agent = helper.loadMockedAgent({ + ctx.nr = {} + ctx.nr.agent = helper.loadMockedAgent({ allow_all_headers: true, serverless_mode: { enabled: true } }) - t.context.lambda = new AwsLambda(t.context.agent) - t.context.lambda._resetModuleState() + ctx.nr.lambda = new AwsLambda(ctx.nr.agent) + ctx.nr.lambda._resetModuleState() - // structuredClone is not available in Node 16 ☹️ - t.context.event = rfdc(v2Event) - t.context.functionContext = { + ctx.nr.event = structuredClone(v2Event) + ctx.nr.functionContext = { done() {}, succeed() {}, fail() {}, @@ -41,39 +43,38 @@ tap.beforeEach((t) => { memoryLimitInMB: '128', awsRequestId: 'testId' } - t.context.responseBody = { + ctx.nr.responseBody = { isBase64Encoded: false, statusCode: 200, headers: { responseHeader: 'headerValue' }, body: 'worked' } - t.context.agent.setState('started') + ctx.nr.agent.setState('started') }) -tap.afterEach((t) => { - helper.unloadAgent(t.context.agent) +test.afterEach((ctx) => { + helper.unloadAgent(ctx.nr.agent) }) -tap.test('should pick up the arn', async (t) => { - const { agent, lambda, event, functionContext } = t.context - t.equal(agent.collector.metadata.arn, null) +test('should pick up the arn', async (t) => { + const { agent, lambda, event, functionContext } = t.nr + assert.equal(agent.collector.metadata.arn, null) lambda.patchLambdaHandler(() => {})(event, functionContext, () => {}) - t.equal(agent.collector.metadata.arn, functionContext.invokedFunctionArn) + assert.equal(agent.collector.metadata.arn, functionContext.invokedFunctionArn) }) -tap.test('should create a web transaction', (t) => { - t.plan(8) - - const { agent, lambda, event, functionContext, responseBody } = t.context +test('should create a web transaction', (t, end) => { + const plan = tspl(t, { plan: 8 }) + const { agent, lambda, event, functionContext, responseBody } = t.nr agent.on('transactionFinished', verifyAttributes) const wrappedHandler = lambda.patchLambdaHandler((event, context, callback) => { const tx = agent.tracer.getTransaction() - t.ok(tx) - t.equal(tx.type, 'web') - t.equal(tx.getFullName(), 'WebTransaction/Function/testFunction') - t.equal(tx.isActive(), true) + plan.ok(tx) + plan.equal(tx.type, 'web') + plan.equal(tx.getFullName(), 'WebTransaction/Function/testFunction') + plan.equal(tx.isActive(), true) callback(null, responseBody) }) @@ -85,23 +86,23 @@ tap.test('should create a web transaction', (t) => { const segment = tx.baseSegment const spanAttributes = segment.attributes.get(ATTR_DEST.SPAN_EVENT) - t.equal(agentAttributes['request.method'], 'POST') - t.equal(agentAttributes['request.uri'], '/my/path') - t.equal(spanAttributes['request.method'], 'POST') - t.equal(spanAttributes['request.uri'], '/my/path') + plan.equal(agentAttributes['request.method'], 'POST') + plan.equal(agentAttributes['request.uri'], '/my/path') + plan.equal(spanAttributes['request.method'], 'POST') + plan.equal(spanAttributes['request.uri'], '/my/path') - t.end() + end() } }) -tap.test('should set w3c tracecontext on transaction if present on request header', (t) => { - t.plan(2) +test('should set w3c tracecontext on transaction if present on request header', (t, end) => { + const plan = tspl(t, { plan: 2 }) const expectedTraceId = '4bf92f3577b34da6a3ce929d0e0e4736' const traceparent = `00-${expectedTraceId}-00f067aa0ba902b7-00` - const { agent, lambda, event, functionContext, responseBody } = t.context + const { agent, lambda, event, functionContext, responseBody } = t.nr agent.on('transactionFinished', () => { - t.end() + end() }) agent.config.distributed_tracing.enabled = true @@ -116,8 +117,8 @@ tap.test('should set w3c tracecontext on transaction if present on request heade const traceParentFields = headers.traceparent.split('-') const [version, traceId] = traceParentFields - t.equal(version, '00') - t.equal(traceId, expectedTraceId) + plan.equal(version, '00') + plan.equal(traceId, expectedTraceId) callback(null, responseBody) }) @@ -125,12 +126,12 @@ tap.test('should set w3c tracecontext on transaction if present on request heade wrappedHandler(event, functionContext, () => {}) }) -tap.test('should add w3c tracecontext to transaction if not present on request header', (t) => { - t.plan(2) +test('should add w3c tracecontext to transaction if not present on request header', (t, end) => { + const plan = tspl(t, { plan: 2 }) - const { agent, lambda, event, functionContext, responseBody } = t.context + const { agent, lambda, event, functionContext, responseBody } = t.nr agent.on('transactionFinished', () => { - t.end() + end() }) agent.config.account_id = 'AccountId1' @@ -144,8 +145,8 @@ tap.test('should add w3c tracecontext to transaction if not present on request h const headers = {} tx.insertDistributedTraceHeaders(headers) - t.match(headers.traceparent, /00-[a-f0-9]{32}-[a-f0-9]{16}-\d{2}/) - t.match(headers.tracestate, /33@nr=.+AccountId1-AppId1.+/) + plan.equal(match(headers.traceparent, /00-[a-f0-9]{32}-[a-f0-9]{16}-\d{2}/), true) + plan.equal(match(headers.tracestate, /33@nr=.+AccountId1-AppId1.+/), true) callback(null, responseBody) }) @@ -153,10 +154,10 @@ tap.test('should add w3c tracecontext to transaction if not present on request h wrappedHandler(event, functionContext, () => {}) }) -tap.test('should capture request parameters', (t) => { - t.plan(5) +test('should capture request parameters', (t, end) => { + const plan = tspl(t, { plan: 5 }) - const { agent, lambda, event, functionContext, responseBody } = t.context + const { agent, lambda, event, functionContext, responseBody } = t.nr agent.on('transactionFinished', verifyAttributes) agent.config.attributes.enabled = true @@ -173,23 +174,23 @@ tap.test('should capture request parameters', (t) => { function verifyAttributes(tx) { const agentAttributes = tx.trace.attributes.get(ATTR_DEST.TRANS_EVENT) - t.equal(agentAttributes['request.parameters.name'], 'me') - t.equal(agentAttributes['request.parameters.team'], 'node agent') + plan.equal(agentAttributes['request.parameters.name'], 'me') + plan.equal(agentAttributes['request.parameters.team'], 'node agent') const spanAttributes = tx.baseSegment.attributes.get(ATTR_DEST.SPAN_EVENT) - t.equal(spanAttributes['request.parameters.name'], 'me') - t.equal(spanAttributes['request.parameters.team'], 'node agent') + plan.equal(spanAttributes['request.parameters.name'], 'me') + plan.equal(spanAttributes['request.parameters.team'], 'node agent') - t.equal(agentAttributes['request.parameters.parameter1'], 'value1,value2') + plan.equal(agentAttributes['request.parameters.parameter1'], 'value1,value2') - t.end() + end() } }) -tap.test('should capture request headers', (t) => { - t.plan(2) +test('should capture request headers', (t, end) => { + const plan = tspl(t, { plan: 2 }) - const { agent, lambda, event, functionContext, responseBody } = t.context + const { agent, lambda, event, functionContext, responseBody } = t.nr agent.on('transactionFinished', verifyAttributes) const wrappedHandler = lambda.patchLambdaHandler((event, context, callback) => { @@ -200,23 +201,22 @@ tap.test('should capture request headers', (t) => { function verifyAttributes(tx) { const attrs = tx.trace.attributes.get(ATTR_DEST.TRANS_EVENT) - t.equal(attrs['request.headers.accept'], 'application/json') - t.equal(attrs['request.headers.header2'], 'value1,value2') + plan.equal(attrs['request.headers.accept'], 'application/json') + plan.equal(attrs['request.headers.header2'], 'value1,value2') - t.end() + end() } }) -tap.test('should not crash when headers are non-existent', (t) => { - const { lambda, event, functionContext, responseBody } = t.context +test('should not crash when headers are non-existent', (t) => { + const { lambda, event, functionContext, responseBody } = t.nr delete event.headers const wrappedHandler = lambda.patchLambdaHandler((event, context, callback) => { callback(null, responseBody) }) - t.doesNotThrow(() => { + assert.doesNotThrow(() => { wrappedHandler(event, functionContext, () => {}) }) - t.end() }) diff --git a/third_party_manifest.json b/third_party_manifest.json index e4ee1bedaf..7713a36e14 100644 --- a/third_party_manifest.json +++ b/third_party_manifest.json @@ -1,5 +1,5 @@ { - "lastUpdated": "Fri Aug 30 2024 14:16:44 GMT-0500 (Central Daylight Time)", + "lastUpdated": "Mon Sep 09 2024 10:05:18 GMT-0400 (Eastern Daylight Time)", "projectName": "New Relic Node Agent", "projectUrl": "https://github.com/newrelic/node-newrelic", "includeOptDeps": true, @@ -226,28 +226,28 @@ } }, "devDependencies": { - "@aws-sdk/client-s3@3.637.0": { + "@aws-sdk/client-s3@3.632.0": { "name": "@aws-sdk/client-s3", - "version": "3.637.0", + "version": "3.632.0", "range": "^3.556.0", "licenses": "Apache-2.0", "repoUrl": "https://github.com/aws/aws-sdk-js-v3", - "versionedRepoUrl": "https://github.com/aws/aws-sdk-js-v3/tree/v3.637.0", + "versionedRepoUrl": "https://github.com/aws/aws-sdk-js-v3/tree/v3.632.0", "licenseFile": "node_modules/@aws-sdk/client-s3/LICENSE", - "licenseUrl": "https://github.com/aws/aws-sdk-js-v3/blob/v3.637.0/LICENSE", + "licenseUrl": "https://github.com/aws/aws-sdk-js-v3/blob/v3.632.0/LICENSE", "licenseTextSource": "file", "publisher": "AWS SDK for JavaScript Team", "url": "https://aws.amazon.com/javascript/" }, - "@aws-sdk/s3-request-presigner@3.637.0": { + "@aws-sdk/s3-request-presigner@3.632.0": { "name": "@aws-sdk/s3-request-presigner", - "version": "3.637.0", + "version": "3.632.0", "range": "^3.556.0", "licenses": "Apache-2.0", "repoUrl": "https://github.com/aws/aws-sdk-js-v3", - "versionedRepoUrl": "https://github.com/aws/aws-sdk-js-v3/tree/v3.637.0", + "versionedRepoUrl": "https://github.com/aws/aws-sdk-js-v3/tree/v3.632.0", "licenseFile": "node_modules/@aws-sdk/s3-request-presigner/LICENSE", - "licenseUrl": "https://github.com/aws/aws-sdk-js-v3/blob/v3.637.0/LICENSE", + "licenseUrl": "https://github.com/aws/aws-sdk-js-v3/blob/v3.632.0/LICENSE", "licenseTextSource": "file", "publisher": "AWS SDK for JavaScript Team", "url": "https://aws.amazon.com/javascript/" @@ -265,6 +265,19 @@ "publisher": "Alex Mingoia", "email": "talk@alexmingoia.com" }, + "@matteo.collina/tspl@0.1.1": { + "name": "@matteo.collina/tspl", + "version": "0.1.1", + "range": "^0.1.1", + "licenses": "MIT", + "repoUrl": "https://github.com/mcollina/tspl", + "versionedRepoUrl": "https://github.com/mcollina/tspl/tree/v0.1.1", + "licenseFile": "node_modules/@matteo.collina/tspl/LICENSE", + "licenseUrl": "https://github.com/mcollina/tspl/blob/v0.1.1/LICENSE", + "licenseTextSource": "file", + "publisher": "Matteo Collina", + "email": "hello@matteocollina.com" + }, "@newrelic/eslint-config@0.3.0": { "name": "@newrelic/eslint-config", "version": "0.3.0", @@ -364,27 +377,27 @@ "licenseTextSource": "file", "publisher": "Evgeny Poberezkin" }, - "async@3.2.6": { + "async@3.2.5": { "name": "async", - "version": "3.2.6", + "version": "3.2.5", "range": "^3.2.4", "licenses": "MIT", "repoUrl": "https://github.com/caolan/async", - "versionedRepoUrl": "https://github.com/caolan/async/tree/v3.2.6", + "versionedRepoUrl": "https://github.com/caolan/async/tree/v3.2.5", "licenseFile": "node_modules/async/LICENSE", - "licenseUrl": "https://github.com/caolan/async/blob/v3.2.6/LICENSE", + "licenseUrl": "https://github.com/caolan/async/blob/v3.2.5/LICENSE", "licenseTextSource": "file", "publisher": "Caolan McMahon" }, - "aws-sdk@2.1687.0": { + "aws-sdk@2.1677.0": { "name": "aws-sdk", - "version": "2.1687.0", + "version": "2.1677.0", "range": "^2.1604.0", "licenses": "Apache-2.0", "repoUrl": "https://github.com/aws/aws-sdk-js", - "versionedRepoUrl": "https://github.com/aws/aws-sdk-js/tree/v2.1687.0", + "versionedRepoUrl": "https://github.com/aws/aws-sdk-js/tree/v2.1677.0", "licenseFile": "node_modules/aws-sdk/LICENSE.txt", - "licenseUrl": "https://github.com/aws/aws-sdk-js/blob/v2.1687.0/LICENSE.txt", + "licenseUrl": "https://github.com/aws/aws-sdk-js/blob/v2.1677.0/LICENSE.txt", "licenseTextSource": "file", "publisher": "Amazon Web Services", "url": "https://aws.amazon.com/" @@ -710,19 +723,6 @@ "licenseTextSource": "file", "publisher": "Thorsten Lorenz" }, - "rfdc@1.4.1": { - "name": "rfdc", - "version": "1.4.1", - "range": "^1.3.1", - "licenses": "MIT", - "repoUrl": "https://github.com/davidmarkclements/rfdc", - "versionedRepoUrl": "https://github.com/davidmarkclements/rfdc/tree/v1.4.1", - "licenseFile": "node_modules/rfdc/LICENSE", - "licenseUrl": "https://github.com/davidmarkclements/rfdc/blob/v1.4.1/LICENSE", - "licenseTextSource": "file", - "publisher": "David Mark Clements", - "email": "david.clements@nearform.com" - }, "rimraf@2.7.1": { "name": "rimraf", "version": "2.7.1", From bb07496df7824d30c882d77f2784af79885ed4a7 Mon Sep 17 00:00:00 2001 From: James Sumners Date: Mon, 9 Sep 2024 15:02:42 -0400 Subject: [PATCH 2/3] update aws-lambda tests --- test/lib/temp-override-uncaught.js | 58 ++ test/lib/temp-remove-listeners.js | 36 + test/unit/serverless/aws-lambda.test.js | 1001 ++++++++++++----------- 3 files changed, 616 insertions(+), 479 deletions(-) create mode 100644 test/lib/temp-override-uncaught.js create mode 100644 test/lib/temp-remove-listeners.js diff --git a/test/lib/temp-override-uncaught.js b/test/lib/temp-override-uncaught.js new file mode 100644 index 0000000000..a860f355a1 --- /dev/null +++ b/test/lib/temp-override-uncaught.js @@ -0,0 +1,58 @@ +/* + * Copyright 2024 New Relic Corporation. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +'use strict' + +const EXCEPTION = 'uncaughtException' +const REJECTION = 'unhandledRejection' + +module.exports = tempOverrideUncaught + +const oldListeners = { + EXCEPTION: [], + REJECTION: [] +} + +/** + * Temporarily removes all listeners for the target exception handler, + * either `uncaughtException` (default) or `unhandledRejection`, subsequently + * restoring the original listeners upon test completion. + * + * @param {object} params + * @param {TestContext} t A `node:test` context object. + * @param {function} handler An error handler function that will replace all + * current listeners. + * @param {string} [type='uncaughtException'] The kind of uncaught event to + * override. + * @property {string} EXCEPTION Constant value usable for `type`. + * @property {string} REJECTION Constant value usable for `type`. + */ +function tempOverrideUncaught({ t, handler, type = EXCEPTION }) { + if (!handler) { + handler = function uncaughtTestHandler() { + t.diagnostic('uncaught handler not defined') + } + } + + oldListeners[type] = process.listeners(type) + process.removeAllListeners(type) + process.once(type, (error) => { + handler(error) + }) + + // We probably shouldn't be adding a `t.after` in this helper. There can only + // be one `t.after` handler per test, and putting in here obscures the fact + // that it has been added. + t.after(() => { + for (const l of oldListeners[type]) { + process.on(type, l) + } + }) +} + +Object.defineProperties(tempOverrideUncaught, { + EXCEPTION: { value: EXCEPTION }, + REJECTION: { value: REJECTION } +}) diff --git a/test/lib/temp-remove-listeners.js b/test/lib/temp-remove-listeners.js new file mode 100644 index 0000000000..58e7010d90 --- /dev/null +++ b/test/lib/temp-remove-listeners.js @@ -0,0 +1,36 @@ +/* + * Copyright 2024 New Relic Corporation. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +'use strict' + +/** + * Temporarily removes all event listeners on an emitter for a specific event + * and re-adds them subsequent to a test completing. + * + * @param {object} params + * @param {TestContext} t A `node:test` test context. + * @param {EventEmitter} emitter The emitter to manipulate. + * @param {string} event The event name to target. + */ +module.exports = function tempRemoveListeners({ t, emitter, event }) { + if (!emitter) { + t.diagnostic(`Not removing ${event} listeners, emitter does not exist`) + return + } + + t.diagnostic(`Removing listeners for ${event}`) + const listeners = emitter.listeners(event) + emitter.removeAllListeners(event) + + // We probably shouldn't be adding a `t.after` in this helper. There can only + // be one `t.after` handler per test, and putting in here obscures the fact + // that it has been added. + t.after(() => { + t.diagnostic(`Re-adding listeners for ${event}`) + for (const l of listeners) { + emitter.on(event, l) + } + }) +} diff --git a/test/unit/serverless/aws-lambda.test.js b/test/unit/serverless/aws-lambda.test.js index e8ec32710a..9e3e2413aa 100644 --- a/test/unit/serverless/aws-lambda.test.js +++ b/test/unit/serverless/aws-lambda.test.js @@ -1,29 +1,35 @@ /* - * Copyright 2020 New Relic Corporation. All rights reserved. + * Copyright 2024 New Relic Corporation. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ 'use strict' -const tap = require('tap') +const test = require('node:test') +const assert = require('node:assert') +const os = require('node:os') -const os = require('os') const helper = require('../../lib/agent_helper') +const tempRemoveListeners = require('../../lib/temp-remove-listeners') +const tempOverrideUncaught = require('../../lib/temp-override-uncaught') const AwsLambda = require('../../../lib/serverless/aws-lambda') const lambdaSampleEvents = require('./lambda-sample-events') -const ATTR_DEST = require('../../../lib/config/attribute-filter').DESTINATIONS +const { DESTINATIONS: ATTR_DEST } = require('../../../lib/config/attribute-filter') const symbols = require('../../../lib/symbols') -// attribute key names + +// Attribute key names: const REQ_ID = 'aws.requestId' const LAMBDA_ARN = 'aws.lambda.arn' const COLDSTART = 'aws.lambda.coldStart' const EVENTSOURCE_ARN = 'aws.lambda.eventSource.arn' const EVENTSOURCE_TYPE = 'aws.lambda.eventSource.eventType' -tap.test('AwsLambda.patchLambdaHandler', (t) => { - t.autoend() +function getMetrics(agent) { + return agent.metrics._metrics +} +test('AwsLambda.patchLambdaHandler', async (t) => { const groupName = 'Function' const functionName = 'testName' const expectedTransactionName = groupName + '/' + functionName @@ -31,89 +37,66 @@ tap.test('AwsLambda.patchLambdaHandler', (t) => { const expectedWebTransactionName = 'WebTransaction/' + expectedTransactionName const errorMessage = 'sad day' - let agent - let awsLambda - - let stubEvent - let stubContext - let stubCallback - - let error + t.beforeEach((ctx) => { + ctx.nr = {} + ctx.nr.agent = helper.loadMockedAgent({ + allow_all_headers: true, + attributes: { + exclude: ['request.headers.x*', 'response.headers.x*'] + }, + serverless_mode: { enabled: true } + }) - t.beforeEach(() => { - if (!agent) { - agent = helper.loadMockedAgent({ - allow_all_headers: true, - attributes: { - exclude: ['request.headers.x*', 'response.headers.x*'] - }, - serverless_mode: { - enabled: true - } - }) - } process.env.NEWRELIC_PIPE_PATH = os.devNull - awsLambda = new AwsLambda(agent) + const awsLambda = new AwsLambda(ctx.nr.agent) + ctx.nr.awsLambda = awsLambda awsLambda._resetModuleState() - stubEvent = {} - ;(stubContext = { - done: () => {}, - succeed: () => {}, - fail: () => {}, + ctx.nr.stubEvent = {} + ctx.nr.stubContext = { + done() {}, + succeed() {}, + fail() {}, functionName: functionName, functionVersion: 'TestVersion', invokedFunctionArn: 'arn:test:function', memoryLimitInMB: '128', awsRequestId: 'testid' - }), - (stubCallback = () => {}) + } + ctx.nr.stubCallback = () => {} process.env.AWS_EXECUTION_ENV = 'Test_nodejsNegative2.3' - error = new SyntaxError(errorMessage) + ctx.nr.error = new SyntaxError(errorMessage) - agent.setState('started') + ctx.nr.agent.setState('started') }) - t.afterEach(() => { - stubEvent = null - stubContext = null - stubCallback = null - error = null - + t.afterEach((ctx) => { delete process.env.AWS_EXECUTION_ENV - - if (agent) { - helper.unloadAgent(agent) - } + helper.unloadAgent(ctx.nr.agent) if (process.emit && process.emit[symbols.unwrap]) { process.emit[symbols.unwrap]() } - - agent = null - awsLambda = null }) - t.test('should return original handler if not a function', (t) => { + await t.test('should return original handler if not a function', (t) => { const handler = {} - const newHandler = awsLambda.patchLambdaHandler(handler) + const newHandler = t.nr.awsLambda.patchLambdaHandler(handler) - t.equal(newHandler, handler) - t.end() + assert.equal(newHandler, handler) }) - t.test('should pick up on the arn', function (t) { - t.equal(agent.collector.metadata.arn, null) + await t.test('should pick up on the arn', function (t) { + const { agent, awsLambda, stubEvent, stubContext, stubCallback } = t.nr + assert.equal(agent.collector.metadata.arn, null) awsLambda.patchLambdaHandler(() => {})(stubEvent, stubContext, stubCallback) - t.equal(agent.collector.metadata.arn, stubContext.invokedFunctionArn) - t.end() + assert.equal(agent.collector.metadata.arn, stubContext.invokedFunctionArn) }) - t.test('when invoked with API Gateway Lambda proxy event', (t) => { - t.autoend() - + await t.test('when invoked with API Gateway Lambda proxy event', async (t) => { + helper.unloadAgent(t.nr.agent) const validResponse = { isBase64Encoded: false, statusCode: 200, @@ -121,7 +104,8 @@ tap.test('AwsLambda.patchLambdaHandler', (t) => { body: 'worked' } - t.test('should create web transaction', async (t) => { + await t.test('should create web transaction', (t, end) => { + const { agent, awsLambda, stubContext, stubCallback } = t.nr agent.on('transactionFinished', confirmAgentAttribute) const apiGatewayProxyEvent = lambdaSampleEvents.apiGatewayProxyEvent @@ -129,10 +113,10 @@ tap.test('AwsLambda.patchLambdaHandler', (t) => { const wrappedHandler = awsLambda.patchLambdaHandler((event, context, callback) => { const transaction = agent.tracer.getTransaction() - t.ok(transaction) - t.equal(transaction.type, 'web') - t.equal(transaction.getFullName(), expectedWebTransactionName) - t.equal(transaction.isActive(), true) + assert.ok(transaction) + assert.equal(transaction.type, 'web') + assert.equal(transaction.getFullName(), expectedWebTransactionName) + assert.equal(transaction.isActive(), true) callback(null, validResponse) }) @@ -144,79 +128,88 @@ tap.test('AwsLambda.patchLambdaHandler', (t) => { const segment = transaction.baseSegment const spanAttributes = segment.attributes.get(ATTR_DEST.SPAN_EVENT) - t.equal(agentAttributes['request.method'], 'GET') - t.equal(agentAttributes['request.uri'], '/test/hello') + assert.equal(agentAttributes['request.method'], 'GET') + assert.equal(agentAttributes['request.uri'], '/test/hello') - t.equal(spanAttributes['request.method'], 'GET') - t.equal(spanAttributes['request.uri'], '/test/hello') + assert.equal(spanAttributes['request.method'], 'GET') + assert.equal(spanAttributes['request.uri'], '/test/hello') - t.end() + end() } }) - t.test('should set w3c tracecontext on transaction if present on request header', (t) => { - const expectedTraceId = '4bf92f3577b34da6a3ce929d0e0e4736' - const traceparent = `00-${expectedTraceId}-00f067aa0ba902b7-00` - - // transaction finished event passes back transaction, - // so can't pass `done` in or will look like errored. - agent.on('transactionFinished', () => { - t.end() - }) - - agent.config.distributed_tracing.enabled = true + await t.test( + 'should set w3c tracecontext on transaction if present on request header', + (t, end) => { + const { agent, awsLambda, stubContext, stubCallback } = t.nr + const expectedTraceId = '4bf92f3577b34da6a3ce929d0e0e4736' + const traceparent = `00-${expectedTraceId}-00f067aa0ba902b7-00` + + // transaction finished event passes back transaction, + // so can't pass `done` in or will look like errored. + agent.on('transactionFinished', () => { + end() + }) - const apiGatewayProxyEvent = lambdaSampleEvents.apiGatewayProxyEvent - apiGatewayProxyEvent.headers.traceparent = traceparent + agent.config.distributed_tracing.enabled = true - const wrappedHandler = awsLambda.patchLambdaHandler((event, context, callback) => { - const transaction = agent.tracer.getTransaction() + const apiGatewayProxyEvent = lambdaSampleEvents.apiGatewayProxyEvent + apiGatewayProxyEvent.headers.traceparent = traceparent - const headers = {} - transaction.insertDistributedTraceHeaders(headers) + const wrappedHandler = awsLambda.patchLambdaHandler((event, context, callback) => { + const transaction = agent.tracer.getTransaction() - const traceParentFields = headers.traceparent.split('-') - const [version, traceId] = traceParentFields + const headers = {} + transaction.insertDistributedTraceHeaders(headers) - t.equal(version, '00') - t.equal(traceId, expectedTraceId) + const traceParentFields = headers.traceparent.split('-') + const [version, traceId] = traceParentFields - callback(null, validResponse) - }) + assert.equal(version, '00') + assert.equal(traceId, expectedTraceId) - wrappedHandler(apiGatewayProxyEvent, stubContext, stubCallback) - }) + callback(null, validResponse) + }) - t.test('should add w3c tracecontext to transaction if not present on request header', (t) => { - // transaction finished event passes back transaction, - // so can't pass `done` in or will look like errored. - agent.on('transactionFinished', () => { - t.end() - }) + wrappedHandler(apiGatewayProxyEvent, stubContext, stubCallback) + } + ) + + await t.test( + 'should add w3c tracecontext to transaction if not present on request header', + (t, end) => { + const { agent, awsLambda, stubContext, stubCallback } = t.nr + // transaction finished event passes back transaction, + // so can't pass `done` in or will look like errored. + agent.on('transactionFinished', () => { + end() + }) - agent.config.account_id = 'AccountId1' - agent.config.primary_application_id = 'AppId1' - agent.config.trusted_account_key = 33 - agent.config.distributed_tracing.enabled = true + agent.config.account_id = 'AccountId1' + agent.config.primary_application_id = 'AppId1' + agent.config.trusted_account_key = 33 + agent.config.distributed_tracing.enabled = true - const apiGatewayProxyEvent = lambdaSampleEvents.apiGatewayProxyEvent + const apiGatewayProxyEvent = lambdaSampleEvents.apiGatewayProxyEvent - const wrappedHandler = awsLambda.patchLambdaHandler((event, context, callback) => { - const transaction = agent.tracer.getTransaction() + const wrappedHandler = awsLambda.patchLambdaHandler((event, context, callback) => { + const transaction = agent.tracer.getTransaction() - const headers = {} - transaction.insertDistributedTraceHeaders(headers) + const headers = {} + transaction.insertDistributedTraceHeaders(headers) - t.ok(headers.traceparent) - t.ok(headers.tracestate) + assert.ok(headers.traceparent) + assert.ok(headers.tracestate) - callback(null, validResponse) - }) + callback(null, validResponse) + }) - wrappedHandler(apiGatewayProxyEvent, stubContext, stubCallback) - }) + wrappedHandler(apiGatewayProxyEvent, stubContext, stubCallback) + } + ) - t.test('should capture request parameters', (t) => { + await t.test('should capture request parameters', (t, end) => { + const { agent, awsLambda, stubContext, stubCallback } = t.nr agent.on('transactionFinished', confirmAgentAttribute) agent.config.attributes.enabled = true @@ -234,14 +227,15 @@ tap.test('AwsLambda.patchLambdaHandler', (t) => { function confirmAgentAttribute(transaction) { const agentAttributes = transaction.trace.attributes.get(ATTR_DEST.TRANS_EVENT) - t.equal(agentAttributes['request.parameters.name'], 'me') - t.equal(agentAttributes['request.parameters.team'], 'node agent') + assert.equal(agentAttributes['request.parameters.name'], 'me') + assert.equal(agentAttributes['request.parameters.team'], 'node agent') - t.end() + end() } }) - t.test('should capture request parameters in Span Attributes', (t) => { + await t.test('should capture request parameters in Span Attributes', (t, end) => { + const { agent, awsLambda, stubContext, stubCallback } = t.nr agent.on('transactionFinished', confirmAgentAttribute) agent.config.attributes.enabled = true @@ -260,14 +254,15 @@ tap.test('AwsLambda.patchLambdaHandler', (t) => { const segment = transaction.baseSegment const spanAttributes = segment.attributes.get(ATTR_DEST.SPAN_EVENT) - t.equal(spanAttributes['request.parameters.name'], 'me') - t.equal(spanAttributes['request.parameters.team'], 'node agent') + assert.equal(spanAttributes['request.parameters.name'], 'me') + assert.equal(spanAttributes['request.parameters.team'], 'node agent') - t.end() + end() } }) - t.test('should capture request headers', (t) => { + await t.test('should capture request headers', (t, end) => { + const { agent, awsLambda, stubContext, stubCallback } = t.nr agent.on('transactionFinished', confirmAgentAttribute) const apiGatewayProxyEvent = lambdaSampleEvents.apiGatewayProxyEvent @@ -281,37 +276,41 @@ tap.test('AwsLambda.patchLambdaHandler', (t) => { function confirmAgentAttribute(transaction) { const agentAttributes = transaction.trace.attributes.get(ATTR_DEST.TRANS_EVENT) - t.equal( + assert.equal( agentAttributes['request.headers.accept'], 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8' ) - t.equal(agentAttributes['request.headers.acceptEncoding'], 'gzip, deflate, lzma, sdch, br') - t.equal(agentAttributes['request.headers.acceptLanguage'], 'en-US,en;q=0.8') - t.equal(agentAttributes['request.headers.cloudFrontForwardedProto'], 'https') - t.equal(agentAttributes['request.headers.cloudFrontIsDesktopViewer'], 'true') - t.equal(agentAttributes['request.headers.cloudFrontIsMobileViewer'], 'false') - t.equal(agentAttributes['request.headers.cloudFrontIsSmartTVViewer'], 'false') - t.equal(agentAttributes['request.headers.cloudFrontIsTabletViewer'], 'false') - t.equal(agentAttributes['request.headers.cloudFrontViewerCountry'], 'US') - t.equal( + assert.equal( + agentAttributes['request.headers.acceptEncoding'], + 'gzip, deflate, lzma, sdch, br' + ) + assert.equal(agentAttributes['request.headers.acceptLanguage'], 'en-US,en;q=0.8') + assert.equal(agentAttributes['request.headers.cloudFrontForwardedProto'], 'https') + assert.equal(agentAttributes['request.headers.cloudFrontIsDesktopViewer'], 'true') + assert.equal(agentAttributes['request.headers.cloudFrontIsMobileViewer'], 'false') + assert.equal(agentAttributes['request.headers.cloudFrontIsSmartTVViewer'], 'false') + assert.equal(agentAttributes['request.headers.cloudFrontIsTabletViewer'], 'false') + assert.equal(agentAttributes['request.headers.cloudFrontViewerCountry'], 'US') + assert.equal( agentAttributes['request.headers.host'], 'wt6mne2s9k.execute-api.us-west-2.amazonaws.com' ) - t.equal(agentAttributes['request.headers.upgradeInsecureRequests'], '1') - t.equal( + assert.equal(agentAttributes['request.headers.upgradeInsecureRequests'], '1') + assert.equal( agentAttributes['request.headers.userAgent'], 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6)' ) - t.equal( + assert.equal( agentAttributes['request.headers.via'], '1.1 fb7cca60f0ecd82ce07790c9c5eef16c.cloudfront.net (CloudFront)' ) - t.end() + end() } }) - t.test('should filter request headers by `exclude` rules', (t) => { + await t.test('should filter request headers by `exclude` rules', (t, end) => { + const { agent, awsLambda, stubContext, stubCallback } = t.nr agent.on('transactionFinished', confirmAgentAttribute) const apiGatewayProxyEvent = lambdaSampleEvents.apiGatewayProxyEvent @@ -325,26 +324,27 @@ tap.test('AwsLambda.patchLambdaHandler', (t) => { function confirmAgentAttribute(transaction) { const agentAttributes = transaction.trace.attributes.get(ATTR_DEST.TRANS_EVENT) - t.notOk('request.headers.X-Amz-Cf-Id' in agentAttributes) - t.notOk('request.headers.X-Forwarded-For' in agentAttributes) - t.notOk('request.headers.X-Forwarded-Port' in agentAttributes) - t.notOk('request.headers.X-Forwarded-Proto' in agentAttributes) + assert.equal('request.headers.X-Amz-Cf-Id' in agentAttributes, false) + assert.equal('request.headers.X-Forwarded-For' in agentAttributes, false) + assert.equal('request.headers.X-Forwarded-Port' in agentAttributes, false) + assert.equal('request.headers.X-Forwarded-Proto' in agentAttributes, false) - t.notOk('request.headers.xAmzCfId' in agentAttributes) - t.notOk('request.headers.xForwardedFor' in agentAttributes) - t.notOk('request.headers.xForwardedPort' in agentAttributes) - t.notOk('request.headers.xForwardedProto' in agentAttributes) + assert.equal('request.headers.xAmzCfId' in agentAttributes, false) + assert.equal('request.headers.xForwardedFor' in agentAttributes, false) + assert.equal('request.headers.xForwardedPort' in agentAttributes, false) + assert.equal('request.headers.xForwardedProto' in agentAttributes, false) - t.notOk('request.headers.XAmzCfId' in agentAttributes) - t.notOk('request.headers.XForwardedFor' in agentAttributes) - t.notOk('request.headers.XForwardedPort' in agentAttributes) - t.notOk('request.headers.XForwardedProto' in agentAttributes) + assert.equal('request.headers.XAmzCfId' in agentAttributes, false) + assert.equal('request.headers.XForwardedFor' in agentAttributes, false) + assert.equal('request.headers.XForwardedPort' in agentAttributes, false) + assert.equal('request.headers.XForwardedProto' in agentAttributes, false) - t.end() + end() } }) - t.test('should capture status code', (t) => { + await t.test('should capture status code', (t, end) => { + const { agent, awsLambda, stubContext, stubCallback } = t.nr agent.on('transactionFinished', confirmAgentAttribute) const apiGatewayProxyEvent = lambdaSampleEvents.apiGatewayProxyEvent @@ -360,15 +360,15 @@ tap.test('AwsLambda.patchLambdaHandler', (t) => { const segment = transaction.agent.tracer.getSegment() const spanAttributes = segment.attributes.get(ATTR_DEST.SPAN_EVENT) - t.equal(agentAttributes['http.statusCode'], '200') + assert.equal(agentAttributes['http.statusCode'], '200') + assert.equal(spanAttributes['http.statusCode'], '200') - t.equal(spanAttributes['http.statusCode'], '200') - - t.end() + end() } }) - t.test('should capture response status code in async lambda', (t) => { + await t.test('should capture response status code in async lambda', (t, end) => { + const { agent, awsLambda, stubContext, stubCallback } = t.nr agent.on('transactionFinished', confirmAgentAttribute) const apiGatewayProxyEvent = lambdaSampleEvents.apiGatewayProxyEvent @@ -392,15 +392,15 @@ tap.test('AwsLambda.patchLambdaHandler', (t) => { const segment = transaction.baseSegment const spanAttributes = segment.attributes.get(ATTR_DEST.SPAN_EVENT) - t.equal(agentAttributes['http.statusCode'], '200') - - t.equal(spanAttributes['http.statusCode'], '200') + assert.equal(agentAttributes['http.statusCode'], '200') + assert.equal(spanAttributes['http.statusCode'], '200') - t.end() + end() } }) - t.test('should capture response headers', (t) => { + await t.test('should capture response headers', (t, end) => { + const { agent, awsLambda, stubContext, stubCallback } = t.nr agent.on('transactionFinished', confirmAgentAttribute) const apiGatewayProxyEvent = lambdaSampleEvents.apiGatewayProxyEvent @@ -414,13 +414,14 @@ tap.test('AwsLambda.patchLambdaHandler', (t) => { function confirmAgentAttribute(transaction) { const agentAttributes = transaction.trace.attributes.get(ATTR_DEST.TRANS_EVENT) - t.equal(agentAttributes['response.headers.responseHeader'], 'headerValue') + assert.equal(agentAttributes['response.headers.responseHeader'], 'headerValue') - t.end() + end() } }) - t.test('should work when responding without headers', (t) => { + await t.test('should work when responding without headers', (t, end) => { + const { agent, awsLambda, stubContext, stubCallback } = t.nr agent.on('transactionFinished', confirmAgentAttribute) const apiGatewayProxyEvent = lambdaSampleEvents.apiGatewayProxyEvent @@ -438,13 +439,14 @@ tap.test('AwsLambda.patchLambdaHandler', (t) => { function confirmAgentAttribute(transaction) { const agentAttributes = transaction.trace.attributes.get(ATTR_DEST.TRANS_EVENT) - t.equal(agentAttributes['http.statusCode'], '200') + assert.equal(agentAttributes['http.statusCode'], '200') - t.end() + end() } }) - t.test('should detect event type', (t) => { + await t.test('should detect event type', (t, end) => { + const { agent, awsLambda, stubContext, stubCallback } = t.nr agent.on('transactionFinished', confirmAgentAttribute) const apiGatewayProxyEvent = lambdaSampleEvents.apiGatewayProxyEvent @@ -458,13 +460,14 @@ tap.test('AwsLambda.patchLambdaHandler', (t) => { function confirmAgentAttribute(transaction) { const agentAttributes = transaction.trace.attributes.get(ATTR_DEST.TRANS_EVENT) - t.equal(agentAttributes[EVENTSOURCE_TYPE], 'apiGateway') + assert.equal(agentAttributes[EVENTSOURCE_TYPE], 'apiGateway') - t.end() + end() } }) - t.test('should collect event source meta data', (t) => { + await t.test('should collect event source meta data', (t, end) => { + const { agent, awsLambda, stubContext, stubCallback } = t.nr agent.on('transactionFinished', confirmAgentAttribute) const apiGatewayProxyEvent = lambdaSampleEvents.apiGatewayProxyEvent @@ -480,23 +483,24 @@ tap.test('AwsLambda.patchLambdaHandler', (t) => { const segment = transaction.agent.tracer.getSegment() const spanAttributes = segment.attributes.get(ATTR_DEST.SPAN_EVENT) - t.equal(agentAttributes['aws.lambda.eventSource.accountId'], '123456789012') - t.equal(agentAttributes['aws.lambda.eventSource.apiId'], 'wt6mne2s9k') - t.equal(agentAttributes['aws.lambda.eventSource.resourceId'], 'us4z18') - t.equal(agentAttributes['aws.lambda.eventSource.resourcePath'], '/{proxy+}') - t.equal(agentAttributes['aws.lambda.eventSource.stage'], 'test') + assert.equal(agentAttributes['aws.lambda.eventSource.accountId'], '123456789012') + assert.equal(agentAttributes['aws.lambda.eventSource.apiId'], 'wt6mne2s9k') + assert.equal(agentAttributes['aws.lambda.eventSource.resourceId'], 'us4z18') + assert.equal(agentAttributes['aws.lambda.eventSource.resourcePath'], '/{proxy+}') + assert.equal(agentAttributes['aws.lambda.eventSource.stage'], 'test') - t.equal(spanAttributes['aws.lambda.eventSource.accountId'], '123456789012') - t.equal(spanAttributes['aws.lambda.eventSource.apiId'], 'wt6mne2s9k') - t.equal(spanAttributes['aws.lambda.eventSource.resourceId'], 'us4z18') - t.equal(spanAttributes['aws.lambda.eventSource.resourcePath'], '/{proxy+}') - t.equal(spanAttributes['aws.lambda.eventSource.stage'], 'test') + assert.equal(spanAttributes['aws.lambda.eventSource.accountId'], '123456789012') + assert.equal(spanAttributes['aws.lambda.eventSource.apiId'], 'wt6mne2s9k') + assert.equal(spanAttributes['aws.lambda.eventSource.resourceId'], 'us4z18') + assert.equal(spanAttributes['aws.lambda.eventSource.resourcePath'], '/{proxy+}') + assert.equal(spanAttributes['aws.lambda.eventSource.stage'], 'test') - t.end() + end() } }) - t.test('should record standard web metrics', (t) => { + await t.test('should record standard web metrics', (t, end) => { + const { agent, awsLambda, stubContext, stubCallback } = t.nr agent.on('harvestStarted', confirmMetrics) const apiGatewayProxyEvent = lambdaSampleEvents.apiGatewayProxyEvent @@ -509,51 +513,51 @@ tap.test('AwsLambda.patchLambdaHandler', (t) => { function confirmMetrics() { const unscopedMetrics = getMetrics(agent).unscoped - t.ok(unscopedMetrics) + assert.ok(unscopedMetrics) - t.ok(unscopedMetrics.HttpDispatcher) - t.equal(unscopedMetrics.HttpDispatcher.callCount, 1) + assert.ok(unscopedMetrics.HttpDispatcher) + assert.equal(unscopedMetrics.HttpDispatcher.callCount, 1) - t.ok(unscopedMetrics.Apdex) - t.equal(unscopedMetrics.Apdex.satisfying, 1) + assert.ok(unscopedMetrics.Apdex) + assert.equal(unscopedMetrics.Apdex.satisfying, 1) const transactionApdex = 'Apdex/' + expectedTransactionName - t.ok(unscopedMetrics[transactionApdex]) - t.equal(unscopedMetrics[transactionApdex].satisfying, 1) + assert.ok(unscopedMetrics[transactionApdex]) + assert.equal(unscopedMetrics[transactionApdex].satisfying, 1) - t.ok(unscopedMetrics.WebTransaction) - t.equal(unscopedMetrics.WebTransaction.callCount, 1) + assert.ok(unscopedMetrics.WebTransaction) + assert.equal(unscopedMetrics.WebTransaction.callCount, 1) - t.ok(unscopedMetrics[expectedWebTransactionName]) - t.equal(unscopedMetrics[expectedWebTransactionName].callCount, 1) + assert.ok(unscopedMetrics[expectedWebTransactionName]) + assert.equal(unscopedMetrics[expectedWebTransactionName].callCount, 1) - t.ok(unscopedMetrics.WebTransactionTotalTime) - t.equal(unscopedMetrics.WebTransactionTotalTime.callCount, 1) + assert.ok(unscopedMetrics.WebTransactionTotalTime) + assert.equal(unscopedMetrics.WebTransactionTotalTime.callCount, 1) const transactionWebTotalTime = 'WebTransactionTotalTime/' + expectedTransactionName - t.ok(unscopedMetrics[transactionWebTotalTime]) - t.equal(unscopedMetrics[transactionWebTotalTime].callCount, 1) + assert.ok(unscopedMetrics[transactionWebTotalTime]) + assert.equal(unscopedMetrics[transactionWebTotalTime].callCount, 1) - t.end() + end() } }) }) - t.test('should create a segment for handler', (t) => { - t.autoend() - + await t.test('should create a segment for handler', (t, end) => { + const { awsLambda, stubEvent, stubContext, stubCallback } = t.nr const wrappedHandler = awsLambda.patchLambdaHandler((event, context, callback) => { const segment = awsLambda.shim.getSegment() - t.not(segment, null) - t.equal(segment.name, functionName) + assert.notEqual(segment, null) + assert.equal(segment.name, functionName) - callback(null, 'worked') + end(callback(null, 'worked')) }) wrappedHandler(stubEvent, stubContext, stubCallback) }) - t.test('should capture cold start boolean on first invocation', (t) => { + await t.test('should capture cold start boolean on first invocation', (t, end) => { + const { agent, awsLambda, stubEvent, stubContext, stubCallback } = t.nr agent.on('transactionFinished', confirmColdStart) const wrappedHandler = awsLambda.patchLambdaHandler((event, context, callback) => { @@ -564,12 +568,13 @@ tap.test('AwsLambda.patchLambdaHandler', (t) => { function confirmColdStart(transaction) { const attributes = transaction.trace.attributes.get(ATTR_DEST.TRANS_EVENT) - t.equal(attributes['aws.lambda.coldStart'], true) - t.end() + assert.equal(attributes['aws.lambda.coldStart'], true) + end() } }) - t.test('should not include cold start on subsequent invocations', (t) => { + await t.test('should not include cold start on subsequent invocations', (t, end) => { + const { agent, awsLambda, stubEvent, stubContext, stubCallback } = t.nr let transactionNum = 1 agent.on('transactionFinished', confirmNoAdditionalColdStart) @@ -580,7 +585,7 @@ tap.test('AwsLambda.patchLambdaHandler', (t) => { wrappedHandler(stubEvent, stubContext, stubCallback) wrappedHandler(stubEvent, stubContext, () => { - t.end() + end() }) function confirmNoAdditionalColdStart(transaction) { @@ -588,15 +593,16 @@ tap.test('AwsLambda.patchLambdaHandler', (t) => { const attributes = transaction.trace.attributes.get(ATTR_DEST.TRANS_EVENT) const segment = transaction.agent.tracer.getSegment() const spanAttributes = segment.attributes.get(ATTR_DEST.SPAN_EVENT) - t.notOk('aws.lambda.coldStart' in attributes) - t.notOk('aws.lambda.coldStart' in spanAttributes) + assert.equal('aws.lambda.coldStart' in attributes, false) + assert.equal('aws.lambda.coldStart' in spanAttributes, false) } transactionNum++ } }) - t.test('should capture AWS agent attributes and send to correct dests', (t) => { + await t.test('should capture AWS agent attributes and send to correct dests', (t, end) => { + const { agent, awsLambda, stubContext, stubCallback } = t.nr agent.on('transactionFinished', confirmAgentAttributes) const wrappedHandler = awsLambda.patchLambdaHandler((event, context, callback) => { @@ -614,11 +620,11 @@ tap.test('AwsLambda.patchLambdaHandler', (t) => { const txTrace = _verifyDestinations(transaction) // now verify actual values - t.equal(txTrace[REQ_ID], stubContext.awsRequestId) - t.equal(txTrace[LAMBDA_ARN], stubContext.invokedFunctionArn) - t.equal(txTrace[COLDSTART], true) + assert.equal(txTrace[REQ_ID], stubContext.awsRequestId) + assert.equal(txTrace[LAMBDA_ARN], stubContext.invokedFunctionArn) + assert.equal(txTrace[COLDSTART], true) - t.end() + end() } function _verifyDestinations(tx) { @@ -629,16 +635,17 @@ tap.test('AwsLambda.patchLambdaHandler', (t) => { const all = [REQ_ID, LAMBDA_ARN, COLDSTART, EVENTSOURCE_ARN] all.forEach((key) => { - t.not(txTrace[key], undefined) - t.not(errEvent[key], undefined) - t.not(txEvent[key], undefined) + assert.notEqual(txTrace[key], undefined) + assert.notEqual(errEvent[key], undefined) + assert.notEqual(txEvent[key], undefined) }) return txTrace } }) - t.test('should not add attributes from empty event', (t) => { + await t.test('should not add attributes from empty event', (t, end) => { + const { agent, awsLambda, stubEvent, stubContext, stubCallback } = t.nr agent.on('transactionFinished', confirmAgentAttribute) const wrappedHandler = awsLambda.patchLambdaHandler((event, context, callback) => { @@ -652,18 +659,19 @@ tap.test('AwsLambda.patchLambdaHandler', (t) => { const segment = transaction.agent.tracer.getSegment() const spanAttributes = segment.attributes.get(ATTR_DEST.SPAN_EVENT) - t.notOk(EVENTSOURCE_ARN in agentAttributes) - t.notOk(EVENTSOURCE_TYPE in agentAttributes) - t.notOk(EVENTSOURCE_ARN in spanAttributes) - t.notOk(EVENTSOURCE_TYPE in spanAttributes) - t.end() + assert.equal(EVENTSOURCE_ARN in agentAttributes, false) + assert.equal(EVENTSOURCE_TYPE in agentAttributes, false) + assert.equal(EVENTSOURCE_ARN in spanAttributes, false) + assert.equal(EVENTSOURCE_TYPE in spanAttributes, false) + end() } }) - t.test('should capture kinesis data stream event source arn', (t) => { + await t.test('should capture kinesis data stream event source arn', (t, end) => { + const { agent, awsLambda, stubContext, stubCallback } = t.nr agent.on('transactionFinished', confirmAgentAttribute) - stubEvent = lambdaSampleEvents.kinesisDataStreamEvent + const stubEvent = lambdaSampleEvents.kinesisDataStreamEvent const wrappedHandler = awsLambda.patchLambdaHandler((event, context, callback) => { callback(null, 'worked') @@ -676,18 +684,19 @@ tap.test('AwsLambda.patchLambdaHandler', (t) => { const segment = transaction.agent.tracer.getSegment() const spanAttributes = segment.attributes.get(ATTR_DEST.SPAN_EVENT) - t.equal(agentAttributes[EVENTSOURCE_ARN], 'kinesis:eventsourcearn') - t.equal(spanAttributes[EVENTSOURCE_ARN], 'kinesis:eventsourcearn') - t.equal(agentAttributes[EVENTSOURCE_TYPE], 'kinesis') - t.equal(spanAttributes[EVENTSOURCE_TYPE], 'kinesis') - t.end() + assert.equal(agentAttributes[EVENTSOURCE_ARN], 'kinesis:eventsourcearn') + assert.equal(spanAttributes[EVENTSOURCE_ARN], 'kinesis:eventsourcearn') + assert.equal(agentAttributes[EVENTSOURCE_TYPE], 'kinesis') + assert.equal(spanAttributes[EVENTSOURCE_TYPE], 'kinesis') + end() } }) - t.test('should capture S3 PUT event source arn attribute', (t) => { + await t.test('should capture S3 PUT event source arn attribute', (t, end) => { + const { agent, awsLambda, stubContext, stubCallback } = t.nr agent.on('transactionFinished', confirmAgentAttribute) - stubEvent = lambdaSampleEvents.s3PutEvent + const stubEvent = lambdaSampleEvents.s3PutEvent const wrappedHandler = awsLambda.patchLambdaHandler((event, context, callback) => { callback(null, 'worked') @@ -700,20 +709,21 @@ tap.test('AwsLambda.patchLambdaHandler', (t) => { const segment = transaction.agent.tracer.getSegment() const spanAttributes = segment.attributes.get(ATTR_DEST.SPAN_EVENT) - t.equal(agentAttributes[EVENTSOURCE_ARN], 'bucketarn') - t.equal(agentAttributes[EVENTSOURCE_TYPE], 's3') + assert.equal(agentAttributes[EVENTSOURCE_ARN], 'bucketarn') + assert.equal(agentAttributes[EVENTSOURCE_TYPE], 's3') - t.equal(spanAttributes[EVENTSOURCE_ARN], 'bucketarn') - t.equal(spanAttributes[EVENTSOURCE_TYPE], 's3') + assert.equal(spanAttributes[EVENTSOURCE_ARN], 'bucketarn') + assert.equal(spanAttributes[EVENTSOURCE_TYPE], 's3') - t.end() + end() } }) - t.test('should capture SNS event source arn attribute', (t) => { + await t.test('should capture SNS event source arn attribute', (t, end) => { + const { agent, awsLambda, stubContext, stubCallback } = t.nr agent.on('transactionFinished', confirmAgentAttribute) - stubEvent = lambdaSampleEvents.snsEvent + const stubEvent = lambdaSampleEvents.snsEvent const wrappedHandler = awsLambda.patchLambdaHandler((event, context, callback) => { callback(null, 'worked') @@ -726,19 +736,20 @@ tap.test('AwsLambda.patchLambdaHandler', (t) => { const segment = transaction.agent.tracer.getSegment() const spanAttributes = segment.attributes.get(ATTR_DEST.SPAN_EVENT) - t.equal(agentAttributes[EVENTSOURCE_ARN], 'eventsubscriptionarn') - t.equal(agentAttributes[EVENTSOURCE_TYPE], 'sns') + assert.equal(agentAttributes[EVENTSOURCE_ARN], 'eventsubscriptionarn') + assert.equal(agentAttributes[EVENTSOURCE_TYPE], 'sns') - t.equal(spanAttributes[EVENTSOURCE_ARN], 'eventsubscriptionarn') - t.equal(spanAttributes[EVENTSOURCE_TYPE], 'sns') - t.end() + assert.equal(spanAttributes[EVENTSOURCE_ARN], 'eventsubscriptionarn') + assert.equal(spanAttributes[EVENTSOURCE_TYPE], 'sns') + end() } }) - t.test('should capture DynamoDB Update event source attribute', (t) => { + await t.test('should capture DynamoDB Update event source attribute', (t, end) => { + const { agent, awsLambda, stubContext, stubCallback } = t.nr agent.on('transactionFinished', confirmAgentAttribute) - stubEvent = lambdaSampleEvents.dynamoDbUpdateEvent + const stubEvent = lambdaSampleEvents.dynamoDbUpdateEvent const wrappedHandler = awsLambda.patchLambdaHandler((event, context, callback) => { callback(null, 'worked') @@ -751,16 +762,17 @@ tap.test('AwsLambda.patchLambdaHandler', (t) => { const segment = transaction.agent.tracer.getSegment() const spanAttributes = segment.attributes.get(ATTR_DEST.SPAN_EVENT) - t.equal(agentAttributes[EVENTSOURCE_ARN], 'dynamodb:eventsourcearn') - t.equal(spanAttributes[EVENTSOURCE_ARN], 'dynamodb:eventsourcearn') - t.end() + assert.equal(agentAttributes[EVENTSOURCE_ARN], 'dynamodb:eventsourcearn') + assert.equal(spanAttributes[EVENTSOURCE_ARN], 'dynamodb:eventsourcearn') + end() } }) - t.test('should capture CodeCommit event source attribute', (t) => { + await t.test('should capture CodeCommit event source attribute', (t, end) => { + const { agent, awsLambda, stubContext, stubCallback } = t.nr agent.on('transactionFinished', confirmAgentAttribute) - stubEvent = lambdaSampleEvents.codeCommitEvent + const stubEvent = lambdaSampleEvents.codeCommitEvent const wrappedHandler = awsLambda.patchLambdaHandler((event, context, callback) => { callback(null, 'worked') @@ -773,16 +785,23 @@ tap.test('AwsLambda.patchLambdaHandler', (t) => { const segment = transaction.agent.tracer.getSegment() const spanAttributes = segment.attributes.get(ATTR_DEST.SPAN_EVENT) - t.equal(agentAttributes[EVENTSOURCE_ARN], 'arn:aws:codecommit:us-west-2:123456789012:my-repo') - t.equal(spanAttributes[EVENTSOURCE_ARN], 'arn:aws:codecommit:us-west-2:123456789012:my-repo') - t.end() + assert.equal( + agentAttributes[EVENTSOURCE_ARN], + 'arn:aws:codecommit:us-west-2:123456789012:my-repo' + ) + assert.equal( + spanAttributes[EVENTSOURCE_ARN], + 'arn:aws:codecommit:us-west-2:123456789012:my-repo' + ) + end() } }) - t.test('should not capture unknown event source attribute', (t) => { + await t.test('should not capture unknown event source attribute', (t, end) => { + const { agent, awsLambda, stubContext, stubCallback } = t.nr agent.on('transactionFinished', confirmAgentAttribute) - stubEvent = lambdaSampleEvents.cloudFrontEvent + const stubEvent = lambdaSampleEvents.cloudFrontEvent const wrappedHandler = awsLambda.patchLambdaHandler((event, context, callback) => { callback(null, 'worked') @@ -795,18 +814,19 @@ tap.test('AwsLambda.patchLambdaHandler', (t) => { const segment = transaction.agent.tracer.getSegment() const spanAttributes = segment.attributes.get(ATTR_DEST.SPAN_EVENT) - t.equal(agentAttributes[EVENTSOURCE_ARN], undefined) - t.equal(agentAttributes[EVENTSOURCE_TYPE], 'cloudFront') - t.equal(spanAttributes[EVENTSOURCE_ARN], undefined) - t.equal(spanAttributes[EVENTSOURCE_TYPE], 'cloudFront') - t.end() + assert.equal(agentAttributes[EVENTSOURCE_ARN], undefined) + assert.equal(agentAttributes[EVENTSOURCE_TYPE], 'cloudFront') + assert.equal(spanAttributes[EVENTSOURCE_ARN], undefined) + assert.equal(spanAttributes[EVENTSOURCE_TYPE], 'cloudFront') + end() } }) - t.test('should capture Kinesis Data Firehose event source attribute', (t) => { + await t.test('should capture Kinesis Data Firehose event source attribute', (t, end) => { + const { agent, awsLambda, stubContext, stubCallback } = t.nr agent.on('transactionFinished', confirmAgentAttribute) - stubEvent = lambdaSampleEvents.kinesisDataFirehoseEvent + const stubEvent = lambdaSampleEvents.kinesisDataFirehoseEvent const wrappedHandler = awsLambda.patchLambdaHandler((event, context, callback) => { callback(null, 'worked') @@ -819,19 +839,20 @@ tap.test('AwsLambda.patchLambdaHandler', (t) => { const segment = transaction.agent.tracer.getSegment() const spanAttributes = segment.attributes.get(ATTR_DEST.SPAN_EVENT) - t.equal(agentAttributes[EVENTSOURCE_ARN], 'aws:lambda:events') - t.equal(agentAttributes[EVENTSOURCE_TYPE], 'firehose') + assert.equal(agentAttributes[EVENTSOURCE_ARN], 'aws:lambda:events') + assert.equal(agentAttributes[EVENTSOURCE_TYPE], 'firehose') - t.equal(spanAttributes[EVENTSOURCE_ARN], 'aws:lambda:events') - t.equal(spanAttributes[EVENTSOURCE_TYPE], 'firehose') - t.end() + assert.equal(spanAttributes[EVENTSOURCE_ARN], 'aws:lambda:events') + assert.equal(spanAttributes[EVENTSOURCE_TYPE], 'firehose') + end() } }) - t.test('should capture ALB event type', (t) => { + await t.test('should capture ALB event type', (t, end) => { + const { agent, awsLambda, stubContext, stubCallback } = t.nr agent.on('transactionFinished', confirmAgentAttribute) - stubEvent = lambdaSampleEvents.albEvent + const stubEvent = lambdaSampleEvents.albEvent const wrappedHandler = awsLambda.patchLambdaHandler((event, context, callback) => { callback(null, 'worked') @@ -844,27 +865,28 @@ tap.test('AwsLambda.patchLambdaHandler', (t) => { const segment = transaction.agent.tracer.getSegment() const spanAttributes = segment.attributes.get(ATTR_DEST.SPAN_EVENT) - t.equal( + assert.equal( agentAttributes[EVENTSOURCE_ARN], 'arn:aws:elasticloadbalancing:us-east-2:123456789012:targetgroup/lambda-279XGJDqGZ5rsrHC2Fjr/49e9d65c45c6791a' ) // eslint-disable-line max-len - t.equal(agentAttributes[EVENTSOURCE_TYPE], 'alb') + assert.equal(agentAttributes[EVENTSOURCE_TYPE], 'alb') - t.equal( + assert.equal( spanAttributes[EVENTSOURCE_ARN], 'arn:aws:elasticloadbalancing:us-east-2:123456789012:targetgroup/lambda-279XGJDqGZ5rsrHC2Fjr/49e9d65c45c6791a' ) // eslint-disable-line max-len - t.equal(spanAttributes[EVENTSOURCE_TYPE], 'alb') - t.end() + assert.equal(spanAttributes[EVENTSOURCE_TYPE], 'alb') + end() } }) - t.test('should capture CloudWatch Scheduled event type', (t) => { + await t.test('should capture CloudWatch Scheduled event type', (t, end) => { + const { agent, awsLambda, stubContext, stubCallback } = t.nr agent.on('transactionFinished', confirmAgentAttribute) - stubEvent = lambdaSampleEvents.cloudwatchScheduled + const stubEvent = lambdaSampleEvents.cloudwatchScheduled const wrappedHandler = awsLambda.patchLambdaHandler((event, context, callback) => { callback(null, 'worked') @@ -877,25 +899,26 @@ tap.test('AwsLambda.patchLambdaHandler', (t) => { const segment = transaction.agent.tracer.getSegment() const spanAttributes = segment.attributes.get(ATTR_DEST.SPAN_EVENT) - t.equal( + assert.equal( agentAttributes[EVENTSOURCE_ARN], 'arn:aws:events:us-west-2:123456789012:rule/ExampleRule' ) - t.equal(agentAttributes[EVENTSOURCE_TYPE], 'cloudWatch_scheduled') + assert.equal(agentAttributes[EVENTSOURCE_TYPE], 'cloudWatch_scheduled') - t.equal( + assert.equal( spanAttributes[EVENTSOURCE_ARN], 'arn:aws:events:us-west-2:123456789012:rule/ExampleRule' ) - t.equal(spanAttributes[EVENTSOURCE_TYPE], 'cloudWatch_scheduled') - t.end() + assert.equal(spanAttributes[EVENTSOURCE_TYPE], 'cloudWatch_scheduled') + end() } }) - t.test('should capture SES event type', (t) => { + await t.test('should capture SES event type', (t, end) => { + const { agent, awsLambda, stubContext, stubCallback } = t.nr agent.on('transactionFinished', confirmAgentAttribute) - stubEvent = lambdaSampleEvents.sesEvent + const stubEvent = lambdaSampleEvents.sesEvent const wrappedHandler = awsLambda.patchLambdaHandler((event, context, callback) => { callback(null, 'worked') @@ -908,20 +931,21 @@ tap.test('AwsLambda.patchLambdaHandler', (t) => { const segment = transaction.agent.tracer.getSegment() const spanAttributes = segment.attributes.get(ATTR_DEST.SPAN_EVENT) - t.equal(agentAttributes[EVENTSOURCE_TYPE], 'ses') - t.equal(spanAttributes[EVENTSOURCE_TYPE], 'ses') - t.end() + assert.equal(agentAttributes[EVENTSOURCE_TYPE], 'ses') + assert.equal(spanAttributes[EVENTSOURCE_TYPE], 'ses') + end() } }) - t.test('should capture ALB event type with multi value parameters', (t) => { + await t.test('should capture ALB event type with multi value parameters', (t, end) => { + const { agent, awsLambda, stubContext, stubCallback } = t.nr agent.on('transactionFinished', confirmAgentAttribute) agent.config.attributes.enabled = true agent.config.attributes.include = ['request.parameters.*'] agent.config.emit('attributes.include') - stubEvent = lambdaSampleEvents.albEventWithMultiValueParameters + const stubEvent = lambdaSampleEvents.albEventWithMultiValueParameters const wrappedHandler = awsLambda.patchLambdaHandler((event, context, callback) => { callback(null, 'worked') @@ -933,38 +957,39 @@ tap.test('AwsLambda.patchLambdaHandler', (t) => { const segment = transaction.agent.tracer.getSegment() const spanAttributes = segment.attributes.get(ATTR_DEST.SPAN_EVENT) - t.equal( + assert.equal( agentAttributes[EVENTSOURCE_ARN], 'arn:aws:elasticloadbalancing:us-east-2:123456789012:targetgroup/lambda-279XGJDqGZ5rsrHC2Fjr/49e9d65c45c6791a' ) // eslint-disable-line max-len - t.equal(agentAttributes[EVENTSOURCE_TYPE], 'alb') + assert.equal(agentAttributes[EVENTSOURCE_TYPE], 'alb') - t.equal(agentAttributes['request.method'], 'GET') + assert.equal(agentAttributes['request.method'], 'GET') // validate that multi value query string parameters are normalized to comma seperated strings - t.equal(agentAttributes['request.parameters.query'], '1234ABCD,other') + assert.equal(agentAttributes['request.parameters.query'], '1234ABCD,other') - t.equal( + assert.equal( spanAttributes[EVENTSOURCE_ARN], 'arn:aws:elasticloadbalancing:us-east-2:123456789012:targetgroup/lambda-279XGJDqGZ5rsrHC2Fjr/49e9d65c45c6791a' ) // eslint-disable-line max-len - t.equal(spanAttributes[EVENTSOURCE_TYPE], 'alb') + assert.equal(spanAttributes[EVENTSOURCE_TYPE], 'alb') // validate that multi value headers are normalized to comma seperated strings - t.equal( + assert.equal( spanAttributes['request.headers.setCookie'], 'cookie-name=cookie-value;Domain=myweb.com;Secure;HttpOnly,cookie-name=cookie-other-value' ) - t.end() + end() } }) - t.test('when callback used', (t) => { - t.autoend() + await t.test('when callback used', async (t) => { + helper.unloadAgent(t.nr.agent) - t.test('should end appropriately', (t) => { + await t.test('should end appropriately', (t, end) => { + const { agent, awsLambda, stubEvent, stubContext } = t.nr let transaction const wrappedHandler = awsLambda.patchLambdaHandler((event, context, callback) => { @@ -973,15 +998,16 @@ tap.test('AwsLambda.patchLambdaHandler', (t) => { }) wrappedHandler(stubEvent, stubContext, function confirmEndCallback() { - t.equal(transaction.isActive(), false) + assert.equal(transaction.isActive(), false) const currentTransaction = agent.tracer.getTransaction() - t.equal(currentTransaction, null) - t.end() + assert.equal(currentTransaction, null) + end() }) }) - t.test('should notice errors', (t) => { + await t.test('should notice errors', (t, end) => { + const { agent, awsLambda, error, stubEvent, stubContext, stubCallback } = t.nr agent.on('harvestStarted', confirmErrorCapture) const wrappedHandler = awsLambda.patchLambdaHandler((event, context, callback) => { @@ -991,17 +1017,18 @@ tap.test('AwsLambda.patchLambdaHandler', (t) => { wrappedHandler(stubEvent, stubContext, stubCallback) function confirmErrorCapture() { - t.equal(agent.errors.traceAggregator.errors.length, 1) + assert.equal(agent.errors.traceAggregator.errors.length, 1) const noticedError = agent.errors.traceAggregator.errors[0] - t.equal(noticedError[1], expectedBgTransactionName) - t.equal(noticedError[2], errorMessage) - t.equal(noticedError[3], 'SyntaxError') + assert.equal(noticedError[1], expectedBgTransactionName) + assert.equal(noticedError[2], errorMessage) + assert.equal(noticedError[3], 'SyntaxError') - t.end() + end() } }) - t.test('should notice string errors', (t) => { + await t.test('should notice string errors', (t, end) => { + const { agent, awsLambda, stubEvent, stubContext, stubCallback } = t.nr agent.on('harvestStarted', confirmErrorCapture) const wrappedHandler = awsLambda.patchLambdaHandler((event, context, callback) => { @@ -1011,24 +1038,25 @@ tap.test('AwsLambda.patchLambdaHandler', (t) => { wrappedHandler(stubEvent, stubContext, stubCallback) function confirmErrorCapture() { - t.equal(agent.errors.traceAggregator.errors.length, 1) + assert.equal(agent.errors.traceAggregator.errors.length, 1) const noticedError = agent.errors.traceAggregator.errors[0] - t.equal(noticedError[1], expectedBgTransactionName) - t.equal(noticedError[2], 'failed') - t.equal(noticedError[3], 'Error') + assert.equal(noticedError[1], expectedBgTransactionName) + assert.equal(noticedError[2], 'failed') + assert.equal(noticedError[3], 'Error') const data = noticedError[4] - t.ok(data.stack_trace) + assert.ok(data.stack_trace) - t.end() + end() } }) }) - t.test('when context.done used', (t) => { - t.autoend() + await test('when context.done used', async (t) => { + helper.unloadAgent(t.nr.agent) - t.test('should end appropriately', (t) => { + await t.test('should end appropriately', (t, end) => { + const { agent, awsLambda, stubEvent, stubContext, stubCallback } = t.nr let transaction stubContext.done = confirmEndCallback @@ -1041,23 +1069,24 @@ tap.test('AwsLambda.patchLambdaHandler', (t) => { wrappedHandler(stubEvent, stubContext, stubCallback) function confirmEndCallback() { - t.equal(transaction.isActive(), false) + assert.equal(transaction.isActive(), false) const currentTransaction = agent.tracer.getTransaction() - t.equal(currentTransaction, null) - t.end() + assert.equal(currentTransaction, null) + end() } }) - t.test('should notice errors', (t) => { + await t.test('should notice errors', (t, end) => { + const { agent, awsLambda, error, stubEvent, stubContext, stubCallback } = t.nr agent.on('harvestStarted', function confirmErrorCapture() { - t.equal(agent.errors.traceAggregator.errors.length, 1) + assert.equal(agent.errors.traceAggregator.errors.length, 1) const noticedError = agent.errors.traceAggregator.errors[0] - t.equal(noticedError[1], expectedBgTransactionName) - t.equal(noticedError[2], errorMessage) - t.equal(noticedError[3], 'SyntaxError') + assert.equal(noticedError[1], expectedBgTransactionName) + assert.equal(noticedError[2], errorMessage) + assert.equal(noticedError[3], 'SyntaxError') - t.end() + end() }) const wrappedHandler = awsLambda.patchLambdaHandler((event, context) => { @@ -1067,18 +1096,19 @@ tap.test('AwsLambda.patchLambdaHandler', (t) => { wrappedHandler(stubEvent, stubContext, stubCallback) }) - t.test('should notice string errors', (t) => { + await t.test('should notice string errors', (t, end) => { + const { agent, awsLambda, stubEvent, stubContext, stubCallback } = t.nr agent.on('harvestStarted', function confirmErrorCapture() { - t.equal(agent.errors.traceAggregator.errors.length, 1) + assert.equal(agent.errors.traceAggregator.errors.length, 1) const noticedError = agent.errors.traceAggregator.errors[0] - t.equal(noticedError[1], expectedBgTransactionName) - t.equal(noticedError[2], 'failed') - t.equal(noticedError[3], 'Error') + assert.equal(noticedError[1], expectedBgTransactionName) + assert.equal(noticedError[2], 'failed') + assert.equal(noticedError[3], 'Error') const data = noticedError[4] - t.ok(data.stack_trace) + assert.ok(data.stack_trace) - t.end() + end() }) const wrappedHandler = awsLambda.patchLambdaHandler((event, context) => { @@ -1089,18 +1119,19 @@ tap.test('AwsLambda.patchLambdaHandler', (t) => { }) }) - t.test('when context.succeed used', (t) => { - t.autoend() + await t.test('when context.succeed used', async (t) => { + helper.unloadAgent(t.nr.agent) - t.test('should end appropriately', (t) => { + await t.test('should end appropriately', (t, end) => { + const { agent, awsLambda, stubEvent, stubContext, stubCallback } = t.nr let transaction stubContext.succeed = function confirmEndCallback() { - t.equal(transaction.isActive(), false) + assert.equal(transaction.isActive(), false) const currentTransaction = agent.tracer.getTransaction() - t.equal(currentTransaction, null) - t.end() + assert.equal(currentTransaction, null) + end() } const wrappedHandler = awsLambda.patchLambdaHandler((event, context) => { @@ -1112,18 +1143,19 @@ tap.test('AwsLambda.patchLambdaHandler', (t) => { }) }) - t.test('when context.fail used', (t) => { - t.autoend() + await t.test('when context.fail used', async (t) => { + helper.unloadAgent(t.nr.agent) - t.test('should end appropriately', (t) => { + await t.test('should end appropriately', (t, end) => { + const { agent, awsLambda, stubEvent, stubContext, stubCallback } = t.nr let transaction stubContext.fail = function confirmEndCallback() { - t.equal(transaction.isActive(), false) + assert.equal(transaction.isActive(), false) const currentTransaction = agent.tracer.getTransaction() - t.equal(currentTransaction, null) - t.end() + assert.equal(currentTransaction, null) + end() } const wrappedHandler = awsLambda.patchLambdaHandler((event, context) => { @@ -1134,15 +1166,16 @@ tap.test('AwsLambda.patchLambdaHandler', (t) => { wrappedHandler(stubEvent, stubContext, stubCallback) }) - t.test('should notice errors', (t) => { + await t.test('should notice errors', (t, end) => { + const { agent, awsLambda, error, stubEvent, stubContext, stubCallback } = t.nr agent.on('harvestStarted', function confirmErrorCapture() { - t.equal(agent.errors.traceAggregator.errors.length, 1) + assert.equal(agent.errors.traceAggregator.errors.length, 1) const noticedError = agent.errors.traceAggregator.errors[0] - t.equal(noticedError[1], expectedBgTransactionName) - t.equal(noticedError[2], errorMessage) - t.equal(noticedError[3], 'SyntaxError') + assert.equal(noticedError[1], expectedBgTransactionName) + assert.equal(noticedError[2], errorMessage) + assert.equal(noticedError[3], 'SyntaxError') - t.end() + end() }) const wrappedHandler = awsLambda.patchLambdaHandler((event, context) => { @@ -1152,18 +1185,19 @@ tap.test('AwsLambda.patchLambdaHandler', (t) => { wrappedHandler(stubEvent, stubContext, stubCallback) }) - t.test('should notice string errors', (t) => { + await t.test('should notice string errors', (t, end) => { + const { agent, awsLambda, stubEvent, stubContext, stubCallback } = t.nr agent.on('harvestStarted', function confirmErrorCapture() { - t.equal(agent.errors.traceAggregator.errors.length, 1) + assert.equal(agent.errors.traceAggregator.errors.length, 1) const noticedError = agent.errors.traceAggregator.errors[0] - t.equal(noticedError[1], expectedBgTransactionName) - t.equal(noticedError[2], 'failed') - t.equal(noticedError[3], 'Error') + assert.equal(noticedError[1], expectedBgTransactionName) + assert.equal(noticedError[2], 'failed') + assert.equal(noticedError[3], 'Error') const data = noticedError[4] - t.ok(data.stack_trace) + assert.ok(data.stack_trace) - t.end() + end() }) const wrappedHandler = awsLambda.patchLambdaHandler((event, context) => { @@ -1174,51 +1208,54 @@ tap.test('AwsLambda.patchLambdaHandler', (t) => { }) }) - t.test('should create a transaction for handler', (t) => { + await t.test('should create a transaction for handler', (t, end) => { + const { agent, awsLambda, stubEvent, stubContext, stubCallback } = t.nr const wrappedHandler = awsLambda.patchLambdaHandler((event, context, callback) => { const transaction = agent.tracer.getTransaction() - t.ok(transaction) - t.equal(transaction.type, 'bg') - t.equal(transaction.getFullName(), expectedBgTransactionName) - t.ok(transaction.isActive()) + assert.ok(transaction) + assert.equal(transaction.type, 'bg') + assert.equal(transaction.getFullName(), expectedBgTransactionName) + assert.ok(transaction.isActive()) callback(null, 'worked') - t.end() + end() }) wrappedHandler(stubEvent, stubContext, stubCallback) }) - t.test('should end transactions on a beforeExit event on process', (t) => { - helper.temporarilyRemoveListeners(t, process, 'beforeExit') + await t.test('should end transactions on a beforeExit event on process', (t, end) => { + const { agent, awsLambda, stubEvent, stubContext, stubCallback } = t.nr + tempRemoveListeners({ t, emitter: process, event: 'beforeExit' }) const wrappedHandler = awsLambda.patchLambdaHandler(() => { const transaction = agent.tracer.getTransaction() - t.ok(transaction) - t.equal(transaction.type, 'bg') - t.equal(transaction.getFullName(), expectedBgTransactionName) - t.ok(transaction.isActive()) + assert.ok(transaction) + assert.equal(transaction.type, 'bg') + assert.equal(transaction.getFullName(), expectedBgTransactionName) + assert.ok(transaction.isActive()) process.emit('beforeExit') - t.equal(transaction.isActive(), false) - t.end() + assert.equal(transaction.isActive(), false) + end() }) wrappedHandler(stubEvent, stubContext, stubCallback) }) - t.test('should end transactions after the returned promise resolves', (t) => { + await t.test('should end transactions after the returned promise resolves', (t, end) => { + const { agent, awsLambda, stubEvent, stubContext, stubCallback } = t.nr let transaction const wrappedHandler = awsLambda.patchLambdaHandler(() => { transaction = agent.tracer.getTransaction() return new Promise((resolve) => { - t.ok(transaction) - t.equal(transaction.type, 'bg') - t.equal(transaction.getFullName(), expectedBgTransactionName) - t.ok(transaction.isActive()) + assert.ok(transaction) + assert.equal(transaction.type, 'bg') + assert.equal(transaction.getFullName(), expectedBgTransactionName) + assert.ok(transaction.isActive()) return resolve('hello') }) @@ -1226,28 +1263,28 @@ tap.test('AwsLambda.patchLambdaHandler', (t) => { wrappedHandler(stubEvent, stubContext, stubCallback) .then((value) => { - t.equal(value, 'hello') - t.equal(transaction.isActive(), false) + assert.equal(value, 'hello') + assert.equal(transaction.isActive(), false) - t.end() + end() }) .catch((err) => { - t.error(err) - t.end() + end(err) }) }) - t.test('should record error event when func is async and promise is rejected', (t) => { + await t.test('should record error event when func is async and promise is rejected', (t, end) => { + const { agent, awsLambda, error, stubEvent, stubContext, stubCallback } = t.nr agent.on('harvestStarted', confirmErrorCapture) let transaction const wrappedHandler = awsLambda.patchLambdaHandler(() => { transaction = agent.tracer.getTransaction() return new Promise((resolve, reject) => { - t.ok(transaction) - t.equal(transaction.type, 'bg') - t.equal(transaction.getFullName(), expectedBgTransactionName) - t.ok(transaction.isActive()) + assert.ok(transaction) + assert.equal(transaction.type, 'bg') + assert.equal(transaction.getFullName(), expectedBgTransactionName) + assert.ok(transaction.isActive()) reject(error) }) @@ -1255,48 +1292,48 @@ tap.test('AwsLambda.patchLambdaHandler', (t) => { wrappedHandler(stubEvent, stubContext, stubCallback) .then(() => { - t.error(new Error('wrapped handler should fail and go to catch block')) - t.end() + end(Error('wrapped handler should fail and go to catch block')) }) .catch((err) => { - t.equal(err, error) - t.equal(transaction.isActive(), false) + assert.equal(err, error) + assert.equal(transaction.isActive(), false) - t.end() + end() }) function confirmErrorCapture() { const errors = agent.errors.traceAggregator.errors - t.equal(errors.length, 1) + assert.equal(errors.length, 1) const noticedError = errors[0] const [, transactionName, message, type] = noticedError - t.equal(transactionName, expectedBgTransactionName) - t.equal(message, errorMessage) - t.equal(type, 'SyntaxError') + assert.equal(transactionName, expectedBgTransactionName) + assert.equal(message, errorMessage) + assert.equal(type, 'SyntaxError') } }) - t.test('should record error event when func is async and error is thrown', (t) => { + await t.test('should record error event when func is async and error is thrown', (t, end) => { + const { agent, awsLambda, error, stubEvent, stubContext, stubCallback } = t.nr agent.on('harvestStarted', function confirmErrorCapture() { const errors = agent.errors.traceAggregator.errors - t.equal(errors.length, 1) + assert.equal(errors.length, 1) const noticedError = errors[0] const [, transactionName, message, type] = noticedError - t.equal(transactionName, expectedBgTransactionName) - t.equal(message, errorMessage) - t.equal(type, 'SyntaxError') + assert.equal(transactionName, expectedBgTransactionName) + assert.equal(message, errorMessage) + assert.equal(type, 'SyntaxError') }) let transaction const wrappedHandler = awsLambda.patchLambdaHandler(() => { transaction = agent.tracer.getTransaction() return new Promise(() => { - t.ok(transaction) - t.equal(transaction.type, 'bg') - t.equal(transaction.getFullName(), expectedBgTransactionName) - t.ok(transaction.isActive()) + assert.ok(transaction) + assert.equal(transaction.type, 'bg') + assert.equal(transaction.getFullName(), expectedBgTransactionName) + assert.ok(transaction.isActive()) throw error }) @@ -1304,29 +1341,29 @@ tap.test('AwsLambda.patchLambdaHandler', (t) => { wrappedHandler(stubEvent, stubContext, stubCallback) .then(() => { - t.error(new Error('wrapped handler should fail and go to catch block')) - t.end() + end(Error('wrapped handler should fail and go to catch block')) }) .catch((err) => { - t.equal(err, error) - t.equal(transaction.isActive(), false) + assert.equal(err, error) + assert.equal(transaction.isActive(), false) - t.end() + end() }) }) - t.test( + await t.test( 'should record error event when func is async an UnhandledPromiseRejection is thrown', - (t) => { + (t, end) => { + const { agent, awsLambda, error, stubEvent, stubContext, stubCallback } = t.nr agent.on('harvestStarted', function confirmErrorCapture() { const errors = agent.errors.traceAggregator.errors - t.equal(errors.length, 1) + assert.equal(errors.length, 1) const noticedError = errors[0] const [, transactionName, message, type] = noticedError - t.equal(transactionName, expectedBgTransactionName) - t.equal(message, errorMessage) - t.equal(type, 'SyntaxError') + assert.equal(transactionName, expectedBgTransactionName) + assert.equal(message, errorMessage) + assert.equal(type, 'SyntaxError') }) let transaction @@ -1334,10 +1371,10 @@ tap.test('AwsLambda.patchLambdaHandler', (t) => { transaction = agent.tracer.getTransaction() // eslint-disable-next-line no-new new Promise(() => { - t.ok(transaction) - t.equal(transaction.type, 'bg') - t.equal(transaction.getFullName(), expectedBgTransactionName) - t.ok(transaction.isActive()) + assert.ok(transaction) + assert.equal(transaction.type, 'bg') + assert.equal(transaction.getFullName(), expectedBgTransactionName) + assert.ok(transaction.isActive()) throw error }) @@ -1345,48 +1382,58 @@ tap.test('AwsLambda.patchLambdaHandler', (t) => { await new Promise((resolve) => setTimeout(resolve, 1)) }) - process.on('unhandledRejection', (err) => { - t.equal(err, error) - t.equal(transaction.isActive(), false) - - t.end() + tempOverrideUncaught({ + t, + type: tempOverrideUncaught.REJECTION, + handler(err) { + assert.equal(err, error) + assert.equal(transaction.isActive(), false) + end() + } }) wrappedHandler(stubEvent, stubContext, stubCallback) } ) - t.test('should record error event when error is thrown', (t) => { - helper.temporarilyOverrideTapUncaughtBehavior(tap, t) + // This test is not triggering any sort of uncaught exception handler when + // it _really_ should be. + await t.todo('should record error event when error is thrown', (t, end) => { + const { agent, awsLambda, error, stubEvent, stubContext, stubCallback } = t.nr + // helper.temporarilyOverrideTapUncaughtBehavior(tap, t) + tempOverrideUncaught({ t, handler }) + // tempOverrideUncaught({ t, handler, type: tempOverrideUncaught.REJECTION }) + + function handler(error) { + console.log('!!!', error) + end() + } - agent.on('harvestStarted', confirmErrorCapture) + agent.on('harvestStarted', function confirmErrorCapture() { + const errors = agent.errors.traceAggregator.errors + assert.equal(errors.length, 1) + + const noticedError = errors[0] + const [, transactionName, message, type] = noticedError + assert.equal(transactionName, expectedBgTransactionName) + assert.equal(message, errorMessage) + assert.equal(type, 'SyntaxError') + }) const wrappedHandler = awsLambda.patchLambdaHandler(() => { const transaction = agent.tracer.getTransaction() - t.ok(transaction) - t.equal(transaction.type, 'bg') - t.equal(transaction.getFullName(), expectedBgTransactionName) - t.ok(transaction.isActive()) + assert.ok(transaction) + assert.equal(transaction.type, 'bg') + assert.equal(transaction.getFullName(), expectedBgTransactionName) + assert.ok(transaction.isActive()) throw error }) wrappedHandler(stubEvent, stubContext, stubCallback) - - function confirmErrorCapture() { - const errors = agent.errors.traceAggregator.errors - t.equal(errors.length, 1) - - const noticedError = errors[0] - const [, transactionName, message, type] = noticedError - t.equal(transactionName, expectedBgTransactionName) - t.equal(message, errorMessage) - t.equal(type, 'SyntaxError') - - t.end() - } }) - t.test('should not end transactions twice', (t) => { + await t.test('should not end transactions twice', (t, end) => { + const { agent, awsLambda, stubEvent, stubContext, stubCallback } = t.nr let transaction const wrappedHandler = awsLambda.patchLambdaHandler((ev, ctx, cb) => { transaction = agent.tracer.getTransaction() @@ -1400,32 +1447,32 @@ tap.test('AwsLambda.patchLambdaHandler', (t) => { return oldEnd.apply(transaction, arguments) } return new Promise((resolve) => { - t.ok(transaction) - t.equal(transaction.type, 'bg') - t.equal(transaction.getFullName(), expectedBgTransactionName) - t.ok(transaction.isActive()) + assert.ok(transaction) + assert.equal(transaction.type, 'bg') + assert.equal(transaction.getFullName(), expectedBgTransactionName) + assert.ok(transaction.isActive()) cb() - t.equal(transaction.isActive(), false) + assert.equal(transaction.isActive(), false) return resolve('hello') }) }) wrappedHandler(stubEvent, stubContext, stubCallback) .then((value) => { - t.equal(value, 'hello') - t.equal(transaction.isActive(), false) + assert.equal(value, 'hello') + assert.equal(transaction.isActive(), false) - t.end() + end() }) .catch((err) => { - t.error(err) - t.end() + end(err) }) }) - t.test('should record standard background metrics', (t) => { + await t.test('should record standard background metrics', (t, end) => { + const { agent, awsLambda, stubEvent, stubContext, stubCallback } = t.nr agent.on('harvestStarted', confirmMetrics) const wrappedHandler = awsLambda.patchLambdaHandler((event, context, callback) => { @@ -1436,31 +1483,27 @@ tap.test('AwsLambda.patchLambdaHandler', (t) => { function confirmMetrics() { const unscopedMetrics = getMetrics(agent).unscoped - t.ok(unscopedMetrics) + assert.ok(unscopedMetrics) const otherTransactionAllName = 'OtherTransaction/all' const otherTransactionAllMetric = unscopedMetrics[otherTransactionAllName] - t.ok(otherTransactionAllMetric) - t.equal(otherTransactionAllMetric.callCount, 1) + assert.ok(otherTransactionAllMetric) + assert.equal(otherTransactionAllMetric.callCount, 1) const bgTransactionNameMetric = unscopedMetrics[expectedBgTransactionName] - t.ok(bgTransactionNameMetric) - t.equal(bgTransactionNameMetric.callCount, 1) + assert.ok(bgTransactionNameMetric) + assert.equal(bgTransactionNameMetric.callCount, 1) const otherTransactionTotalTimeMetric = unscopedMetrics.OtherTransactionTotalTime - t.ok(otherTransactionTotalTimeMetric) - t.equal(otherTransactionAllMetric.callCount, 1) + assert.ok(otherTransactionTotalTimeMetric) + assert.equal(otherTransactionAllMetric.callCount, 1) const otherTotalTimeBgTransactionName = 'OtherTransactionTotalTime/' + expectedTransactionName const otherTotalTimeBgTransactionNameMetric = unscopedMetrics[otherTotalTimeBgTransactionName] - t.ok(otherTotalTimeBgTransactionNameMetric) - t.equal(otherTotalTimeBgTransactionNameMetric.callCount, 1) + assert.ok(otherTotalTimeBgTransactionNameMetric) + assert.equal(otherTotalTimeBgTransactionNameMetric.callCount, 1) - t.end() + end() } }) }) - -function getMetrics(agent) { - return agent.metrics._metrics -} From 5d356a44c40e70b8ffc8a4d2f138bc7f5b7fc909 Mon Sep 17 00:00:00 2001 From: James Sumners Date: Thu, 12 Sep 2024 07:42:19 -0400 Subject: [PATCH 3/3] fix broken test --- test/unit/serverless/aws-lambda.test.js | 39 ++++++++++++------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/test/unit/serverless/aws-lambda.test.js b/test/unit/serverless/aws-lambda.test.js index 9e3e2413aa..00e529601d 100644 --- a/test/unit/serverless/aws-lambda.test.js +++ b/test/unit/serverless/aws-lambda.test.js @@ -9,6 +9,7 @@ const test = require('node:test') const assert = require('node:assert') const os = require('node:os') +const { tspl } = require('@matteo.collina/tspl') const helper = require('../../lib/agent_helper') const tempRemoveListeners = require('../../lib/temp-remove-listeners') const tempOverrideUncaught = require('../../lib/temp-override-uncaught') @@ -1396,40 +1397,38 @@ test('AwsLambda.patchLambdaHandler', async (t) => { } ) - // This test is not triggering any sort of uncaught exception handler when - // it _really_ should be. - await t.todo('should record error event when error is thrown', (t, end) => { + await t.test('should record error event when error is thrown', (t, end) => { + const plan = tspl(t, { plan: 8 }) const { agent, awsLambda, error, stubEvent, stubContext, stubCallback } = t.nr - // helper.temporarilyOverrideTapUncaughtBehavior(tap, t) - tempOverrideUncaught({ t, handler }) - // tempOverrideUncaught({ t, handler, type: tempOverrideUncaught.REJECTION }) - - function handler(error) { - console.log('!!!', error) - end() - } agent.on('harvestStarted', function confirmErrorCapture() { const errors = agent.errors.traceAggregator.errors - assert.equal(errors.length, 1) + plan.equal(errors.length, 1) const noticedError = errors[0] const [, transactionName, message, type] = noticedError - assert.equal(transactionName, expectedBgTransactionName) - assert.equal(message, errorMessage) - assert.equal(type, 'SyntaxError') + plan.equal(transactionName, expectedBgTransactionName) + plan.equal(message, errorMessage) + plan.equal(type, 'SyntaxError') }) const wrappedHandler = awsLambda.patchLambdaHandler(() => { const transaction = agent.tracer.getTransaction() - assert.ok(transaction) - assert.equal(transaction.type, 'bg') - assert.equal(transaction.getFullName(), expectedBgTransactionName) - assert.ok(transaction.isActive()) + plan.ok(transaction) + plan.equal(transaction.type, 'bg') + plan.equal(transaction.getFullName(), expectedBgTransactionName) + plan.ok(transaction.isActive()) throw error }) - wrappedHandler(stubEvent, stubContext, stubCallback) + try { + wrappedHandler(stubEvent, stubContext, stubCallback) + } catch (error) { + if (error.name !== 'SyntaxError') { + throw error + } + end() + } }) await t.test('should not end transactions twice', (t, end) => {