diff --git a/.github/actions/cached-node-modules/action.yml b/.github/actions/cached-node-modules/action.yml index 1ae3e738d2..c3df647248 100644 --- a/.github/actions/cached-node-modules/action.yml +++ b/.github/actions/cached-node-modules/action.yml @@ -41,5 +41,6 @@ runs: npm run build -w packages/metrics & \ npm run build -w packages/parameters & \ npm run build -w packages/idempotency & \ - npm run build -w packages/batch + npm run build -w packages/batch & \ + npm run build -w packages/testing shell: bash \ No newline at end of file diff --git a/layers/package.json b/layers/package.json index 0e8f54baaf..ce626f56f8 100644 --- a/layers/package.json +++ b/layers/package.json @@ -34,6 +34,12 @@ }, "homepage": "https://github.com/aws-powertools/powertools-lambda-typescript#readme", "devDependencies": { + "@aws-lambda-powertools/testing-utils": "file:../packages/testing", "source-map-support": "^0.5.21" + }, + "dependencies": { + "aws-cdk": "^2.88.0", + "aws-cdk-lib": "^2.88.0", + "esbuild": "^0.18.17" } } diff --git a/layers/tests/e2e/layerPublisher.test.ts b/layers/tests/e2e/layerPublisher.test.ts index 3da035472f..7b4bab6988 100644 --- a/layers/tests/e2e/layerPublisher.test.ts +++ b/layers/tests/e2e/layerPublisher.test.ts @@ -3,13 +3,13 @@ * * @group e2e/layers/all */ -import { App, Stack } from 'aws-cdk-lib'; -import { Tracing } from 'aws-cdk-lib/aws-lambda'; +import { App } from 'aws-cdk-lib'; +import { LayerVersion, Tracing } from 'aws-cdk-lib/aws-lambda'; import { LayerPublisherStack } from '../../src/layer-publisher-stack'; import { - deployStack, - destroyStack, -} from '../../../packages/commons/tests/utils/cdk-cli'; + TestStack, + defaultRuntime, +} from '@aws-lambda-powertools/testing-utils'; import { generateUniqueName, invokeFunction, @@ -30,7 +30,7 @@ import { v4 } from 'uuid'; import path from 'path'; import packageJson from '../../package.json'; -const runtime: string = process.env.RUNTIME || 'nodejs18x'; +const runtime: string = process.env.RUNTIME || defaultRuntime; if (!isValidRuntimeKey(runtime)) { throw new Error(`Invalid runtime key: ${runtime}`); @@ -66,30 +66,33 @@ describe(`layers E2E tests (LayerPublisherStack) for runtime: ${runtime}`, () => const lambdaFunctionCodeFile = 'layerPublisher.class.test.functionCode.ts'; const invocationCount = 1; - - const integTestApp = new App(); - let stackLayer: LayerPublisherStack; - let stackFunction: Stack; - const powerToolsPackageVersion = packageJson.version; + const layerName = generateUniqueName( + RESOURCE_NAME_PREFIX, + uuid, + runtime, + 'layer' + ); - beforeAll(async () => { - const layerName = generateUniqueName( - RESOURCE_NAME_PREFIX, - uuid, - runtime, - 'layer' - ); + const testStack = new TestStack(stackNameFunction); + const layerApp = new App(); + const layerStack = new LayerPublisherStack(layerApp, stackNameLayers, { + layerName, + powertoolsPackageVersion: powerToolsPackageVersion, + ssmParameterLayerArn: ssmParameterLayerName, + }); + const testLayerStack = new TestStack(stackNameLayers, layerApp, layerStack); - stackLayer = new LayerPublisherStack(integTestApp, stackNameLayers, { - layerName: layerName, - powertoolsPackageVersion: powerToolsPackageVersion, - ssmParameterLayerArn: ssmParameterLayerName, - }); + beforeAll(async () => { + const outputs = await testLayerStack.deploy(); - stackFunction = createStackWithLambdaFunction({ - app: integTestApp, - stackName: stackNameFunction, + const layerVersion = LayerVersion.fromLayerVersionArn( + testStack.stack, + 'LayerVersionArnReference', + outputs['LatestLayerArn'] + ); + createStackWithLambdaFunction({ + stack: testStack.stack, functionName: functionName, functionEntry: path.join(__dirname, lambdaFunctionCodeFile), tracing: Tracing.ACTIVE, @@ -107,11 +110,10 @@ describe(`layers E2E tests (LayerPublisherStack) for runtime: ${runtime}`, () => '@aws-lambda-powertools/tracer', ], }, - layers: [stackLayer.lambdaLayerVersion], + layers: [layerVersion], }); - await deployStack(integTestApp, stackLayer); - await deployStack(integTestApp, stackFunction); + await testStack.deploy(); invocationLogs = await invokeFunction( functionName, @@ -167,8 +169,8 @@ describe(`layers E2E tests (LayerPublisherStack) for runtime: ${runtime}`, () => afterAll(async () => { if (!process.env.DISABLE_TEARDOWN) { - await destroyStack(integTestApp, stackFunction); - await destroyStack(integTestApp, stackLayer); + await testLayerStack.destroy(); + await testStack.destroy(); } }, TEARDOWN_TIMEOUT); }); diff --git a/lerna.json b/lerna.json index f77aa27b3a..863cd19258 100644 --- a/lerna.json +++ b/lerna.json @@ -7,6 +7,7 @@ "packages/parameters", "packages/idempotency", "packages/batch", + "packages/testing", "examples/cdk", "examples/sam", "layers" diff --git a/package-lock.json b/package-lock.json index 60cd7cfbea..9e61c13363 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,28 +15,21 @@ "packages/tracer", "packages/parameters", "packages/idempotency", + "packages/batch", + "packages/testing", "docs/snippets", "layers", "examples/cdk", - "examples/sam", - "packages/batch" + "examples/sam" ], "devDependencies": { - "@aws-cdk/cloudformation-diff": "^2.73.0", - "@aws-cdk/cx-api": "^2.73.0", "@middy/core": "^3.6.2", "@types/aws-lambda": "^8.10.109", "@types/jest": "^29.2.4", "@types/node": "^18.16.18", - "@types/uuid": "^9.0.0", + "@types/uuid": "^9.0.2", "@typescript-eslint/eslint-plugin": "^5.46.1", "@typescript-eslint/parser": "^5.46.1", - "archiver": "^5.3.1", - "aws-cdk": "^2.73.0", - "aws-cdk-lib": "^2.73.0", - "cdk-assets": "^2.72.1", - "constructs": "^10.1.190", - "esbuild": "^0.16.7", "eslint": "^8.29.0", "eslint-config-prettier": "^8.8.0", "eslint-import-resolver-node": "^0.3.6", @@ -49,8 +42,6 @@ "lerna": "^6.6.2", "lint-staged": "^13.1.2", "prettier": "^2.8.8", - "promptly": "^3.2.0", - "proxy-agent": "^5.0.0", "rimraf": "^5.0.1", "ts-jest": "^29.0.3", "ts-node": "^10.9.1", @@ -428,207 +419,454 @@ "layers": { "version": "1.12.1", "license": "MIT-0", + "dependencies": { + "aws-cdk": "^2.88.0", + "aws-cdk-lib": "^2.88.0", + "esbuild": "^0.18.17" + }, "bin": { "layer": "bin/layers.js" }, "devDependencies": { + "@aws-lambda-powertools/testing-utils": "file:../packages/testing", "source-map-support": "^0.5.21" } }, - "layers/node_modules/source-map-support": { - "version": "0.5.21", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" + "layers/node_modules/@esbuild/android-arm": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.17.tgz", + "integrity": "sha512-wHsmJG/dnL3OkpAcwbgoBTTMHVi4Uyou3F5mf58ZtmUyIKfcdA7TROav/6tCzET4A3QW2Q2FC+eFneMU+iyOxg==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" } }, - "node_modules/@ampproject/remapping": { - "version": "2.2.0", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@jridgewell/gen-mapping": "^0.1.0", - "@jridgewell/trace-mapping": "^0.3.9" - }, + "layers/node_modules/@esbuild/android-arm64": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.17.tgz", + "integrity": "sha512-9np+YYdNDed5+Jgr1TdWBsozZ85U1Oa3xW0c7TWqH0y2aGghXtZsuT8nYRbzOMcl0bXZXjOGbksoTtVOlWrRZg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">=6.0.0" + "node": ">=12" } }, - "node_modules/@aws-cdk/asset-awscli-v1": { - "version": "2.2.196", - "resolved": "https://registry.npmjs.org/@aws-cdk/asset-awscli-v1/-/asset-awscli-v1-2.2.196.tgz", - "integrity": "sha512-F8hU1rEzYS7z5Dt2s+ttd0/jMvPuUE9BcXexgq+dIOLuZsRpDwNnkMBtjNaJXJS48ZGJ2X4b8VlklseepdtoSA==" - }, - "node_modules/@aws-cdk/asset-kubectl-v20": { - "version": "2.1.1", - "license": "Apache-2.0" - }, - "node_modules/@aws-cdk/asset-node-proxy-agent-v5": { - "version": "2.0.165", - "resolved": "https://registry.npmjs.org/@aws-cdk/asset-node-proxy-agent-v5/-/asset-node-proxy-agent-v5-2.0.165.tgz", - "integrity": "sha512-bsyLQD/vqXQcc9RDmlM1XqiFNO/yewgVFXmkMcQkndJbmE/jgYkzewwYGrBlfL725hGLQipXq19+jwWwdsXQqg==" - }, - "node_modules/@aws-cdk/cfnspec": { - "version": "2.73.0-alpha.0", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "fs-extra": "^9.1.0", - "md5": "^2.3.0" + "layers/node_modules/@esbuild/android-x64": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.17.tgz", + "integrity": "sha512-O+FeWB/+xya0aLg23hHEM2E3hbfwZzjqumKMSIqcHbNvDa+dza2D0yLuymRBQQnC34CWrsJUXyH2MG5VnLd6uw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" } }, - "node_modules/@aws-cdk/cloud-assembly-schema": { - "version": "2.73.0", - "bundleDependencies": [ - "jsonschema", - "semver" + "layers/node_modules/@esbuild/darwin-arm64": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.17.tgz", + "integrity": "sha512-M9uJ9VSB1oli2BE/dJs3zVr9kcCBBsE883prage1NWz6pBS++1oNn/7soPNS3+1DGj0FrkSvnED4Bmlu1VAE9g==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" ], - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "jsonschema": "^1.4.1", - "semver": "^7.3.8" - }, "engines": { - "node": ">= 14.15.0" + "node": ">=12" } }, - "node_modules/@aws-cdk/cloud-assembly-schema/node_modules/jsonschema": { - "version": "1.4.1", - "dev": true, - "inBundle": true, - "license": "MIT", + "layers/node_modules/@esbuild/darwin-x64": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.17.tgz", + "integrity": "sha512-XDre+J5YeIJDMfp3n0279DFNrGCXlxOuGsWIkRb1NThMZ0BsrWXoTg23Jer7fEXQ9Ye5QjrvXpxnhzl3bHtk0g==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": "*" + "node": ">=12" } }, - "node_modules/@aws-cdk/cloud-assembly-schema/node_modules/lru-cache": { - "version": "6.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, + "layers/node_modules/@esbuild/freebsd-arm64": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.17.tgz", + "integrity": "sha512-cjTzGa3QlNfERa0+ptykyxs5A6FEUQQF0MuilYXYBGdBxD3vxJcKnzDlhDCa1VAJCmAxed6mYhA2KaJIbtiNuQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": ">=10" + "node": ">=12" } }, - "node_modules/@aws-cdk/cloud-assembly-schema/node_modules/semver": { - "version": "7.3.8", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, + "layers/node_modules/@esbuild/freebsd-x64": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.17.tgz", + "integrity": "sha512-sOxEvR8d7V7Kw8QqzxWc7bFfnWnGdaFBut1dRUYtu+EIRXefBc/eIsiUiShnW0hM3FmQ5Zf27suDuHsKgZ5QrA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": ">=10" + "node": ">=12" } }, - "node_modules/@aws-cdk/cloud-assembly-schema/node_modules/yallist": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/@aws-cdk/cloudformation-diff": { - "version": "2.73.0", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@aws-cdk/cfnspec": "2.73.0-alpha.0", - "chalk": "^4", - "diff": "^5.1.0", - "fast-deep-equal": "^3.1.3", - "string-width": "^4.2.3", - "table": "^6.8.1" - }, + "layers/node_modules/@esbuild/linux-arm": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.17.tgz", + "integrity": "sha512-2d3Lw6wkwgSLC2fIvXKoMNGVaeY8qdN0IC3rfuVxJp89CRfA3e3VqWifGDfuakPmp90+ZirmTfye1n4ncjv2lg==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">= 14.15.0" + "node": ">=12" } }, - "node_modules/@aws-cdk/cx-api": { - "version": "2.73.0", - "bundleDependencies": [ - "semver" + "layers/node_modules/@esbuild/linux-arm64": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.17.tgz", + "integrity": "sha512-c9w3tE7qA3CYWjT+M3BMbwMt+0JYOp3vCMKgVBrCl1nwjAlOMYzEo+gG7QaZ9AtqZFj5MbUc885wuBBmu6aADQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" ], - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@aws-cdk/cloud-assembly-schema": "2.73.0", - "semver": "^7.3.8" - }, "engines": { - "node": ">= 14.15.0" - }, - "peerDependencies": { - "@aws-cdk/cloud-assembly-schema": "2.73.0" + "node": ">=12" } }, - "node_modules/@aws-cdk/cx-api/node_modules/lru-cache": { - "version": "6.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, + "layers/node_modules/@esbuild/linux-ia32": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.17.tgz", + "integrity": "sha512-1DS9F966pn5pPnqXYz16dQqWIB0dmDfAQZd6jSSpiT9eX1NzKh07J6VKR3AoXXXEk6CqZMojiVDSZi1SlmKVdg==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=10" + "node": ">=12" } }, - "node_modules/@aws-cdk/cx-api/node_modules/semver": { - "version": "7.3.8", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, + "layers/node_modules/@esbuild/linux-loong64": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.17.tgz", + "integrity": "sha512-EvLsxCk6ZF0fpCB6w6eOI2Fc8KW5N6sHlIovNe8uOFObL2O+Mr0bflPHyHwLT6rwMg9r77WOAWb2FqCQrVnwFg==", + "cpu": [ + "loong64" + ], + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=10" + "node": ">=12" } }, - "node_modules/@aws-cdk/cx-api/node_modules/yallist": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "ISC" + "layers/node_modules/@esbuild/linux-mips64el": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.17.tgz", + "integrity": "sha512-e0bIdHA5p6l+lwqTE36NAW5hHtw2tNRmHlGBygZC14QObsA3bD4C6sXLJjvnDIjSKhW1/0S3eDy+QmX/uZWEYQ==", + "cpu": [ + "mips64el" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } }, - "node_modules/@aws-crypto/crc32": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-3.0.0.tgz", - "integrity": "sha512-IzSgsrxUcsrejQbPVilIKy16kAT52EwB6zSaI+M3xxIhKh5+aldEyvI+z6erM7TCLB2BJsFrtHjp6/4/sr+3dA==", - "dependencies": { - "@aws-crypto/util": "^3.0.0", - "@aws-sdk/types": "^3.222.0", - "tslib": "^1.11.1" + "layers/node_modules/@esbuild/linux-ppc64": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.17.tgz", + "integrity": "sha512-BAAilJ0M5O2uMxHYGjFKn4nJKF6fNCdP1E0o5t5fvMYYzeIqy2JdAP88Az5LHt9qBoUa4tDaRpfWt21ep5/WqQ==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" } }, - "node_modules/@aws-crypto/crc32/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + "layers/node_modules/@esbuild/linux-riscv64": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.17.tgz", + "integrity": "sha512-Wh/HW2MPnC3b8BqRSIme/9Zhab36PPH+3zam5pqGRH4pE+4xTrVLx2+XdGp6fVS3L2x+DrsIcsbMleex8fbE6g==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } }, - "node_modules/@aws-crypto/ie11-detection": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/ie11-detection/-/ie11-detection-3.0.0.tgz", - "integrity": "sha512-341lBBkiY1DfDNKai/wXM3aujNBkXR7tq1URPQDL9wi3AUbI80NR74uF1TXHMm7po1AcnFk8iu2S2IeU/+/A+Q==", - "dependencies": { - "tslib": "^1.11.1" + "layers/node_modules/@esbuild/linux-s390x": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.17.tgz", + "integrity": "sha512-j/34jAl3ul3PNcK3pfI0NSlBANduT2UO5kZ7FCaK33XFv3chDhICLY8wJJWIhiQ+YNdQ9dxqQctRg2bvrMlYgg==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" } }, - "node_modules/@aws-crypto/ie11-detection/node_modules/tslib": { - "version": "1.14.1", + "layers/node_modules/@esbuild/linux-x64": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.17.tgz", + "integrity": "sha512-QM50vJ/y+8I60qEmFxMoxIx4de03pGo2HwxdBeFd4nMh364X6TIBZ6VQ5UQmPbQWUVWHWws5MmJXlHAXvJEmpQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "layers/node_modules/@esbuild/netbsd-x64": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.17.tgz", + "integrity": "sha512-/jGlhWR7Sj9JPZHzXyyMZ1RFMkNPjC6QIAan0sDOtIo2TYk3tZn5UDrkE0XgsTQCxWTTOcMPf9p6Rh2hXtl5TQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "layers/node_modules/@esbuild/openbsd-x64": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.17.tgz", + "integrity": "sha512-rSEeYaGgyGGf4qZM2NonMhMOP/5EHp4u9ehFiBrg7stH6BYEEjlkVREuDEcQ0LfIl53OXLxNbfuIj7mr5m29TA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "layers/node_modules/@esbuild/sunos-x64": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.17.tgz", + "integrity": "sha512-Y7ZBbkLqlSgn4+zot4KUNYst0bFoO68tRgI6mY2FIM+b7ZbyNVtNbDP5y8qlu4/knZZ73fgJDlXID+ohY5zt5g==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "layers/node_modules/@esbuild/win32-arm64": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.17.tgz", + "integrity": "sha512-bwPmTJsEQcbZk26oYpc4c/8PvTY3J5/QK8jM19DVlEsAB41M39aWovWoHtNm78sd6ip6prilxeHosPADXtEJFw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "layers/node_modules/@esbuild/win32-ia32": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.17.tgz", + "integrity": "sha512-H/XaPtPKli2MhW+3CQueo6Ni3Avggi6hP/YvgkEe1aSaxw+AeO8MFjq8DlgfTd9Iz4Yih3QCZI6YLMoyccnPRg==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "layers/node_modules/@esbuild/win32-x64": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.17.tgz", + "integrity": "sha512-fGEb8f2BSA3CW7riJVurug65ACLuQAzKq0SSqkY2b2yHHH0MzDfbLyKIGzHwOI/gkHcxM/leuSW6D5w/LMNitA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "layers/node_modules/esbuild": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.17.tgz", + "integrity": "sha512-1GJtYnUxsJreHYA0Y+iQz2UEykonY66HNWOb0yXYZi9/kNrORUEHVg87eQsCtqh59PEJ5YVZJO98JHznMJSWjg==", + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.18.17", + "@esbuild/android-arm64": "0.18.17", + "@esbuild/android-x64": "0.18.17", + "@esbuild/darwin-arm64": "0.18.17", + "@esbuild/darwin-x64": "0.18.17", + "@esbuild/freebsd-arm64": "0.18.17", + "@esbuild/freebsd-x64": "0.18.17", + "@esbuild/linux-arm": "0.18.17", + "@esbuild/linux-arm64": "0.18.17", + "@esbuild/linux-ia32": "0.18.17", + "@esbuild/linux-loong64": "0.18.17", + "@esbuild/linux-mips64el": "0.18.17", + "@esbuild/linux-ppc64": "0.18.17", + "@esbuild/linux-riscv64": "0.18.17", + "@esbuild/linux-s390x": "0.18.17", + "@esbuild/linux-x64": "0.18.17", + "@esbuild/netbsd-x64": "0.18.17", + "@esbuild/openbsd-x64": "0.18.17", + "@esbuild/sunos-x64": "0.18.17", + "@esbuild/win32-arm64": "0.18.17", + "@esbuild/win32-ia32": "0.18.17", + "@esbuild/win32-x64": "0.18.17" + } + }, + "layers/node_modules/source-map-support": { + "version": "0.5.21", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.2.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.1.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@aws-cdk/asset-awscli-v1": { + "version": "2.2.200", + "resolved": "https://registry.npmjs.org/@aws-cdk/asset-awscli-v1/-/asset-awscli-v1-2.2.200.tgz", + "integrity": "sha512-Kf5J8DfJK4wZFWT2Myca0lhwke7LwHcHBo+4TvWOGJrFVVKVuuiLCkzPPRBQQVDj0Vtn2NBokZAz8pfMpAqAKg==" + }, + "node_modules/@aws-cdk/asset-kubectl-v20": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@aws-cdk/asset-kubectl-v20/-/asset-kubectl-v20-2.1.2.tgz", + "integrity": "sha512-3M2tELJOxQv0apCIiuKQ4pAbncz9GuLwnKFqxifWfe77wuMxyTRPmxssYHs42ePqzap1LT6GDcPygGs+hHstLg==" + }, + "node_modules/@aws-cdk/asset-node-proxy-agent-v5": { + "version": "2.0.165", + "resolved": "https://registry.npmjs.org/@aws-cdk/asset-node-proxy-agent-v5/-/asset-node-proxy-agent-v5-2.0.165.tgz", + "integrity": "sha512-bsyLQD/vqXQcc9RDmlM1XqiFNO/yewgVFXmkMcQkndJbmE/jgYkzewwYGrBlfL725hGLQipXq19+jwWwdsXQqg==" + }, + "node_modules/@aws-cdk/cli-lib-alpha": { + "version": "2.88.0-alpha.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/cli-lib-alpha/-/cli-lib-alpha-2.88.0-alpha.0.tgz", + "integrity": "sha512-UKYAwGcNxSlPLZHlLyf/JEziTt830xl5A2OFJ5R3D2vgpT3YuQb5lTz07Wzi8qacHjaSbHV5gAf5r73rBtYXeA==", + "engines": { + "node": ">= 14.15.0" + } + }, + "node_modules/@aws-crypto/crc32": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-3.0.0.tgz", + "integrity": "sha512-IzSgsrxUcsrejQbPVilIKy16kAT52EwB6zSaI+M3xxIhKh5+aldEyvI+z6erM7TCLB2BJsFrtHjp6/4/sr+3dA==", + "dependencies": { + "@aws-crypto/util": "^3.0.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-crypto/crc32/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@aws-crypto/ie11-detection": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/ie11-detection/-/ie11-detection-3.0.0.tgz", + "integrity": "sha512-341lBBkiY1DfDNKai/wXM3aujNBkXR7tq1URPQDL9wi3AUbI80NR74uF1TXHMm7po1AcnFk8iu2S2IeU/+/A+Q==", + "dependencies": { + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-crypto/ie11-detection/node_modules/tslib": { + "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, @@ -719,6 +957,10 @@ "resolved": "packages/parameters", "link": true }, + "node_modules/@aws-lambda-powertools/testing-utils": { + "resolved": "packages/testing", + "link": true + }, "node_modules/@aws-lambda-powertools/tracer": { "resolved": "packages/tracer", "link": true @@ -5503,14 +5745,6 @@ "node": ">=14.0.0" } }, - "node_modules/@tootallnate/once": { - "version": "1.1.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, "node_modules/@tsconfig/node10": { "version": "1.0.9", "dev": true, @@ -5763,9 +5997,10 @@ "license": "MIT" }, "node_modules/@types/uuid": { - "version": "9.0.0", - "dev": true, - "license": "MIT" + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.2.tgz", + "integrity": "sha512-kNnC1GFBLuhImSnV7w4njQkUiJi0ZXUycu1rUaouPqiKlXkh77JKgdRnTAp1x5eBwcIwbtI+3otwzuIDEuDoxQ==", + "dev": true }, "node_modules/@types/yargs": { "version": "17.0.17", @@ -6102,21 +6337,6 @@ "node": ">=8" } }, - "node_modules/ajv": { - "version": "8.11.2", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, "node_modules/ansi-colors": { "version": "4.1.3", "dev": true, @@ -6195,70 +6415,6 @@ "dev": true, "license": "ISC" }, - "node_modules/archiver": { - "version": "5.3.1", - "dev": true, - "license": "MIT", - "dependencies": { - "archiver-utils": "^2.1.0", - "async": "^3.2.3", - "buffer-crc32": "^0.2.1", - "readable-stream": "^3.6.0", - "readdir-glob": "^1.0.0", - "tar-stream": "^2.2.0", - "zip-stream": "^4.1.0" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/archiver-utils": { - "version": "2.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "glob": "^7.1.4", - "graceful-fs": "^4.2.0", - "lazystream": "^1.0.0", - "lodash.defaults": "^4.2.0", - "lodash.difference": "^4.5.0", - "lodash.flatten": "^4.4.0", - "lodash.isplainobject": "^4.0.6", - "lodash.union": "^4.6.0", - "normalize-path": "^3.0.0", - "readable-stream": "^2.0.0" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/archiver-utils/node_modules/readable-stream": { - "version": "2.3.7", - "dev": true, - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/archiver-utils/node_modules/safe-buffer": { - "version": "5.1.2", - "dev": true, - "license": "MIT" - }, - "node_modules/archiver-utils/node_modules/string_decoder": { - "version": "1.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, "node_modules/are-we-there-yet": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz", @@ -6348,17 +6504,6 @@ "node": ">=0.10.0" } }, - "node_modules/ast-types": { - "version": "0.13.4", - "dev": true, - "license": "MIT", - "dependencies": { - "tslib": "^2.0.1" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/astral-regex": { "version": "2.0.0", "dev": true, @@ -6411,9 +6556,9 @@ } }, "node_modules/aws-cdk": { - "version": "2.73.0", - "dev": true, - "license": "Apache-2.0", + "version": "2.88.0", + "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.88.0.tgz", + "integrity": "sha512-7Tj0uusA2nsEOsqkd4kB5vmzciz7l/eGBN5a+Ce4/CCcoe4ZCvT85L+T6tK0aohUTLZTAlTPBceH34RN5iMYpA==", "bin": { "cdk": "bin/cdk" }, @@ -6425,9 +6570,9 @@ } }, "node_modules/aws-cdk-lib": { - "version": "2.80.0", - "resolved": "https://registry.npmjs.org/aws-cdk-lib/-/aws-cdk-lib-2.80.0.tgz", - "integrity": "sha512-PoqD3Yms5I0ajuTi071nTW/hpkH3XsdyZzn5gYsPv0qD7mqP3h6Qr+6RiGx+yQ1KcVFyxWdX15uK+DsC0KwvcQ==", + "version": "2.88.0", + "resolved": "https://registry.npmjs.org/aws-cdk-lib/-/aws-cdk-lib-2.88.0.tgz", + "integrity": "sha512-bmhokh30HVeqlotWaoEmK7mKB9SJbJwpbsiVgmYe3JcMu8DposHQqaIPI7LnC+dg015tZaxUsExxOYBEw+vntQ==", "bundleDependencies": [ "@balena/dockerignore", "case", @@ -6441,9 +6586,9 @@ "yaml" ], "dependencies": { - "@aws-cdk/asset-awscli-v1": "^2.2.177", - "@aws-cdk/asset-kubectl-v20": "^2.1.1", - "@aws-cdk/asset-node-proxy-agent-v5": "^2.0.148", + "@aws-cdk/asset-awscli-v1": "^2.2.200", + "@aws-cdk/asset-kubectl-v20": "^2.1.2", + "@aws-cdk/asset-node-proxy-agent-v5": "^2.0.165", "@balena/dockerignore": "^1.0.2", "case": "1.6.3", "fs-extra": "^11.1.1", @@ -6451,7 +6596,7 @@ "jsonschema": "^1.4.1", "minimatch": "^3.1.2", "punycode": "^2.3.0", - "semver": "^7.5.1", + "semver": "^7.5.4", "table": "^6.8.1", "yaml": "1.10.2" }, @@ -6667,7 +6812,7 @@ } }, "node_modules/aws-cdk-lib/node_modules/semver": { - "version": "7.5.1", + "version": "7.5.4", "inBundle": true, "license": "ISC", "dependencies": { @@ -6768,7 +6913,6 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, "hasInstallScript": true, "optional": true, "os": [ @@ -7142,14 +7286,6 @@ "isarray": "^1.0.0" } }, - "node_modules/buffer-crc32": { - "version": "0.2.13", - "dev": true, - "license": "MIT", - "engines": { - "node": "*" - } - }, "node_modules/buffer-from": { "version": "1.1.2", "license": "MIT" @@ -7171,14 +7307,6 @@ "node": ">=10" } }, - "node_modules/bytes": { - "version": "3.1.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "node_modules/cacache": { "version": "17.1.3", "resolved": "https://registry.npmjs.org/cacache/-/cacache-17.1.3.tgz", @@ -7329,195 +7457,19 @@ ], "license": "CC-BY-4.0" }, - "node_modules/cdk-assets": { - "version": "2.72.1", + "node_modules/cdk-sample": { + "resolved": "examples/cdk", + "link": true + }, + "node_modules/centra": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/centra/-/centra-2.6.0.tgz", + "integrity": "sha512-dgh+YleemrT8u85QL11Z6tYhegAs3MMxsaWAq/oXeAmYJ7VxL3SI9TZtnfaEvNDMAPolj25FXIb3S+HCI4wQaQ==" + }, + "node_modules/chalk": { + "version": "4.1.2", "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@aws-cdk/cloud-assembly-schema": "2.72.1", - "@aws-cdk/cx-api": "2.72.1", - "archiver": "^5.3.1", - "aws-sdk": "^2.1329.0", - "glob": "^7.2.3", - "mime": "^2.6.0", - "yargs": "^16.2.0" - }, - "bin": { - "cdk-assets": "bin/cdk-assets", - "docker-credential-cdk-assets": "bin/docker-credential-cdk-assets" - }, - "engines": { - "node": ">= 14.15.0" - } - }, - "node_modules/cdk-assets/node_modules/@aws-cdk/cloud-assembly-schema": { - "version": "2.72.1", - "bundleDependencies": [ - "jsonschema", - "semver" - ], - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "jsonschema": "^1.4.1", - "semver": "^7.3.8" - }, - "engines": { - "node": ">= 14.15.0" - } - }, - "node_modules/cdk-assets/node_modules/@aws-cdk/cloud-assembly-schema/node_modules/jsonschema": { - "version": "1.4.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": "*" - } - }, - "node_modules/cdk-assets/node_modules/@aws-cdk/cloud-assembly-schema/node_modules/lru-cache": { - "version": "6.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/cdk-assets/node_modules/@aws-cdk/cloud-assembly-schema/node_modules/semver": { - "version": "7.3.8", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/cdk-assets/node_modules/@aws-cdk/cloud-assembly-schema/node_modules/yallist": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/cdk-assets/node_modules/@aws-cdk/cx-api": { - "version": "2.72.1", - "bundleDependencies": [ - "semver" - ], - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@aws-cdk/cloud-assembly-schema": "2.72.1", - "semver": "^7.3.8" - }, - "engines": { - "node": ">= 14.15.0" - }, - "peerDependencies": { - "@aws-cdk/cloud-assembly-schema": "2.72.1" - } - }, - "node_modules/cdk-assets/node_modules/@aws-cdk/cx-api/node_modules/lru-cache": { - "version": "6.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/cdk-assets/node_modules/@aws-cdk/cx-api/node_modules/semver": { - "version": "7.3.8", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/cdk-assets/node_modules/@aws-cdk/cx-api/node_modules/yallist": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/cdk-assets/node_modules/cliui": { - "version": "7.0.4", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/cdk-assets/node_modules/mime": { - "version": "2.6.0", - "dev": true, - "license": "MIT", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/cdk-assets/node_modules/yargs": { - "version": "16.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/cdk-assets/node_modules/yargs-parser": { - "version": "20.2.9", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/cdk-sample": { - "resolved": "examples/cdk", - "link": true - }, - "node_modules/centra": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/centra/-/centra-2.6.0.tgz", - "integrity": "sha512-dgh+YleemrT8u85QL11Z6tYhegAs3MMxsaWAq/oXeAmYJ7VxL3SI9TZtnfaEvNDMAPolj25FXIb3S+HCI4wQaQ==" - }, - "node_modules/chalk": { - "version": "4.1.2", - "dev": true, - "license": "MIT", + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -7542,14 +7494,6 @@ "dev": true, "license": "MIT" }, - "node_modules/charenc": { - "version": "0.0.2", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": "*" - } - }, "node_modules/chownr": { "version": "2.0.0", "dev": true, @@ -7888,20 +7832,6 @@ "node": ">=8" } }, - "node_modules/compress-commons": { - "version": "4.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer-crc32": "^0.2.13", - "crc32-stream": "^4.0.2", - "normalize-path": "^3.0.0", - "readable-stream": "^3.6.0" - }, - "engines": { - "node": ">= 10" - } - }, "node_modules/concat-map": { "version": "0.0.1", "dev": true, @@ -8143,29 +8073,6 @@ "node": ">=10" } }, - "node_modules/crc-32": { - "version": "1.2.2", - "dev": true, - "license": "Apache-2.0", - "bin": { - "crc32": "bin/crc32.njs" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/crc32-stream": { - "version": "4.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "crc-32": "^1.2.0", - "readable-stream": "^3.4.0" - }, - "engines": { - "node": ">= 10" - } - }, "node_modules/create-require": { "version": "1.1.1", "dev": true, @@ -8184,14 +8091,6 @@ "node": ">= 8" } }, - "node_modules/crypt": { - "version": "0.0.2", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": "*" - } - }, "node_modules/crypto-random-string": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", @@ -8222,14 +8121,6 @@ "node": ">=8" } }, - "node_modules/data-uri-to-buffer": { - "version": "3.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, "node_modules/dateformat": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", @@ -8341,20 +8232,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/degenerator": { - "version": "3.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "ast-types": "^0.13.2", - "escodegen": "^1.8.1", - "esprima": "^4.0.0", - "vm2": "^3.9.8" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/del": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/del/-/del-6.1.1.tgz", @@ -9095,120 +8972,53 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/escodegen": { - "version": "1.14.3", + "node_modules/eslint": { + "version": "8.30.0", "dev": true, - "license": "BSD-2-Clause", + "license": "MIT", "dependencies": { - "esprima": "^4.0.1", - "estraverse": "^4.2.0", + "@eslint/eslintrc": "^1.4.0", + "@humanwhocodes/config-array": "^0.11.8", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.1", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.4.0", + "esquery": "^1.4.0", "esutils": "^2.0.2", - "optionator": "^0.8.1" + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-sdsl": "^4.1.4", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0" }, "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" - }, - "engines": { - "node": ">=4.0" - }, - "optionalDependencies": { - "source-map": "~0.6.1" - } - }, - "node_modules/escodegen/node_modules/levn": { - "version": "0.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/escodegen/node_modules/optionator": { - "version": "0.8.3", - "dev": true, - "license": "MIT", - "dependencies": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/escodegen/node_modules/prelude-ls": { - "version": "1.1.2", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/escodegen/node_modules/type-check": { - "version": "0.3.2", - "dev": true, - "license": "MIT", - "dependencies": { - "prelude-ls": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/eslint": { - "version": "8.30.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint/eslintrc": "^1.4.0", - "@humanwhocodes/config-array": "^0.11.8", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.1", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.4.0", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "grapheme-splitter": "^1.0.4", - "ignore": "^5.2.0", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-sdsl": "^4.1.4", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "regexpp": "^3.2.0", - "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" + "eslint": "bin/eslint.js" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -9775,14 +9585,6 @@ "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/file-uri-to-path": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, "node_modules/file-url": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/file-url/-/file-url-3.0.0.tgz", @@ -9989,38 +9791,6 @@ "dev": true, "license": "ISC" }, - "node_modules/ftp": { - "version": "0.3.10", - "dev": true, - "dependencies": { - "readable-stream": "1.1.x", - "xregexp": "2.0.0" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/ftp/node_modules/isarray": { - "version": "0.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/ftp/node_modules/readable-stream": { - "version": "1.1.14", - "dev": true, - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "node_modules/ftp/node_modules/string_decoder": { - "version": "0.10.31", - "dev": true, - "license": "MIT" - }, "node_modules/function-bind": { "version": "1.1.1", "dev": true, @@ -10264,51 +10034,6 @@ "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" } }, - "node_modules/get-uri": { - "version": "3.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "@tootallnate/once": "1", - "data-uri-to-buffer": "3", - "debug": "4", - "file-uri-to-path": "2", - "fs-extra": "^8.1.0", - "ftp": "^0.3.10" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/get-uri/node_modules/fs-extra": { - "version": "8.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/get-uri/node_modules/jsonfile": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/get-uri/node_modules/universalify": { - "version": "0.1.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4.0.0" - } - }, "node_modules/git-raw-commits": { "version": "2.0.11", "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-2.0.11.tgz", @@ -10630,34 +10355,6 @@ "dev": true, "license": "BSD-2-Clause" }, - "node_modules/http-errors": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/http-proxy-agent": { - "version": "4.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@tootallnate/once": "1", - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/https-proxy-agent": { "version": "5.0.1", "dev": true, @@ -10931,11 +10628,6 @@ "node": ">= 0.4" } }, - "node_modules/ip": { - "version": "1.1.8", - "dev": true, - "license": "MIT" - }, "node_modules/is-arguments": { "version": "1.1.1", "dev": true, @@ -10982,11 +10674,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-buffer": { - "version": "1.1.6", - "dev": true, - "license": "MIT" - }, "node_modules/is-callable": { "version": "1.2.7", "dev": true, @@ -12065,11 +11752,6 @@ "dev": true, "license": "MIT" }, - "node_modules/json-schema-traverse": { - "version": "1.0.0", - "dev": true, - "license": "MIT" - }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "dev": true, @@ -12179,44 +11861,6 @@ "resolved": "layers", "link": true }, - "node_modules/lazystream": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "readable-stream": "^2.0.5" - }, - "engines": { - "node": ">= 0.6.3" - } - }, - "node_modules/lazystream/node_modules/readable-stream": { - "version": "2.3.7", - "dev": true, - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/lazystream/node_modules/safe-buffer": { - "version": "5.1.2", - "dev": true, - "license": "MIT" - }, - "node_modules/lazystream/node_modules/string_decoder": { - "version": "1.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, "node_modules/lerna": { "version": "6.6.2", "resolved": "https://registry.npmjs.org/lerna/-/lerna-6.6.2.tgz", @@ -12900,21 +12544,6 @@ "dev": true, "license": "MIT" }, - "node_modules/lodash.defaults": { - "version": "4.2.0", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.difference": { - "version": "4.5.0", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.flatten": { - "version": "4.4.0", - "dev": true, - "license": "MIT" - }, "node_modules/lodash.get": { "version": "4.4.2", "dev": true, @@ -12926,11 +12555,6 @@ "integrity": "sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g==", "dev": true }, - "node_modules/lodash.isplainobject": { - "version": "4.0.6", - "dev": true, - "license": "MIT" - }, "node_modules/lodash.memoize": { "version": "4.1.2", "dev": true, @@ -12940,16 +12564,6 @@ "version": "4.6.2", "license": "MIT" }, - "node_modules/lodash.truncate": { - "version": "4.4.2", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.union": { - "version": "4.6.0", - "dev": true, - "license": "MIT" - }, "node_modules/log-symbols": { "version": "4.1.0", "dev": true, @@ -13306,16 +12920,6 @@ "node": ">= 12" } }, - "node_modules/md5": { - "version": "2.3.0", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "charenc": "0.0.2", - "crypt": "0.0.2", - "is-buffer": "~1.1.6" - } - }, "node_modules/meow": { "version": "8.1.2", "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", @@ -13885,14 +13489,6 @@ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", "dev": true }, - "node_modules/netmask": { - "version": "2.0.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4.0" - } - }, "node_modules/nise": { "version": "5.1.4", "dev": true, @@ -15030,42 +14626,10 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/pac-proxy-agent": { - "version": "5.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@tootallnate/once": "1", - "agent-base": "6", - "debug": "4", - "get-uri": "3", - "http-proxy-agent": "^4.0.1", - "https-proxy-agent": "5", - "pac-resolver": "^5.0.0", - "raw-body": "^2.2.0", - "socks-proxy-agent": "5" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/pac-resolver": { - "version": "5.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "degenerator": "^3.0.2", - "ip": "^1.1.5", - "netmask": "^2.0.2" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/pacote": { - "version": "15.1.1", - "resolved": "https://registry.npmjs.org/pacote/-/pacote-15.1.1.tgz", - "integrity": "sha512-eeqEe77QrA6auZxNHIp+1TzHQ0HBKf5V6c8zcaYZ134EJe1lCi+fjXATkNiEEfbG+e50nu02GLvUtmZcGOYabQ==", + "node_modules/pacote": { + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-15.1.1.tgz", + "integrity": "sha512-eeqEe77QrA6auZxNHIp+1TzHQ0HBKf5V6c8zcaYZ134EJe1lCi+fjXATkNiEEfbG+e50nu02GLvUtmZcGOYabQ==", "dev": true, "dependencies": { "@npmcli/git": "^4.0.0", @@ -15676,14 +15240,6 @@ "node": ">=10" } }, - "node_modules/promptly": { - "version": "3.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "read": "^1.0.4" - } - }, "node_modules/prompts": { "version": "2.4.2", "dev": true, @@ -15717,37 +15273,6 @@ "integrity": "sha512-/XJ368cyBJ7fzLMwLKv1e4vLxOju2MNAIokcr7meSaNcVbWz/CPcW22cP04mwxOErdA5mwjA8Q6w/cdAQxVn7Q==", "dev": true }, - "node_modules/proxy-agent": { - "version": "5.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "^6.0.0", - "debug": "4", - "http-proxy-agent": "^4.0.0", - "https-proxy-agent": "^5.0.0", - "lru-cache": "^5.1.1", - "pac-proxy-agent": "^5.0.0", - "proxy-from-env": "^1.0.0", - "socks-proxy-agent": "^5.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/proxy-agent/node_modules/lru-cache": { - "version": "5.1.1", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/proxy-agent/node_modules/yallist": { - "version": "3.1.1", - "dev": true, - "license": "ISC" - }, "node_modules/proxy-from-env": { "version": "1.1.0", "dev": true, @@ -15805,20 +15330,6 @@ "node": ">=8" } }, - "node_modules/raw-body": { - "version": "2.5.1", - "dev": true, - "license": "MIT", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/react-is": { "version": "18.2.0", "dev": true, @@ -16146,33 +15657,6 @@ "node": ">= 6" } }, - "node_modules/readdir-glob": { - "version": "1.1.2", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "minimatch": "^5.1.0" - } - }, - "node_modules/readdir-glob/node_modules/brace-expansion": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/readdir-glob/node_modules/minimatch": { - "version": "5.1.2", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/redent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", @@ -16221,14 +15705,6 @@ "node": ">=0.10.0" } }, - "node_modules/require-from-string": { - "version": "2.0.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/resolve": { "version": "1.22.1", "dev": true, @@ -16495,11 +15971,6 @@ "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", "dev": true }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "dev": true, - "license": "ISC" - }, "node_modules/shallow-clone": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", @@ -16760,19 +16231,6 @@ "npm": ">= 3.0.0" } }, - "node_modules/socks-proxy-agent": { - "version": "5.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "^6.0.2", - "debug": "4", - "socks": "^2.3.3" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/socks/node_modules/ip": { "version": "2.0.0", "dev": true, @@ -16909,14 +16367,6 @@ "node": ">=8" } }, - "node_modules/statuses": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "node_modules/string_decoder": { "version": "1.3.0", "dev": true, @@ -17121,21 +16571,6 @@ "url": "https://opencollective.com/unts" } }, - "node_modules/table": { - "version": "6.8.1", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "ajv": "^8.0.1", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=10.0.0" - } - }, "node_modules/tapable": { "version": "2.2.1", "dev": true, @@ -17347,14 +16782,6 @@ "node": ">=8.0" } }, - "node_modules/toidentifier": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.6" - } - }, "node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", @@ -17826,14 +17253,6 @@ "node": ">= 10.0.0" } }, - "node_modules/unpipe": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "node_modules/upath": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/upath/-/upath-2.0.1.tgz", @@ -17910,8 +17329,9 @@ }, "node_modules/uuid": { "version": "9.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", + "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", "dev": true, - "license": "MIT", "bin": { "uuid": "dist/bin/uuid" } @@ -17966,22 +17386,6 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, - "node_modules/vm2": { - "version": "3.9.18", - "resolved": "https://registry.npmjs.org/vm2/-/vm2-3.9.18.tgz", - "integrity": "sha512-iM7PchOElv6Uv6Q+0Hq7dcgDtWWT6SizYqVcvol+1WQc+E9HlgTCnPozbQNSP3yDV9oXHQOEQu530w2q/BCVZg==", - "dev": true, - "dependencies": { - "acorn": "^8.7.0", - "acorn-walk": "^8.2.0" - }, - "bin": { - "vm2": "bin/vm2" - }, - "engines": { - "node": ">=6.0" - } - }, "node_modules/vscode-oniguruma": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz", @@ -18257,11 +17661,6 @@ "node": ">=4.0" } }, - "node_modules/xregexp": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, "node_modules/xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", @@ -18345,19 +17744,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/zip-stream": { - "version": "4.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "archiver-utils": "^2.1.0", - "compress-commons": "^4.1.0", - "readable-stream": "^3.6.0" - }, - "engines": { - "node": ">= 10" - } - }, "packages/batch": { "name": "@aws-lambda-powertools/batch", "version": "1.12.1", @@ -18387,6 +17773,7 @@ "jmespath": "^0.16.0" }, "devDependencies": { + "@aws-lambda-powertools/testing-utils": "file:../testing", "@aws-sdk/client-dynamodb": "^3.360.0", "@types/jmespath": "^0.15.0", "aws-sdk-client-mock": "^2.2.0", @@ -18605,6 +17992,7 @@ "lodash.merge": "^4.6.2" }, "devDependencies": { + "@aws-lambda-powertools/testing-utils": "file:../testing", "@types/lodash.merge": "^4.6.7" } }, @@ -18616,6 +18004,7 @@ "@aws-lambda-powertools/commons": "^1.12.1" }, "devDependencies": { + "@aws-lambda-powertools/testing-utils": "file:../testing", "@aws-sdk/client-cloudwatch": "^3.360.0", "@types/promise-retry": "^1.1.3", "promise-retry": "^2.0.1" @@ -18842,6 +18231,382 @@ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, + "packages/testing": { + "name": "@aws-lambda-powertools/testing-utils", + "version": "1.12.1", + "license": "MIT-0", + "dependencies": { + "@aws-cdk/cli-lib-alpha": "^2.88.0-alpha.0", + "aws-cdk-lib": "^2.88.0", + "esbuild": "^0.18.17" + } + }, + "packages/testing/node_modules/@esbuild/android-arm": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.17.tgz", + "integrity": "sha512-wHsmJG/dnL3OkpAcwbgoBTTMHVi4Uyou3F5mf58ZtmUyIKfcdA7TROav/6tCzET4A3QW2Q2FC+eFneMU+iyOxg==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "packages/testing/node_modules/@esbuild/android-arm64": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.17.tgz", + "integrity": "sha512-9np+YYdNDed5+Jgr1TdWBsozZ85U1Oa3xW0c7TWqH0y2aGghXtZsuT8nYRbzOMcl0bXZXjOGbksoTtVOlWrRZg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "packages/testing/node_modules/@esbuild/android-x64": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.17.tgz", + "integrity": "sha512-O+FeWB/+xya0aLg23hHEM2E3hbfwZzjqumKMSIqcHbNvDa+dza2D0yLuymRBQQnC34CWrsJUXyH2MG5VnLd6uw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "packages/testing/node_modules/@esbuild/darwin-arm64": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.17.tgz", + "integrity": "sha512-M9uJ9VSB1oli2BE/dJs3zVr9kcCBBsE883prage1NWz6pBS++1oNn/7soPNS3+1DGj0FrkSvnED4Bmlu1VAE9g==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "packages/testing/node_modules/@esbuild/darwin-x64": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.17.tgz", + "integrity": "sha512-XDre+J5YeIJDMfp3n0279DFNrGCXlxOuGsWIkRb1NThMZ0BsrWXoTg23Jer7fEXQ9Ye5QjrvXpxnhzl3bHtk0g==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "packages/testing/node_modules/@esbuild/freebsd-arm64": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.17.tgz", + "integrity": "sha512-cjTzGa3QlNfERa0+ptykyxs5A6FEUQQF0MuilYXYBGdBxD3vxJcKnzDlhDCa1VAJCmAxed6mYhA2KaJIbtiNuQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "packages/testing/node_modules/@esbuild/freebsd-x64": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.17.tgz", + "integrity": "sha512-sOxEvR8d7V7Kw8QqzxWc7bFfnWnGdaFBut1dRUYtu+EIRXefBc/eIsiUiShnW0hM3FmQ5Zf27suDuHsKgZ5QrA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "packages/testing/node_modules/@esbuild/linux-arm": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.17.tgz", + "integrity": "sha512-2d3Lw6wkwgSLC2fIvXKoMNGVaeY8qdN0IC3rfuVxJp89CRfA3e3VqWifGDfuakPmp90+ZirmTfye1n4ncjv2lg==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "packages/testing/node_modules/@esbuild/linux-arm64": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.17.tgz", + "integrity": "sha512-c9w3tE7qA3CYWjT+M3BMbwMt+0JYOp3vCMKgVBrCl1nwjAlOMYzEo+gG7QaZ9AtqZFj5MbUc885wuBBmu6aADQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "packages/testing/node_modules/@esbuild/linux-ia32": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.17.tgz", + "integrity": "sha512-1DS9F966pn5pPnqXYz16dQqWIB0dmDfAQZd6jSSpiT9eX1NzKh07J6VKR3AoXXXEk6CqZMojiVDSZi1SlmKVdg==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "packages/testing/node_modules/@esbuild/linux-loong64": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.17.tgz", + "integrity": "sha512-EvLsxCk6ZF0fpCB6w6eOI2Fc8KW5N6sHlIovNe8uOFObL2O+Mr0bflPHyHwLT6rwMg9r77WOAWb2FqCQrVnwFg==", + "cpu": [ + "loong64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "packages/testing/node_modules/@esbuild/linux-mips64el": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.17.tgz", + "integrity": "sha512-e0bIdHA5p6l+lwqTE36NAW5hHtw2tNRmHlGBygZC14QObsA3bD4C6sXLJjvnDIjSKhW1/0S3eDy+QmX/uZWEYQ==", + "cpu": [ + "mips64el" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "packages/testing/node_modules/@esbuild/linux-ppc64": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.17.tgz", + "integrity": "sha512-BAAilJ0M5O2uMxHYGjFKn4nJKF6fNCdP1E0o5t5fvMYYzeIqy2JdAP88Az5LHt9qBoUa4tDaRpfWt21ep5/WqQ==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "packages/testing/node_modules/@esbuild/linux-riscv64": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.17.tgz", + "integrity": "sha512-Wh/HW2MPnC3b8BqRSIme/9Zhab36PPH+3zam5pqGRH4pE+4xTrVLx2+XdGp6fVS3L2x+DrsIcsbMleex8fbE6g==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "packages/testing/node_modules/@esbuild/linux-s390x": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.17.tgz", + "integrity": "sha512-j/34jAl3ul3PNcK3pfI0NSlBANduT2UO5kZ7FCaK33XFv3chDhICLY8wJJWIhiQ+YNdQ9dxqQctRg2bvrMlYgg==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "packages/testing/node_modules/@esbuild/linux-x64": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.17.tgz", + "integrity": "sha512-QM50vJ/y+8I60qEmFxMoxIx4de03pGo2HwxdBeFd4nMh364X6TIBZ6VQ5UQmPbQWUVWHWws5MmJXlHAXvJEmpQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "packages/testing/node_modules/@esbuild/netbsd-x64": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.17.tgz", + "integrity": "sha512-/jGlhWR7Sj9JPZHzXyyMZ1RFMkNPjC6QIAan0sDOtIo2TYk3tZn5UDrkE0XgsTQCxWTTOcMPf9p6Rh2hXtl5TQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "packages/testing/node_modules/@esbuild/openbsd-x64": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.17.tgz", + "integrity": "sha512-rSEeYaGgyGGf4qZM2NonMhMOP/5EHp4u9ehFiBrg7stH6BYEEjlkVREuDEcQ0LfIl53OXLxNbfuIj7mr5m29TA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "packages/testing/node_modules/@esbuild/sunos-x64": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.17.tgz", + "integrity": "sha512-Y7ZBbkLqlSgn4+zot4KUNYst0bFoO68tRgI6mY2FIM+b7ZbyNVtNbDP5y8qlu4/knZZ73fgJDlXID+ohY5zt5g==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "packages/testing/node_modules/@esbuild/win32-arm64": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.17.tgz", + "integrity": "sha512-bwPmTJsEQcbZk26oYpc4c/8PvTY3J5/QK8jM19DVlEsAB41M39aWovWoHtNm78sd6ip6prilxeHosPADXtEJFw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "packages/testing/node_modules/@esbuild/win32-ia32": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.17.tgz", + "integrity": "sha512-H/XaPtPKli2MhW+3CQueo6Ni3Avggi6hP/YvgkEe1aSaxw+AeO8MFjq8DlgfTd9Iz4Yih3QCZI6YLMoyccnPRg==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "packages/testing/node_modules/@esbuild/win32-x64": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.17.tgz", + "integrity": "sha512-fGEb8f2BSA3CW7riJVurug65ACLuQAzKq0SSqkY2b2yHHH0MzDfbLyKIGzHwOI/gkHcxM/leuSW6D5w/LMNitA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "packages/testing/node_modules/esbuild": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.17.tgz", + "integrity": "sha512-1GJtYnUxsJreHYA0Y+iQz2UEykonY66HNWOb0yXYZi9/kNrORUEHVg87eQsCtqh59PEJ5YVZJO98JHznMJSWjg==", + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.18.17", + "@esbuild/android-arm64": "0.18.17", + "@esbuild/android-x64": "0.18.17", + "@esbuild/darwin-arm64": "0.18.17", + "@esbuild/darwin-x64": "0.18.17", + "@esbuild/freebsd-arm64": "0.18.17", + "@esbuild/freebsd-x64": "0.18.17", + "@esbuild/linux-arm": "0.18.17", + "@esbuild/linux-arm64": "0.18.17", + "@esbuild/linux-ia32": "0.18.17", + "@esbuild/linux-loong64": "0.18.17", + "@esbuild/linux-mips64el": "0.18.17", + "@esbuild/linux-ppc64": "0.18.17", + "@esbuild/linux-riscv64": "0.18.17", + "@esbuild/linux-s390x": "0.18.17", + "@esbuild/linux-x64": "0.18.17", + "@esbuild/netbsd-x64": "0.18.17", + "@esbuild/openbsd-x64": "0.18.17", + "@esbuild/sunos-x64": "0.18.17", + "@esbuild/win32-arm64": "0.18.17", + "@esbuild/win32-ia32": "0.18.17", + "@esbuild/win32-x64": "0.18.17" + } + }, "packages/tracer": { "name": "@aws-lambda-powertools/tracer", "version": "1.12.1", @@ -18851,6 +18616,7 @@ "aws-xray-sdk-core": "^3.4.1" }, "devDependencies": { + "@aws-lambda-powertools/testing-utils": "file:../testing", "@aws-sdk/client-dynamodb": "^3.360.0", "@aws-sdk/client-sts": "^3.360.0", "@aws-sdk/client-xray": "^3.360.0", diff --git a/package.json b/package.json index 73bd6845da..b9186a7128 100644 --- a/package.json +++ b/package.json @@ -9,11 +9,12 @@ "packages/tracer", "packages/parameters", "packages/idempotency", + "packages/batch", + "packages/testing", "docs/snippets", "layers", "examples/cdk", - "examples/sam", - "packages/batch" + "examples/sam" ], "scripts": { "init-environment": "husky install", @@ -45,21 +46,13 @@ }, "homepage": "https://github.com/aws-powertools/powertools-lambda-typescript#readme", "devDependencies": { - "@aws-cdk/cloudformation-diff": "^2.73.0", - "@aws-cdk/cx-api": "^2.73.0", "@middy/core": "^3.6.2", "@types/aws-lambda": "^8.10.109", "@types/jest": "^29.2.4", "@types/node": "^18.16.18", - "@types/uuid": "^9.0.0", + "@types/uuid": "^9.0.2", "@typescript-eslint/eslint-plugin": "^5.46.1", "@typescript-eslint/parser": "^5.46.1", - "archiver": "^5.3.1", - "aws-cdk": "^2.73.0", - "aws-cdk-lib": "^2.73.0", - "cdk-assets": "^2.72.1", - "constructs": "^10.1.190", - "esbuild": "^0.16.7", "eslint": "^8.29.0", "eslint-config-prettier": "^8.8.0", "eslint-import-resolver-node": "^0.3.6", @@ -72,8 +65,6 @@ "lerna": "^6.6.2", "lint-staged": "^13.1.2", "prettier": "^2.8.8", - "promptly": "^3.2.0", - "proxy-agent": "^5.0.0", "rimraf": "^5.0.1", "ts-jest": "^29.0.3", "ts-node": "^10.9.1", diff --git a/packages/commons/tests/utils/cdk-cli.ts b/packages/commons/tests/utils/cdk-cli.ts deleted file mode 100644 index 65c78fa14c..0000000000 --- a/packages/commons/tests/utils/cdk-cli.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { App, Stack } from 'aws-cdk-lib'; -import * as cxapi from '@aws-cdk/cx-api'; -import { CloudFormationDeployments } from 'aws-cdk/lib/api/cloudformation-deployments'; -import { SdkProvider } from 'aws-cdk/lib/api/aws-auth'; -import { DeployStackResult } from 'aws-cdk/lib/api/deploy-stack'; - -export const deployStack = async ( - app: App, - stack: Stack, - quiet?: boolean -): Promise => { - const stackArtifact = getStackArtifact(app, stack); - - const cloudFormation = await createCloudFormationDeployments(); - - return cloudFormation.deployStack({ - stack: stackArtifact, - quiet: quiet ? quiet : true, - }); -}; - -export const destroyStack = async ( - app: App, - stack: Stack, - quiet?: boolean -): Promise => { - const stackArtifact = getStackArtifact(app, stack); - - const cloudFormation = await createCloudFormationDeployments(); - - await cloudFormation.destroyStack({ - stack: stackArtifact, - quiet: quiet ? quiet : true, - }); -}; - -const getStackArtifact = ( - app: App, - stack: Stack -): cxapi.CloudFormationStackArtifact => { - const synthesized = app.synth(); - - // Reload the synthesized artifact for stack using the cxapi from dependencies - const assembly = new cxapi.CloudAssembly(synthesized.directory); - - return cxapi.CloudFormationStackArtifact.fromManifest( - assembly, - stack.artifactId, - synthesized.getStackArtifact(stack.artifactId).manifest - ) as cxapi.CloudFormationStackArtifact; -}; - -const createCloudFormationDeployments = - async (): Promise => { - const sdkProvider = await SdkProvider.withAwsCliCompatibleDefaults({ - profile: process.env.AWS_PROFILE, - }); - const cloudFormation = new CloudFormationDeployments({ sdkProvider }); - - return cloudFormation; - }; diff --git a/packages/commons/tests/utils/e2eUtils.ts b/packages/commons/tests/utils/e2eUtils.ts index d8f32ad607..2bf5fdbdc1 100644 --- a/packages/commons/tests/utils/e2eUtils.ts +++ b/packages/commons/tests/utils/e2eUtils.ts @@ -2,7 +2,7 @@ * E2E utils is used by e2e tests. They are helper function that calls either CDK or SDK * to interact with services. */ -import { App, CfnOutput, Duration, Stack } from 'aws-cdk-lib'; +import { CfnOutput, Duration, Stack } from 'aws-cdk-lib'; import { NodejsFunction, NodejsFunctionProps, @@ -25,8 +25,7 @@ export const TEST_RUNTIMES: Record = { }; export type StackWithLambdaFunctionOptions = { - app: App; - stackName: string; + stack: Stack; functionName: string; functionEntry: string; tracing?: Tracing; @@ -48,9 +47,8 @@ export const isValidRuntimeKey = ( export const createStackWithLambdaFunction = ( params: StackWithLambdaFunctionOptions -): Stack => { - const stack = new Stack(params.app, params.stackName); - const testFunction = new NodejsFunction(stack, `testFunction`, { +): void => { + const testFunction = new NodejsFunction(params.stack, `testFunction`, { functionName: params.functionName, entry: params.functionEntry, tracing: params.tracing, @@ -63,12 +61,10 @@ export const createStackWithLambdaFunction = ( }); if (params.logGroupOutputKey) { - new CfnOutput(stack, params.logGroupOutputKey, { + new CfnOutput(params.stack, params.logGroupOutputKey, { value: testFunction.logGroup.logGroupName, }); } - - return stack; }; export const generateUniqueName = ( diff --git a/packages/idempotency/package.json b/packages/idempotency/package.json index 3c177ef177..5ed19121b3 100644 --- a/packages/idempotency/package.json +++ b/packages/idempotency/package.json @@ -94,6 +94,7 @@ "nodejs" ], "devDependencies": { + "@aws-lambda-powertools/testing-utils": "file:../testing", "@aws-sdk/client-dynamodb": "^3.360.0", "@types/jmespath": "^0.15.0", "aws-sdk-client-mock": "^2.2.0", diff --git a/packages/idempotency/tests/e2e/makeHandlerIdempotent.test.ts b/packages/idempotency/tests/e2e/makeHandlerIdempotent.test.ts index f5bef822db..5d4ccd82c7 100644 --- a/packages/idempotency/tests/e2e/makeHandlerIdempotent.test.ts +++ b/packages/idempotency/tests/e2e/makeHandlerIdempotent.test.ts @@ -16,17 +16,16 @@ import { TEST_CASE_TIMEOUT, } from './constants'; import { - deployStack, - destroyStack, -} from '../../../commons/tests/utils/cdk-cli'; + TestStack, + defaultRuntime, +} from '@aws-lambda-powertools/testing-utils'; import { v4 } from 'uuid'; -import { App, Stack } from 'aws-cdk-lib'; import { DynamoDBClient } from '@aws-sdk/client-dynamodb'; import { createHash } from 'node:crypto'; import { ScanCommand } from '@aws-sdk/lib-dynamodb'; import { createIdempotencyResources } from '../helpers/idempotencyUtils'; -const runtime: string = process.env.RUNTIME || 'nodejs18x'; +const runtime: string = process.env.RUNTIME || defaultRuntime; if (!isValidRuntimeKey(runtime)) { throw new Error(`Invalid runtime key value: ${runtime}`); @@ -41,10 +40,8 @@ const stackName = generateUniqueName( ); const makeHandlerIdempotentFile = 'makeHandlerIdempotent.test.FunctionCode.ts'; -const app = new App(); - const ddb = new DynamoDBClient({}); -const stack = new Stack(app, stackName); +const testStack = new TestStack(stackName); const testDefault = 'default-sequential'; const functionNameDefault = generateUniqueName( @@ -60,7 +57,7 @@ const ddbTableNameDefault = generateUniqueName( `${testDefault}-table` ); createIdempotencyResources( - stack, + testStack.stack, runtime, ddbTableNameDefault, makeHandlerIdempotentFile, @@ -82,7 +79,7 @@ const ddbTableNameDefaultParallel = generateUniqueName( `${testDefaultParallel}-table` ); createIdempotencyResources( - stack, + testStack.stack, runtime, ddbTableNameDefaultParallel, makeHandlerIdempotentFile, @@ -104,7 +101,7 @@ const ddbTableNameTimeout = generateUniqueName( `${testTimeout}-table` ); createIdempotencyResources( - stack, + testStack.stack, runtime, ddbTableNameTimeout, makeHandlerIdempotentFile, @@ -128,7 +125,7 @@ const ddbTableNameExpired = generateUniqueName( `${testExpired}-table` ); createIdempotencyResources( - stack, + testStack.stack, runtime, ddbTableNameExpired, makeHandlerIdempotentFile, @@ -140,7 +137,7 @@ createIdempotencyResources( describe(`Idempotency E2E tests, middy middleware usage for runtime ${runtime}`, () => { beforeAll(async () => { - await deployStack(app, stack); + await testStack.deploy(); }, SETUP_TIMEOUT); test( @@ -385,6 +382,6 @@ describe(`Idempotency E2E tests, middy middleware usage for runtime ${runtime}`, ); afterAll(async () => { - await destroyStack(app, stack); + await testStack.destroy(); }, TEARDOWN_TIMEOUT); }); diff --git a/packages/idempotency/tests/e2e/makeIdempotent.test.ts b/packages/idempotency/tests/e2e/makeIdempotent.test.ts index 1906a8a16d..3feaefb3f1 100644 --- a/packages/idempotency/tests/e2e/makeIdempotent.test.ts +++ b/packages/idempotency/tests/e2e/makeIdempotent.test.ts @@ -15,18 +15,17 @@ import { TEST_CASE_TIMEOUT, } from './constants'; import { v4 } from 'uuid'; -import { App, Stack } from 'aws-cdk-lib'; import { DynamoDBClient } from '@aws-sdk/client-dynamodb'; import { createHash } from 'node:crypto'; import { - deployStack, - destroyStack, -} from '../../../commons/tests/utils/cdk-cli'; + TestStack, + defaultRuntime, +} from '@aws-lambda-powertools/testing-utils'; import { ScanCommand } from '@aws-sdk/lib-dynamodb'; import { createIdempotencyResources } from '../helpers/idempotencyUtils'; import { InvocationLogs } from '@aws-lambda-powertools/commons/tests/utils/InvocationLogs'; -const runtime: string = process.env.RUNTIME || 'nodejs18x'; +const runtime: string = process.env.RUNTIME || defaultRuntime; if (!isValidRuntimeKey(runtime)) { throw new Error(`Invalid runtime key value: ${runtime}`); @@ -40,10 +39,8 @@ const stackName = generateUniqueName( ); const makeFunctionIdempotentFile = 'makeIdempotent.test.FunctionCode.ts'; -const app = new App(); - const ddb = new DynamoDBClient({ region: 'eu-west-1' }); -const stack = new Stack(app, stackName); +const testStack = new TestStack(stackName); const testDefault = 'default'; const functionNameDefault = generateUniqueName( @@ -59,7 +56,7 @@ const ddbTableNameDefault = generateUniqueName( `${testDefault}-table` ); createIdempotencyResources( - stack, + testStack.stack, runtime, ddbTableNameDefault, makeFunctionIdempotentFile, @@ -81,7 +78,7 @@ const ddbTableNameCustomConfig = generateUniqueName( `${testCustomConfig}-fn` ); createIdempotencyResources( - stack, + testStack.stack, runtime, ddbTableNameCustomConfig, makeFunctionIdempotentFile, @@ -104,7 +101,7 @@ const ddbTableNameLambdaHandler = generateUniqueName( `${testLambdaHandler}-table` ); createIdempotencyResources( - stack, + testStack.stack, runtime, ddbTableNameLambdaHandler, makeFunctionIdempotentFile, @@ -114,7 +111,7 @@ createIdempotencyResources( describe(`Idempotency E2E tests, wrapper function usage for runtime`, () => { beforeAll(async () => { - await deployStack(app, stack); + await testStack.deploy(); }, SETUP_TIMEOUT); it( @@ -330,7 +327,7 @@ describe(`Idempotency E2E tests, wrapper function usage for runtime`, () => { afterAll(async () => { if (!process.env.DISABLE_TEARDOWN) { - await destroyStack(app, stack); + await testStack.destroy(); } }, TEARDOWN_TIMEOUT); }); diff --git a/packages/logger/package.json b/packages/logger/package.json index 013530368b..321648326c 100644 --- a/packages/logger/package.json +++ b/packages/logger/package.json @@ -32,6 +32,7 @@ "main": "./lib/index.js", "types": "./lib/index.d.ts", "devDependencies": { + "@aws-lambda-powertools/testing-utils": "file:../testing", "@types/lodash.merge": "^4.6.7" }, "files": [ diff --git a/packages/logger/tests/e2e/basicFeatures.middy.test.ts b/packages/logger/tests/e2e/basicFeatures.middy.test.ts index 7f16412182..971050b5db 100644 --- a/packages/logger/tests/e2e/basicFeatures.middy.test.ts +++ b/packages/logger/tests/e2e/basicFeatures.middy.test.ts @@ -4,7 +4,6 @@ * @group e2e/logger/basicFeatures */ import path from 'path'; -import { App, Stack } from 'aws-cdk-lib'; import { APIGatewayAuthorizerResult } from 'aws-lambda'; import { v4 } from 'uuid'; import { @@ -15,9 +14,9 @@ import { } from '../../../commons/tests/utils/e2eUtils'; import { InvocationLogs } from '../../../commons/tests/utils/InvocationLogs'; import { - deployStack, - destroyStack, -} from '../../../commons/tests/utils/cdk-cli'; + TestStack, + defaultRuntime, +} from '@aws-lambda-powertools/testing-utils'; import { RESOURCE_NAME_PREFIX, SETUP_TIMEOUT, @@ -27,7 +26,7 @@ import { XRAY_TRACE_ID_REGEX, } from './constants'; -const runtime: string = process.env.RUNTIME || 'nodejs18x'; +const runtime: string = process.env.RUNTIME || defaultRuntime; if (!isValidRuntimeKey(runtime)) { throw new Error(`Invalid runtime key value: ${runtime}`); @@ -64,18 +63,16 @@ const ERROR_MSG = 'error'; const ARBITRARY_OBJECT_KEY = 'arbitraryObjectKey'; const ARBITRARY_OBJECT_DATA = 'arbitraryObjectData'; -const integTestApp = new App(); +const testStack = new TestStack(stackName); let logGroupName: string; // We do not know it until deployment -let stack: Stack; 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, - stackName: stackName, + createStackWithLambdaFunction({ + stack: testStack.stack, functionName: functionName, functionEntry: path.join(__dirname, lambdaFunctionCodeFile), environment: { @@ -99,8 +96,8 @@ describe(`logger E2E tests basic functionalities (middy) for runtime: ${runtime} runtime: runtime, }); - const result = await deployStack(integTestApp, stack); - logGroupName = result.outputs[STACK_OUTPUT_LOG_GROUP]; + const result = await testStack.deploy(); + logGroupName = result[STACK_OUTPUT_LOG_GROUP]; // Invoke the function three time (one for cold start, then two for warm start) invocationLogs = await invokeFunction( @@ -378,7 +375,7 @@ describe(`logger E2E tests basic functionalities (middy) for runtime: ${runtime} afterAll(async () => { if (!process.env.DISABLE_TEARDOWN) { - await destroyStack(integTestApp, stack); + await testStack.destroy(); } }, TEARDOWN_TIMEOUT); }); diff --git a/packages/logger/tests/e2e/childLogger.manual.test.ts b/packages/logger/tests/e2e/childLogger.manual.test.ts index 642d2292df..b3ec427f77 100644 --- a/packages/logger/tests/e2e/childLogger.manual.test.ts +++ b/packages/logger/tests/e2e/childLogger.manual.test.ts @@ -4,7 +4,6 @@ * @group e2e/logger/childLogger */ import path from 'path'; -import { App, Stack } from 'aws-cdk-lib'; import { v4 } from 'uuid'; import { createStackWithLambdaFunction, @@ -14,9 +13,9 @@ import { } from '../../../commons/tests/utils/e2eUtils'; import { InvocationLogs } from '../../../commons/tests/utils/InvocationLogs'; import { - deployStack, - destroyStack, -} from '../../../commons/tests/utils/cdk-cli'; + TestStack, + defaultRuntime, +} from '@aws-lambda-powertools/testing-utils'; import { RESOURCE_NAME_PREFIX, STACK_OUTPUT_LOG_GROUP, @@ -25,7 +24,7 @@ import { TEARDOWN_TIMEOUT, } from './constants'; -const runtime: string = process.env.RUNTIME || 'nodejs18x'; +const runtime: string = process.env.RUNTIME || defaultRuntime; if (!isValidRuntimeKey(runtime)) { throw new Error(`Invalid runtime key value: ${runtime}`); @@ -57,18 +56,16 @@ const PARENT_LOG_MSG = 'parent-only-log-msg'; const CHILD_LOG_MSG = 'child-only-log-msg'; const CHILD_LOG_LEVEL = LEVEL.ERROR; -const integTestApp = new App(); +const testStack = new TestStack(stackName); let logGroupName: string; // We do not know it until deployment -let stack: Stack; describe(`logger E2E tests child logger functionalities (manual) for runtime: ${runtime}`, () => { let invocationLogs: InvocationLogs[]; beforeAll(async () => { // Create and deploy a stack with AWS CDK - stack = createStackWithLambdaFunction({ - app: integTestApp, - stackName: stackName, + createStackWithLambdaFunction({ + stack: testStack.stack, functionName: functionName, functionEntry: path.join(__dirname, lambdaFunctionCodeFile), environment: { @@ -86,8 +83,9 @@ describe(`logger E2E tests child logger functionalities (manual) for runtime: ${ logGroupOutputKey: STACK_OUTPUT_LOG_GROUP, runtime: runtime, }); - const result = await deployStack(integTestApp, stack); - logGroupName = result.outputs[STACK_OUTPUT_LOG_GROUP]; + + const result = await testStack.deploy(); + logGroupName = result[STACK_OUTPUT_LOG_GROUP]; // Invoke the function three time (one for cold start, then two for warm start) invocationLogs = await invokeFunction(functionName, invocationCount); @@ -184,7 +182,7 @@ describe(`logger E2E tests child logger functionalities (manual) for runtime: ${ afterAll(async () => { if (!process.env.DISABLE_TEARDOWN) { - await destroyStack(integTestApp, stack); + await testStack.destroy(); } }, TEARDOWN_TIMEOUT); }); diff --git a/packages/logger/tests/e2e/logEventEnvVarSetting.middy.test.ts b/packages/logger/tests/e2e/logEventEnvVarSetting.middy.test.ts index 0894c9c18e..9b4e10a727 100644 --- a/packages/logger/tests/e2e/logEventEnvVarSetting.middy.test.ts +++ b/packages/logger/tests/e2e/logEventEnvVarSetting.middy.test.ts @@ -4,7 +4,6 @@ * @group e2e/logger/logEventEnvVarSetting */ import path from 'path'; -import { App, Stack } from 'aws-cdk-lib'; import { v4 } from 'uuid'; import { createStackWithLambdaFunction, @@ -14,9 +13,9 @@ import { } from '../../../commons/tests/utils/e2eUtils'; import { InvocationLogs } from '../../../commons/tests/utils/InvocationLogs'; import { - deployStack, - destroyStack, -} from '../../../commons/tests/utils/cdk-cli'; + TestStack, + defaultRuntime, +} from '@aws-lambda-powertools/testing-utils'; import { RESOURCE_NAME_PREFIX, STACK_OUTPUT_LOG_GROUP, @@ -25,7 +24,7 @@ import { TEARDOWN_TIMEOUT, } from './constants'; -const runtime: string = process.env.RUNTIME || 'nodejs18x'; +const runtime: string = process.env.RUNTIME || defaultRuntime; if (!isValidRuntimeKey(runtime)) { throw new Error(`Invalid runtime key value: ${runtime}`); @@ -49,18 +48,16 @@ const lambdaFunctionCodeFile = const invocationCount = 3; -const integTestApp = new App(); +const testStack = new TestStack(stackName); let logGroupName: string; // We do not know it until deployment -let stack: Stack; describe(`logger E2E tests log event via env var setting (middy) for runtime: ${runtime}`, () => { let invocationLogs: InvocationLogs[]; beforeAll(async () => { // Create and deploy a stack with AWS CDK - stack = createStackWithLambdaFunction({ - app: integTestApp, - stackName: stackName, + createStackWithLambdaFunction({ + stack: testStack.stack, functionName: functionName, functionEntry: path.join(__dirname, lambdaFunctionCodeFile), environment: { @@ -75,8 +72,8 @@ describe(`logger E2E tests log event via env var setting (middy) for runtime: ${ runtime: runtime, }); - const result = await deployStack(integTestApp, stack); - logGroupName = result.outputs[STACK_OUTPUT_LOG_GROUP]; + const result = await testStack.deploy(); + logGroupName = result[STACK_OUTPUT_LOG_GROUP]; // Invoke the function three time (one for cold start, then two for warm start) invocationLogs = await invokeFunction( @@ -117,7 +114,7 @@ describe(`logger E2E tests log event via env var setting (middy) for runtime: ${ afterAll(async () => { if (!process.env.DISABLE_TEARDOWN) { - await destroyStack(integTestApp, stack); + await testStack.destroy(); } }, TEARDOWN_TIMEOUT); }); diff --git a/packages/logger/tests/e2e/sampleRate.decorator.test.ts b/packages/logger/tests/e2e/sampleRate.decorator.test.ts index 354e4c461d..53f6401aee 100644 --- a/packages/logger/tests/e2e/sampleRate.decorator.test.ts +++ b/packages/logger/tests/e2e/sampleRate.decorator.test.ts @@ -4,7 +4,6 @@ * @group e2e/logger/sampleRate */ import path from 'path'; -import { App, Stack } from 'aws-cdk-lib'; import { v4 } from 'uuid'; import { createStackWithLambdaFunction, @@ -14,9 +13,9 @@ import { } from '../../../commons/tests/utils/e2eUtils'; import { InvocationLogs } from '../../../commons/tests/utils/InvocationLogs'; import { - deployStack, - destroyStack, -} from '../../../commons/tests/utils/cdk-cli'; + TestStack, + defaultRuntime, +} from '@aws-lambda-powertools/testing-utils'; import { RESOURCE_NAME_PREFIX, STACK_OUTPUT_LOG_GROUP, @@ -25,7 +24,7 @@ import { TEARDOWN_TIMEOUT, } from './constants'; -const runtime: string = process.env.RUNTIME || 'nodejs18x'; +const runtime: string = process.env.RUNTIME || defaultRuntime; if (!isValidRuntimeKey(runtime)) { throw new Error(`Invalid runtime key value: ${runtime}`); @@ -55,8 +54,7 @@ const LOG_MSG = `Log message ${uuid}`; const SAMPLE_RATE = '0.5'; const LOG_LEVEL = LEVEL.ERROR; -const integTestApp = new App(); -let stack: Stack; +const testStack = new TestStack(stackName); let logGroupName: string; // We do not know the exact name until deployment describe(`logger E2E tests sample rate and injectLambdaContext() for runtime: nodejs18x`, () => { @@ -64,9 +62,8 @@ describe(`logger E2E tests sample rate and injectLambdaContext() for runtime: no beforeAll(async () => { // Create and deploy a stack with AWS CDK - stack = createStackWithLambdaFunction({ - app: integTestApp, - stackName: stackName, + createStackWithLambdaFunction({ + stack: testStack.stack, functionName: functionName, functionEntry: path.join(__dirname, lambdaFunctionCodeFile), environment: { @@ -81,8 +78,9 @@ describe(`logger E2E tests sample rate and injectLambdaContext() for runtime: no logGroupOutputKey: STACK_OUTPUT_LOG_GROUP, runtime: runtime, }); - const result = await deployStack(integTestApp, stack); - logGroupName = result.outputs[STACK_OUTPUT_LOG_GROUP]; + + const result = await testStack.deploy(); + logGroupName = result[STACK_OUTPUT_LOG_GROUP]; invocationLogs = await invokeFunction(functionName, invocationCount); @@ -150,7 +148,7 @@ describe(`logger E2E tests sample rate and injectLambdaContext() for runtime: no afterAll(async () => { if (!process.env.DISABLE_TEARDOWN) { - await destroyStack(integTestApp, stack); + await testStack.destroy(); } }, TEARDOWN_TIMEOUT); }); diff --git a/packages/metrics/package.json b/packages/metrics/package.json index 2a9d94c8da..6c75003d8b 100644 --- a/packages/metrics/package.json +++ b/packages/metrics/package.json @@ -32,6 +32,7 @@ "main": "./lib/index.js", "types": "./lib/index.d.ts", "devDependencies": { + "@aws-lambda-powertools/testing-utils": "file:../testing", "@aws-sdk/client-cloudwatch": "^3.360.0", "@types/promise-retry": "^1.1.3", "promise-retry": "^2.0.1" diff --git a/packages/metrics/tests/e2e/basicFeatures.decorators.test.ts b/packages/metrics/tests/e2e/basicFeatures.decorators.test.ts index 297e81ecc4..e2dbd76c3d 100644 --- a/packages/metrics/tests/e2e/basicFeatures.decorators.test.ts +++ b/packages/metrics/tests/e2e/basicFeatures.decorators.test.ts @@ -5,7 +5,6 @@ */ import path from 'path'; import { Tracing } from 'aws-cdk-lib/aws-lambda'; -import { App, Stack } from 'aws-cdk-lib'; import { CloudWatchClient, GetMetricStatisticsCommand, @@ -18,9 +17,9 @@ import { invokeFunction, } from '../../../commons/tests/utils/e2eUtils'; import { - deployStack, - destroyStack, -} from '../../../commons/tests/utils/cdk-cli'; + TestStack, + defaultRuntime, +} from '@aws-lambda-powertools/testing-utils'; import { MetricUnits } from '../../src'; import { ONE_MINUTE, @@ -31,7 +30,7 @@ import { } from './constants'; import { getMetrics } from '../helpers/metricsUtils'; -const runtime: string = process.env.RUNTIME || 'nodejs18x'; +const runtime: string = process.env.RUNTIME || defaultRuntime; if (!isValidRuntimeKey(runtime)) { throw new Error(`Invalid runtime key value: ${runtime}`); @@ -70,15 +69,13 @@ const expectedSingleMetricName = 'MySingleMetric'; const expectedSingleMetricUnit = MetricUnits.Percent; const expectedSingleMetricValue = '2'; -const integTestApp = new App(); -let stack: Stack; +const testStack = new TestStack(stackName); describe(`metrics E2E tests (decorator) for runtime: ${runtime}`, () => { beforeAll(async () => { // GIVEN a stack - stack = createStackWithLambdaFunction({ - app: integTestApp, - stackName: stackName, + createStackWithLambdaFunction({ + stack: testStack.stack, functionName: functionName, functionEntry: path.join(__dirname, lambdaFunctionCodeFile), tracing: Tracing.ACTIVE, @@ -104,7 +101,7 @@ describe(`metrics E2E tests (decorator) for runtime: ${runtime}`, () => { runtime: runtime, }); - await deployStack(integTestApp, stack); + await testStack.deploy(); // and invoked await invokeFunction(functionName, invocationCount, 'SEQUENTIAL'); @@ -233,7 +230,7 @@ describe(`metrics E2E tests (decorator) for runtime: ${runtime}`, () => { }); afterAll(async () => { if (!process.env.DISABLE_TEARDOWN) { - await destroyStack(integTestApp, stack); + await testStack.destroy(); } }, TEARDOWN_TIMEOUT); }); diff --git a/packages/metrics/tests/e2e/basicFeatures.manual.test.ts b/packages/metrics/tests/e2e/basicFeatures.manual.test.ts index 585c2e9abf..4bde10e7f3 100644 --- a/packages/metrics/tests/e2e/basicFeatures.manual.test.ts +++ b/packages/metrics/tests/e2e/basicFeatures.manual.test.ts @@ -6,7 +6,6 @@ import path from 'path'; import { Tracing } from 'aws-cdk-lib/aws-lambda'; -import { App, Stack } from 'aws-cdk-lib'; import { CloudWatchClient, GetMetricStatisticsCommand, @@ -19,9 +18,9 @@ import { invokeFunction, } from '../../../commons/tests/utils/e2eUtils'; import { - deployStack, - destroyStack, -} from '../../../commons/tests/utils/cdk-cli'; + TestStack, + defaultRuntime, +} from '@aws-lambda-powertools/testing-utils'; import { MetricUnits } from '../../src'; import { ONE_MINUTE, @@ -32,7 +31,7 @@ import { } from './constants'; import { getMetrics } from '../helpers/metricsUtils'; -const runtime: string = process.env.RUNTIME || 'nodejs18x'; +const runtime: string = process.env.RUNTIME || defaultRuntime; if (!isValidRuntimeKey(runtime)) { throw new Error(`Invalid runtime key value: ${runtime}`); @@ -71,15 +70,13 @@ const expectedSingleMetricName = 'MySingleMetric'; const expectedSingleMetricUnit = MetricUnits.Percent; const expectedSingleMetricValue = '2'; -const integTestApp = new App(); -let stack: Stack; +const testStack = new TestStack(stackName); describe(`metrics E2E tests (manual) for runtime: ${runtime}`, () => { beforeAll(async () => { // GIVEN a stack - stack = createStackWithLambdaFunction({ - app: integTestApp, - stackName: stackName, + createStackWithLambdaFunction({ + stack: testStack.stack, functionName: functionName, functionEntry: path.join(__dirname, lambdaFunctionCodeFile), tracing: Tracing.ACTIVE, @@ -104,7 +101,7 @@ describe(`metrics E2E tests (manual) for runtime: ${runtime}`, () => { }, runtime: runtime, }); - await deployStack(integTestApp, stack); + await testStack.deploy(); // and invoked await invokeFunction(functionName, invocationCount, 'SEQUENTIAL'); @@ -228,7 +225,7 @@ describe(`metrics E2E tests (manual) for runtime: ${runtime}`, () => { afterAll(async () => { if (!process.env.DISABLE_TEARDOWN) { - await destroyStack(integTestApp, stack); + await testStack.destroy(); } }, TEARDOWN_TIMEOUT); }); diff --git a/packages/parameters/tests/e2e/appConfigProvider.class.test.ts b/packages/parameters/tests/e2e/appConfigProvider.class.test.ts index 2e75f8cc6b..ec662d8bb4 100644 --- a/packages/parameters/tests/e2e/appConfigProvider.class.test.ts +++ b/packages/parameters/tests/e2e/appConfigProvider.class.test.ts @@ -4,7 +4,7 @@ * @group e2e/parameters/appconfig/class */ import path from 'path'; -import { App, Stack, Aspects } from 'aws-cdk-lib'; +import { Aspects } from 'aws-cdk-lib'; import { toBase64 } from '@aws-sdk/util-base64-node'; import { v4 } from 'uuid'; import { @@ -15,9 +15,9 @@ import { } from '../../../commons/tests/utils/e2eUtils'; import { InvocationLogs } from '../../../commons/tests/utils/InvocationLogs'; import { - deployStack, - destroyStack, -} from '../../../commons/tests/utils/cdk-cli'; + TestStack, + defaultRuntime, +} from '@aws-lambda-powertools/testing-utils'; import { ResourceAccessGranter } from '../helpers/cdkAspectGrantAccess'; import { RESOURCE_NAME_PREFIX, @@ -30,7 +30,7 @@ import { createAppConfigConfigurationProfile, } from '../helpers/parametersUtils'; -const runtime: string = process.env.RUNTIME || 'nodejs18x'; +const runtime: string = process.env.RUNTIME || defaultRuntime; if (!isValidRuntimeKey(runtime)) { throw new Error(`Invalid runtime key value: ${runtime}`); @@ -119,8 +119,7 @@ const featureFlagValue = { }, }; -const integTestApp = new App(); -let stack: Stack; +const testStack = new TestStack(stackName); /** * This test suite deploys a CDK stack with a Lambda function and a number of AppConfig parameters. @@ -180,9 +179,8 @@ describe(`parameters E2E tests (appConfigProvider) for runtime ${runtime}`, () = beforeAll(async () => { // Create a stack with a Lambda function - stack = createStackWithLambdaFunction({ - app: integTestApp, - stackName, + createStackWithLambdaFunction({ + stack: testStack.stack, functionName, functionEntry: path.join(__dirname, lambdaFunctionCodeFile), environment: { @@ -202,7 +200,7 @@ describe(`parameters E2E tests (appConfigProvider) for runtime ${runtime}`, () = // Create the base resources for an AppConfig application. const { application, environment, deploymentStrategy } = createBaseAppConfigResources({ - stack, + stack: testStack.stack, applicationName, environmentName, deploymentStrategyName, @@ -210,7 +208,7 @@ describe(`parameters E2E tests (appConfigProvider) for runtime ${runtime}`, () = // Create configuration profiles for tests. const freeFormJson = createAppConfigConfigurationProfile({ - stack, + stack: testStack.stack, application, environment, deploymentStrategy, @@ -223,7 +221,7 @@ describe(`parameters E2E tests (appConfigProvider) for runtime ${runtime}`, () = }); const freeFormYaml = createAppConfigConfigurationProfile({ - stack, + stack: testStack.stack, application, environment, deploymentStrategy, @@ -237,7 +235,7 @@ describe(`parameters E2E tests (appConfigProvider) for runtime ${runtime}`, () = freeFormYaml.node.addDependency(freeFormJson); const freeFormBase64PlainText = createAppConfigConfigurationProfile({ - stack, + stack: testStack.stack, application, environment, deploymentStrategy, @@ -251,7 +249,7 @@ describe(`parameters E2E tests (appConfigProvider) for runtime ${runtime}`, () = freeFormBase64PlainText.node.addDependency(freeFormYaml); const featureFlag = createAppConfigConfigurationProfile({ - stack, + stack: testStack.stack, application, environment, deploymentStrategy, @@ -265,7 +263,7 @@ describe(`parameters E2E tests (appConfigProvider) for runtime ${runtime}`, () = featureFlag.node.addDependency(freeFormBase64PlainText); // Grant access to the Lambda function to the AppConfig resources. - Aspects.of(stack).add( + Aspects.of(testStack.stack).add( new ResourceAccessGranter([ freeFormJson, freeFormYaml, @@ -275,7 +273,7 @@ describe(`parameters E2E tests (appConfigProvider) for runtime ${runtime}`, () = ); // Deploy the stack - await deployStack(integTestApp, stack); + await testStack.deploy(); // and invoke the Lambda function invocationLogs = await invokeFunction( @@ -388,7 +386,7 @@ describe(`parameters E2E tests (appConfigProvider) for runtime ${runtime}`, () = afterAll(async () => { if (!process.env.DISABLE_TEARDOWN) { - await destroyStack(integTestApp, stack); + await testStack.destroy(); } }, TEARDOWN_TIMEOUT); }); diff --git a/packages/parameters/tests/e2e/dynamoDBProvider.class.test.ts b/packages/parameters/tests/e2e/dynamoDBProvider.class.test.ts index a63f225db1..c47a006e30 100644 --- a/packages/parameters/tests/e2e/dynamoDBProvider.class.test.ts +++ b/packages/parameters/tests/e2e/dynamoDBProvider.class.test.ts @@ -5,7 +5,7 @@ */ import path from 'path'; import { AttributeType } from 'aws-cdk-lib/aws-dynamodb'; -import { App, Stack, Aspects } from 'aws-cdk-lib'; +import { Aspects } from 'aws-cdk-lib'; import { v4 } from 'uuid'; import { generateUniqueName, @@ -15,9 +15,9 @@ import { } from '../../../commons/tests/utils/e2eUtils'; import { InvocationLogs } from '../../../commons/tests/utils/InvocationLogs'; import { - deployStack, - destroyStack, -} from '../../../commons/tests/utils/cdk-cli'; + TestStack, + defaultRuntime, +} from '@aws-lambda-powertools/testing-utils'; import { ResourceAccessGranter } from '../helpers/cdkAspectGrantAccess'; import { RESOURCE_NAME_PREFIX, @@ -30,7 +30,7 @@ import { putDynamoDBItem, } from '../helpers/parametersUtils'; -const runtime: string = process.env.RUNTIME || 'nodejs18x'; +const runtime: string = process.env.RUNTIME || defaultRuntime; if (!isValidRuntimeKey(runtime)) { throw new Error(`Invalid runtime key value: ${runtime}`); @@ -82,8 +82,7 @@ const keyAttr = 'key'; const sortAttr = 'sort'; const valueAttr = 'val'; -const integTestApp = new App(); -let stack: Stack; +const testStack = new TestStack(stackName); /** * This test suite deploys a CDK stack with a Lambda function and a number of DynamoDB tables. @@ -166,9 +165,8 @@ describe(`parameters E2E tests (dynamoDBProvider) for runtime: ${runtime}`, () = beforeAll(async () => { // Create a stack with a Lambda function - stack = createStackWithLambdaFunction({ - app: integTestApp, - stackName, + createStackWithLambdaFunction({ + stack: testStack.stack, functionName, functionEntry: path.join(__dirname, lambdaFunctionCodeFile), environment: { @@ -188,7 +186,7 @@ describe(`parameters E2E tests (dynamoDBProvider) for runtime: ${runtime}`, () = // Create the DynamoDB tables const ddbTableGet = createDynamoDBTable({ - stack, + stack: testStack.stack, id: 'Table-get', tableName: tableGet, partitionKey: { @@ -197,7 +195,7 @@ describe(`parameters E2E tests (dynamoDBProvider) for runtime: ${runtime}`, () = }, }); const ddbTableGetMultiple = createDynamoDBTable({ - stack, + stack: testStack.stack, id: 'Table-getMultiple', tableName: tableGetMultiple, partitionKey: { @@ -210,7 +208,7 @@ describe(`parameters E2E tests (dynamoDBProvider) for runtime: ${runtime}`, () = }, }); const ddbTableGetCustomKeys = createDynamoDBTable({ - stack, + stack: testStack.stack, id: 'Table-getCustomKeys', tableName: tableGetCustomkeys, partitionKey: { @@ -219,7 +217,7 @@ describe(`parameters E2E tests (dynamoDBProvider) for runtime: ${runtime}`, () = }, }); const ddbTabelGetMultipleCustomKeys = createDynamoDBTable({ - stack, + stack: testStack.stack, id: 'Table-getMultipleCustomKeys', tableName: tableGetMultipleCustomkeys, partitionKey: { @@ -233,7 +231,7 @@ describe(`parameters E2E tests (dynamoDBProvider) for runtime: ${runtime}`, () = }); // Give the Lambda access to the DynamoDB tables - Aspects.of(stack).add( + Aspects.of(testStack.stack).add( new ResourceAccessGranter([ ddbTableGet, ddbTableGetMultiple, @@ -245,7 +243,7 @@ describe(`parameters E2E tests (dynamoDBProvider) for runtime: ${runtime}`, () = // Seed tables with test data // Test 1 putDynamoDBItem({ - stack, + stack: testStack.stack, id: 'my-param-test1', table: ddbTableGet, item: { @@ -256,7 +254,7 @@ describe(`parameters E2E tests (dynamoDBProvider) for runtime: ${runtime}`, () = // Test 2 putDynamoDBItem({ - stack, + stack: testStack.stack, id: 'my-param-test2-a', table: ddbTableGetMultiple, item: { @@ -266,7 +264,7 @@ describe(`parameters E2E tests (dynamoDBProvider) for runtime: ${runtime}`, () = }, }); putDynamoDBItem({ - stack, + stack: testStack.stack, id: 'my-param-test2-b', table: ddbTableGetMultiple, item: { @@ -278,7 +276,7 @@ describe(`parameters E2E tests (dynamoDBProvider) for runtime: ${runtime}`, () = // Test 3 putDynamoDBItem({ - stack, + stack: testStack.stack, id: 'my-param-test3', table: ddbTableGetCustomKeys, item: { @@ -289,7 +287,7 @@ describe(`parameters E2E tests (dynamoDBProvider) for runtime: ${runtime}`, () = // Test 4 putDynamoDBItem({ - stack, + stack: testStack.stack, id: 'my-param-test4-a', table: ddbTabelGetMultipleCustomKeys, item: { @@ -299,7 +297,7 @@ describe(`parameters E2E tests (dynamoDBProvider) for runtime: ${runtime}`, () = }, }); putDynamoDBItem({ - stack, + stack: testStack.stack, id: 'my-param-test4-b', table: ddbTabelGetMultipleCustomKeys, item: { @@ -311,7 +309,7 @@ describe(`parameters E2E tests (dynamoDBProvider) for runtime: ${runtime}`, () = // Test 5 putDynamoDBItem({ - stack, + stack: testStack.stack, id: 'my-param-test5', table: ddbTableGet, item: { @@ -322,7 +320,7 @@ describe(`parameters E2E tests (dynamoDBProvider) for runtime: ${runtime}`, () = // Test 6 putDynamoDBItem({ - stack, + stack: testStack.stack, id: 'my-param-test6', table: ddbTableGet, item: { @@ -333,7 +331,7 @@ describe(`parameters E2E tests (dynamoDBProvider) for runtime: ${runtime}`, () = // Test 7 putDynamoDBItem({ - stack, + stack: testStack.stack, id: 'my-param-test7-a', table: ddbTableGetMultiple, item: { @@ -343,7 +341,7 @@ describe(`parameters E2E tests (dynamoDBProvider) for runtime: ${runtime}`, () = }, }); putDynamoDBItem({ - stack, + stack: testStack.stack, id: 'my-param-test7-b', table: ddbTableGetMultiple, item: { @@ -356,7 +354,7 @@ describe(`parameters E2E tests (dynamoDBProvider) for runtime: ${runtime}`, () = // Test 8 & 9 use the same items as Test 1 // Deploy the stack - await deployStack(integTestApp, stack); + await testStack.deploy(); // and invoke the Lambda function invocationLogs = await invokeFunction( @@ -488,7 +486,7 @@ describe(`parameters E2E tests (dynamoDBProvider) for runtime: ${runtime}`, () = afterAll(async () => { if (!process.env.DISABLE_TEARDOWN) { - await destroyStack(integTestApp, stack); + await testStack.destroy(); } }, TEARDOWN_TIMEOUT); }); diff --git a/packages/parameters/tests/e2e/secretsProvider.class.test.ts b/packages/parameters/tests/e2e/secretsProvider.class.test.ts index d656b4a3c3..d43dd768e5 100644 --- a/packages/parameters/tests/e2e/secretsProvider.class.test.ts +++ b/packages/parameters/tests/e2e/secretsProvider.class.test.ts @@ -18,16 +18,16 @@ import { import { v4 } from 'uuid'; import { Tracing } from 'aws-cdk-lib/aws-lambda'; import { - deployStack, - destroyStack, -} from '../../../commons/tests/utils/cdk-cli'; -import { App, Aspects, SecretValue, Stack } from 'aws-cdk-lib'; + TestStack, + defaultRuntime, +} from '@aws-lambda-powertools/testing-utils'; +import { Aspects, SecretValue } from 'aws-cdk-lib'; import path from 'path'; import { Secret } from 'aws-cdk-lib/aws-secretsmanager'; import { InvocationLogs } from '../../../commons/tests/utils/InvocationLogs'; import { ResourceAccessGranter } from '../helpers/cdkAspectGrantAccess'; -const runtime: string = process.env.RUNTIME || 'nodejs18x'; +const runtime: string = process.env.RUNTIME || defaultRuntime; if (!isValidRuntimeKey(runtime)) { throw new Error(`Invalid runtime key: ${runtime}`); @@ -68,8 +68,7 @@ describe(`parameters E2E tests (SecretsProvider) for runtime: ${runtime}`, () => const invocationCount = 1; - const integTestApp = new App(); - let stack: Stack; + const testStack = new TestStack(stackName); beforeAll(async () => { // use unique names for each test to keep a clean state @@ -106,9 +105,8 @@ describe(`parameters E2E tests (SecretsProvider) for runtime: ${runtime}`, () => // creates the test fuction that uses Powertools for AWS Lambda (TypeScript) secret provider we want to test // pass env vars with secret names we want to fetch - stack = createStackWithLambdaFunction({ - app: integTestApp, - stackName: stackName, + createStackWithLambdaFunction({ + stack: testStack.stack, functionName: functionName, functionEntry: path.join(__dirname, lambdaFunctionCodeFile), tracing: Tracing.ACTIVE, @@ -123,30 +121,34 @@ describe(`parameters E2E tests (SecretsProvider) for runtime: ${runtime}`, () => runtime: runtime, }); - const secretString = new Secret(stack, 'testSecretPlain', { + const secretString = new Secret(testStack.stack, 'testSecretPlain', { secretName: secretNamePlain, secretStringValue: SecretValue.unsafePlainText('foo'), }); - const secretObject = new Secret(stack, 'testSecretObject', { + const secretObject = new Secret(testStack.stack, 'testSecretObject', { secretName: secretNameObject, secretObjectValue: { foo: SecretValue.unsafePlainText('bar'), }, }); - const secretBinary = new Secret(stack, 'testSecretBinary', { + const secretBinary = new Secret(testStack.stack, 'testSecretBinary', { secretName: secretNameBinary, secretStringValue: SecretValue.unsafePlainText('Zm9v'), // 'foo' encoded in base64 }); - const secretStringCached = new Secret(stack, 'testSecretStringCached', { - secretName: secretNamePlainCached, - secretStringValue: SecretValue.unsafePlainText('foo'), - }); + const secretStringCached = new Secret( + testStack.stack, + 'testSecretStringCached', + { + secretName: secretNamePlainCached, + secretStringValue: SecretValue.unsafePlainText('foo'), + } + ); const secretStringForceFetch = new Secret( - stack, + testStack.stack, 'testSecretStringForceFetch', { secretName: secretNamePlainForceFetch, @@ -155,7 +157,7 @@ describe(`parameters E2E tests (SecretsProvider) for runtime: ${runtime}`, () => ); // add secrets here to grant lambda permisisons to access secrets - Aspects.of(stack).add( + Aspects.of(testStack.stack).add( new ResourceAccessGranter([ secretString, secretObject, @@ -165,7 +167,7 @@ describe(`parameters E2E tests (SecretsProvider) for runtime: ${runtime}`, () => ]) ); - await deployStack(integTestApp, stack); + await testStack.deploy(); invocationLogs = await invokeFunction( functionName, @@ -242,7 +244,7 @@ describe(`parameters E2E tests (SecretsProvider) for runtime: ${runtime}`, () => afterAll(async () => { if (!process.env.DISABLE_TEARDOWN) { - await destroyStack(integTestApp, stack); + await testStack.destroy(); } }, TEARDOWN_TIMEOUT); }); diff --git a/packages/parameters/tests/e2e/ssmProvider.class.test.ts b/packages/parameters/tests/e2e/ssmProvider.class.test.ts index e71f123703..a685a988f5 100644 --- a/packages/parameters/tests/e2e/ssmProvider.class.test.ts +++ b/packages/parameters/tests/e2e/ssmProvider.class.test.ts @@ -4,7 +4,7 @@ * @group e2e/parameters/ssm/class */ import path from 'path'; -import { App, Stack, Aspects } from 'aws-cdk-lib'; +import { Aspects } from 'aws-cdk-lib'; import { StringParameter } from 'aws-cdk-lib/aws-ssm'; import { v4 } from 'uuid'; import { @@ -15,9 +15,9 @@ import { } from '../../../commons/tests/utils/e2eUtils'; import { InvocationLogs } from '../../../commons/tests/utils/InvocationLogs'; import { - deployStack, - destroyStack, -} from '../../../commons/tests/utils/cdk-cli'; + TestStack, + defaultRuntime, +} from '@aws-lambda-powertools/testing-utils'; import { ResourceAccessGranter } from '../helpers/cdkAspectGrantAccess'; import { RESOURCE_NAME_PREFIX, @@ -27,7 +27,7 @@ import { } from './constants'; import { createSSMSecureString } from '../helpers/parametersUtils'; -const runtime: string = process.env.RUNTIME || 'nodejs18x'; +const runtime: string = process.env.RUNTIME || defaultRuntime; if (!isValidRuntimeKey(runtime)) { throw new Error(`Invalid runtime key value: ${runtime}`); @@ -82,8 +82,7 @@ const paramBValue = 'bar'; const paramEncryptedAValue = 'foo-encrypted'; const paramEncryptedBValue = 'bar-encrypted'; -const integTestApp = new App(); -let stack: Stack; +const testStack = new TestStack(stackName); /** * This test suite deploys a CDK stack with a Lambda function and a number of SSM parameters. @@ -139,9 +138,8 @@ describe(`parameters E2E tests (ssmProvider) for runtime: ${runtime}`, () => { beforeAll(async () => { // Create a stack with a Lambda function - stack = createStackWithLambdaFunction({ - app: integTestApp, - stackName, + createStackWithLambdaFunction({ + stack: testStack.stack, functionName, functionEntry: path.join(__dirname, lambdaFunctionCodeFile), environment: { @@ -157,31 +155,31 @@ describe(`parameters E2E tests (ssmProvider) for runtime: ${runtime}`, () => { }); // Create SSM parameters - const parameterGetA = new StringParameter(stack, 'Param-a', { + const parameterGetA = new StringParameter(testStack.stack, 'Param-a', { parameterName: paramA, stringValue: paramAValue, }); - const parameterGetB = new StringParameter(stack, 'Param-b', { + const parameterGetB = new StringParameter(testStack.stack, 'Param-b', { parameterName: paramB, stringValue: paramBValue, }); const parameterEncryptedA = createSSMSecureString({ - stack, + stack: testStack.stack, id: 'Param-encrypted-a', name: paramEncryptedA, value: paramEncryptedAValue, }); const parameterEncryptedB = createSSMSecureString({ - stack, + stack: testStack.stack, id: 'Param-encrypted-b', name: paramEncryptedB, value: paramEncryptedBValue, }); // Give the Lambda function access to the SSM parameters - Aspects.of(stack).add( + Aspects.of(testStack.stack).add( new ResourceAccessGranter([ parameterGetA, parameterGetB, @@ -191,7 +189,7 @@ describe(`parameters E2E tests (ssmProvider) for runtime: ${runtime}`, () => { ); // Deploy the stack - await deployStack(integTestApp, stack); + await testStack.deploy(); // and invoke the Lambda function invocationLogs = await invokeFunction( @@ -377,7 +375,7 @@ describe(`parameters E2E tests (ssmProvider) for runtime: ${runtime}`, () => { afterAll(async () => { if (!process.env.DISABLE_TEARDOWN) { - await destroyStack(integTestApp, stack); + await testStack.destroy(); } }, TEARDOWN_TIMEOUT); }); diff --git a/packages/testing/jest.config.js b/packages/testing/jest.config.js new file mode 100644 index 0000000000..6d6c2fecf2 --- /dev/null +++ b/packages/testing/jest.config.js @@ -0,0 +1,28 @@ +module.exports = { + displayName: { + name: 'Powertools for AWS Lambda (TypeScript) utility: TESTING', + color: 'blue', + }, + runner: 'groups', + preset: 'ts-jest', + transform: { + '^.+\\.ts?$': 'ts-jest', + }, + moduleFileExtensions: ['js', 'ts'], + collectCoverageFrom: ['**/src/**/*.ts', '!**/node_modules/**'], + testMatch: ['**/?(*.)+(spec|test).ts'], + roots: ['/src', '/tests'], + testPathIgnorePatterns: ['/node_modules/'], + testEnvironment: 'node', + coveragePathIgnorePatterns: ['/node_modules/', '/types/'], + coverageThreshold: { + global: { + statements: 100, + branches: 100, + functions: 100, + lines: 100, + }, + }, + coverageReporters: ['json-summary', 'text', 'lcov'], + setupFiles: ['/tests/helpers/populateEnvironmentVariables.ts'], +}; diff --git a/packages/testing/package.json b/packages/testing/package.json new file mode 100644 index 0000000000..375374f9ef --- /dev/null +++ b/packages/testing/package.json @@ -0,0 +1,50 @@ +{ + "name": "@aws-lambda-powertools/testing-utils", + "version": "1.12.1", + "description": "A package containing utilities to test your serverless workloads", + "author": { + "name": "Amazon Web Services", + "url": "https://aws.amazon.com" + }, + "private": true, + "scripts": { + "test": "npm run test:unit", + "test:unit": "jest --group=unit --detectOpenHandles --coverage --verbose", + "test:e2e": "echo 'Not implemented'", + "watch": "jest --watch", + "build": "tsc", + "lint": "eslint --ext .ts,.js --no-error-on-unmatched-pattern .", + "lint-fix": "eslint --fix --ext .ts,.js --no-error-on-unmatched-pattern .", + "prebuild": "rimraf ./lib", + "prepack": "node ../../.github/scripts/release_patch_package_json.js ." + }, + "lint-staged": { + "*.{js,ts}": "npm run lint-fix" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/aws-powertools/powertools-lambda-typescript.git" + }, + "files": [ + "lib" + ], + "main": "./lib/index.js", + "types": "./lib/index.d.ts", + "keywords": [ + "aws", + "lambda", + "powertools", + "testing", + "serverless" + ], + "license": "MIT-0", + "bugs": { + "url": "https://github.com/aws-powertools/powertools-lambda-typescript/issues" + }, + "homepage": "https://github.com/aws-powertools/powertools-lambda-typescript/tree/main/packages/testing#readme", + "dependencies": { + "@aws-cdk/cli-lib-alpha": "^2.88.0-alpha.0", + "aws-cdk-lib": "^2.88.0", + "esbuild": "^0.18.17" + } +} diff --git a/packages/testing/src/TestStack.ts b/packages/testing/src/TestStack.ts new file mode 100644 index 0000000000..8c84e86fb8 --- /dev/null +++ b/packages/testing/src/TestStack.ts @@ -0,0 +1,83 @@ +import { tmpdir } from 'node:os'; +import { join } from 'node:path'; +import { readFile } from 'node:fs/promises'; +import { App, Stack } from 'aws-cdk-lib'; +import { AwsCdkCli, RequireApproval } from '@aws-cdk/cli-lib-alpha'; +import type { ICloudAssemblyDirectoryProducer } from '@aws-cdk/cli-lib-alpha'; + +/** + * Test stack that can be deployed to the selected environment. + */ +class TestStack implements ICloudAssemblyDirectoryProducer { + /** + * Reference to the AWS CDK App object. + * @default new App() + */ + public app: App; + /** + * Reference to the AWS CDK Stack object. + * @default new Stack(this.app, stackName) + */ + public stack: Stack; + /** + * @internal + * Reference to the AWS CDK CLI object. + */ + #cli: AwsCdkCli; + + public constructor(stackName: string, app?: App, stack?: Stack) { + this.app = app ?? new App(); + this.stack = stack ?? new Stack(this.app, stackName); + this.#cli = AwsCdkCli.fromCloudAssemblyDirectoryProducer(this); + } + + /** + * Deploy the test stack to the selected environment. + * + * It returns the outputs of the deployed stack. + */ + public async deploy(): Promise> { + const outputFilePath = join( + tmpdir(), + 'powertools-e2e-testing', + `${this.stack.stackName}.outputs.json` + ); + await this.#cli.deploy({ + stacks: [this.stack.stackName], + requireApproval: RequireApproval.NEVER, + outputsFile: outputFilePath, + }); + + return JSON.parse(await readFile(outputFilePath, 'utf-8'))[ + this.stack.stackName + ]; + } + + /** + * Destroy the test stack. + */ + public async destroy(): Promise { + await this.#cli.destroy({ + stacks: [this.stack.stackName], + requireApproval: false, + }); + } + + /** + * Produce the Cloud Assembly directory. + */ + public async produce(_context: Record): Promise { + return this.app.synth().directory; + } + + /** + * Synthesize the test stack. + */ + public async synth(): Promise { + await this.#cli.synth({ + stacks: [this.stack.stackName], + }); + } +} + +export { TestStack }; diff --git a/packages/testing/src/constants.ts b/packages/testing/src/constants.ts new file mode 100644 index 0000000000..85d66e625a --- /dev/null +++ b/packages/testing/src/constants.ts @@ -0,0 +1,17 @@ +import { Runtime } from 'aws-cdk-lib/aws-lambda'; + +/** + * The default AWS Lambda runtime to use when none is provided. + */ +const defaultRuntime = 'nodejs18x'; + +/** + * The AWS Lambda runtimes that are supported by the project. + */ +const TEST_RUNTIMES = { + nodejs14x: Runtime.NODEJS_14_X, + nodejs16x: Runtime.NODEJS_16_X, + [defaultRuntime]: Runtime.NODEJS_18_X, +} as const; + +export { TEST_RUNTIMES, defaultRuntime }; diff --git a/packages/testing/src/index.ts b/packages/testing/src/index.ts new file mode 100644 index 0000000000..6ba0fd1d5a --- /dev/null +++ b/packages/testing/src/index.ts @@ -0,0 +1,2 @@ +export * from './TestStack'; +export * from './constants'; diff --git a/packages/testing/tests/helpers/populateEnvironmentVariables.ts b/packages/testing/tests/helpers/populateEnvironmentVariables.ts new file mode 100644 index 0000000000..4d4166743d --- /dev/null +++ b/packages/testing/tests/helpers/populateEnvironmentVariables.ts @@ -0,0 +1,16 @@ +// Reserved variables +process.env._X_AMZN_TRACE_ID = '1-abcdef12-3456abcdef123456abcdef12'; +process.env.AWS_LAMBDA_FUNCTION_NAME = 'my-lambda-function'; +process.env.AWS_EXECUTION_ENV = 'nodejs16.x'; +process.env.AWS_LAMBDA_FUNCTION_MEMORY_SIZE = '128'; +if ( + process.env.AWS_REGION === undefined && + process.env.CDK_DEFAULT_REGION === undefined +) { + process.env.AWS_REGION = 'eu-west-1'; +} +process.env._HANDLER = 'index.handler'; + +// Powertools for AWS Lambda (TypeScript) variables +process.env.POWERTOOLS_SERVICE_NAME = 'hello-world'; +process.env.AWS_XRAY_LOGGING_LEVEL = 'silent'; diff --git a/packages/testing/tsconfig.es.json b/packages/testing/tsconfig.es.json new file mode 100644 index 0000000000..802f18e8f9 --- /dev/null +++ b/packages/testing/tsconfig.es.json @@ -0,0 +1,31 @@ +{ + "compilerOptions": { + "experimentalDecorators": true, + "noImplicitAny": true, + "target": "ES2020", + "module": "commonjs", + "declaration": true, + "declarationMap": true, + "outDir": "lib", + "removeComments": false, + "strict": true, + "inlineSourceMap": true, + "moduleResolution": "node", + "resolveJsonModule": true, + "pretty": true, + "baseUrl": "src/", + "rootDirs": [ "src/" ] + }, + "include": [ "src/**/*", "tests/**/*" ], + "exclude": [ "./node_modules"], + "watchOptions": { + "watchFile": "useFsEvents", + "watchDirectory": "useFsEvents", + "fallbackPolling": "dynamicPriority" + }, + "lib": [ "es2020" ], + "types": [ + "jest", + "node" + ] +} \ No newline at end of file diff --git a/packages/testing/tsconfig.json b/packages/testing/tsconfig.json new file mode 100644 index 0000000000..8b93f8c299 --- /dev/null +++ b/packages/testing/tsconfig.json @@ -0,0 +1,32 @@ +{ + "compilerOptions": { + "experimentalDecorators": true, + "noImplicitAny": true, + "target": "ES2020", + "module": "commonjs", + "declaration": true, + "declarationMap": true, + "outDir": "lib", + "removeComments": false, + "strict": true, + "inlineSourceMap": true, + "moduleResolution": "node", + "resolveJsonModule": true, + "pretty": true, + "baseUrl": "src/", + "rootDirs": [ "src/" ], + "esModuleInterop": true + }, + "include": [ "src/**/*" ], + "exclude": [ "./node_modules"], + "watchOptions": { + "watchFile": "useFsEvents", + "watchDirectory": "useFsEvents", + "fallbackPolling": "dynamicPriority" + }, + "lib": [ "es2020" ], + "types": [ + "jest", + "node" + ] +} \ No newline at end of file diff --git a/packages/tracer/package.json b/packages/tracer/package.json index a5a6f034ee..364eba31df 100644 --- a/packages/tracer/package.json +++ b/packages/tracer/package.json @@ -32,6 +32,7 @@ "main": "./lib/index.js", "types": "./lib/index.d.ts", "devDependencies": { + "@aws-lambda-powertools/testing-utils": "file:../testing", "@aws-sdk/client-dynamodb": "^3.360.0", "@aws-sdk/client-sts": "^3.360.0", "@aws-sdk/client-xray": "^3.360.0", diff --git a/packages/tracer/tests/e2e/allFeatures.decorator.test.ts b/packages/tracer/tests/e2e/allFeatures.decorator.test.ts index 43594d7791..a6f9c0911d 100644 --- a/packages/tracer/tests/e2e/allFeatures.decorator.test.ts +++ b/packages/tracer/tests/e2e/allFeatures.decorator.test.ts @@ -3,17 +3,16 @@ * * @group e2e/tracer/decorator */ - import path from 'path'; +import { + TestStack, + defaultRuntime, +} from '@aws-lambda-powertools/testing-utils'; import { AttributeType, BillingMode, Table } from 'aws-cdk-lib/aws-dynamodb'; -import { App, RemovalPolicy, Stack } from 'aws-cdk-lib'; +import { RemovalPolicy } from 'aws-cdk-lib'; import { XRayClient } from '@aws-sdk/client-xray'; import { STSClient } from '@aws-sdk/client-sts'; import { v4 } from 'uuid'; -import { - deployStack, - destroyStack, -} from '../../../commons/tests/utils/cdk-cli'; import { createTracerTestFunction, getFirstSubsegment, @@ -44,7 +43,7 @@ import { assertErrorAndFault, } from '../helpers/traceAssertions'; -const runtime: string = process.env.RUNTIME || 'nodejs18x'; +const runtime: string = process.env.RUNTIME || defaultRuntime; if (!isValidRuntimeKey(runtime)) { throw new Error(`Invalid runtime key value: ${runtime}`); @@ -120,17 +119,15 @@ const xrayClient = new XRayClient({}); const stsClient = new STSClient({}); const invocations = 3; -const integTestApp = new App(); -let stack: Stack; +const testStack = new TestStack(stackName); describe(`Tracer E2E tests, all features with decorator instantiation for runtime: ${runtime}`, () => { beforeAll(async () => { // Prepare startTime = new Date(); const ddbTableName = stackName + '-table'; - stack = new Stack(integTestApp, stackName); - const ddbTable = new Table(stack, 'Table', { + const ddbTable = new Table(testStack.stack, 'Table', { tableName: ddbTableName, partitionKey: { name: 'id', @@ -142,7 +139,7 @@ describe(`Tracer E2E tests, all features with decorator instantiation for runtim const entry = path.join(__dirname, lambdaFunctionCodeFile); const functionWithAllFlagsEnabled = createTracerTestFunction({ - stack, + stack: testStack.stack, functionName: functionNameWithAllFlagsEnabled, entry, expectedServiceName: serviceNameWithAllFlagsEnabled, @@ -158,7 +155,7 @@ describe(`Tracer E2E tests, all features with decorator instantiation for runtim const functionThatDoesNotCapturesErrorAndResponse = createTracerTestFunction({ - stack, + stack: testStack.stack, functionName: functionNameWithNoCaptureErrorOrResponse, entry, expectedServiceName: serviceNameWithNoCaptureErrorOrResponse, @@ -173,7 +170,7 @@ describe(`Tracer E2E tests, all features with decorator instantiation for runtim ddbTable.grantWriteData(functionThatDoesNotCapturesErrorAndResponse); const functionWithTracerDisabled = createTracerTestFunction({ - stack, + stack: testStack.stack, functionName: functionNameWithTracerDisabled, entry, expectedServiceName: serviceNameWithTracerDisabled, @@ -188,7 +185,7 @@ describe(`Tracer E2E tests, all features with decorator instantiation for runtim ddbTable.grantWriteData(functionWithTracerDisabled); const functionWithCaptureResponseFalse = createTracerTestFunction({ - stack, + stack: testStack.stack, functionName: functionNameWithCaptureResponseFalse, handler: 'handlerWithCaptureResponseFalse', entry, @@ -203,7 +200,7 @@ describe(`Tracer E2E tests, all features with decorator instantiation for runtim }); ddbTable.grantWriteData(functionWithCaptureResponseFalse); - await deployStack(integTestApp, stack); + await testStack.deploy(); // Act await Promise.all([ @@ -216,7 +213,7 @@ describe(`Tracer E2E tests, all features with decorator instantiation for runtim afterAll(async () => { if (!process.env.DISABLE_TEARDOWN) { - await destroyStack(integTestApp, stack); + await testStack.destroy(); } }, TEARDOWN_TIMEOUT); diff --git a/packages/tracer/tests/e2e/allFeatures.manual.test.ts b/packages/tracer/tests/e2e/allFeatures.manual.test.ts index dbbebc34ea..9d8cbb7bed 100644 --- a/packages/tracer/tests/e2e/allFeatures.manual.test.ts +++ b/packages/tracer/tests/e2e/allFeatures.manual.test.ts @@ -3,17 +3,16 @@ * * @group e2e/tracer/manual */ - import path from 'path'; import { AttributeType, BillingMode, Table } from 'aws-cdk-lib/aws-dynamodb'; -import { App, RemovalPolicy, Stack } from 'aws-cdk-lib'; +import { RemovalPolicy } from 'aws-cdk-lib'; import { XRayClient } from '@aws-sdk/client-xray'; import { STSClient } from '@aws-sdk/client-sts'; import { v4 } from 'uuid'; import { - deployStack, - destroyStack, -} from '../../../commons/tests/utils/cdk-cli'; + TestStack, + defaultRuntime, +} from '@aws-lambda-powertools/testing-utils'; import { createTracerTestFunction, getFirstSubsegment, @@ -45,7 +44,7 @@ import { assertErrorAndFault, } from '../helpers/traceAssertions'; -const runtime: string = process.env.RUNTIME || 'nodejs18x'; +const runtime: string = process.env.RUNTIME || defaultRuntime; if (!isValidRuntimeKey(runtime)) { throw new Error(`Invalid runtime key value: ${runtime}`); @@ -72,15 +71,13 @@ const stsClient = new STSClient({}); const invocations = 3; let sortedTraces: ParsedTrace[]; -const integTestApp = new App(); -let stack: Stack; +const testStack = new TestStack(stackName); describe(`Tracer E2E tests, all features with manual instantiation for runtime: ${runtime}`, () => { beforeAll(async () => { // Prepare const startTime = new Date(); const ddbTableName = stackName + '-table'; - stack = new Stack(integTestApp, stackName); const entry = path.join(__dirname, lambdaFunctionCodeFile); const environmentParams = { @@ -90,7 +87,7 @@ describe(`Tracer E2E tests, all features with manual instantiation for runtime: POWERTOOLS_TRACE_ENABLED: 'true', }; const testFunction = createTracerTestFunction({ - stack, + stack: testStack.stack, functionName, entry, expectedServiceName, @@ -98,7 +95,7 @@ describe(`Tracer E2E tests, all features with manual instantiation for runtime: runtime, }); - const ddbTable = new Table(stack, 'Table', { + const ddbTable = new Table(testStack.stack, 'Table', { tableName: ddbTableName, partitionKey: { name: 'id', @@ -110,7 +107,7 @@ describe(`Tracer E2E tests, all features with manual instantiation for runtime: ddbTable.grantWriteData(testFunction); - await deployStack(integTestApp, stack); + await testStack.deploy(); // Act await invokeAllTestCases(functionName); @@ -128,7 +125,7 @@ describe(`Tracer E2E tests, all features with manual instantiation for runtime: afterAll(async () => { if (!process.env.DISABLE_TEARDOWN) { - await destroyStack(integTestApp, stack); + await testStack.destroy(); } }, TEARDOWN_TIMEOUT); diff --git a/packages/tracer/tests/e2e/allFeatures.middy.test.ts b/packages/tracer/tests/e2e/allFeatures.middy.test.ts index 69b612b604..7066a549db 100644 --- a/packages/tracer/tests/e2e/allFeatures.middy.test.ts +++ b/packages/tracer/tests/e2e/allFeatures.middy.test.ts @@ -6,14 +6,14 @@ import path from 'path'; import { AttributeType, BillingMode, Table } from 'aws-cdk-lib/aws-dynamodb'; -import { App, RemovalPolicy, Stack } from 'aws-cdk-lib'; +import { RemovalPolicy } from 'aws-cdk-lib'; import { XRayClient } from '@aws-sdk/client-xray'; import { STSClient } from '@aws-sdk/client-sts'; import { v4 } from 'uuid'; import { - deployStack, - destroyStack, -} from '../../../commons/tests/utils/cdk-cli'; + TestStack, + defaultRuntime, +} from '@aws-lambda-powertools/testing-utils'; import { createTracerTestFunction, getFirstSubsegment, @@ -44,7 +44,7 @@ import { assertErrorAndFault, } from '../helpers/traceAssertions'; -const runtime: string = process.env.RUNTIME || 'nodejs18x'; +const runtime: string = process.env.RUNTIME || defaultRuntime; if (!isValidRuntimeKey(runtime)) { throw new Error(`Invalid runtime key value: ${runtime}`); @@ -120,17 +120,15 @@ const xrayClient = new XRayClient({}); const stsClient = new STSClient({}); const invocations = 3; -const integTestApp = new App(); -let stack: Stack; +const testStack = new TestStack(stackName); describe(`Tracer E2E tests, all features with middy instantiation for runtime: ${runtime}`, () => { beforeAll(async () => { // Prepare startTime = new Date(); const ddbTableName = stackName + '-table'; - stack = new Stack(integTestApp, stackName); - const ddbTable = new Table(stack, 'Table', { + const ddbTable = new Table(testStack.stack, 'Table', { tableName: ddbTableName, partitionKey: { name: 'id', @@ -142,7 +140,7 @@ describe(`Tracer E2E tests, all features with middy instantiation for runtime: $ const entry = path.join(__dirname, lambdaFunctionCodeFile); const functionWithAllFlagsEnabled = createTracerTestFunction({ - stack, + stack: testStack.stack, functionName: functionNameWithAllFlagsEnabled, entry, expectedServiceName: serviceNameWithAllFlagsEnabled, @@ -158,7 +156,7 @@ describe(`Tracer E2E tests, all features with middy instantiation for runtime: $ const functionThatDoesNotCapturesErrorAndResponse = createTracerTestFunction({ - stack, + stack: testStack.stack, functionName: functionNameWithNoCaptureErrorOrResponse, entry, expectedServiceName: serviceNameWithNoCaptureErrorOrResponse, @@ -173,7 +171,7 @@ describe(`Tracer E2E tests, all features with middy instantiation for runtime: $ ddbTable.grantWriteData(functionThatDoesNotCapturesErrorAndResponse); const functionWithTracerDisabled = createTracerTestFunction({ - stack, + stack: testStack.stack, functionName: functionNameWithTracerDisabled, entry, expectedServiceName: serviceNameWithTracerDisabled, @@ -189,7 +187,7 @@ describe(`Tracer E2E tests, all features with middy instantiation for runtime: $ const functionThatDoesNotCaptureResponseViaMiddlewareOption = createTracerTestFunction({ - stack, + stack: testStack.stack, functionName: functionNameWithNoCaptureResponseViaMiddlewareOption, entry, handler: 'handlerWithNoCaptureResponseViaMiddlewareOption', @@ -207,7 +205,7 @@ describe(`Tracer E2E tests, all features with middy instantiation for runtime: $ functionThatDoesNotCaptureResponseViaMiddlewareOption ); - await deployStack(integTestApp, stack); + await testStack.deploy(); // Act await Promise.all([ @@ -220,7 +218,7 @@ describe(`Tracer E2E tests, all features with middy instantiation for runtime: $ afterAll(async () => { if (!process.env.DISABLE_TEARDOWN) { - await destroyStack(integTestApp, stack); + await testStack.destroy(); } }, TEARDOWN_TIMEOUT); diff --git a/packages/tracer/tests/e2e/asyncHandler.decorator.test.ts b/packages/tracer/tests/e2e/asyncHandler.decorator.test.ts index 13693dfbdd..8d460ee0f1 100644 --- a/packages/tracer/tests/e2e/asyncHandler.decorator.test.ts +++ b/packages/tracer/tests/e2e/asyncHandler.decorator.test.ts @@ -6,14 +6,14 @@ import path from 'path'; import { AttributeType, BillingMode, Table } from 'aws-cdk-lib/aws-dynamodb'; -import { App, RemovalPolicy, Stack } from 'aws-cdk-lib'; +import { RemovalPolicy } from 'aws-cdk-lib'; import { XRayClient } from '@aws-sdk/client-xray'; import { STSClient } from '@aws-sdk/client-sts'; import { v4 } from 'uuid'; import { - deployStack, - destroyStack, -} from '../../../commons/tests/utils/cdk-cli'; + TestStack, + defaultRuntime, +} from '@aws-lambda-powertools/testing-utils'; import { createTracerTestFunction, getFirstSubsegment, @@ -45,7 +45,7 @@ import { assertErrorAndFault, } from '../helpers/traceAssertions'; -const runtime: string = process.env.RUNTIME || 'nodejs18x'; +const runtime: string = process.env.RUNTIME || defaultRuntime; if (!isValidRuntimeKey(runtime)) { throw new Error(`Invalid runtime key value: ${runtime}`); @@ -89,17 +89,15 @@ const xrayClient = new XRayClient({}); const stsClient = new STSClient({}); const invocations = 3; -const integTestApp = new App(); -let stack: Stack; +const testStack = new TestStack(stackName); describe(`Tracer E2E tests, asynchronous handler with decorator instantiation for runtime: ${runtime}`, () => { beforeAll(async () => { // Prepare startTime = new Date(); const ddbTableName = stackName + '-table'; - stack = new Stack(integTestApp, stackName); - const ddbTable = new Table(stack, 'Table', { + const ddbTable = new Table(testStack.stack, 'Table', { tableName: ddbTableName, partitionKey: { name: 'id', @@ -111,7 +109,7 @@ describe(`Tracer E2E tests, asynchronous handler with decorator instantiation fo const entry = path.join(__dirname, lambdaFunctionCodeFile); const functionWithAllFlagsEnabled = createTracerTestFunction({ - stack, + stack: testStack.stack, functionName: functionNameWithAllFlagsEnabled, entry, expectedServiceName: serviceNameWithAllFlagsEnabled, @@ -126,7 +124,7 @@ describe(`Tracer E2E tests, asynchronous handler with decorator instantiation fo ddbTable.grantWriteData(functionWithAllFlagsEnabled); const functionWithCustomSubsegmentNameInMethod = createTracerTestFunction({ - stack, + stack: testStack.stack, functionName: functionNameWithCustomSubsegmentNameInMethod, handler: 'handlerWithCustomSubsegmentNameInMethod', entry, @@ -142,7 +140,7 @@ describe(`Tracer E2E tests, asynchronous handler with decorator instantiation fo }); ddbTable.grantWriteData(functionWithCustomSubsegmentNameInMethod); - await deployStack(integTestApp, stack); + await testStack.deploy(); // Act await Promise.all([ @@ -153,7 +151,7 @@ describe(`Tracer E2E tests, asynchronous handler with decorator instantiation fo afterAll(async () => { if (!process.env.DISABLE_TEARDOWN) { - await destroyStack(integTestApp, stack); + await testStack.destroy(); } }, TEARDOWN_TIMEOUT);