From 8763f7afcf1d4a7911fef5f5c5334f97ee5e0721 Mon Sep 17 00:00:00 2001 From: Anthony Brown <121869075+anthony-nhs@users.noreply.github.com> Date: Tue, 26 Nov 2024 09:01:21 +0000 Subject: [PATCH 1/2] add @middy/core v6 as peer dependency --- package-lock.json | 28 +++-- package.json | 1 + packages/idempotency/package.json | 2 +- packages/logger/package.json | 2 +- ...basicFeatures.middy5.test.FunctionCode.ts} | 0 .../basicFeatures.middy6.test.FunctionCode.ts | 79 ++++++++++++++ ...EnvVarSetting.middy4.test.FunctionCode.ts} | 0 ...s => logEventEnvVarSetting.middy4.test.ts} | 2 +- ...tEnvVarSetting.middy5.test.FunctionCode.ts | 18 ++++ .../e2e/logEventEnvVarSetting.middy5.test.ts | 100 ++++++++++++++++++ ...tEnvVarSetting.middy6.test.FunctionCode.ts | 18 ++++ .../e2e/logEventEnvVarSetting.middy6.test.ts | 100 ++++++++++++++++++ packages/metrics/package.json | 2 +- packages/parameters/package.json | 2 +- packages/parser/package.json | 2 +- packages/tracer/package.json | 2 +- ...ionCode.ts => middy5.test.functionCode.ts} | 0 .../tests/e2e/middy6.test.functionCode.ts | 45 ++++++++ 18 files changed, 390 insertions(+), 13 deletions(-) rename packages/logger/tests/e2e/{basicFeatures.middy.test.FunctionCode.ts => basicFeatures.middy5.test.FunctionCode.ts} (100%) create mode 100644 packages/logger/tests/e2e/basicFeatures.middy6.test.FunctionCode.ts rename packages/logger/tests/e2e/{logEventEnvVarSetting.middy.test.FunctionCode.ts => logEventEnvVarSetting.middy4.test.FunctionCode.ts} (100%) rename packages/logger/tests/e2e/{logEventEnvVarSetting.middy.test.ts => logEventEnvVarSetting.middy4.test.ts} (97%) create mode 100644 packages/logger/tests/e2e/logEventEnvVarSetting.middy5.test.FunctionCode.ts create mode 100644 packages/logger/tests/e2e/logEventEnvVarSetting.middy5.test.ts create mode 100644 packages/logger/tests/e2e/logEventEnvVarSetting.middy6.test.FunctionCode.ts create mode 100644 packages/logger/tests/e2e/logEventEnvVarSetting.middy6.test.ts rename packages/tracer/tests/e2e/{middy.test.functionCode.ts => middy5.test.functionCode.ts} (100%) create mode 100644 packages/tracer/tests/e2e/middy6.test.functionCode.ts diff --git a/package-lock.json b/package-lock.json index 342d061cc5..b9c628d0cd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -38,6 +38,7 @@ "markdownlint-cli2": "^0.15.0", "middy4": "npm:@middy/core@^4.7.0", "middy5": "npm:@middy/core@^5.4.3", + "middy6": "npm:@middy/core@^6.0.0", "ts-jest": "^29.2.5", "ts-node": "^10.9.2", "typedoc": "^0.26.11", @@ -11885,6 +11886,21 @@ "url": "https://github.com/sponsors/willfarrell" } }, + "node_modules/middy6": { + "name": "@middy/core", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@middy/core/-/core-6.0.0.tgz", + "integrity": "sha512-EFsvMkyFfaIu3Uzye26w2NzycwMAbh/99XlhRH9p240y/YKA0nlQ7itE8y7lBJOJ/clj1qu9evQeLfaiWhJAFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/willfarrell" + } + }, "node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", @@ -17810,7 +17826,7 @@ "peerDependencies": { "@aws-sdk/client-dynamodb": ">=3.x", "@aws-sdk/lib-dynamodb": ">=3.x", - "@middy/core": "4.x || 5.x" + "@middy/core": "4.x || 5.x || 6.x" }, "peerDependenciesMeta": { "@aws-sdk/client-dynamodb": { @@ -17845,7 +17861,7 @@ "@types/lodash.merge": "^4.6.9" }, "peerDependencies": { - "@middy/core": "4.x || 5.x" + "@middy/core": "4.x || 5.x || 6.x" }, "peerDependenciesMeta": { "@middy/core": { @@ -17867,7 +17883,7 @@ "promise-retry": "^2.0.1" }, "peerDependencies": { - "@middy/core": "4.x || 5.x" + "@middy/core": "4.x || 5.x || 6.x" }, "peerDependenciesMeta": { "@middy/core": { @@ -17899,7 +17915,7 @@ "@aws-sdk/client-secrets-manager": ">=3.x", "@aws-sdk/client-ssm": ">=3.x", "@aws-sdk/util-dynamodb": ">=3.x", - "@middy/core": "4.x || 5.x" + "@middy/core": "4.x || 5.x || 6.x" }, "peerDependenciesMeta": { "@aws-sdk/client-appconfigdata": { @@ -17931,7 +17947,7 @@ "@faker-js/faker": "^9.0.2" }, "peerDependencies": { - "@middy/core": "4.x || 5.x", + "@middy/core": "4.x || 5.x || 6.x", "zod": ">=3.x" }, "peerDependenciesMeta": { @@ -17974,7 +17990,7 @@ "@aws-sdk/client-xray": "^3.698.0" }, "peerDependencies": { - "@middy/core": "4.x || 5.x" + "@middy/core": "4.x || 5.x || 6.x" }, "peerDependenciesMeta": { "@middy/core": { diff --git a/package.json b/package.json index 79a73ca2aa..cd38b54319 100644 --- a/package.json +++ b/package.json @@ -63,6 +63,7 @@ "markdownlint-cli2": "^0.15.0", "middy4": "npm:@middy/core@^4.7.0", "middy5": "npm:@middy/core@^5.4.3", + "middy6": "npm:@middy/core@^6.0.0", "ts-jest": "^29.2.5", "ts-node": "^10.9.2", "typedoc": "^0.26.11", diff --git a/packages/idempotency/package.json b/packages/idempotency/package.json index fc4a89627d..bcde401b78 100644 --- a/packages/idempotency/package.json +++ b/packages/idempotency/package.json @@ -104,7 +104,7 @@ "peerDependencies": { "@aws-sdk/client-dynamodb": ">=3.x", "@aws-sdk/lib-dynamodb": ">=3.x", - "@middy/core": "4.x || 5.x" + "@middy/core": "4.x || 5.x || 6.x" }, "peerDependenciesMeta": { "@aws-sdk/client-dynamodb": { diff --git a/packages/logger/package.json b/packages/logger/package.json index fecc0cdba9..7604685782 100644 --- a/packages/logger/package.json +++ b/packages/logger/package.json @@ -68,7 +68,7 @@ "@types/lodash.merge": "^4.6.9" }, "peerDependencies": { - "@middy/core": "4.x || 5.x" + "@middy/core": "4.x || 5.x || 6.x" }, "peerDependenciesMeta": { "@middy/core": { diff --git a/packages/logger/tests/e2e/basicFeatures.middy.test.FunctionCode.ts b/packages/logger/tests/e2e/basicFeatures.middy5.test.FunctionCode.ts similarity index 100% rename from packages/logger/tests/e2e/basicFeatures.middy.test.FunctionCode.ts rename to packages/logger/tests/e2e/basicFeatures.middy5.test.FunctionCode.ts diff --git a/packages/logger/tests/e2e/basicFeatures.middy6.test.FunctionCode.ts b/packages/logger/tests/e2e/basicFeatures.middy6.test.FunctionCode.ts new file mode 100644 index 0000000000..c9babb9b68 --- /dev/null +++ b/packages/logger/tests/e2e/basicFeatures.middy6.test.FunctionCode.ts @@ -0,0 +1,79 @@ +import type { APIGatewayAuthorizerResult, Context } from 'aws-lambda'; +import middy from 'middy6'; +import { Logger } from '../../src/index.js'; +import { injectLambdaContext } from '../../src/middleware/middy.js'; +import type { TestEvent, TestOutput } from '../helpers/types.js'; + +const PERSISTENT_KEY = process.env.PERSISTENT_KEY || 'persistentKey'; +const PERSISTENT_VALUE = process.env.PERSISTENT_VALUE || 'persistentValue'; +const REMOVABLE_KEY = process.env.REMOVABLE_KEY || 'removableKey'; +const REMOVABLE_VALUE = process.env.REMOVABLE_VALUE || 'remvovableValue'; +const ERROR_MSG = process.env.ERROR_MSG || 'error'; +const RUNTIME_ADDED_KEY = process.env.RUNTIME_ADDED_KEY || 'runtimeAddedKey'; +const SINGLE_LOG_ITEM_KEY = + process.env.SINGLE_LOG_ITEM_KEY || 'keyForSingleLogItem'; +const SINGLE_LOG_ITEM_VALUE = + process.env.SINGLE_LOG_ITEM_VALUE || 'valueForSingleLogItem'; +const ARBITRARY_OBJECT_KEY = + process.env.ARBITRARY_OBJECT_KEY || 'keyForArbitraryObject'; +const ARBITRARY_OBJECT_DATA = + process.env.ARBITRARY_OBJECT_DATA || 'arbitrary object data'; + +const logger = new Logger({ + persistentLogAttributes: { + [PERSISTENT_KEY]: PERSISTENT_VALUE, // This key-value pair will be added to every log + [REMOVABLE_KEY]: REMOVABLE_VALUE, // This other one will be removed at runtime and not displayed in any log + }, +}); + +const testFunction = async (event: TestEvent, context: Context): TestOutput => { + // Test feature 1: Context data injection (all logs should have the same context data) + // Test feature 2: Event log (this log should have the event data) + // Test feature 3: Log level filtering (log level is set to INFO) + logger.debug('##### This should not appear'); + + // Test feature 4: Add and remove persistent additional log keys and value + logger.removeKeys([REMOVABLE_KEY]); // This key should not appear in any log (except the event log) + logger.appendKeys({ + // This key-value pair should appear in every log (except the event log) + [RUNTIME_ADDED_KEY]: 'bar', + }); + + // Test feature 5: One-time additional log keys and values + logger.info('This is an one-time log with an additional key-value', { + [SINGLE_LOG_ITEM_KEY]: SINGLE_LOG_ITEM_VALUE, + }); + + // Test feature 6: Error logging + try { + throw new Error(ERROR_MSG); + } catch (e) { + logger.error(ERROR_MSG, e as Error); + } + + // Test feature 7: Arbitrary object logging + const obj: APIGatewayAuthorizerResult = { + principalId: ARBITRARY_OBJECT_DATA, + policyDocument: { + Version: 'Version 1', + Statement: [ + { + Effect: 'Allow', + Action: 'geo:*', + Resource: '*', + }, + ], + }, + }; + logger.info('A log entry with an object', { [ARBITRARY_OBJECT_KEY]: obj }); + + // Test feature 8: X-Ray Trace ID injection (all logs should have the same X-Ray Trace ID) + + return { + requestId: context.awsRequestId, + }; +}; + +export const handler = middy(testFunction).use( + injectLambdaContext(logger, { clearState: true, logEvent: true }) +); diff --git a/packages/logger/tests/e2e/logEventEnvVarSetting.middy.test.FunctionCode.ts b/packages/logger/tests/e2e/logEventEnvVarSetting.middy4.test.FunctionCode.ts similarity index 100% rename from packages/logger/tests/e2e/logEventEnvVarSetting.middy.test.FunctionCode.ts rename to packages/logger/tests/e2e/logEventEnvVarSetting.middy4.test.FunctionCode.ts diff --git a/packages/logger/tests/e2e/logEventEnvVarSetting.middy.test.ts b/packages/logger/tests/e2e/logEventEnvVarSetting.middy4.test.ts similarity index 97% rename from packages/logger/tests/e2e/logEventEnvVarSetting.middy.test.ts rename to packages/logger/tests/e2e/logEventEnvVarSetting.middy4.test.ts index 21c2dad621..90aa5900ed 100644 --- a/packages/logger/tests/e2e/logEventEnvVarSetting.middy.test.ts +++ b/packages/logger/tests/e2e/logEventEnvVarSetting.middy4.test.ts @@ -25,7 +25,7 @@ describe('Logger E2E tests, log event via env var setting with middy', () => { // Location of the lambda function code const lambdaFunctionCodeFilePath = join( __dirname, - 'logEventEnvVarSetting.middy.test.FunctionCode.ts' + 'logEventEnvVarSetting.middy4.test.FunctionCode.ts' ); const invocationCount = 3; diff --git a/packages/logger/tests/e2e/logEventEnvVarSetting.middy5.test.FunctionCode.ts b/packages/logger/tests/e2e/logEventEnvVarSetting.middy5.test.FunctionCode.ts new file mode 100644 index 0000000000..bcefc6a583 --- /dev/null +++ b/packages/logger/tests/e2e/logEventEnvVarSetting.middy5.test.FunctionCode.ts @@ -0,0 +1,18 @@ +import type { Context } from 'aws-lambda'; +import middy from 'middy5'; +import { Logger } from '../../src/index.js'; +import { injectLambdaContext } from '../../src/middleware/middy.js'; +import type { TestEvent, TestOutput } from '../helpers/types.js'; + +const logger = new Logger(); + +const testFunction = async ( + _event: TestEvent, + context: Context +): TestOutput => ({ + requestId: context.awsRequestId, +}); + +export const handler = middy(testFunction) + // The event should be logged because POWERTOOLS_LOGGER_LOG_EVENT is set to true + .use(injectLambdaContext(logger)); diff --git a/packages/logger/tests/e2e/logEventEnvVarSetting.middy5.test.ts b/packages/logger/tests/e2e/logEventEnvVarSetting.middy5.test.ts new file mode 100644 index 0000000000..4f2ac66b4a --- /dev/null +++ b/packages/logger/tests/e2e/logEventEnvVarSetting.middy5.test.ts @@ -0,0 +1,100 @@ +import { join } from 'node:path'; +import { + TestInvocationLogs, + TestStack, + invokeFunction, +} from '@aws-lambda-powertools/testing-utils'; +import { afterAll, beforeAll, describe, expect, it } from 'vitest'; +import { LoggerTestNodejsFunction } from '../helpers/resources.js'; +import { + RESOURCE_NAME_PREFIX, + SETUP_TIMEOUT, + STACK_OUTPUT_LOG_GROUP, + TEARDOWN_TIMEOUT, + TEST_CASE_TIMEOUT, +} from './constants.js'; + +describe('Logger E2E tests, log event via env var setting with middy', () => { + const testStack = new TestStack({ + stackNameProps: { + stackNamePrefix: RESOURCE_NAME_PREFIX, + testName: 'LogEventFromEnv-Middy', + }, + }); + + // Location of the lambda function code + const lambdaFunctionCodeFilePath = join( + __dirname, + 'logEventEnvVarSetting.middy5.test.FunctionCode.ts' + ); + + const invocationCount = 3; + let invocationLogs: TestInvocationLogs[]; + let logGroupName: string; + + beforeAll(async () => { + // Prepare + new LoggerTestNodejsFunction( + testStack, + { + entry: lambdaFunctionCodeFilePath, + environment: { + POWERTOOLS_LOGGER_LOG_EVENT: 'true', + }, + }, + { + logGroupOutputKey: STACK_OUTPUT_LOG_GROUP, + nameSuffix: 'LogEventFromEnv', + } + ); + + await testStack.deploy(); + logGroupName = testStack.findAndGetStackOutputValue(STACK_OUTPUT_LOG_GROUP); + const functionName = + testStack.findAndGetStackOutputValue('LogEventFromEnv'); + + invocationLogs = await invokeFunction({ + functionName, + invocationMode: 'SEQUENTIAL', + times: invocationCount, + payload: { + foo: 'bar', + }, + }); + + console.log('logGroupName', logGroupName); + }, SETUP_TIMEOUT); + + describe('Log event', () => { + it( + 'should log the event as the first log of each invocation only', + async () => { + for (let i = 0; i < invocationCount; i++) { + // Get log messages of the invocation + const logMessages = invocationLogs[i].getFunctionLogs(); + + for (const [index, message] of logMessages.entries()) { + const log = TestInvocationLogs.parseFunctionLog(message); + // Check that the event is logged on the first log + if (index === 0) { + expect(log).toHaveProperty('event'); + expect(log.event).toStrictEqual( + expect.objectContaining({ foo: 'bar' }) + ); + // Check that the event is not logged again on the rest of the logs + } else { + expect(log).not.toHaveProperty('event'); + } + } + } + }, + TEST_CASE_TIMEOUT + ); + }); + + afterAll(async () => { + if (!process.env.DISABLE_TEARDOWN) { + await testStack.destroy(); + } + }, TEARDOWN_TIMEOUT); +}); diff --git a/packages/logger/tests/e2e/logEventEnvVarSetting.middy6.test.FunctionCode.ts b/packages/logger/tests/e2e/logEventEnvVarSetting.middy6.test.FunctionCode.ts new file mode 100644 index 0000000000..5afa7b17b4 --- /dev/null +++ b/packages/logger/tests/e2e/logEventEnvVarSetting.middy6.test.FunctionCode.ts @@ -0,0 +1,18 @@ +import type { Context } from 'aws-lambda'; +import middy from 'middy6'; +import { Logger } from '../../src/index.js'; +import { injectLambdaContext } from '../../src/middleware/middy.js'; +import type { TestEvent, TestOutput } from '../helpers/types.js'; + +const logger = new Logger(); + +const testFunction = async ( + _event: TestEvent, + context: Context +): TestOutput => ({ + requestId: context.awsRequestId, +}); + +export const handler = middy(testFunction) + // The event should be logged because POWERTOOLS_LOGGER_LOG_EVENT is set to true + .use(injectLambdaContext(logger)); diff --git a/packages/logger/tests/e2e/logEventEnvVarSetting.middy6.test.ts b/packages/logger/tests/e2e/logEventEnvVarSetting.middy6.test.ts new file mode 100644 index 0000000000..1c392f0173 --- /dev/null +++ b/packages/logger/tests/e2e/logEventEnvVarSetting.middy6.test.ts @@ -0,0 +1,100 @@ +import { join } from 'node:path'; +import { + TestInvocationLogs, + TestStack, + invokeFunction, +} from '@aws-lambda-powertools/testing-utils'; +import { afterAll, beforeAll, describe, expect, it } from 'vitest'; +import { LoggerTestNodejsFunction } from '../helpers/resources.js'; +import { + RESOURCE_NAME_PREFIX, + SETUP_TIMEOUT, + STACK_OUTPUT_LOG_GROUP, + TEARDOWN_TIMEOUT, + TEST_CASE_TIMEOUT, +} from './constants.js'; + +describe('Logger E2E tests, log event via env var setting with middy', () => { + const testStack = new TestStack({ + stackNameProps: { + stackNamePrefix: RESOURCE_NAME_PREFIX, + testName: 'LogEventFromEnv-Middy', + }, + }); + + // Location of the lambda function code + const lambdaFunctionCodeFilePath = join( + __dirname, + 'logEventEnvVarSetting.middy6.test.FunctionCode.ts' + ); + + const invocationCount = 3; + let invocationLogs: TestInvocationLogs[]; + let logGroupName: string; + + beforeAll(async () => { + // Prepare + new LoggerTestNodejsFunction( + testStack, + { + entry: lambdaFunctionCodeFilePath, + environment: { + POWERTOOLS_LOGGER_LOG_EVENT: 'true', + }, + }, + { + logGroupOutputKey: STACK_OUTPUT_LOG_GROUP, + nameSuffix: 'LogEventFromEnv', + } + ); + + await testStack.deploy(); + logGroupName = testStack.findAndGetStackOutputValue(STACK_OUTPUT_LOG_GROUP); + const functionName = + testStack.findAndGetStackOutputValue('LogEventFromEnv'); + + invocationLogs = await invokeFunction({ + functionName, + invocationMode: 'SEQUENTIAL', + times: invocationCount, + payload: { + foo: 'bar', + }, + }); + + console.log('logGroupName', logGroupName); + }, SETUP_TIMEOUT); + + describe('Log event', () => { + it( + 'should log the event as the first log of each invocation only', + async () => { + for (let i = 0; i < invocationCount; i++) { + // Get log messages of the invocation + const logMessages = invocationLogs[i].getFunctionLogs(); + + for (const [index, message] of logMessages.entries()) { + const log = TestInvocationLogs.parseFunctionLog(message); + // Check that the event is logged on the first log + if (index === 0) { + expect(log).toHaveProperty('event'); + expect(log.event).toStrictEqual( + expect.objectContaining({ foo: 'bar' }) + ); + // Check that the event is not logged again on the rest of the logs + } else { + expect(log).not.toHaveProperty('event'); + } + } + } + }, + TEST_CASE_TIMEOUT + ); + }); + + afterAll(async () => { + if (!process.env.DISABLE_TEARDOWN) { + await testStack.destroy(); + } + }, TEARDOWN_TIMEOUT); +}); diff --git a/packages/metrics/package.json b/packages/metrics/package.json index a4d13bc4ec..5545ad81e9 100644 --- a/packages/metrics/package.json +++ b/packages/metrics/package.json @@ -70,7 +70,7 @@ "promise-retry": "^2.0.1" }, "peerDependencies": { - "@middy/core": "4.x || 5.x" + "@middy/core": "4.x || 5.x || 6.x" }, "peerDependenciesMeta": { "@middy/core": { diff --git a/packages/parameters/package.json b/packages/parameters/package.json index a6720b7079..516ea24d51 100644 --- a/packages/parameters/package.json +++ b/packages/parameters/package.json @@ -174,7 +174,7 @@ "@aws-sdk/client-secrets-manager": ">=3.x", "@aws-sdk/client-ssm": ">=3.x", "@aws-sdk/util-dynamodb": ">=3.x", - "@middy/core": "4.x || 5.x" + "@middy/core": "4.x || 5.x || 6.x" }, "peerDependenciesMeta": { "@middy/core": { diff --git a/packages/parser/package.json b/packages/parser/package.json index 6a74b75836..a504e15cc2 100644 --- a/packages/parser/package.json +++ b/packages/parser/package.json @@ -357,7 +357,7 @@ "nodejs" ], "peerDependencies": { - "@middy/core": "4.x || 5.x", + "@middy/core": "4.x || 5.x || 6.x", "zod": ">=3.x" }, "peerDependenciesMeta": { diff --git a/packages/tracer/package.json b/packages/tracer/package.json index d75563b2d6..dbc4c50c2e 100644 --- a/packages/tracer/package.json +++ b/packages/tracer/package.json @@ -34,7 +34,7 @@ "@aws-sdk/client-xray": "^3.698.0" }, "peerDependencies": { - "@middy/core": "4.x || 5.x" + "@middy/core": "4.x || 5.x || 6.x" }, "peerDependenciesMeta": { "@middy/core": { diff --git a/packages/tracer/tests/e2e/middy.test.functionCode.ts b/packages/tracer/tests/e2e/middy5.test.functionCode.ts similarity index 100% rename from packages/tracer/tests/e2e/middy.test.functionCode.ts rename to packages/tracer/tests/e2e/middy5.test.functionCode.ts diff --git a/packages/tracer/tests/e2e/middy6.test.functionCode.ts b/packages/tracer/tests/e2e/middy6.test.functionCode.ts new file mode 100644 index 0000000000..491ab74ebb --- /dev/null +++ b/packages/tracer/tests/e2e/middy6.test.functionCode.ts @@ -0,0 +1,45 @@ +import { DynamoDBClient, PutItemCommand } from '@aws-sdk/client-dynamodb'; +import type { Context } from 'aws-lambda'; +import middy from 'middy6'; +import { Tracer } from '../../src/index.js'; +import { captureLambdaHandler } from '../../src/middleware/middy.js'; +import { + EXPECTED_ANNOTATION_KEY as customAnnotationKey, + EXPECTED_ANNOTATION_VALUE as customAnnotationValue, + EXPECTED_ERROR_MESSAGE as customErrorMessage, + EXPECTED_METADATA_KEY as customMetadataKey, + EXPECTED_METADATA_VALUE as customMetadataValue, +} from './constants.js'; + +type CustomEvent = { + throw: boolean; + invocation: number; +}; + +const tracer = new Tracer(); +const dynamoDB = tracer.captureAWSv3Client(new DynamoDBClient({})); + +export const handler = middy( + async (event: CustomEvent, _context: Context): Promise => { + tracer.putAnnotation(customAnnotationKey, customAnnotationValue); + tracer.putMetadata(customMetadataKey, customMetadataValue); + + await dynamoDB.send( + new PutItemCommand({ + TableName: process.env.TEST_TABLE_NAME ?? 'TestTable', + Item: { + id: { + S: `${process.env.POWERTOOLS_SERVICE_NAME ?? 'service'}-${event.invocation}-sdkv3`, + }, + }, + }) + ); + await fetch('https://docs.powertools.aws.dev/lambda/typescript/latest/'); + + if (event.throw) { + throw new Error(customErrorMessage); + } + + return 'success'; + } +).use(captureLambdaHandler(tracer, { captureResponse: false })); From 507ccd54cd46938493f6290d54c8c81a090aba3f Mon Sep 17 00:00:00 2001 From: Anthony Brown <121869075+anthony-nhs@users.noreply.github.com> Date: Tue, 26 Nov 2024 17:35:59 +0000 Subject: [PATCH 2/2] remove duplicate tests --- ...makeHandlerIdempotent.test.FunctionCode.ts | 2 +- ... basicFeatures.middy.test.FunctionCode.ts} | 0 .../basicFeatures.middy6.test.FunctionCode.ts | 79 -------------- ...tEnvVarSetting.middy.test.FunctionCode.ts} | 0 ...ts => logEventEnvVarSetting.middy.test.ts} | 2 +- ...tEnvVarSetting.middy5.test.FunctionCode.ts | 18 ---- .../e2e/logEventEnvVarSetting.middy5.test.ts | 100 ------------------ ...tEnvVarSetting.middy6.test.FunctionCode.ts | 18 ---- .../e2e/logEventEnvVarSetting.middy6.test.ts | 100 ------------------ ...tionCode.ts => middy.test.functionCode.ts} | 0 .../tests/e2e/middy6.test.functionCode.ts | 45 -------- 11 files changed, 2 insertions(+), 362 deletions(-) rename packages/logger/tests/e2e/{basicFeatures.middy5.test.FunctionCode.ts => basicFeatures.middy.test.FunctionCode.ts} (100%) delete mode 100644 packages/logger/tests/e2e/basicFeatures.middy6.test.FunctionCode.ts rename packages/logger/tests/e2e/{logEventEnvVarSetting.middy4.test.FunctionCode.ts => logEventEnvVarSetting.middy.test.FunctionCode.ts} (100%) rename packages/logger/tests/e2e/{logEventEnvVarSetting.middy4.test.ts => logEventEnvVarSetting.middy.test.ts} (97%) delete mode 100644 packages/logger/tests/e2e/logEventEnvVarSetting.middy5.test.FunctionCode.ts delete mode 100644 packages/logger/tests/e2e/logEventEnvVarSetting.middy5.test.ts delete mode 100644 packages/logger/tests/e2e/logEventEnvVarSetting.middy6.test.FunctionCode.ts delete mode 100644 packages/logger/tests/e2e/logEventEnvVarSetting.middy6.test.ts rename packages/tracer/tests/e2e/{middy5.test.functionCode.ts => middy.test.functionCode.ts} (100%) delete mode 100644 packages/tracer/tests/e2e/middy6.test.functionCode.ts diff --git a/packages/idempotency/tests/e2e/makeHandlerIdempotent.test.FunctionCode.ts b/packages/idempotency/tests/e2e/makeHandlerIdempotent.test.FunctionCode.ts index 44addbf10f..7358697039 100644 --- a/packages/idempotency/tests/e2e/makeHandlerIdempotent.test.FunctionCode.ts +++ b/packages/idempotency/tests/e2e/makeHandlerIdempotent.test.FunctionCode.ts @@ -1,5 +1,5 @@ import { Logger } from '@aws-lambda-powertools/logger'; -import middy from '@middy/core'; +import middy from 'middy6'; import type { Context } from 'aws-lambda'; import { IdempotencyConfig } from '../../src/IdempotencyConfig.js'; import { makeHandlerIdempotent } from '../../src/middleware/makeHandlerIdempotent.js'; diff --git a/packages/logger/tests/e2e/basicFeatures.middy5.test.FunctionCode.ts b/packages/logger/tests/e2e/basicFeatures.middy.test.FunctionCode.ts similarity index 100% rename from packages/logger/tests/e2e/basicFeatures.middy5.test.FunctionCode.ts rename to packages/logger/tests/e2e/basicFeatures.middy.test.FunctionCode.ts diff --git a/packages/logger/tests/e2e/basicFeatures.middy6.test.FunctionCode.ts b/packages/logger/tests/e2e/basicFeatures.middy6.test.FunctionCode.ts deleted file mode 100644 index c9babb9b68..0000000000 --- a/packages/logger/tests/e2e/basicFeatures.middy6.test.FunctionCode.ts +++ /dev/null @@ -1,79 +0,0 @@ -import type { APIGatewayAuthorizerResult, Context } from 'aws-lambda'; -import middy from 'middy6'; -import { Logger } from '../../src/index.js'; -import { injectLambdaContext } from '../../src/middleware/middy.js'; -import type { TestEvent, TestOutput } from '../helpers/types.js'; - -const PERSISTENT_KEY = process.env.PERSISTENT_KEY || 'persistentKey'; -const PERSISTENT_VALUE = process.env.PERSISTENT_VALUE || 'persistentValue'; -const REMOVABLE_KEY = process.env.REMOVABLE_KEY || 'removableKey'; -const REMOVABLE_VALUE = process.env.REMOVABLE_VALUE || 'remvovableValue'; -const ERROR_MSG = process.env.ERROR_MSG || 'error'; -const RUNTIME_ADDED_KEY = process.env.RUNTIME_ADDED_KEY || 'runtimeAddedKey'; -const SINGLE_LOG_ITEM_KEY = - process.env.SINGLE_LOG_ITEM_KEY || 'keyForSingleLogItem'; -const SINGLE_LOG_ITEM_VALUE = - process.env.SINGLE_LOG_ITEM_VALUE || 'valueForSingleLogItem'; -const ARBITRARY_OBJECT_KEY = - process.env.ARBITRARY_OBJECT_KEY || 'keyForArbitraryObject'; -const ARBITRARY_OBJECT_DATA = - process.env.ARBITRARY_OBJECT_DATA || 'arbitrary object data'; - -const logger = new Logger({ - persistentLogAttributes: { - [PERSISTENT_KEY]: PERSISTENT_VALUE, // This key-value pair will be added to every log - [REMOVABLE_KEY]: REMOVABLE_VALUE, // This other one will be removed at runtime and not displayed in any log - }, -}); - -const testFunction = async (event: TestEvent, context: Context): TestOutput => { - // Test feature 1: Context data injection (all logs should have the same context data) - // Test feature 2: Event log (this log should have the event data) - // Test feature 3: Log level filtering (log level is set to INFO) - logger.debug('##### This should not appear'); - - // Test feature 4: Add and remove persistent additional log keys and value - logger.removeKeys([REMOVABLE_KEY]); // This key should not appear in any log (except the event log) - logger.appendKeys({ - // This key-value pair should appear in every log (except the event log) - [RUNTIME_ADDED_KEY]: 'bar', - }); - - // Test feature 5: One-time additional log keys and values - logger.info('This is an one-time log with an additional key-value', { - [SINGLE_LOG_ITEM_KEY]: SINGLE_LOG_ITEM_VALUE, - }); - - // Test feature 6: Error logging - try { - throw new Error(ERROR_MSG); - } catch (e) { - logger.error(ERROR_MSG, e as Error); - } - - // Test feature 7: Arbitrary object logging - const obj: APIGatewayAuthorizerResult = { - principalId: ARBITRARY_OBJECT_DATA, - policyDocument: { - Version: 'Version 1', - Statement: [ - { - Effect: 'Allow', - Action: 'geo:*', - Resource: '*', - }, - ], - }, - }; - logger.info('A log entry with an object', { [ARBITRARY_OBJECT_KEY]: obj }); - - // Test feature 8: X-Ray Trace ID injection (all logs should have the same X-Ray Trace ID) - - return { - requestId: context.awsRequestId, - }; -}; - -export const handler = middy(testFunction).use( - injectLambdaContext(logger, { clearState: true, logEvent: true }) -); diff --git a/packages/logger/tests/e2e/logEventEnvVarSetting.middy4.test.FunctionCode.ts b/packages/logger/tests/e2e/logEventEnvVarSetting.middy.test.FunctionCode.ts similarity index 100% rename from packages/logger/tests/e2e/logEventEnvVarSetting.middy4.test.FunctionCode.ts rename to packages/logger/tests/e2e/logEventEnvVarSetting.middy.test.FunctionCode.ts diff --git a/packages/logger/tests/e2e/logEventEnvVarSetting.middy4.test.ts b/packages/logger/tests/e2e/logEventEnvVarSetting.middy.test.ts similarity index 97% rename from packages/logger/tests/e2e/logEventEnvVarSetting.middy4.test.ts rename to packages/logger/tests/e2e/logEventEnvVarSetting.middy.test.ts index 90aa5900ed..21c2dad621 100644 --- a/packages/logger/tests/e2e/logEventEnvVarSetting.middy4.test.ts +++ b/packages/logger/tests/e2e/logEventEnvVarSetting.middy.test.ts @@ -25,7 +25,7 @@ describe('Logger E2E tests, log event via env var setting with middy', () => { // Location of the lambda function code const lambdaFunctionCodeFilePath = join( __dirname, - 'logEventEnvVarSetting.middy4.test.FunctionCode.ts' + 'logEventEnvVarSetting.middy.test.FunctionCode.ts' ); const invocationCount = 3; diff --git a/packages/logger/tests/e2e/logEventEnvVarSetting.middy5.test.FunctionCode.ts b/packages/logger/tests/e2e/logEventEnvVarSetting.middy5.test.FunctionCode.ts deleted file mode 100644 index bcefc6a583..0000000000 --- a/packages/logger/tests/e2e/logEventEnvVarSetting.middy5.test.FunctionCode.ts +++ /dev/null @@ -1,18 +0,0 @@ -import type { Context } from 'aws-lambda'; -import middy from 'middy5'; -import { Logger } from '../../src/index.js'; -import { injectLambdaContext } from '../../src/middleware/middy.js'; -import type { TestEvent, TestOutput } from '../helpers/types.js'; - -const logger = new Logger(); - -const testFunction = async ( - _event: TestEvent, - context: Context -): TestOutput => ({ - requestId: context.awsRequestId, -}); - -export const handler = middy(testFunction) - // The event should be logged because POWERTOOLS_LOGGER_LOG_EVENT is set to true - .use(injectLambdaContext(logger)); diff --git a/packages/logger/tests/e2e/logEventEnvVarSetting.middy5.test.ts b/packages/logger/tests/e2e/logEventEnvVarSetting.middy5.test.ts deleted file mode 100644 index 4f2ac66b4a..0000000000 --- a/packages/logger/tests/e2e/logEventEnvVarSetting.middy5.test.ts +++ /dev/null @@ -1,100 +0,0 @@ -import { join } from 'node:path'; -import { - TestInvocationLogs, - TestStack, - invokeFunction, -} from '@aws-lambda-powertools/testing-utils'; -import { afterAll, beforeAll, describe, expect, it } from 'vitest'; -import { LoggerTestNodejsFunction } from '../helpers/resources.js'; -import { - RESOURCE_NAME_PREFIX, - SETUP_TIMEOUT, - STACK_OUTPUT_LOG_GROUP, - TEARDOWN_TIMEOUT, - TEST_CASE_TIMEOUT, -} from './constants.js'; - -describe('Logger E2E tests, log event via env var setting with middy', () => { - const testStack = new TestStack({ - stackNameProps: { - stackNamePrefix: RESOURCE_NAME_PREFIX, - testName: 'LogEventFromEnv-Middy', - }, - }); - - // Location of the lambda function code - const lambdaFunctionCodeFilePath = join( - __dirname, - 'logEventEnvVarSetting.middy5.test.FunctionCode.ts' - ); - - const invocationCount = 3; - let invocationLogs: TestInvocationLogs[]; - let logGroupName: string; - - beforeAll(async () => { - // Prepare - new LoggerTestNodejsFunction( - testStack, - { - entry: lambdaFunctionCodeFilePath, - environment: { - POWERTOOLS_LOGGER_LOG_EVENT: 'true', - }, - }, - { - logGroupOutputKey: STACK_OUTPUT_LOG_GROUP, - nameSuffix: 'LogEventFromEnv', - } - ); - - await testStack.deploy(); - logGroupName = testStack.findAndGetStackOutputValue(STACK_OUTPUT_LOG_GROUP); - const functionName = - testStack.findAndGetStackOutputValue('LogEventFromEnv'); - - invocationLogs = await invokeFunction({ - functionName, - invocationMode: 'SEQUENTIAL', - times: invocationCount, - payload: { - foo: 'bar', - }, - }); - - console.log('logGroupName', logGroupName); - }, SETUP_TIMEOUT); - - describe('Log event', () => { - it( - 'should log the event as the first log of each invocation only', - async () => { - for (let i = 0; i < invocationCount; i++) { - // Get log messages of the invocation - const logMessages = invocationLogs[i].getFunctionLogs(); - - for (const [index, message] of logMessages.entries()) { - const log = TestInvocationLogs.parseFunctionLog(message); - // Check that the event is logged on the first log - if (index === 0) { - expect(log).toHaveProperty('event'); - expect(log.event).toStrictEqual( - expect.objectContaining({ foo: 'bar' }) - ); - // Check that the event is not logged again on the rest of the logs - } else { - expect(log).not.toHaveProperty('event'); - } - } - } - }, - TEST_CASE_TIMEOUT - ); - }); - - afterAll(async () => { - if (!process.env.DISABLE_TEARDOWN) { - await testStack.destroy(); - } - }, TEARDOWN_TIMEOUT); -}); diff --git a/packages/logger/tests/e2e/logEventEnvVarSetting.middy6.test.FunctionCode.ts b/packages/logger/tests/e2e/logEventEnvVarSetting.middy6.test.FunctionCode.ts deleted file mode 100644 index 5afa7b17b4..0000000000 --- a/packages/logger/tests/e2e/logEventEnvVarSetting.middy6.test.FunctionCode.ts +++ /dev/null @@ -1,18 +0,0 @@ -import type { Context } from 'aws-lambda'; -import middy from 'middy6'; -import { Logger } from '../../src/index.js'; -import { injectLambdaContext } from '../../src/middleware/middy.js'; -import type { TestEvent, TestOutput } from '../helpers/types.js'; - -const logger = new Logger(); - -const testFunction = async ( - _event: TestEvent, - context: Context -): TestOutput => ({ - requestId: context.awsRequestId, -}); - -export const handler = middy(testFunction) - // The event should be logged because POWERTOOLS_LOGGER_LOG_EVENT is set to true - .use(injectLambdaContext(logger)); diff --git a/packages/logger/tests/e2e/logEventEnvVarSetting.middy6.test.ts b/packages/logger/tests/e2e/logEventEnvVarSetting.middy6.test.ts deleted file mode 100644 index 1c392f0173..0000000000 --- a/packages/logger/tests/e2e/logEventEnvVarSetting.middy6.test.ts +++ /dev/null @@ -1,100 +0,0 @@ -import { join } from 'node:path'; -import { - TestInvocationLogs, - TestStack, - invokeFunction, -} from '@aws-lambda-powertools/testing-utils'; -import { afterAll, beforeAll, describe, expect, it } from 'vitest'; -import { LoggerTestNodejsFunction } from '../helpers/resources.js'; -import { - RESOURCE_NAME_PREFIX, - SETUP_TIMEOUT, - STACK_OUTPUT_LOG_GROUP, - TEARDOWN_TIMEOUT, - TEST_CASE_TIMEOUT, -} from './constants.js'; - -describe('Logger E2E tests, log event via env var setting with middy', () => { - const testStack = new TestStack({ - stackNameProps: { - stackNamePrefix: RESOURCE_NAME_PREFIX, - testName: 'LogEventFromEnv-Middy', - }, - }); - - // Location of the lambda function code - const lambdaFunctionCodeFilePath = join( - __dirname, - 'logEventEnvVarSetting.middy6.test.FunctionCode.ts' - ); - - const invocationCount = 3; - let invocationLogs: TestInvocationLogs[]; - let logGroupName: string; - - beforeAll(async () => { - // Prepare - new LoggerTestNodejsFunction( - testStack, - { - entry: lambdaFunctionCodeFilePath, - environment: { - POWERTOOLS_LOGGER_LOG_EVENT: 'true', - }, - }, - { - logGroupOutputKey: STACK_OUTPUT_LOG_GROUP, - nameSuffix: 'LogEventFromEnv', - } - ); - - await testStack.deploy(); - logGroupName = testStack.findAndGetStackOutputValue(STACK_OUTPUT_LOG_GROUP); - const functionName = - testStack.findAndGetStackOutputValue('LogEventFromEnv'); - - invocationLogs = await invokeFunction({ - functionName, - invocationMode: 'SEQUENTIAL', - times: invocationCount, - payload: { - foo: 'bar', - }, - }); - - console.log('logGroupName', logGroupName); - }, SETUP_TIMEOUT); - - describe('Log event', () => { - it( - 'should log the event as the first log of each invocation only', - async () => { - for (let i = 0; i < invocationCount; i++) { - // Get log messages of the invocation - const logMessages = invocationLogs[i].getFunctionLogs(); - - for (const [index, message] of logMessages.entries()) { - const log = TestInvocationLogs.parseFunctionLog(message); - // Check that the event is logged on the first log - if (index === 0) { - expect(log).toHaveProperty('event'); - expect(log.event).toStrictEqual( - expect.objectContaining({ foo: 'bar' }) - ); - // Check that the event is not logged again on the rest of the logs - } else { - expect(log).not.toHaveProperty('event'); - } - } - } - }, - TEST_CASE_TIMEOUT - ); - }); - - afterAll(async () => { - if (!process.env.DISABLE_TEARDOWN) { - await testStack.destroy(); - } - }, TEARDOWN_TIMEOUT); -}); diff --git a/packages/tracer/tests/e2e/middy5.test.functionCode.ts b/packages/tracer/tests/e2e/middy.test.functionCode.ts similarity index 100% rename from packages/tracer/tests/e2e/middy5.test.functionCode.ts rename to packages/tracer/tests/e2e/middy.test.functionCode.ts diff --git a/packages/tracer/tests/e2e/middy6.test.functionCode.ts b/packages/tracer/tests/e2e/middy6.test.functionCode.ts deleted file mode 100644 index 491ab74ebb..0000000000 --- a/packages/tracer/tests/e2e/middy6.test.functionCode.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { DynamoDBClient, PutItemCommand } from '@aws-sdk/client-dynamodb'; -import type { Context } from 'aws-lambda'; -import middy from 'middy6'; -import { Tracer } from '../../src/index.js'; -import { captureLambdaHandler } from '../../src/middleware/middy.js'; -import { - EXPECTED_ANNOTATION_KEY as customAnnotationKey, - EXPECTED_ANNOTATION_VALUE as customAnnotationValue, - EXPECTED_ERROR_MESSAGE as customErrorMessage, - EXPECTED_METADATA_KEY as customMetadataKey, - EXPECTED_METADATA_VALUE as customMetadataValue, -} from './constants.js'; - -type CustomEvent = { - throw: boolean; - invocation: number; -}; - -const tracer = new Tracer(); -const dynamoDB = tracer.captureAWSv3Client(new DynamoDBClient({})); - -export const handler = middy( - async (event: CustomEvent, _context: Context): Promise => { - tracer.putAnnotation(customAnnotationKey, customAnnotationValue); - tracer.putMetadata(customMetadataKey, customMetadataValue); - - await dynamoDB.send( - new PutItemCommand({ - TableName: process.env.TEST_TABLE_NAME ?? 'TestTable', - Item: { - id: { - S: `${process.env.POWERTOOLS_SERVICE_NAME ?? 'service'}-${event.invocation}-sdkv3`, - }, - }, - }) - ); - await fetch('https://docs.powertools.aws.dev/lambda/typescript/latest/'); - - if (event.throw) { - throw new Error(customErrorMessage); - } - - return 'success'; - } -).use(captureLambdaHandler(tracer, { captureResponse: false }));