diff --git a/packages/logger/package-lock.json b/packages/logger/package-lock.json index 356904589f..ab94ba4e59 100644 --- a/packages/logger/package-lock.json +++ b/packages/logger/package-lock.json @@ -16,6 +16,7 @@ "lodash.pickby": "^4.6.0" }, "devDependencies": { + "@aws-cdk/aws-lambda": "^1.137.0", "@aws-cdk/aws-lambda-nodejs": "^1.137.0", "@aws-cdk/core": "^1.137.0", "@middy/core": "^2.5.6", @@ -28,6 +29,7 @@ "@typescript-eslint/parser": "^5.4.0", "aws-cdk": "^1.137.0", "aws-sdk": "^2.1048.0", + "concurrently": "7.0.0", "eslint": "^8.3.0", "eslint-import-resolver-node": "^0.3.6", "eslint-import-resolver-typescript": "^2.5.0", @@ -5673,6 +5675,43 @@ "dev": true, "license": "MIT" }, + "node_modules/concurrently": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-7.0.0.tgz", + "integrity": "sha512-WKM7PUsI8wyXpF80H+zjHP32fsgsHNQfPLw/e70Z5dYkV7hF+rf8q3D+ScWJIEr57CpkO3OWBko6hwhQLPR8Pw==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "date-fns": "^2.16.1", + "lodash": "^4.17.21", + "rxjs": "^6.6.3", + "spawn-command": "^0.0.2-1", + "supports-color": "^8.1.0", + "tree-kill": "^1.2.2", + "yargs": "^16.2.0" + }, + "bin": { + "concurrently": "dist/bin/concurrently.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.0 || >=16.0.0" + } + }, + "node_modules/concurrently/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, "node_modules/constructs": { "version": "3.3.193", "dev": true, @@ -5741,6 +5780,19 @@ "node": ">=10" } }, + "node_modules/date-fns": { + "version": "2.28.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.28.0.tgz", + "integrity": "sha512-8d35hViGYx/QH0icHYCeLmsLmMUheMmTyV9Fcm6gvNwdw31yXXH+O85sOBJ+OLnLQMKZowvpKb6FgMIQjcpvQw==", + "dev": true, + "engines": { + "node": ">=0.11" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/date-fns" + } + }, "node_modules/debug": { "version": "4.3.3", "dev": true, @@ -8561,6 +8613,18 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "npm": ">=2.0.0" + } + }, "node_modules/safe-buffer": { "version": "5.1.2", "dev": true, @@ -8668,6 +8732,12 @@ "source-map": "^0.6.0" } }, + "node_modules/spawn-command": { + "version": "0.0.2-1", + "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2-1.tgz", + "integrity": "sha1-YvXpRmmBwbeW3Fkpk34RycaSG9A=", + "dev": true + }, "node_modules/sprintf-js": { "version": "1.0.3", "dev": true, @@ -8904,6 +8974,15 @@ "node": ">=8" } }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "bin": { + "tree-kill": "cli.js" + } + }, "node_modules/ts-jest": { "version": "27.1.2", "dev": true, @@ -13047,6 +13126,33 @@ "version": "0.0.1", "dev": true }, + "concurrently": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-7.0.0.tgz", + "integrity": "sha512-WKM7PUsI8wyXpF80H+zjHP32fsgsHNQfPLw/e70Z5dYkV7hF+rf8q3D+ScWJIEr57CpkO3OWBko6hwhQLPR8Pw==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "date-fns": "^2.16.1", + "lodash": "^4.17.21", + "rxjs": "^6.6.3", + "spawn-command": "^0.0.2-1", + "supports-color": "^8.1.0", + "tree-kill": "^1.2.2", + "yargs": "^16.2.0" + }, + "dependencies": { + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, "constructs": { "version": "3.3.193", "dev": true @@ -13097,6 +13203,12 @@ "whatwg-url": "^8.0.0" } }, + "date-fns": { + "version": "2.28.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.28.0.tgz", + "integrity": "sha512-8d35hViGYx/QH0icHYCeLmsLmMUheMmTyV9Fcm6gvNwdw31yXXH+O85sOBJ+OLnLQMKZowvpKb6FgMIQjcpvQw==", + "dev": true + }, "debug": { "version": "4.3.3", "dev": true, @@ -14892,6 +15004,15 @@ "queue-microtask": "^1.2.2" } }, + "rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, "safe-buffer": { "version": "5.1.2", "dev": true @@ -14962,6 +15083,12 @@ "source-map": "^0.6.0" } }, + "spawn-command": { + "version": "0.0.2-1", + "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2-1.tgz", + "integrity": "sha1-YvXpRmmBwbeW3Fkpk34RycaSG9A=", + "dev": true + }, "sprintf-js": { "version": "1.0.3", "dev": true @@ -15110,6 +15237,12 @@ "punycode": "^2.1.1" } }, + "tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true + }, "ts-jest": { "version": "27.1.2", "dev": true, diff --git a/packages/logger/package.json b/packages/logger/package.json index d04dab8276..90deb9ea88 100644 --- a/packages/logger/package.json +++ b/packages/logger/package.json @@ -13,7 +13,9 @@ "commit": "commit", "test": "npm run test:unit", "test:unit": "jest --group=unit --detectOpenHandles --coverage --verbose", - "test:e2e": "jest --group=e2e", + "test:e2e:nodejs12x": "RUNTIME=nodejs12x jest --group=e2e/logger", + "test:e2e:nodejs14x": "RUNTIME=nodejs14x jest --group=e2e/logger", + "test:e2e": "concurrently \"npm:test:e2e:nodejs12x\" \"npm:test:e2e:nodejs14x\"", "watch": "jest --watch", "build": "tsc", "lint": "eslint --ext .ts --fix --no-error-on-unmatched-pattern src tests", @@ -43,6 +45,7 @@ "types": "./lib/index.d.ts", "typedocMain": "src/index.ts", "devDependencies": { + "@aws-cdk/aws-lambda": "^1.137.0", "@aws-cdk/aws-lambda-nodejs": "^1.137.0", "@aws-cdk/core": "^1.137.0", "@middy/core": "^2.5.6", @@ -55,6 +58,7 @@ "@typescript-eslint/parser": "^5.4.0", "aws-cdk": "^1.137.0", "aws-sdk": "^2.1048.0", + "concurrently": "^7.0.0", "eslint": "^8.3.0", "eslint-import-resolver-node": "^0.3.6", "eslint-import-resolver-typescript": "^2.5.0", diff --git a/packages/logger/tests/e2e/basicFeatures.middy.test.ts b/packages/logger/tests/e2e/basicFeatures.middy.test.ts index d193f5ce1e..f2f90f2e6a 100644 --- a/packages/logger/tests/e2e/basicFeatures.middy.test.ts +++ b/packages/logger/tests/e2e/basicFeatures.middy.test.ts @@ -10,18 +10,24 @@ import path from 'path'; import { randomUUID } from 'crypto'; import { App, Stack } from '@aws-cdk/core'; -import { createStackWithLambdaFunction, deployStack, destroyStack, invokeFunction } from '../helpers/e2eUtils'; +import { createStackWithLambdaFunction, deployStack, destroyStack, generateUniqueName, invokeFunction, isValidRuntimeKey } from '../helpers/e2eUtils'; import { InvocationLogs } from '../helpers/InvocationLogs'; +const runtime: string = process.env.RUNTIME || 'nodejs14x'; + +if (!isValidRuntimeKey(runtime)) { + throw new Error(`Invalid runtime key value: ${runtime}`); +} + const LEVEL = InvocationLogs.LEVEL; const TEST_CASE_TIMEOUT = 20000; // 20 seconds -const SETUP_TIMEOUT = 200000; // 200 seconds +const SETUP_TIMEOUT = 300000; // 300 seconds const TEARDOWN_TIMEOUT = 200000; const STACK_OUTPUT_LOG_GROUP = 'LogGroupName'; const uuid = randomUUID(); -const stackName = `LoggerE2EBasicFeatureMiddyStack-${uuid}`; -const functionName = `loggerE2EBasicFeaturesMiddy-${uuid}`; +const stackName = generateUniqueName(uuid, runtime, 'BasicFeatures-Middy'); +const functionName = generateUniqueName(uuid, runtime, 'BasicFeatures-Middy'); const lambdaFunctionCodeFile = 'basicFeatures.middy.test.FunctionCode.ts'; // Text to be used by Logger in the Lambda function @@ -34,12 +40,12 @@ const ERROR_MSG = `error-${uuid}`; const integTestApp = new App(); let logGroupName: string; // We do not know it until deployment let stack: Stack; -describe('logger E2E tests basic functionalities (middy)', () => { + +describe(`logger E2E tests basic functionalities (middy) for runtime: ${runtime}`, () => { let invocationLogs: InvocationLogs[]; beforeAll(async () => { - // Create and deploy a stack with AWS CDK stack = createStackWithLambdaFunction({ app: integTestApp, @@ -58,7 +64,8 @@ describe('logger E2E tests basic functionalities (middy)', () => { SINGLE_LOG_ITEM_VALUE, ERROR_MSG, }, - logGroupOutputKey: STACK_OUTPUT_LOG_GROUP + logGroupOutputKey: STACK_OUTPUT_LOG_GROUP, + runtime: runtime, }); const stackArtifact = integTestApp.synth().getStackByName(stack.stackName); const outputs = await deployStack(stackArtifact); diff --git a/packages/logger/tests/e2e/childLogger.manual.test.ts b/packages/logger/tests/e2e/childLogger.manual.test.ts index 558f8adb4c..b8421c41dc 100644 --- a/packages/logger/tests/e2e/childLogger.manual.test.ts +++ b/packages/logger/tests/e2e/childLogger.manual.test.ts @@ -10,18 +10,24 @@ import path from 'path'; import { randomUUID } from 'crypto'; import { App, Stack } from '@aws-cdk/core'; -import { createStackWithLambdaFunction, deployStack, destroyStack, invokeFunction } from '../helpers/e2eUtils'; +import { createStackWithLambdaFunction, deployStack, destroyStack, generateUniqueName, invokeFunction, isValidRuntimeKey } from '../helpers/e2eUtils'; import { InvocationLogs } from '../helpers/InvocationLogs'; +const runtime: string = process.env.RUNTIME || 'nodejs14x'; + +if (!isValidRuntimeKey(runtime)) { + throw new Error(`Invalid runtime key value: ${runtime}`); +} + const LEVEL = InvocationLogs.LEVEL; const TEST_CASE_TIMEOUT = 20000; // 20 seconds -const SETUP_TIMEOUT = 200000; // 200 seconds +const SETUP_TIMEOUT = 300000; // 300 seconds const TEARDOWN_TIMEOUT = 200000; const STACK_OUTPUT_LOG_GROUP = 'LogGroupName'; const uuid = randomUUID(); -const stackName = `LoggerE2EChildLoggerManualStack-${uuid}`; -const functionName = `LoggerE2EChildLoggerManual-${uuid}`; +const stackName = generateUniqueName(uuid, runtime, 'ChildLogger-Manual'); +const functionName = generateUniqueName(uuid, runtime, 'ChildLogger-Manual'); const lambdaFunctionCodeFile = 'childLogger.manual.test.FunctionCode.ts'; // Parameters to be used by Logger in the Lambda function @@ -34,7 +40,7 @@ const CHILD_LOG_LEVEL = LEVEL.ERROR.toString(); const integTestApp = new App(); let logGroupName: string; // We do not know it until deployment let stack: Stack; -describe('logger E2E tests child logger functionalities (manual)', () => { +describe(`logger E2E tests child logger functionalities (manual) for runtime: ${runtime}`, () => { let invocationLogs: InvocationLogs[]; @@ -58,7 +64,8 @@ describe('logger E2E tests child logger functionalities (manual)', () => { CHILD_LOG_MSG, CHILD_LOG_LEVEL, }, - logGroupOutputKey: STACK_OUTPUT_LOG_GROUP + logGroupOutputKey: STACK_OUTPUT_LOG_GROUP, + runtime: runtime, }); const stackArtifact = integTestApp.synth().getStackByName(stack.stackName); const outputs = await deployStack(stackArtifact); diff --git a/packages/logger/tests/e2e/sampleRate.decorator.test.ts b/packages/logger/tests/e2e/sampleRate.decorator.test.ts index d7eeca4e84..1d2eac93c4 100644 --- a/packages/logger/tests/e2e/sampleRate.decorator.test.ts +++ b/packages/logger/tests/e2e/sampleRate.decorator.test.ts @@ -10,19 +10,24 @@ import path from 'path'; import { randomUUID } from 'crypto'; import { App, Stack } from '@aws-cdk/core'; -import { createStackWithLambdaFunction, deployStack, destroyStack, invokeFunction } from '../helpers/e2eUtils'; +import { createStackWithLambdaFunction, deployStack, destroyStack, generateUniqueName, invokeFunction, isValidRuntimeKey } from '../helpers/e2eUtils'; import { InvocationLogs } from '../helpers/InvocationLogs'; -const LEVEL = InvocationLogs.LEVEL; +const runtime: string = process.env.RUNTIME || 'nodejs14x'; + +if (!isValidRuntimeKey(runtime)) { + throw new Error(`Invalid runtime key value: ${runtime}`); +} +const LEVEL = InvocationLogs.LEVEL; const TEST_CASE_TIMEOUT = 30000; // 30 seconds -const SETUP_TIMEOUT = 200000; // 200 seconds +const SETUP_TIMEOUT = 300000; // 300 seconds const TEARDOWN_TIMEOUT = 200000; const STACK_OUTPUT_LOG_GROUP = 'LogGroupName'; const uuid = randomUUID(); -const stackName = `LoggerE2ESampleRateDecoratorStack-${uuid}`; -const functionName = `LoggerE2EampleRateDecorator-${uuid}`; +const stackName = generateUniqueName(uuid, runtime, 'SampleRate-Decorator'); +const functionName = generateUniqueName(uuid, runtime, 'SampleRate-Decorator'); const lambdaFunctionCodeFile = 'sampleRate.decorator.test.FunctionCode.ts'; // Parameters to be used by Logger in the Lambda function @@ -32,7 +37,7 @@ const LOG_LEVEL = LEVEL.ERROR.toString(); const integTestApp = new App(); let logGroupName: string; // We do not know it until deployment let stack: Stack; -describe('logger E2E tests sample rate and injectLambdaContext()', () => { +describe(`logger E2E tests sample rate and injectLambdaContext() for runtime: ${runtime}`, () => { let invocationLogs: InvocationLogs[]; @@ -53,7 +58,8 @@ describe('logger E2E tests sample rate and injectLambdaContext()', () => { LOG_MSG, SAMPLE_RATE, }, - logGroupOutputKey: STACK_OUTPUT_LOG_GROUP + logGroupOutputKey: STACK_OUTPUT_LOG_GROUP, + runtime: runtime, }); const stackArtifact = integTestApp.synth().getStackByName(stack.stackName); const outputs = await deployStack(stackArtifact); diff --git a/packages/logger/tests/helpers/e2eUtils.ts b/packages/logger/tests/helpers/e2eUtils.ts index a3b8e7517f..67de1343f0 100644 --- a/packages/logger/tests/helpers/e2eUtils.ts +++ b/packages/logger/tests/helpers/e2eUtils.ts @@ -6,12 +6,21 @@ import { SdkProvider } from 'aws-cdk/lib/api/aws-auth'; import { CloudFormationDeployments } from 'aws-cdk/lib/api/cloudformation-deployments'; import { App, CfnOutput, Stack } from '@aws-cdk/core'; import * as lambda from '@aws-cdk/aws-lambda-nodejs'; +import { Runtime } from '@aws-cdk/aws-lambda'; import * as AWS from 'aws-sdk'; import { InvocationLogs } from './InvocationLogs'; const lambdaClient = new AWS.Lambda(); +const NAME_PREFIX = 'Logger-E2E'; +const testRuntimeKeys = [ 'nodejs12x', 'nodejs14x' ]; +export type TestRuntimesKey = typeof testRuntimeKeys[number]; +const TEST_RUNTIMES: Record = { + nodejs12x: Runtime.NODEJS_12_X, + nodejs14x: Runtime.NODEJS_14_X, +}; + export type StackWithLambdaFunctionOptions = { app: App stackName: string @@ -19,8 +28,11 @@ export type StackWithLambdaFunctionOptions = { functionEntry: string environment: {[key: string]: string} logGroupOutputKey: string + runtime: string }; +export const isValidRuntimeKey = (runtime: string): runtime is TestRuntimesKey => testRuntimeKeys.includes(runtime); + export const createStackWithLambdaFunction = (params: StackWithLambdaFunctionOptions): Stack => { const stack = new Stack(params.app, params.stackName); @@ -28,6 +40,7 @@ export const createStackWithLambdaFunction = (params: StackWithLambdaFunctionOpt functionName: params.functionName, entry: params.functionEntry, environment: params.environment, + runtime: TEST_RUNTIMES[params.runtime as TestRuntimesKey], }); new CfnOutput(stack, params.logGroupOutputKey, { @@ -37,6 +50,9 @@ export const createStackWithLambdaFunction = (params: StackWithLambdaFunctionOpt return stack; }; +export const generateUniqueName = (uuid: string, runtime: string, testName: string): string => + `${NAME_PREFIX}-${runtime}-${testName}-${uuid}`.substring(0, 64); + export const deployStack = async (stackArtifact: CloudFormationStackArtifact ): Promise<{[name:string]: string}> => { const sdkProvider = await SdkProvider.withAwsCliCompatibleDefaults({ profile: process.env.AWS_PROFILE,