From ea887abb938687ca5bcc3359cac260f2c17c1f32 Mon Sep 17 00:00:00 2001 From: Andrea Amorosi Date: Mon, 24 Jul 2023 14:58:44 +0200 Subject: [PATCH 01/15] tests(ci): add testing package --- package-lock.json | 412 +++++++++++++++++- package.json | 5 +- packages/testing/jest.config.js | 28 ++ packages/testing/package.json | 49 +++ packages/testing/src/TestCase.ts | 211 +++++++++ packages/testing/src/TestStack.ts | 253 +++++++++++ packages/testing/src/constants.ts | 17 + packages/testing/src/factories.ts | 161 +++++++ packages/testing/src/index.ts | 1 + packages/testing/src/types/TestStack.ts | 39 ++ packages/testing/src/types/factories.ts | 242 ++++++++++ packages/testing/src/types/index.ts | 2 + .../helpers/populateEnvironmentVariables.ts | 16 + packages/testing/tsconfig.es.json | 31 ++ packages/testing/tsconfig.json | 32 ++ 15 files changed, 1495 insertions(+), 4 deletions(-) create mode 100644 packages/testing/jest.config.js create mode 100644 packages/testing/package.json create mode 100644 packages/testing/src/TestCase.ts create mode 100644 packages/testing/src/TestStack.ts create mode 100644 packages/testing/src/constants.ts create mode 100644 packages/testing/src/factories.ts create mode 100644 packages/testing/src/index.ts create mode 100644 packages/testing/src/types/TestStack.ts create mode 100644 packages/testing/src/types/factories.ts create mode 100644 packages/testing/src/types/index.ts create mode 100644 packages/testing/tests/helpers/populateEnvironmentVariables.ts create mode 100644 packages/testing/tsconfig.es.json create mode 100644 packages/testing/tsconfig.json diff --git a/package-lock.json b/package-lock.json index 60cd7cfbea..a864909c5b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,11 +15,12 @@ "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", @@ -479,6 +480,15 @@ "md5": "^2.3.0" } }, + "node_modules/@aws-cdk/cli-lib-alpha": { + "version": "2.87.0-alpha.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/cli-lib-alpha/-/cli-lib-alpha-2.87.0-alpha.0.tgz", + "integrity": "sha512-6hhu7YT4zn4ByPbN8R2pmLJTnYQUXqS5tqiBalzKy8luUnG9QIkvke9m8N/QnyLvjj7L4mWUjVNC4fGUjZsSBw==", + "dev": true, + "engines": { + "node": ">= 14.15.0" + } + }, "node_modules/@aws-cdk/cloud-assembly-schema": { "version": "2.73.0", "bundleDependencies": [ @@ -719,6 +729,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 @@ -18842,6 +18856,400 @@ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, + "packages/testing": { + "name": "@aws-lambda-powertools/testing-utils", + "version": "1.11.1", + "license": "MIT-0", + "devDependencies": { + "@aws-cdk/cli-lib-alpha": "^2.87.0-alpha.0", + "aws-cdk-lib": "^2.73.0" + } + }, + "packages/testing/node_modules/aws-cdk-lib": { + "version": "2.73.0", + "resolved": "https://registry.npmjs.org/aws-cdk-lib/-/aws-cdk-lib-2.73.0.tgz", + "integrity": "sha512-r9CUe3R7EThr9U0Eb7kQCK4Ee34TDeMH+bonvGD9rNRRTYDauvAgNCsx4DZYYksPrXLRzWjzVbuXAHaDDzWt+A==", + "bundleDependencies": [ + "@balena/dockerignore", + "case", + "fs-extra", + "ignore", + "jsonschema", + "minimatch", + "punycode", + "semver", + "table", + "yaml" + ], + "dev": true, + "dependencies": { + "@aws-cdk/asset-awscli-v1": "^2.2.97", + "@aws-cdk/asset-kubectl-v20": "^2.1.1", + "@aws-cdk/asset-node-proxy-agent-v5": "^2.0.77", + "@balena/dockerignore": "^1.0.2", + "case": "1.6.3", + "fs-extra": "^9.1.0", + "ignore": "^5.2.4", + "jsonschema": "^1.4.1", + "minimatch": "^3.1.2", + "punycode": "^2.3.0", + "semver": "^7.3.8", + "table": "^6.8.1", + "yaml": "1.10.2" + }, + "engines": { + "node": ">= 14.15.0" + }, + "peerDependencies": { + "constructs": "^10.0.0" + } + }, + "packages/testing/node_modules/aws-cdk-lib/node_modules/@balena/dockerignore": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "Apache-2.0" + }, + "packages/testing/node_modules/aws-cdk-lib/node_modules/ajv": { + "version": "8.12.0", + "dev": true, + "inBundle": 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" + } + }, + "packages/testing/node_modules/aws-cdk-lib/node_modules/ansi-regex": { + "version": "5.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "packages/testing/node_modules/aws-cdk-lib/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "packages/testing/node_modules/aws-cdk-lib/node_modules/astral-regex": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "packages/testing/node_modules/aws-cdk-lib/node_modules/at-least-node": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": ">= 4.0.0" + } + }, + "packages/testing/node_modules/aws-cdk-lib/node_modules/balanced-match": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "packages/testing/node_modules/aws-cdk-lib/node_modules/brace-expansion": { + "version": "1.1.11", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "packages/testing/node_modules/aws-cdk-lib/node_modules/case": { + "version": "1.6.3", + "dev": true, + "inBundle": true, + "license": "(MIT OR GPL-3.0-or-later)", + "engines": { + "node": ">= 0.8.0" + } + }, + "packages/testing/node_modules/aws-cdk-lib/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "packages/testing/node_modules/aws-cdk-lib/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "packages/testing/node_modules/aws-cdk-lib/node_modules/concat-map": { + "version": "0.0.1", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "packages/testing/node_modules/aws-cdk-lib/node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "packages/testing/node_modules/aws-cdk-lib/node_modules/fast-deep-equal": { + "version": "3.1.3", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "packages/testing/node_modules/aws-cdk-lib/node_modules/fs-extra": { + "version": "9.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "packages/testing/node_modules/aws-cdk-lib/node_modules/graceful-fs": { + "version": "4.2.10", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "packages/testing/node_modules/aws-cdk-lib/node_modules/ignore": { + "version": "5.2.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "packages/testing/node_modules/aws-cdk-lib/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "packages/testing/node_modules/aws-cdk-lib/node_modules/json-schema-traverse": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "packages/testing/node_modules/aws-cdk-lib/node_modules/jsonfile": { + "version": "6.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "packages/testing/node_modules/aws-cdk-lib/node_modules/jsonschema": { + "version": "1.4.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "packages/testing/node_modules/aws-cdk-lib/node_modules/lodash.truncate": { + "version": "4.4.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "packages/testing/node_modules/aws-cdk-lib/node_modules/lru-cache": { + "version": "6.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "packages/testing/node_modules/aws-cdk-lib/node_modules/minimatch": { + "version": "3.1.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "packages/testing/node_modules/aws-cdk-lib/node_modules/punycode": { + "version": "2.3.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "packages/testing/node_modules/aws-cdk-lib/node_modules/require-from-string": { + "version": "2.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "packages/testing/node_modules/aws-cdk-lib/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" + } + }, + "packages/testing/node_modules/aws-cdk-lib/node_modules/slice-ansi": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "packages/testing/node_modules/aws-cdk-lib/node_modules/string-width": { + "version": "4.2.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "packages/testing/node_modules/aws-cdk-lib/node_modules/strip-ansi": { + "version": "6.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "packages/testing/node_modules/aws-cdk-lib/node_modules/table": { + "version": "6.8.1", + "dev": true, + "inBundle": 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" + } + }, + "packages/testing/node_modules/aws-cdk-lib/node_modules/universalify": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "packages/testing/node_modules/aws-cdk-lib/node_modules/uri-js": { + "version": "4.4.1", + "dev": true, + "inBundle": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "packages/testing/node_modules/aws-cdk-lib/node_modules/yallist": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "packages/testing/node_modules/aws-cdk-lib/node_modules/yaml": { + "version": "1.10.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": ">= 6" + } + }, "packages/tracer": { "name": "@aws-lambda-powertools/tracer", "version": "1.12.1", diff --git a/package.json b/package.json index 73bd6845da..110d422f74 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", 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..5e9762219b --- /dev/null +++ b/packages/testing/package.json @@ -0,0 +1,49 @@ +{ + "name": "@aws-lambda-powertools/testing-utils", + "version": "1.11.1", + "description": "A package containing utilities to test your serverless workloads", + "author": { + "name": "Amazon Web Services", + "url": "https://aws.amazon.com" + }, + "private": true, + "devDependencies": { + "@aws-cdk/cli-lib-alpha": "^2.87.0-alpha.0", + "aws-cdk-lib": "^2.73.0" + }, + "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" +} diff --git a/packages/testing/src/TestCase.ts b/packages/testing/src/TestCase.ts new file mode 100644 index 0000000000..d1692d790c --- /dev/null +++ b/packages/testing/src/TestCase.ts @@ -0,0 +1,211 @@ +import type { NodejsFunction } from 'aws-cdk-lib/aws-lambda-nodejs'; +import type { Table } from 'aws-cdk-lib/aws-dynamodb'; +import type { IStringParameter, StringParameter } from 'aws-cdk-lib/aws-ssm'; +import { PolicyStatement, Effect } from 'aws-cdk-lib/aws-iam'; + +class NodeJsFunction { + public functionName: string; + public ref: NodejsFunction; + + public constructor(name: string, ref: NodejsFunction) { + this.functionName = name; + this.ref = ref; + } +} + +class DynamoDBTable { + public ref: Table; + public tableName: string; + readonly #envVariableName?: string; + + public constructor(name: string, ref: Table, envVariableName?: string) { + this.tableName = name; + this.ref = ref; + this.#envVariableName = envVariableName; + } + + public get envVariableName(): string { + return this.#envVariableName || 'TABLE_NAME'; + } +} + +class SsmSecureString { + public parameterName: string; + public ref: IStringParameter; + readonly #envVariableName?: string; + + public constructor( + name: string, + ref: IStringParameter, + envVariableName?: string + ) { + this.parameterName = name; + this.ref = ref; + this.#envVariableName = envVariableName; + } + + public get envVariableName(): string { + return this.#envVariableName || 'SECURE_STRING_NAME'; + } +} + +class SsmString { + public parameterName: string; + public ref: StringParameter; + readonly #envVariableName?: string; + + public constructor( + name: string, + ref: StringParameter, + envVariableName?: string + ) { + this.parameterName = name; + this.ref = ref; + this.#envVariableName = envVariableName; + } + + public get envVariableName(): string { + return this.#envVariableName || 'SSM_STRING_NAME'; + } +} + +/** + * A test case that can be added to a test stack. + */ +class TestCase { + public testName: string; + #dynamodb?: DynamoDBTable; + #function?: NodeJsFunction; + #ssmSecureString?: SsmSecureString; + #ssmString?: SsmString; + + public constructor(testName: string) { + this.testName = testName; + } + + /** + * The NodejsFunction that is associated with this test case. + */ + public set function(fn: NodeJsFunction) { + if (this.#dynamodb) { + this.#grantAccessToDynamoDBTableAndSetEnv(fn, this.#dynamodb); + } + if (this.#ssmSecureString) { + this.#grantAccessToSsmeStringAndSetEnv(fn, this.#ssmSecureString); + } + if (this.#ssmString) { + this.#grantAccessToSsmeStringAndSetEnv(fn, this.#ssmString); + } + this.#function = fn; + } + + /** + * Get the NodejsFunction that is associated with this test case. + */ + public get function(): NodeJsFunction { + if (!this.#function) throw new Error('This test case has no function.'); + + return this.#function; + } + + /** + * The DynamoDB table that is associated with this test case. + */ + public set dynamodb(table: DynamoDBTable) { + if (this.#function) { + this.#grantAccessToDynamoDBTableAndSetEnv(this.#function, table); + } + this.#dynamodb = table; + } + + /** + * Get the DynamoDB table that is associated with this test case. + */ + public get dynamodb(): DynamoDBTable { + if (!this.#dynamodb) + throw new Error('This test case has no DynamoDB table.'); + + return this.#dynamodb; + } + + /** + * Grant access to the DynamoDB table and set the environment variable to + * the table name. + * + * @param fn - The function to grant access to the table and set the environment variable. + * @param table - The table to grant access to and identified by the environment variable. + */ + #grantAccessToDynamoDBTableAndSetEnv = ( + fn: NodeJsFunction, + table: DynamoDBTable + ): void => { + table.ref.grantReadWriteData(fn.ref); + fn.ref.addEnvironment(table.envVariableName, table.ref.tableName); + }; + + /** + * The SSM SecureString that is associated with this test case. + */ + public set ssmSecureString(parameter: SsmSecureString) { + if (this.#function) { + this.#grantAccessToSsmeStringAndSetEnv(this.#function, parameter); + } + this.#ssmSecureString = parameter; + } + + /** + * Get the SSM SecureString that is associated with this test case. + */ + public get ssmSecureString(): SsmSecureString { + if (!this.#ssmSecureString) + throw new Error('This test case has no SSM SecureString.'); + + return this.#ssmSecureString; + } + + /** + * The SSM String that is associated with this test case. + */ + public set ssmString(parameter: SsmString) { + if (this.#function) { + this.#grantAccessToSsmeStringAndSetEnv(this.#function, parameter); + } + this.#ssmString = parameter; + } + + /** + * Get the SSM String that is associated with this test case. + */ + public get ssmString(): SsmString { + if (!this.#ssmString) throw new Error('This test case has no SSM String.'); + + return this.#ssmString; + } + + /** + * Grant access to the SSM String and set the environment variable to + * the parameter name. + * + * @param fn - The function to grant access to the parameter and set the environment variable. + * @param parameter - The parameter to grant access to and identified by the environment variable. + */ + #grantAccessToSsmeStringAndSetEnv = ( + fn: NodeJsFunction, + parameter: SsmSecureString | SsmString + ): void => { + fn.ref.addEnvironment(parameter.envVariableName, parameter.parameterName); + // Grant access also to the path of the parameter + fn.ref.addToRolePolicy( + new PolicyStatement({ + effect: Effect.ALLOW, + actions: ['ssm:GetParametersByPath'], + resources: [ + parameter.ref.parameterArn.split(':').slice(0, -1).join(':'), + ], + }) + ); + parameter.ref.grantRead(fn.ref); + }; +} + +export { TestCase, NodeJsFunction, DynamoDBTable, SsmSecureString, SsmString }; diff --git a/packages/testing/src/TestStack.ts b/packages/testing/src/TestStack.ts new file mode 100644 index 0000000000..34d963f250 --- /dev/null +++ b/packages/testing/src/TestStack.ts @@ -0,0 +1,253 @@ +import { App, Stack } from 'aws-cdk-lib'; +import { AwsCdkCli, RequireApproval } from '@aws-cdk/cli-lib-alpha'; +import { randomUUID } from 'node:crypto'; +import type { ICloudAssemblyDirectoryProducer } from '@aws-cdk/cli-lib-alpha'; +import { + dynamoDBTable, + dynamoDBItem, + nodejsFunction, + ssmSecureString, + ssmString, +} from './factories'; +import { TEST_RUNTIMES, defaultRuntime } from './constants'; +import { + NodeJsFunction, + DynamoDBTable, + SsmSecureString, + TestCase, + SsmString, +} from './TestCase'; +import type { + AddFunctionOptions, + AddDynamoDBTableOptions, + AddTestCaseOptions, + AddSsmSecureStringOptions, + AddSsmStringOptions, +} from './types'; + +class TestStack implements ICloudAssemblyDirectoryProducer { + public app: App; + public cli: AwsCdkCli; + public stack: Stack; + readonly #resourceNamePrefix; + readonly #runtime: keyof typeof TEST_RUNTIMES; + readonly #testCases = new Map(); + + public constructor(resourceNamePrefix: string, testName: string) { + this.#resourceNamePrefix = resourceNamePrefix; + const providedRuntime = process.env.RUNTIME || defaultRuntime; + if (!(providedRuntime in TEST_RUNTIMES)) { + throw new Error( + `Invalid runtime: ${providedRuntime}. Valid runtimes are: ${Object.keys( + TEST_RUNTIMES + ).join(', ')}` + ); + } + this.#runtime = providedRuntime as keyof typeof TEST_RUNTIMES; + this.app = new App(); + this.stack = new Stack(this.app, this.#generateUniqueName(testName)); + this.cli = AwsCdkCli.fromCloudAssemblyDirectoryProducer(this); + } + + /** + * Add a DynamoDB table to the test stack. + * + * @returns A reference to the DynamoDB table that was added to the stack. + */ + #addDynamoDBTable = ( + testCaseName: string, + options: AddDynamoDBTableOptions + ): DynamoDBTable => { + const resourceId = this.#generateUniqueName(`${testCaseName}-table`); + const name = options.name || resourceId; + const table = dynamoDBTable({ + ...options, + stack: this.stack, + resourceId, + name, + }); + + return new DynamoDBTable(name, table, options.envVariableName); + }; + + /** + * Add a NodejsFunction to the test stack. + * + * @returns A reference to the NodejsFunction that was added to the stack. + */ + #addFunction = ( + testCaseName: string, + options: AddFunctionOptions + ): NodeJsFunction => { + const resourceId = this.#generateUniqueName(`${testCaseName}-fn`); + const name = options.functionConfigs?.name || resourceId; + const fn = nodejsFunction({ + stack: this.stack, + resourceId, + runtime: this.#runtime, + functionConfigs: { + ...options.functionConfigs, + name, + }, + functionCode: options.functionCode, + }); + + return new NodeJsFunction(name, fn); + }; + + /** + * Add a SSM SecureString to the test stack. + */ + #addSsmSecureString = ( + testCaseName: string, + options: AddSsmSecureStringOptions + ): SsmSecureString => { + const resourceId = this.#generateUniqueName(`${testCaseName}-ssmSecure`); + const name = options.name || resourceId; + const ssmSecure = ssmSecureString({ + stack: this.stack, + resourceId, + name, + value: options.value, + }); + + return new SsmSecureString(name, ssmSecure, options.envVariableName); + }; + + /** + * Add a SSM String to the test stack. + */ + #addSsmString = ( + testCaseName: string, + options: AddSsmStringOptions + ): SsmString => { + const resourceId = this.#generateUniqueName(`${testCaseName}-ssmString`); + const name = options.name || resourceId; + const ssm = ssmString({ + stack: this.stack, + resourceId, + name, + value: options.value, + }); + + return new SsmString(name, ssm, options.envVariableName); + }; + + /** + * Create a TestCase and add it to the test stack. + * + * @param options - The options for creating a TestCase. + */ + public addTestCase = (options: AddTestCaseOptions): void => { + if (this.#testCases.has(options.testCaseName)) { + throw new Error( + `A test case with the name ${options.testCaseName} already exists.` + ); + } + // Initialize the test case + const test = new TestCase(options.testCaseName); + // Add the function to the test case + const fn = this.#addFunction(options.testCaseName, options.function); + test.function = fn; + // If the test case has a DynamoDB table, add it + if (options?.dynamodb) { + const table = this.#addDynamoDBTable( + options.testCaseName, + options.dynamodb + ); + // If the test case has items, add them to the table + if (options.dynamodb?.items) { + options.dynamodb.items.forEach((item, index) => { + dynamoDBItem({ + stack: this.stack, + resourceId: this.#generateUniqueName( + `${options.testCaseName}-item${index}` + ), + tableName: table.tableName, + tableArn: table.ref.tableArn, + item, + }); + }); + } + // Save a reference to the table in the test case + test.dynamodb = table; + } + // If the test case has a SSM SecureString, add it + if (options?.ssmSecureString) { + const ssmSecureString = this.#addSsmSecureString( + options.testCaseName, + options.ssmSecureString + ); + // Save a reference to the SSM SecureString in the test case + test.ssmSecureString = ssmSecureString; + } + // If the test case has a SSM String, add it + if (options?.ssmString) { + const ssmString = this.#addSsmString( + options.testCaseName, + options.ssmString + ); + // Save a reference to the SSM String in the test case + test.ssmString = ssmString; + } + + this.#testCases.set(options.testCaseName, test); + }; + + /** + * Deploy the test stack to the selected environment. + */ + public async deploy(): Promise { + await this.cli.deploy({ + stacks: [this.stack.stackName], + requireApproval: RequireApproval.NEVER, + }); + } + + /** + * Destroy the test stack. + */ + public async destroy(): Promise { + await this.cli.destroy({ + stacks: [this.stack.stackName], + requireApproval: false, + }); + } + + /** + * Get a test case from the test stack. + * + * If no test case with the provided name exists, an error is thrown. + * + * @param testCaseName - The name of the test case to get. + */ + public getTestCase = (testCaseName: string): TestCase => { + const testCase = this.#testCases.get(testCaseName); + if (!testCase) { + throw new Error(`No test case with name ${testCaseName} exists.`); + } + + return testCase; + }; + + public async produce(_context: Record): Promise { + return this.app.synth().directory; + } + + public async synth(): Promise { + await this.cli.synth({ + stacks: [this.stack.stackName], + }); + } + + #generateUniqueName = (resourceName: string): string => { + const uuid = randomUUID(); + + return `${this.#resourceNamePrefix}-${this.#runtime}-${uuid.substring( + 0, + 5 + )}-${resourceName}`.substring(0, 64); + }; +} + +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/factories.ts b/packages/testing/src/factories.ts new file mode 100644 index 0000000000..05c519fcc4 --- /dev/null +++ b/packages/testing/src/factories.ts @@ -0,0 +1,161 @@ +import { CfnOutput, Duration, RemovalPolicy } from 'aws-cdk-lib'; +import { NodejsFunction } from 'aws-cdk-lib/aws-lambda-nodejs'; +import { Tracing, Architecture } from 'aws-cdk-lib/aws-lambda'; +import { RetentionDays } from 'aws-cdk-lib/aws-logs'; +import { PhysicalResourceId } from 'aws-cdk-lib/custom-resources'; +import { + AwsCustomResource, + AwsCustomResourcePolicy, +} from 'aws-cdk-lib/custom-resources'; +import { StringParameter } from 'aws-cdk-lib/aws-ssm'; +import { Table, BillingMode, AttributeType } from 'aws-cdk-lib/aws-dynamodb'; +import { TEST_RUNTIMES } from './constants'; +import { marshall } from '@aws-sdk/util-dynamodb'; +import type { IStringParameter } from 'aws-cdk-lib/aws-ssm'; +import type { + NodejsFunctionOptions, + DynamoDBTableOptions, + SsmSecureStringOptions, + DynamoDBItemOptions, + SsmStringOptions, +} from './types'; + +/** + * Add a NodejsFunction to the test stack. + * + * @param options - The options for creating a NodejsFunction. + */ +const nodejsFunction = (options: NodejsFunctionOptions): NodejsFunction => { + const nodeJsFunction = new NodejsFunction(options.stack, options.resourceId, { + runtime: TEST_RUNTIMES[options.runtime], + functionName: options.functionConfigs?.name, + timeout: Duration.seconds(options.functionConfigs?.timeout || 30), + entry: options?.functionCode?.path, + handler: options?.functionCode?.handler || 'handler', + environment: { + ...(options.functionConfigs?.environment || {}), + }, + tracing: options.functionConfigs?.tracing || Tracing.ACTIVE, + memorySize: options.functionConfigs?.memorySize || 256, + architecture: options.functionConfigs?.architecture || Architecture.X86_64, + logRetention: RetentionDays.ONE_DAY, + bundling: options?.functionCode?.bundling, + }); + + if (options.logGroupOutputKey) { + new CfnOutput(options.stack, options.logGroupOutputKey, { + value: nodeJsFunction.logGroup.logGroupName, + }); + } + + return nodeJsFunction; +}; + +/** + * Add a DynamoDB table to the test stack. + * + * @param options - The options for creating a DynamoDB table. + */ +const dynamoDBTable = (options: DynamoDBTableOptions): Table => { + const table = new Table(options.stack, options.resourceId, { + tableName: options.name, + partitionKey: { + name: options?.partitionKey?.name || 'id', + type: options?.partitionKey?.type || AttributeType.STRING, + }, + ...(options?.sortKey || {}), + billingMode: options.billingMode || BillingMode.PAY_PER_REQUEST, + removalPolicy: RemovalPolicy.DESTROY, + }); + + return table; +}; + +/** + * Add an item to a DynamoDB table in the test stack. + * + * @param options - The options for creating a DynamoDB item. + */ +const dynamoDBItem = (options: DynamoDBItemOptions): void => { + new AwsCustomResource(options.stack, options.resourceId, { + onCreate: { + service: 'DynamoDB', + action: 'putItem', + parameters: { + TableName: options.tableName, + Item: marshall(options.item), + }, + physicalResourceId: PhysicalResourceId.of(options.resourceId), + }, + policy: AwsCustomResourcePolicy.fromSdkCalls({ + resources: [options.tableArn], + }), + }); +}; + +/** + * Add a SSM String parameter to the test stack. + * + * @param options - The options for creating a SSM String parameter. + */ +const ssmString = (options: SsmStringOptions): StringParameter => { + const ssmString = new StringParameter(options.stack, options.resourceId, { + parameterName: options.name, + stringValue: options.value, + }); + + return ssmString; +}; + +/** + * Add a SSM SecureString parameter to the test stack. + * + * @param options - The options for creating a SSM SecureString parameter. + */ +const ssmSecureString = (options: SsmSecureStringOptions): IStringParameter => { + const resourceCreator = new AwsCustomResource( + options.stack, + `creator-${options.resourceId}`, + { + onCreate: { + service: 'SSM', + action: 'putParameter', + parameters: { + Name: options.name || options.resourceId, + Value: options.value, + Type: 'SecureString', + }, + physicalResourceId: PhysicalResourceId.of(options.resourceId), + }, + onDelete: { + service: 'SSM', + action: 'deleteParameter', + parameters: { + Name: options.name || options.resourceId, + }, + }, + policy: AwsCustomResourcePolicy.fromSdkCalls({ + resources: AwsCustomResourcePolicy.ANY_RESOURCE, + }), + } + ); + + const secureString = StringParameter.fromSecureStringParameterAttributes( + options.stack, + options.resourceId, + { + parameterName: options.name || options.resourceId, + } + ); + secureString.node.addDependency(resourceCreator); + + return secureString; +}; + +export { + nodejsFunction, + dynamoDBTable, + dynamoDBItem, + ssmSecureString, + ssmString, +}; diff --git a/packages/testing/src/index.ts b/packages/testing/src/index.ts new file mode 100644 index 0000000000..11d3cd4421 --- /dev/null +++ b/packages/testing/src/index.ts @@ -0,0 +1 @@ +export * from './TestStack'; diff --git a/packages/testing/src/types/TestStack.ts b/packages/testing/src/types/TestStack.ts new file mode 100644 index 0000000000..a93ff27dc3 --- /dev/null +++ b/packages/testing/src/types/TestStack.ts @@ -0,0 +1,39 @@ +import type { + NodejsFunctionOptions, + DynamoDBTableOptions, + SsmSecureStringOptions, + SsmStringOptions, +} from './factories'; + +type AddFunctionOptions = Omit< + NodejsFunctionOptions, + 'stack' | 'resourceId' | 'runtime' +>; + +type AddDynamoDBTableOptions = Omit< + DynamoDBTableOptions, + 'stack' | 'resourceId' +>; + +type AddSsmSecureStringOptions = Omit< + SsmSecureStringOptions, + 'stack' | 'resourceId' +>; + +type AddSsmStringOptions = Omit; + +type AddTestCaseOptions = { + testCaseName: string; + function: AddFunctionOptions; + dynamodb?: AddDynamoDBTableOptions; + ssmSecureString?: AddSsmSecureStringOptions; + ssmString?: AddSsmStringOptions; +}; + +export { + AddFunctionOptions, + AddDynamoDBTableOptions, + AddTestCaseOptions, + AddSsmSecureStringOptions, + AddSsmStringOptions, +}; diff --git a/packages/testing/src/types/factories.ts b/packages/testing/src/types/factories.ts new file mode 100644 index 0000000000..fbeeea984d --- /dev/null +++ b/packages/testing/src/types/factories.ts @@ -0,0 +1,242 @@ +import type { Stack } from 'aws-cdk-lib'; +import type { FunctionOptions } from 'aws-cdk-lib/aws-lambda'; +import type { NodejsFunctionProps } from 'aws-cdk-lib/aws-lambda-nodejs'; +import type { AttributeType, BillingMode } from 'aws-cdk-lib/aws-dynamodb'; +import { TEST_RUNTIMES } from '../constants'; + +/** + * Options for creating a NodejsFunction. + */ +type NodejsFunctionOptions = { + /** + * The stack to add the function to. + */ + stack: Stack; + /** + * The unique identifier for the function. + */ + resourceId: string; + /** + * The runtime for the function. + */ + runtime: keyof typeof TEST_RUNTIMES; + /** + * The function code. + */ + functionCode: { + /** + * The absolute path to the entry file. + * @default - None + */ + path: NodejsFunctionProps['entry']; + /** + * The name of the function handler. + * @default - handler + */ + handler?: NodejsFunctionProps['handler']; + /** + * Options for bundling with esbuild. + */ + bundling?: NodejsFunctionProps['bundling']; + }; + /** + * Function configurations. + */ + functionConfigs?: { + /** + * The amount of memory, in MB, that is allocated to your Lambda function. + * @default - The default value is 256 MB. + */ + memorySize?: FunctionOptions['memorySize']; + /** + * The function execution time (in seconds) after which Lambda terminates the function. + * @default - The default value is 30 seconds. + */ + timeout?: number; + /** + * The environment variables for the Lambda function service. + * @default - No environment variables. + */ + environment?: FunctionOptions['environment']; + /** + * A name for the function. + * @default - The utility will generate a unique name for the function. + */ + name?: FunctionOptions['functionName']; + /** + * Enable AWS X-Ray Tracing for Lambda Function. + * @default - Enabled + */ + tracing?: FunctionOptions['tracing']; + /** + * The Lambda runtime architecture to use. + * @default - x86_64 + */ + architecture?: FunctionOptions['architecture']; + }; + /** + * The name of the CloudFormation Output key to store the log group name. + * + * When this property is set, the log group name will be stored in the CloudFormation Output. + * + * @default - No output + */ + logGroupOutputKey?: string; +}; + +/** + * Options for creating a DynamoDB table. + */ +type DynamoDBTableOptions = { + /** + * The stack to add the table to. + */ + stack: Stack; + /** + * The unique identifier for the table. + */ + resourceId: string; + /** + * The name of the table. + */ + name?: string; + /** + * The partition key for the table. + * @default - id (string) + */ + partitionKey?: { + /** + * The name of the partition key. + * @default - id + */ + name?: string; + /** + * The type of the partition key. + * @default - AttributeType.STRING + */ + type?: AttributeType; + }; + /** + * The sort key for the table. + * @default - None + */ + sortKey?: { + /** + * The name of the sort key. + * @default - None + */ + name?: string; + /** + * The type of the sort key. + * @default - None + */ + type?: AttributeType; + }; + /** + * The billing mode for the table. + * @default - BillingMode.PAY_PER_REQUEST + */ + billingMode?: BillingMode; + /** + * The name of the environment variable that will store the table name + * and that will be applied to the function. + * @default - TABLE_NAME + */ + envVariableName?: string; + /** + * Items to add to the table. + */ + items?: Array; +}; + +/** + * Add an item to a DynamoDB table. + */ +type DynamoDBItemOptions = { + /** + * The stack to of the table to add the item to. + */ + stack: Stack; + /** + * The unique identifier for the item. + */ + resourceId: string; + /** + * The name of the table to add the item to. + */ + tableName: string; + /** + * The arn of the table to add the item to. + */ + tableArn: string; + /** + * The item to add to the table. + */ + item: Record; +}; + +/** + * Options for creating a SSM Secure String. + */ +type SsmSecureStringOptions = { + /** + * The stack to add the secure string to. + */ + stack: Stack; + /** + * The unique identifier for the secure string. + */ + resourceId: string; + /** + * The name of the secure string. + * @default - Same as resourceId + */ + name?: string; + /** + * The value of the secure string. + */ + value: string; + /** + * The name of the environment variable that will store the name + * of the string and that will be applied to the function. + * @default - SECURE_STRING_NAME + */ + envVariableName?: string; +}; + +/** + * Options for creating a SSM String. + */ +type SsmStringOptions = { + /** + * The stack to add the string to. + */ + stack: Stack; + /** + * The unique identifier for the string. + */ + resourceId: string; + /** + * The name of the string. + * @default - Same as resourceId + */ + name?: string; + /** + * The value of the string. + */ + value: string; + /** + * The name of the environment variable that will store the name + * of the string and that will be applied to the function. + * @default - SECURE_STRING_NAME + */ + envVariableName?: string; +}; + +export { + NodejsFunctionOptions, + DynamoDBTableOptions, + DynamoDBItemOptions, + SsmSecureStringOptions, + SsmStringOptions, +}; diff --git a/packages/testing/src/types/index.ts b/packages/testing/src/types/index.ts new file mode 100644 index 0000000000..71c096ea42 --- /dev/null +++ b/packages/testing/src/types/index.ts @@ -0,0 +1,2 @@ +export * from './factories'; +export * from './TestStack'; 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 From 2f251f2d9aa35bc9d5f985172c2dc832e28cae95 Mon Sep 17 00:00:00 2001 From: Andrea Amorosi Date: Mon, 24 Jul 2023 14:59:29 +0200 Subject: [PATCH 02/15] chore: add comments on types --- packages/testing/src/types/TestStack.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/packages/testing/src/types/TestStack.ts b/packages/testing/src/types/TestStack.ts index a93ff27dc3..197cbb4f6c 100644 --- a/packages/testing/src/types/TestStack.ts +++ b/packages/testing/src/types/TestStack.ts @@ -5,23 +5,38 @@ import type { SsmStringOptions, } from './factories'; +/** + * Options to add a NodejsFunction to the test stack. + */ type AddFunctionOptions = Omit< NodejsFunctionOptions, 'stack' | 'resourceId' | 'runtime' >; +/** + * Options to add a DynamoDB table to the test stack. + */ type AddDynamoDBTableOptions = Omit< DynamoDBTableOptions, 'stack' | 'resourceId' >; +/** + * Options to add a SSM Secure String to the test stack. + */ type AddSsmSecureStringOptions = Omit< SsmSecureStringOptions, 'stack' | 'resourceId' >; +/** + * Options to add a SSM String to the test stack. + */ type AddSsmStringOptions = Omit; +/** + * Options to add a test case to the test stack. + */ type AddTestCaseOptions = { testCaseName: string; function: AddFunctionOptions; From c73e2406d46c386e6e85e5d9118046e98a1ff808 Mon Sep 17 00:00:00 2001 From: Andrea Amorosi Date: Mon, 24 Jul 2023 18:50:39 +0200 Subject: [PATCH 03/15] chore: improve code smells --- packages/testing/src/TestCase.ts | 36 +++++++++++++++++-------------- packages/testing/src/TestStack.ts | 6 +++--- packages/testing/src/factories.ts | 34 +++++++++++++++-------------- 3 files changed, 41 insertions(+), 35 deletions(-) diff --git a/packages/testing/src/TestCase.ts b/packages/testing/src/TestCase.ts index d1692d790c..51de2992b4 100644 --- a/packages/testing/src/TestCase.ts +++ b/packages/testing/src/TestCase.ts @@ -25,47 +25,51 @@ class DynamoDBTable { } public get envVariableName(): string { - return this.#envVariableName || 'TABLE_NAME'; + return this.#envVariableName ?? 'TABLE_NAME'; } } -class SsmSecureString { +abstract class SSMResource { public parameterName: string; - public ref: IStringParameter; - readonly #envVariableName?: string; + public ref: StringParameter | IStringParameter; + protected readonly envVarName?: string; public constructor( name: string, - ref: IStringParameter, + ref: StringParameter | IStringParameter, envVariableName?: string ) { this.parameterName = name; this.ref = ref; - this.#envVariableName = envVariableName; + this.envVarName = envVariableName; + } +} + +class SsmSecureString extends SSMResource { + public constructor( + name: string, + ref: IStringParameter, + envVariableName?: string + ) { + super(name, ref, envVariableName); } public get envVariableName(): string { - return this.#envVariableName || 'SECURE_STRING_NAME'; + return this.envVarName ?? 'SECURE_STRING_NAME'; } } -class SsmString { - public parameterName: string; - public ref: StringParameter; - readonly #envVariableName?: string; - +class SsmString extends SSMResource { public constructor( name: string, ref: StringParameter, envVariableName?: string ) { - this.parameterName = name; - this.ref = ref; - this.#envVariableName = envVariableName; + super(name, ref, envVariableName); } public get envVariableName(): string { - return this.#envVariableName || 'SSM_STRING_NAME'; + return this.envVarName ?? 'SSM_STRING_NAME'; } } diff --git a/packages/testing/src/TestStack.ts b/packages/testing/src/TestStack.ts index 34d963f250..798df92404 100644 --- a/packages/testing/src/TestStack.ts +++ b/packages/testing/src/TestStack.ts @@ -59,7 +59,7 @@ class TestStack implements ICloudAssemblyDirectoryProducer { options: AddDynamoDBTableOptions ): DynamoDBTable => { const resourceId = this.#generateUniqueName(`${testCaseName}-table`); - const name = options.name || resourceId; + const name = options.name ?? resourceId; const table = dynamoDBTable({ ...options, stack: this.stack, @@ -80,7 +80,7 @@ class TestStack implements ICloudAssemblyDirectoryProducer { options: AddFunctionOptions ): NodeJsFunction => { const resourceId = this.#generateUniqueName(`${testCaseName}-fn`); - const name = options.functionConfigs?.name || resourceId; + const name = options.functionConfigs?.name ?? resourceId; const fn = nodejsFunction({ stack: this.stack, resourceId, @@ -103,7 +103,7 @@ class TestStack implements ICloudAssemblyDirectoryProducer { options: AddSsmSecureStringOptions ): SsmSecureString => { const resourceId = this.#generateUniqueName(`${testCaseName}-ssmSecure`); - const name = options.name || resourceId; + const name = options.name ?? resourceId; const ssmSecure = ssmSecureString({ stack: this.stack, resourceId, diff --git a/packages/testing/src/factories.ts b/packages/testing/src/factories.ts index 05c519fcc4..a4322d4f39 100644 --- a/packages/testing/src/factories.ts +++ b/packages/testing/src/factories.ts @@ -2,8 +2,8 @@ import { CfnOutput, Duration, RemovalPolicy } from 'aws-cdk-lib'; import { NodejsFunction } from 'aws-cdk-lib/aws-lambda-nodejs'; import { Tracing, Architecture } from 'aws-cdk-lib/aws-lambda'; import { RetentionDays } from 'aws-cdk-lib/aws-logs'; -import { PhysicalResourceId } from 'aws-cdk-lib/custom-resources'; import { + PhysicalResourceId, AwsCustomResource, AwsCustomResourcePolicy, } from 'aws-cdk-lib/custom-resources'; @@ -29,15 +29,15 @@ const nodejsFunction = (options: NodejsFunctionOptions): NodejsFunction => { const nodeJsFunction = new NodejsFunction(options.stack, options.resourceId, { runtime: TEST_RUNTIMES[options.runtime], functionName: options.functionConfigs?.name, - timeout: Duration.seconds(options.functionConfigs?.timeout || 30), + timeout: Duration.seconds(options.functionConfigs?.timeout ?? 30), entry: options?.functionCode?.path, - handler: options?.functionCode?.handler || 'handler', + handler: options?.functionCode?.handler ?? 'handler', environment: { - ...(options.functionConfigs?.environment || {}), + ...(options.functionConfigs?.environment ?? {}), }, - tracing: options.functionConfigs?.tracing || Tracing.ACTIVE, - memorySize: options.functionConfigs?.memorySize || 256, - architecture: options.functionConfigs?.architecture || Architecture.X86_64, + tracing: options.functionConfigs?.tracing ?? Tracing.ACTIVE, + memorySize: options.functionConfigs?.memorySize ?? 256, + architecture: options.functionConfigs?.architecture ?? Architecture.X86_64, logRetention: RetentionDays.ONE_DAY, bundling: options?.functionCode?.bundling, }); @@ -60,11 +60,11 @@ const dynamoDBTable = (options: DynamoDBTableOptions): Table => { const table = new Table(options.stack, options.resourceId, { tableName: options.name, partitionKey: { - name: options?.partitionKey?.name || 'id', - type: options?.partitionKey?.type || AttributeType.STRING, + name: options?.partitionKey?.name ?? 'id', + type: options?.partitionKey?.type ?? AttributeType.STRING, }, - ...(options?.sortKey || {}), - billingMode: options.billingMode || BillingMode.PAY_PER_REQUEST, + ...(options?.sortKey ?? {}), + billingMode: options.billingMode ?? BillingMode.PAY_PER_REQUEST, removalPolicy: RemovalPolicy.DESTROY, }); @@ -76,8 +76,8 @@ const dynamoDBTable = (options: DynamoDBTableOptions): Table => { * * @param options - The options for creating a DynamoDB item. */ -const dynamoDBItem = (options: DynamoDBItemOptions): void => { - new AwsCustomResource(options.stack, options.resourceId, { +const dynamoDBItem = (options: DynamoDBItemOptions): AwsCustomResource => { + const item = new AwsCustomResource(options.stack, options.resourceId, { onCreate: { service: 'DynamoDB', action: 'putItem', @@ -91,6 +91,8 @@ const dynamoDBItem = (options: DynamoDBItemOptions): void => { resources: [options.tableArn], }), }); + + return item; }; /** @@ -121,7 +123,7 @@ const ssmSecureString = (options: SsmSecureStringOptions): IStringParameter => { service: 'SSM', action: 'putParameter', parameters: { - Name: options.name || options.resourceId, + Name: options.name ?? options.resourceId, Value: options.value, Type: 'SecureString', }, @@ -131,7 +133,7 @@ const ssmSecureString = (options: SsmSecureStringOptions): IStringParameter => { service: 'SSM', action: 'deleteParameter', parameters: { - Name: options.name || options.resourceId, + Name: options.name ?? options.resourceId, }, }, policy: AwsCustomResourcePolicy.fromSdkCalls({ @@ -144,7 +146,7 @@ const ssmSecureString = (options: SsmSecureStringOptions): IStringParameter => { options.stack, options.resourceId, { - parameterName: options.name || options.resourceId, + parameterName: options.name ?? options.resourceId, } ); secureString.node.addDependency(resourceCreator); From c9f07dfc7500800d05d1b0c350e57c4581f31cf4 Mon Sep 17 00:00:00 2001 From: Andrea Amorosi Date: Mon, 24 Jul 2023 18:52:05 +0200 Subject: [PATCH 04/15] chore: improve code smells --- packages/testing/src/TestStack.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/testing/src/TestStack.ts b/packages/testing/src/TestStack.ts index 798df92404..7bc91e00aa 100644 --- a/packages/testing/src/TestStack.ts +++ b/packages/testing/src/TestStack.ts @@ -122,7 +122,7 @@ class TestStack implements ICloudAssemblyDirectoryProducer { options: AddSsmStringOptions ): SsmString => { const resourceId = this.#generateUniqueName(`${testCaseName}-ssmString`); - const name = options.name || resourceId; + const name = options.name ?? resourceId; const ssm = ssmString({ stack: this.stack, resourceId, From c560aafe654a89a1f6a10eaae343ed03f6ddfb93 Mon Sep 17 00:00:00 2001 From: Andrea Amorosi Date: Thu, 27 Jul 2023 13:51:33 +0200 Subject: [PATCH 05/15] feat(testing): created base testing --- packages/testing/package.json | 8 +- packages/testing/src/TestCase.ts | 215 --------------------- packages/testing/src/TestStack.ts | 218 +-------------------- packages/testing/src/factories.ts | 163 ---------------- packages/testing/src/index.ts | 1 + packages/testing/src/types/TestStack.ts | 54 ------ packages/testing/src/types/factories.ts | 242 ------------------------ packages/testing/src/types/index.ts | 2 - 8 files changed, 11 insertions(+), 892 deletions(-) delete mode 100644 packages/testing/src/TestCase.ts delete mode 100644 packages/testing/src/factories.ts delete mode 100644 packages/testing/src/types/TestStack.ts delete mode 100644 packages/testing/src/types/factories.ts delete mode 100644 packages/testing/src/types/index.ts diff --git a/packages/testing/package.json b/packages/testing/package.json index 5e9762219b..a039363618 100644 --- a/packages/testing/package.json +++ b/packages/testing/package.json @@ -1,6 +1,6 @@ { "name": "@aws-lambda-powertools/testing-utils", - "version": "1.11.1", + "version": "1.12.1", "description": "A package containing utilities to test your serverless workloads", "author": { "name": "Amazon Web Services", @@ -8,8 +8,8 @@ }, "private": true, "devDependencies": { - "@aws-cdk/cli-lib-alpha": "^2.87.0-alpha.0", - "aws-cdk-lib": "^2.73.0" + "@aws-cdk/cli-lib-alpha": "^2.88.0-alpha.0", + "aws-cdk-lib": "^2.88.0" }, "scripts": { "test": "npm run test:unit", @@ -46,4 +46,4 @@ "url": "https://github.com/aws-powertools/powertools-lambda-typescript/issues" }, "homepage": "https://github.com/aws-powertools/powertools-lambda-typescript/tree/main/packages/testing#readme" -} +} \ No newline at end of file diff --git a/packages/testing/src/TestCase.ts b/packages/testing/src/TestCase.ts deleted file mode 100644 index 51de2992b4..0000000000 --- a/packages/testing/src/TestCase.ts +++ /dev/null @@ -1,215 +0,0 @@ -import type { NodejsFunction } from 'aws-cdk-lib/aws-lambda-nodejs'; -import type { Table } from 'aws-cdk-lib/aws-dynamodb'; -import type { IStringParameter, StringParameter } from 'aws-cdk-lib/aws-ssm'; -import { PolicyStatement, Effect } from 'aws-cdk-lib/aws-iam'; - -class NodeJsFunction { - public functionName: string; - public ref: NodejsFunction; - - public constructor(name: string, ref: NodejsFunction) { - this.functionName = name; - this.ref = ref; - } -} - -class DynamoDBTable { - public ref: Table; - public tableName: string; - readonly #envVariableName?: string; - - public constructor(name: string, ref: Table, envVariableName?: string) { - this.tableName = name; - this.ref = ref; - this.#envVariableName = envVariableName; - } - - public get envVariableName(): string { - return this.#envVariableName ?? 'TABLE_NAME'; - } -} - -abstract class SSMResource { - public parameterName: string; - public ref: StringParameter | IStringParameter; - protected readonly envVarName?: string; - - public constructor( - name: string, - ref: StringParameter | IStringParameter, - envVariableName?: string - ) { - this.parameterName = name; - this.ref = ref; - this.envVarName = envVariableName; - } -} - -class SsmSecureString extends SSMResource { - public constructor( - name: string, - ref: IStringParameter, - envVariableName?: string - ) { - super(name, ref, envVariableName); - } - - public get envVariableName(): string { - return this.envVarName ?? 'SECURE_STRING_NAME'; - } -} - -class SsmString extends SSMResource { - public constructor( - name: string, - ref: StringParameter, - envVariableName?: string - ) { - super(name, ref, envVariableName); - } - - public get envVariableName(): string { - return this.envVarName ?? 'SSM_STRING_NAME'; - } -} - -/** - * A test case that can be added to a test stack. - */ -class TestCase { - public testName: string; - #dynamodb?: DynamoDBTable; - #function?: NodeJsFunction; - #ssmSecureString?: SsmSecureString; - #ssmString?: SsmString; - - public constructor(testName: string) { - this.testName = testName; - } - - /** - * The NodejsFunction that is associated with this test case. - */ - public set function(fn: NodeJsFunction) { - if (this.#dynamodb) { - this.#grantAccessToDynamoDBTableAndSetEnv(fn, this.#dynamodb); - } - if (this.#ssmSecureString) { - this.#grantAccessToSsmeStringAndSetEnv(fn, this.#ssmSecureString); - } - if (this.#ssmString) { - this.#grantAccessToSsmeStringAndSetEnv(fn, this.#ssmString); - } - this.#function = fn; - } - - /** - * Get the NodejsFunction that is associated with this test case. - */ - public get function(): NodeJsFunction { - if (!this.#function) throw new Error('This test case has no function.'); - - return this.#function; - } - - /** - * The DynamoDB table that is associated with this test case. - */ - public set dynamodb(table: DynamoDBTable) { - if (this.#function) { - this.#grantAccessToDynamoDBTableAndSetEnv(this.#function, table); - } - this.#dynamodb = table; - } - - /** - * Get the DynamoDB table that is associated with this test case. - */ - public get dynamodb(): DynamoDBTable { - if (!this.#dynamodb) - throw new Error('This test case has no DynamoDB table.'); - - return this.#dynamodb; - } - - /** - * Grant access to the DynamoDB table and set the environment variable to - * the table name. - * - * @param fn - The function to grant access to the table and set the environment variable. - * @param table - The table to grant access to and identified by the environment variable. - */ - #grantAccessToDynamoDBTableAndSetEnv = ( - fn: NodeJsFunction, - table: DynamoDBTable - ): void => { - table.ref.grantReadWriteData(fn.ref); - fn.ref.addEnvironment(table.envVariableName, table.ref.tableName); - }; - - /** - * The SSM SecureString that is associated with this test case. - */ - public set ssmSecureString(parameter: SsmSecureString) { - if (this.#function) { - this.#grantAccessToSsmeStringAndSetEnv(this.#function, parameter); - } - this.#ssmSecureString = parameter; - } - - /** - * Get the SSM SecureString that is associated with this test case. - */ - public get ssmSecureString(): SsmSecureString { - if (!this.#ssmSecureString) - throw new Error('This test case has no SSM SecureString.'); - - return this.#ssmSecureString; - } - - /** - * The SSM String that is associated with this test case. - */ - public set ssmString(parameter: SsmString) { - if (this.#function) { - this.#grantAccessToSsmeStringAndSetEnv(this.#function, parameter); - } - this.#ssmString = parameter; - } - - /** - * Get the SSM String that is associated with this test case. - */ - public get ssmString(): SsmString { - if (!this.#ssmString) throw new Error('This test case has no SSM String.'); - - return this.#ssmString; - } - - /** - * Grant access to the SSM String and set the environment variable to - * the parameter name. - * - * @param fn - The function to grant access to the parameter and set the environment variable. - * @param parameter - The parameter to grant access to and identified by the environment variable. - */ - #grantAccessToSsmeStringAndSetEnv = ( - fn: NodeJsFunction, - parameter: SsmSecureString | SsmString - ): void => { - fn.ref.addEnvironment(parameter.envVariableName, parameter.parameterName); - // Grant access also to the path of the parameter - fn.ref.addToRolePolicy( - new PolicyStatement({ - effect: Effect.ALLOW, - actions: ['ssm:GetParametersByPath'], - resources: [ - parameter.ref.parameterArn.split(':').slice(0, -1).join(':'), - ], - }) - ); - parameter.ref.grantRead(fn.ref); - }; -} - -export { TestCase, NodeJsFunction, DynamoDBTable, SsmSecureString, SsmString }; diff --git a/packages/testing/src/TestStack.ts b/packages/testing/src/TestStack.ts index 7bc91e00aa..a5e75ab70d 100644 --- a/packages/testing/src/TestStack.ts +++ b/packages/testing/src/TestStack.ts @@ -1,205 +1,24 @@ import { App, Stack } from 'aws-cdk-lib'; import { AwsCdkCli, RequireApproval } from '@aws-cdk/cli-lib-alpha'; -import { randomUUID } from 'node:crypto'; import type { ICloudAssemblyDirectoryProducer } from '@aws-cdk/cli-lib-alpha'; -import { - dynamoDBTable, - dynamoDBItem, - nodejsFunction, - ssmSecureString, - ssmString, -} from './factories'; -import { TEST_RUNTIMES, defaultRuntime } from './constants'; -import { - NodeJsFunction, - DynamoDBTable, - SsmSecureString, - TestCase, - SsmString, -} from './TestCase'; -import type { - AddFunctionOptions, - AddDynamoDBTableOptions, - AddTestCaseOptions, - AddSsmSecureStringOptions, - AddSsmStringOptions, -} from './types'; class TestStack implements ICloudAssemblyDirectoryProducer { public app: App; public cli: AwsCdkCli; - public stack: Stack; - readonly #resourceNamePrefix; - readonly #runtime: keyof typeof TEST_RUNTIMES; - readonly #testCases = new Map(); + public stackRef: Stack; - public constructor(resourceNamePrefix: string, testName: string) { - this.#resourceNamePrefix = resourceNamePrefix; - const providedRuntime = process.env.RUNTIME || defaultRuntime; - if (!(providedRuntime in TEST_RUNTIMES)) { - throw new Error( - `Invalid runtime: ${providedRuntime}. Valid runtimes are: ${Object.keys( - TEST_RUNTIMES - ).join(', ')}` - ); - } - this.#runtime = providedRuntime as keyof typeof TEST_RUNTIMES; + public constructor(stackName: string) { this.app = new App(); - this.stack = new Stack(this.app, this.#generateUniqueName(testName)); + this.stackRef = new Stack(this.app, stackName); this.cli = AwsCdkCli.fromCloudAssemblyDirectoryProducer(this); } - /** - * Add a DynamoDB table to the test stack. - * - * @returns A reference to the DynamoDB table that was added to the stack. - */ - #addDynamoDBTable = ( - testCaseName: string, - options: AddDynamoDBTableOptions - ): DynamoDBTable => { - const resourceId = this.#generateUniqueName(`${testCaseName}-table`); - const name = options.name ?? resourceId; - const table = dynamoDBTable({ - ...options, - stack: this.stack, - resourceId, - name, - }); - - return new DynamoDBTable(name, table, options.envVariableName); - }; - - /** - * Add a NodejsFunction to the test stack. - * - * @returns A reference to the NodejsFunction that was added to the stack. - */ - #addFunction = ( - testCaseName: string, - options: AddFunctionOptions - ): NodeJsFunction => { - const resourceId = this.#generateUniqueName(`${testCaseName}-fn`); - const name = options.functionConfigs?.name ?? resourceId; - const fn = nodejsFunction({ - stack: this.stack, - resourceId, - runtime: this.#runtime, - functionConfigs: { - ...options.functionConfigs, - name, - }, - functionCode: options.functionCode, - }); - - return new NodeJsFunction(name, fn); - }; - - /** - * Add a SSM SecureString to the test stack. - */ - #addSsmSecureString = ( - testCaseName: string, - options: AddSsmSecureStringOptions - ): SsmSecureString => { - const resourceId = this.#generateUniqueName(`${testCaseName}-ssmSecure`); - const name = options.name ?? resourceId; - const ssmSecure = ssmSecureString({ - stack: this.stack, - resourceId, - name, - value: options.value, - }); - - return new SsmSecureString(name, ssmSecure, options.envVariableName); - }; - - /** - * Add a SSM String to the test stack. - */ - #addSsmString = ( - testCaseName: string, - options: AddSsmStringOptions - ): SsmString => { - const resourceId = this.#generateUniqueName(`${testCaseName}-ssmString`); - const name = options.name ?? resourceId; - const ssm = ssmString({ - stack: this.stack, - resourceId, - name, - value: options.value, - }); - - return new SsmString(name, ssm, options.envVariableName); - }; - - /** - * Create a TestCase and add it to the test stack. - * - * @param options - The options for creating a TestCase. - */ - public addTestCase = (options: AddTestCaseOptions): void => { - if (this.#testCases.has(options.testCaseName)) { - throw new Error( - `A test case with the name ${options.testCaseName} already exists.` - ); - } - // Initialize the test case - const test = new TestCase(options.testCaseName); - // Add the function to the test case - const fn = this.#addFunction(options.testCaseName, options.function); - test.function = fn; - // If the test case has a DynamoDB table, add it - if (options?.dynamodb) { - const table = this.#addDynamoDBTable( - options.testCaseName, - options.dynamodb - ); - // If the test case has items, add them to the table - if (options.dynamodb?.items) { - options.dynamodb.items.forEach((item, index) => { - dynamoDBItem({ - stack: this.stack, - resourceId: this.#generateUniqueName( - `${options.testCaseName}-item${index}` - ), - tableName: table.tableName, - tableArn: table.ref.tableArn, - item, - }); - }); - } - // Save a reference to the table in the test case - test.dynamodb = table; - } - // If the test case has a SSM SecureString, add it - if (options?.ssmSecureString) { - const ssmSecureString = this.#addSsmSecureString( - options.testCaseName, - options.ssmSecureString - ); - // Save a reference to the SSM SecureString in the test case - test.ssmSecureString = ssmSecureString; - } - // If the test case has a SSM String, add it - if (options?.ssmString) { - const ssmString = this.#addSsmString( - options.testCaseName, - options.ssmString - ); - // Save a reference to the SSM String in the test case - test.ssmString = ssmString; - } - - this.#testCases.set(options.testCaseName, test); - }; - /** * Deploy the test stack to the selected environment. */ public async deploy(): Promise { await this.cli.deploy({ - stacks: [this.stack.stackName], + stacks: [this.stackRef.stackName], requireApproval: RequireApproval.NEVER, }); } @@ -209,45 +28,20 @@ class TestStack implements ICloudAssemblyDirectoryProducer { */ public async destroy(): Promise { await this.cli.destroy({ - stacks: [this.stack.stackName], + stacks: [this.stackRef.stackName], requireApproval: false, }); } - /** - * Get a test case from the test stack. - * - * If no test case with the provided name exists, an error is thrown. - * - * @param testCaseName - The name of the test case to get. - */ - public getTestCase = (testCaseName: string): TestCase => { - const testCase = this.#testCases.get(testCaseName); - if (!testCase) { - throw new Error(`No test case with name ${testCaseName} exists.`); - } - - return testCase; - }; - public async produce(_context: Record): Promise { return this.app.synth().directory; } public async synth(): Promise { await this.cli.synth({ - stacks: [this.stack.stackName], + stacks: [this.stackRef.stackName], }); } - - #generateUniqueName = (resourceName: string): string => { - const uuid = randomUUID(); - - return `${this.#resourceNamePrefix}-${this.#runtime}-${uuid.substring( - 0, - 5 - )}-${resourceName}`.substring(0, 64); - }; } export { TestStack }; diff --git a/packages/testing/src/factories.ts b/packages/testing/src/factories.ts deleted file mode 100644 index a4322d4f39..0000000000 --- a/packages/testing/src/factories.ts +++ /dev/null @@ -1,163 +0,0 @@ -import { CfnOutput, Duration, RemovalPolicy } from 'aws-cdk-lib'; -import { NodejsFunction } from 'aws-cdk-lib/aws-lambda-nodejs'; -import { Tracing, Architecture } from 'aws-cdk-lib/aws-lambda'; -import { RetentionDays } from 'aws-cdk-lib/aws-logs'; -import { - PhysicalResourceId, - AwsCustomResource, - AwsCustomResourcePolicy, -} from 'aws-cdk-lib/custom-resources'; -import { StringParameter } from 'aws-cdk-lib/aws-ssm'; -import { Table, BillingMode, AttributeType } from 'aws-cdk-lib/aws-dynamodb'; -import { TEST_RUNTIMES } from './constants'; -import { marshall } from '@aws-sdk/util-dynamodb'; -import type { IStringParameter } from 'aws-cdk-lib/aws-ssm'; -import type { - NodejsFunctionOptions, - DynamoDBTableOptions, - SsmSecureStringOptions, - DynamoDBItemOptions, - SsmStringOptions, -} from './types'; - -/** - * Add a NodejsFunction to the test stack. - * - * @param options - The options for creating a NodejsFunction. - */ -const nodejsFunction = (options: NodejsFunctionOptions): NodejsFunction => { - const nodeJsFunction = new NodejsFunction(options.stack, options.resourceId, { - runtime: TEST_RUNTIMES[options.runtime], - functionName: options.functionConfigs?.name, - timeout: Duration.seconds(options.functionConfigs?.timeout ?? 30), - entry: options?.functionCode?.path, - handler: options?.functionCode?.handler ?? 'handler', - environment: { - ...(options.functionConfigs?.environment ?? {}), - }, - tracing: options.functionConfigs?.tracing ?? Tracing.ACTIVE, - memorySize: options.functionConfigs?.memorySize ?? 256, - architecture: options.functionConfigs?.architecture ?? Architecture.X86_64, - logRetention: RetentionDays.ONE_DAY, - bundling: options?.functionCode?.bundling, - }); - - if (options.logGroupOutputKey) { - new CfnOutput(options.stack, options.logGroupOutputKey, { - value: nodeJsFunction.logGroup.logGroupName, - }); - } - - return nodeJsFunction; -}; - -/** - * Add a DynamoDB table to the test stack. - * - * @param options - The options for creating a DynamoDB table. - */ -const dynamoDBTable = (options: DynamoDBTableOptions): Table => { - const table = new Table(options.stack, options.resourceId, { - tableName: options.name, - partitionKey: { - name: options?.partitionKey?.name ?? 'id', - type: options?.partitionKey?.type ?? AttributeType.STRING, - }, - ...(options?.sortKey ?? {}), - billingMode: options.billingMode ?? BillingMode.PAY_PER_REQUEST, - removalPolicy: RemovalPolicy.DESTROY, - }); - - return table; -}; - -/** - * Add an item to a DynamoDB table in the test stack. - * - * @param options - The options for creating a DynamoDB item. - */ -const dynamoDBItem = (options: DynamoDBItemOptions): AwsCustomResource => { - const item = new AwsCustomResource(options.stack, options.resourceId, { - onCreate: { - service: 'DynamoDB', - action: 'putItem', - parameters: { - TableName: options.tableName, - Item: marshall(options.item), - }, - physicalResourceId: PhysicalResourceId.of(options.resourceId), - }, - policy: AwsCustomResourcePolicy.fromSdkCalls({ - resources: [options.tableArn], - }), - }); - - return item; -}; - -/** - * Add a SSM String parameter to the test stack. - * - * @param options - The options for creating a SSM String parameter. - */ -const ssmString = (options: SsmStringOptions): StringParameter => { - const ssmString = new StringParameter(options.stack, options.resourceId, { - parameterName: options.name, - stringValue: options.value, - }); - - return ssmString; -}; - -/** - * Add a SSM SecureString parameter to the test stack. - * - * @param options - The options for creating a SSM SecureString parameter. - */ -const ssmSecureString = (options: SsmSecureStringOptions): IStringParameter => { - const resourceCreator = new AwsCustomResource( - options.stack, - `creator-${options.resourceId}`, - { - onCreate: { - service: 'SSM', - action: 'putParameter', - parameters: { - Name: options.name ?? options.resourceId, - Value: options.value, - Type: 'SecureString', - }, - physicalResourceId: PhysicalResourceId.of(options.resourceId), - }, - onDelete: { - service: 'SSM', - action: 'deleteParameter', - parameters: { - Name: options.name ?? options.resourceId, - }, - }, - policy: AwsCustomResourcePolicy.fromSdkCalls({ - resources: AwsCustomResourcePolicy.ANY_RESOURCE, - }), - } - ); - - const secureString = StringParameter.fromSecureStringParameterAttributes( - options.stack, - options.resourceId, - { - parameterName: options.name ?? options.resourceId, - } - ); - secureString.node.addDependency(resourceCreator); - - return secureString; -}; - -export { - nodejsFunction, - dynamoDBTable, - dynamoDBItem, - ssmSecureString, - ssmString, -}; diff --git a/packages/testing/src/index.ts b/packages/testing/src/index.ts index 11d3cd4421..6ba0fd1d5a 100644 --- a/packages/testing/src/index.ts +++ b/packages/testing/src/index.ts @@ -1 +1,2 @@ export * from './TestStack'; +export * from './constants'; diff --git a/packages/testing/src/types/TestStack.ts b/packages/testing/src/types/TestStack.ts deleted file mode 100644 index 197cbb4f6c..0000000000 --- a/packages/testing/src/types/TestStack.ts +++ /dev/null @@ -1,54 +0,0 @@ -import type { - NodejsFunctionOptions, - DynamoDBTableOptions, - SsmSecureStringOptions, - SsmStringOptions, -} from './factories'; - -/** - * Options to add a NodejsFunction to the test stack. - */ -type AddFunctionOptions = Omit< - NodejsFunctionOptions, - 'stack' | 'resourceId' | 'runtime' ->; - -/** - * Options to add a DynamoDB table to the test stack. - */ -type AddDynamoDBTableOptions = Omit< - DynamoDBTableOptions, - 'stack' | 'resourceId' ->; - -/** - * Options to add a SSM Secure String to the test stack. - */ -type AddSsmSecureStringOptions = Omit< - SsmSecureStringOptions, - 'stack' | 'resourceId' ->; - -/** - * Options to add a SSM String to the test stack. - */ -type AddSsmStringOptions = Omit; - -/** - * Options to add a test case to the test stack. - */ -type AddTestCaseOptions = { - testCaseName: string; - function: AddFunctionOptions; - dynamodb?: AddDynamoDBTableOptions; - ssmSecureString?: AddSsmSecureStringOptions; - ssmString?: AddSsmStringOptions; -}; - -export { - AddFunctionOptions, - AddDynamoDBTableOptions, - AddTestCaseOptions, - AddSsmSecureStringOptions, - AddSsmStringOptions, -}; diff --git a/packages/testing/src/types/factories.ts b/packages/testing/src/types/factories.ts deleted file mode 100644 index fbeeea984d..0000000000 --- a/packages/testing/src/types/factories.ts +++ /dev/null @@ -1,242 +0,0 @@ -import type { Stack } from 'aws-cdk-lib'; -import type { FunctionOptions } from 'aws-cdk-lib/aws-lambda'; -import type { NodejsFunctionProps } from 'aws-cdk-lib/aws-lambda-nodejs'; -import type { AttributeType, BillingMode } from 'aws-cdk-lib/aws-dynamodb'; -import { TEST_RUNTIMES } from '../constants'; - -/** - * Options for creating a NodejsFunction. - */ -type NodejsFunctionOptions = { - /** - * The stack to add the function to. - */ - stack: Stack; - /** - * The unique identifier for the function. - */ - resourceId: string; - /** - * The runtime for the function. - */ - runtime: keyof typeof TEST_RUNTIMES; - /** - * The function code. - */ - functionCode: { - /** - * The absolute path to the entry file. - * @default - None - */ - path: NodejsFunctionProps['entry']; - /** - * The name of the function handler. - * @default - handler - */ - handler?: NodejsFunctionProps['handler']; - /** - * Options for bundling with esbuild. - */ - bundling?: NodejsFunctionProps['bundling']; - }; - /** - * Function configurations. - */ - functionConfigs?: { - /** - * The amount of memory, in MB, that is allocated to your Lambda function. - * @default - The default value is 256 MB. - */ - memorySize?: FunctionOptions['memorySize']; - /** - * The function execution time (in seconds) after which Lambda terminates the function. - * @default - The default value is 30 seconds. - */ - timeout?: number; - /** - * The environment variables for the Lambda function service. - * @default - No environment variables. - */ - environment?: FunctionOptions['environment']; - /** - * A name for the function. - * @default - The utility will generate a unique name for the function. - */ - name?: FunctionOptions['functionName']; - /** - * Enable AWS X-Ray Tracing for Lambda Function. - * @default - Enabled - */ - tracing?: FunctionOptions['tracing']; - /** - * The Lambda runtime architecture to use. - * @default - x86_64 - */ - architecture?: FunctionOptions['architecture']; - }; - /** - * The name of the CloudFormation Output key to store the log group name. - * - * When this property is set, the log group name will be stored in the CloudFormation Output. - * - * @default - No output - */ - logGroupOutputKey?: string; -}; - -/** - * Options for creating a DynamoDB table. - */ -type DynamoDBTableOptions = { - /** - * The stack to add the table to. - */ - stack: Stack; - /** - * The unique identifier for the table. - */ - resourceId: string; - /** - * The name of the table. - */ - name?: string; - /** - * The partition key for the table. - * @default - id (string) - */ - partitionKey?: { - /** - * The name of the partition key. - * @default - id - */ - name?: string; - /** - * The type of the partition key. - * @default - AttributeType.STRING - */ - type?: AttributeType; - }; - /** - * The sort key for the table. - * @default - None - */ - sortKey?: { - /** - * The name of the sort key. - * @default - None - */ - name?: string; - /** - * The type of the sort key. - * @default - None - */ - type?: AttributeType; - }; - /** - * The billing mode for the table. - * @default - BillingMode.PAY_PER_REQUEST - */ - billingMode?: BillingMode; - /** - * The name of the environment variable that will store the table name - * and that will be applied to the function. - * @default - TABLE_NAME - */ - envVariableName?: string; - /** - * Items to add to the table. - */ - items?: Array; -}; - -/** - * Add an item to a DynamoDB table. - */ -type DynamoDBItemOptions = { - /** - * The stack to of the table to add the item to. - */ - stack: Stack; - /** - * The unique identifier for the item. - */ - resourceId: string; - /** - * The name of the table to add the item to. - */ - tableName: string; - /** - * The arn of the table to add the item to. - */ - tableArn: string; - /** - * The item to add to the table. - */ - item: Record; -}; - -/** - * Options for creating a SSM Secure String. - */ -type SsmSecureStringOptions = { - /** - * The stack to add the secure string to. - */ - stack: Stack; - /** - * The unique identifier for the secure string. - */ - resourceId: string; - /** - * The name of the secure string. - * @default - Same as resourceId - */ - name?: string; - /** - * The value of the secure string. - */ - value: string; - /** - * The name of the environment variable that will store the name - * of the string and that will be applied to the function. - * @default - SECURE_STRING_NAME - */ - envVariableName?: string; -}; - -/** - * Options for creating a SSM String. - */ -type SsmStringOptions = { - /** - * The stack to add the string to. - */ - stack: Stack; - /** - * The unique identifier for the string. - */ - resourceId: string; - /** - * The name of the string. - * @default - Same as resourceId - */ - name?: string; - /** - * The value of the string. - */ - value: string; - /** - * The name of the environment variable that will store the name - * of the string and that will be applied to the function. - * @default - SECURE_STRING_NAME - */ - envVariableName?: string; -}; - -export { - NodejsFunctionOptions, - DynamoDBTableOptions, - DynamoDBItemOptions, - SsmSecureStringOptions, - SsmStringOptions, -}; diff --git a/packages/testing/src/types/index.ts b/packages/testing/src/types/index.ts deleted file mode 100644 index 71c096ea42..0000000000 --- a/packages/testing/src/types/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './factories'; -export * from './TestStack'; From dd959ca7ee004805f6b936f4768a6540d2015d2e Mon Sep 17 00:00:00 2001 From: Andrea Amorosi Date: Thu, 27 Jul 2023 13:52:27 +0200 Subject: [PATCH 06/15] chore: removed aws-cdk-lib & aws-cdk --- package-lock.json | 1478 +---------------------- package.json | 12 +- packages/commons/tests/utils/cdk-cli.ts | 61 - 3 files changed, 56 insertions(+), 1495 deletions(-) delete mode 100644 packages/commons/tests/utils/cdk-cli.ts diff --git a/package-lock.json b/package-lock.json index a864909c5b..6f02272c34 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,21 +23,13 @@ "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", @@ -50,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", @@ -458,162 +448,29 @@ } }, "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==" + "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.1", - "license": "Apache-2.0" + "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/cfnspec": { - "version": "2.73.0-alpha.0", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "fs-extra": "^9.1.0", - "md5": "^2.3.0" - } - }, "node_modules/@aws-cdk/cli-lib-alpha": { - "version": "2.87.0-alpha.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/cli-lib-alpha/-/cli-lib-alpha-2.87.0-alpha.0.tgz", - "integrity": "sha512-6hhu7YT4zn4ByPbN8R2pmLJTnYQUXqS5tqiBalzKy8luUnG9QIkvke9m8N/QnyLvjj7L4mWUjVNC4fGUjZsSBw==", - "dev": true, - "engines": { - "node": ">= 14.15.0" - } - }, - "node_modules/@aws-cdk/cloud-assembly-schema": { - "version": "2.73.0", - "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/@aws-cdk/cloud-assembly-schema/node_modules/jsonschema": { - "version": "1.4.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": "*" - } - }, - "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/@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/@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" - }, - "engines": { - "node": ">= 14.15.0" - } - }, - "node_modules/@aws-cdk/cx-api": { - "version": "2.73.0", - "bundleDependencies": [ - "semver" - ], + "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==", "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_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/@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/@aws-cdk/cx-api/node_modules/yallist": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "ISC" - }, "node_modules/@aws-crypto/crc32": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-3.0.0.tgz", @@ -5517,14 +5374,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, @@ -5777,9 +5626,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", @@ -6116,21 +5966,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, @@ -6209,70 +6044,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", @@ -6362,17 +6133,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, @@ -6439,9 +6199,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", @@ -6455,9 +6215,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", @@ -6465,7 +6225,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" }, @@ -6681,7 +6441,7 @@ } }, "node_modules/aws-cdk-lib/node_modules/semver": { - "version": "7.5.1", + "version": "7.5.4", "inBundle": true, "license": "ISC", "dependencies": { @@ -7156,14 +6916,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" @@ -7185,14 +6937,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", @@ -7343,229 +7087,45 @@ ], "license": "CC-BY-4.0" }, - "node_modules/cdk-assets": { - "version": "2.72.1", - "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-sample": { + "resolved": "examples/cdk", + "link": true }, - "node_modules/cdk-assets/node_modules/@aws-cdk/cloud-assembly-schema": { - "version": "2.72.1", - "bundleDependencies": [ - "jsonschema", - "semver" - ], + "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", + "license": "MIT", "dependencies": { - "jsonschema": "^1.4.1", - "semver": "^7.3.8" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">= 14.15.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/cdk-assets/node_modules/@aws-cdk/cloud-assembly-schema/node_modules/jsonschema": { - "version": "1.4.1", + "node_modules/char-regex": { + "version": "1.0.2", "dev": true, - "inBundle": true, "license": "MIT", "engines": { - "node": "*" + "node": ">=10" } }, - "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", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/char-regex": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/chardet": { - "version": "0.7.0", - "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", + "node_modules/chardet": { + "version": "0.7.0", + "dev": true, + "license": "MIT" + }, + "node_modules/chownr": { + "version": "2.0.0", "dev": true, "license": "ISC", "engines": { @@ -7902,20 +7462,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, @@ -8157,29 +7703,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, @@ -8198,14 +7721,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", @@ -8236,14 +7751,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", @@ -8355,20 +7862,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", @@ -9109,73 +8602,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/escodegen": { - "version": "1.14.3", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "esprima": "^4.0.1", - "estraverse": "^4.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1" - }, - "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, @@ -9789,14 +9215,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", @@ -10003,38 +9421,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, @@ -10278,51 +9664,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", @@ -10644,34 +9985,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, @@ -10945,11 +10258,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, @@ -10996,11 +10304,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, @@ -12079,11 +11382,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, @@ -12193,44 +11491,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", @@ -12914,21 +12174,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, @@ -12940,11 +12185,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, @@ -12954,16 +12194,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, @@ -13320,16 +12550,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", @@ -13899,14 +13119,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, @@ -15044,38 +14256,6 @@ "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", @@ -15690,14 +14870,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, @@ -15731,37 +14903,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, @@ -15819,20 +14960,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, @@ -16160,33 +15287,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", @@ -16235,14 +15335,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, @@ -16509,11 +15601,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", @@ -16774,19 +15861,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, @@ -16923,14 +15997,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, @@ -17135,21 +16201,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, @@ -17361,14 +16412,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", @@ -17840,14 +16883,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", @@ -17924,8 +16959,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" } @@ -17980,22 +17016,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", @@ -18271,11 +17291,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", @@ -18619,6 +17634,7 @@ "lodash.merge": "^4.6.2" }, "devDependencies": { + "@aws-lambda-powertools/testing-utils": "file:../testing", "@types/lodash.merge": "^4.6.7" } }, @@ -18861,393 +17877,8 @@ "version": "1.11.1", "license": "MIT-0", "devDependencies": { - "@aws-cdk/cli-lib-alpha": "^2.87.0-alpha.0", - "aws-cdk-lib": "^2.73.0" - } - }, - "packages/testing/node_modules/aws-cdk-lib": { - "version": "2.73.0", - "resolved": "https://registry.npmjs.org/aws-cdk-lib/-/aws-cdk-lib-2.73.0.tgz", - "integrity": "sha512-r9CUe3R7EThr9U0Eb7kQCK4Ee34TDeMH+bonvGD9rNRRTYDauvAgNCsx4DZYYksPrXLRzWjzVbuXAHaDDzWt+A==", - "bundleDependencies": [ - "@balena/dockerignore", - "case", - "fs-extra", - "ignore", - "jsonschema", - "minimatch", - "punycode", - "semver", - "table", - "yaml" - ], - "dev": true, - "dependencies": { - "@aws-cdk/asset-awscli-v1": "^2.2.97", - "@aws-cdk/asset-kubectl-v20": "^2.1.1", - "@aws-cdk/asset-node-proxy-agent-v5": "^2.0.77", - "@balena/dockerignore": "^1.0.2", - "case": "1.6.3", - "fs-extra": "^9.1.0", - "ignore": "^5.2.4", - "jsonschema": "^1.4.1", - "minimatch": "^3.1.2", - "punycode": "^2.3.0", - "semver": "^7.3.8", - "table": "^6.8.1", - "yaml": "1.10.2" - }, - "engines": { - "node": ">= 14.15.0" - }, - "peerDependencies": { - "constructs": "^10.0.0" - } - }, - "packages/testing/node_modules/aws-cdk-lib/node_modules/@balena/dockerignore": { - "version": "1.0.2", - "dev": true, - "inBundle": true, - "license": "Apache-2.0" - }, - "packages/testing/node_modules/aws-cdk-lib/node_modules/ajv": { - "version": "8.12.0", - "dev": true, - "inBundle": 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" - } - }, - "packages/testing/node_modules/aws-cdk-lib/node_modules/ansi-regex": { - "version": "5.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "packages/testing/node_modules/aws-cdk-lib/node_modules/ansi-styles": { - "version": "4.3.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "packages/testing/node_modules/aws-cdk-lib/node_modules/astral-regex": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "packages/testing/node_modules/aws-cdk-lib/node_modules/at-least-node": { - "version": "1.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": ">= 4.0.0" - } - }, - "packages/testing/node_modules/aws-cdk-lib/node_modules/balanced-match": { - "version": "1.0.2", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "packages/testing/node_modules/aws-cdk-lib/node_modules/brace-expansion": { - "version": "1.1.11", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "packages/testing/node_modules/aws-cdk-lib/node_modules/case": { - "version": "1.6.3", - "dev": true, - "inBundle": true, - "license": "(MIT OR GPL-3.0-or-later)", - "engines": { - "node": ">= 0.8.0" - } - }, - "packages/testing/node_modules/aws-cdk-lib/node_modules/color-convert": { - "version": "2.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "packages/testing/node_modules/aws-cdk-lib/node_modules/color-name": { - "version": "1.1.4", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "packages/testing/node_modules/aws-cdk-lib/node_modules/concat-map": { - "version": "0.0.1", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "packages/testing/node_modules/aws-cdk-lib/node_modules/emoji-regex": { - "version": "8.0.0", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "packages/testing/node_modules/aws-cdk-lib/node_modules/fast-deep-equal": { - "version": "3.1.3", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "packages/testing/node_modules/aws-cdk-lib/node_modules/fs-extra": { - "version": "9.1.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "packages/testing/node_modules/aws-cdk-lib/node_modules/graceful-fs": { - "version": "4.2.10", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "packages/testing/node_modules/aws-cdk-lib/node_modules/ignore": { - "version": "5.2.4", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "packages/testing/node_modules/aws-cdk-lib/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "packages/testing/node_modules/aws-cdk-lib/node_modules/json-schema-traverse": { - "version": "1.0.0", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "packages/testing/node_modules/aws-cdk-lib/node_modules/jsonfile": { - "version": "6.1.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "packages/testing/node_modules/aws-cdk-lib/node_modules/jsonschema": { - "version": "1.4.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": "*" - } - }, - "packages/testing/node_modules/aws-cdk-lib/node_modules/lodash.truncate": { - "version": "4.4.2", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "packages/testing/node_modules/aws-cdk-lib/node_modules/lru-cache": { - "version": "6.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "packages/testing/node_modules/aws-cdk-lib/node_modules/minimatch": { - "version": "3.1.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "packages/testing/node_modules/aws-cdk-lib/node_modules/punycode": { - "version": "2.3.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "packages/testing/node_modules/aws-cdk-lib/node_modules/require-from-string": { - "version": "2.0.2", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "packages/testing/node_modules/aws-cdk-lib/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" - } - }, - "packages/testing/node_modules/aws-cdk-lib/node_modules/slice-ansi": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, - "packages/testing/node_modules/aws-cdk-lib/node_modules/string-width": { - "version": "4.2.3", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "packages/testing/node_modules/aws-cdk-lib/node_modules/strip-ansi": { - "version": "6.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "packages/testing/node_modules/aws-cdk-lib/node_modules/table": { - "version": "6.8.1", - "dev": true, - "inBundle": 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" - } - }, - "packages/testing/node_modules/aws-cdk-lib/node_modules/universalify": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">= 10.0.0" - } - }, - "packages/testing/node_modules/aws-cdk-lib/node_modules/uri-js": { - "version": "4.4.1", - "dev": true, - "inBundle": true, - "license": "BSD-2-Clause", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "packages/testing/node_modules/aws-cdk-lib/node_modules/yallist": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "packages/testing/node_modules/aws-cdk-lib/node_modules/yaml": { - "version": "1.10.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": ">= 6" + "@aws-cdk/cli-lib-alpha": "^2.88.0-alpha.0", + "aws-cdk-lib": "^2.88.0" } }, "packages/tracer": { @@ -19259,6 +17890,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 110d422f74..b9186a7128 100644 --- a/package.json +++ b/package.json @@ -46,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", @@ -73,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; - }; From 55b92bdbd0759e688af00b4cdcf00144513c32bc Mon Sep 17 00:00:00 2001 From: Andrea Amorosi Date: Thu, 27 Jul 2023 13:53:03 +0200 Subject: [PATCH 07/15] tests: moved tracer to new testing lib --- packages/tracer/package.json | 1 + .../tests/e2e/allFeatures.decorator.test.ts | 31 +++++++++---------- .../tests/e2e/allFeatures.manual.test.ts | 23 ++++++-------- .../tests/e2e/allFeatures.middy.test.ts | 28 ++++++++--------- .../tests/e2e/asyncHandler.decorator.test.ts | 24 +++++++------- 5 files changed, 49 insertions(+), 58 deletions(-) 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..b1404cf201 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.stackRef, '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.stackRef, 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.stackRef, 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.stackRef, 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.stackRef, 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..ff6f251fb3 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.stackRef, 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.stackRef, '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..1d08e6799a 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.stackRef, '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.stackRef, 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.stackRef, 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.stackRef, 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.stackRef, 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..d5b6f2fc1e 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.stackRef, '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.stackRef, 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.stackRef, 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); From 88790e629a22a371158e025ac6d13fd5a0d3ea7d Mon Sep 17 00:00:00 2001 From: Andrea Amorosi Date: Thu, 27 Jul 2023 15:56:38 +0200 Subject: [PATCH 08/15] tests: move logger to new testing --- packages/commons/tests/utils/e2eUtils.ts | 14 ++++------- packages/logger/package.json | 1 + .../tests/e2e/basicFeatures.middy.test.ts | 23 ++++++++--------- .../tests/e2e/childLogger.manual.test.ts | 24 ++++++++---------- .../e2e/logEventEnvVarSetting.middy.test.ts | 25 ++++++++----------- .../tests/e2e/sampleRate.decorator.test.ts | 24 ++++++++---------- packages/testing/src/TestStack.ts | 17 ++++++++++++- 7 files changed, 65 insertions(+), 63 deletions(-) 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/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..78e0b3a565 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.stackRef, 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..671b1c3fa4 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.stackRef, 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..e50b0672a4 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}`, () => { +describe(`logger E2E tests log event via env var setting (middy) for runtime:`, () => { let invocationLogs: InvocationLogs[]; beforeAll(async () => { // Create and deploy a stack with AWS CDK - stack = createStackWithLambdaFunction({ - app: integTestApp, - stackName: stackName, + createStackWithLambdaFunction({ + stack: testStack.stackRef, 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..80a3b190a5 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.stackRef, 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/testing/src/TestStack.ts b/packages/testing/src/TestStack.ts index a5e75ab70d..b727f2ff9c 100644 --- a/packages/testing/src/TestStack.ts +++ b/packages/testing/src/TestStack.ts @@ -1,3 +1,6 @@ +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'; @@ -15,12 +18,24 @@ class TestStack implements ICloudAssemblyDirectoryProducer { /** * Deploy the test stack to the selected environment. + * + * It returns the outputs of the deployed stack. */ - public async deploy(): Promise { + public async deploy(): Promise> { + const outputFilePath = join( + tmpdir(), + 'powertools-e2e-testing', + `${this.stackRef.stackName}.outputs.json` + ); await this.cli.deploy({ stacks: [this.stackRef.stackName], requireApproval: RequireApproval.NEVER, + outputsFile: outputFilePath, }); + + return JSON.parse(await readFile(outputFilePath, 'utf-8'))[ + this.stackRef.stackName + ]; } /** From 39bf3a5b380bb9304d422dbbbc0fa759c9baeef9 Mon Sep 17 00:00:00 2001 From: Andrea Amorosi Date: Thu, 27 Jul 2023 16:01:32 +0200 Subject: [PATCH 09/15] tests: move metrics to new testing --- package-lock.json | 3 +- packages/metrics/package.json | 1 + .../e2e/basicFeatures.decorators.test.ts | 21 +++++----- .../tests/e2e/basicFeatures.manual.test.ts | 21 +++++----- packages/testing/src/TestStack.ts | 39 ++++++++++++++----- 5 files changed, 51 insertions(+), 34 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6f02272c34..0b1cc3d4c2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17646,6 +17646,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" @@ -17874,7 +17875,7 @@ }, "packages/testing": { "name": "@aws-lambda-powertools/testing-utils", - "version": "1.11.1", + "version": "1.12.1", "license": "MIT-0", "devDependencies": { "@aws-cdk/cli-lib-alpha": "^2.88.0-alpha.0", 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..cebbd2f140 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.stackRef, 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..8ac8af1364 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.stackRef, 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/testing/src/TestStack.ts b/packages/testing/src/TestStack.ts index b727f2ff9c..86d6e9f3fb 100644 --- a/packages/testing/src/TestStack.ts +++ b/packages/testing/src/TestStack.ts @@ -5,15 +5,30 @@ 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 { - public app: App; - public cli: AwsCdkCli; + /** + * Reference to the AWS CDK App object. + * @default new App() + */ + public appRef: App; + /** + * Reference to the AWS CDK Stack object. + * @default new Stack(this.appRef, stackName) + */ public stackRef: Stack; + /** + * @internal + * Reference to the AWS CDK CLI object. + */ + #cli: AwsCdkCli; public constructor(stackName: string) { - this.app = new App(); - this.stackRef = new Stack(this.app, stackName); - this.cli = AwsCdkCli.fromCloudAssemblyDirectoryProducer(this); + this.appRef = new App(); + this.stackRef = new Stack(this.appRef, stackName); + this.#cli = AwsCdkCli.fromCloudAssemblyDirectoryProducer(this); } /** @@ -27,7 +42,7 @@ class TestStack implements ICloudAssemblyDirectoryProducer { 'powertools-e2e-testing', `${this.stackRef.stackName}.outputs.json` ); - await this.cli.deploy({ + await this.#cli.deploy({ stacks: [this.stackRef.stackName], requireApproval: RequireApproval.NEVER, outputsFile: outputFilePath, @@ -42,18 +57,24 @@ class TestStack implements ICloudAssemblyDirectoryProducer { * Destroy the test stack. */ public async destroy(): Promise { - await this.cli.destroy({ + await this.#cli.destroy({ stacks: [this.stackRef.stackName], requireApproval: false, }); } + /** + * Produce the Cloud Assembly directory. + */ public async produce(_context: Record): Promise { - return this.app.synth().directory; + return this.appRef.synth().directory; } + /** + * Synthesize the test stack. + */ public async synth(): Promise { - await this.cli.synth({ + await this.#cli.synth({ stacks: [this.stackRef.stackName], }); } From 0e4b436668f6b3ef1f395c310f1014a1ebc0d188 Mon Sep 17 00:00:00 2001 From: Andrea Amorosi Date: Thu, 27 Jul 2023 16:05:01 +0200 Subject: [PATCH 10/15] restored string --- packages/logger/tests/e2e/logEventEnvVarSetting.middy.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/logger/tests/e2e/logEventEnvVarSetting.middy.test.ts b/packages/logger/tests/e2e/logEventEnvVarSetting.middy.test.ts index e50b0672a4..79c1b9ae28 100644 --- a/packages/logger/tests/e2e/logEventEnvVarSetting.middy.test.ts +++ b/packages/logger/tests/e2e/logEventEnvVarSetting.middy.test.ts @@ -51,7 +51,7 @@ const invocationCount = 3; const testStack = new TestStack(stackName); let logGroupName: string; // We do not know it until deployment -describe(`logger E2E tests log event via env var setting (middy) for runtime:`, () => { +describe(`logger E2E tests log event via env var setting (middy) for runtime: ${runtime}`, () => { let invocationLogs: InvocationLogs[]; beforeAll(async () => { From 5ec9767388662caaf57924b0c9356031b1eac607 Mon Sep 17 00:00:00 2001 From: Andrea Amorosi Date: Thu, 27 Jul 2023 16:11:04 +0200 Subject: [PATCH 11/15] tests: move idempotency to new testing --- package-lock.json | 1 + packages/idempotency/package.json | 1 + .../tests/e2e/makeHandlerIdempotent.test.ts | 25 ++++++++----------- .../tests/e2e/makeIdempotent.test.ts | 23 ++++++++--------- 4 files changed, 23 insertions(+), 27 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0b1cc3d4c2..2c4d02740f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17416,6 +17416,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", 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..8f656b10a4 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.stackRef, runtime, ddbTableNameDefault, makeHandlerIdempotentFile, @@ -82,7 +79,7 @@ const ddbTableNameDefaultParallel = generateUniqueName( `${testDefaultParallel}-table` ); createIdempotencyResources( - stack, + testStack.stackRef, runtime, ddbTableNameDefaultParallel, makeHandlerIdempotentFile, @@ -104,7 +101,7 @@ const ddbTableNameTimeout = generateUniqueName( `${testTimeout}-table` ); createIdempotencyResources( - stack, + testStack.stackRef, runtime, ddbTableNameTimeout, makeHandlerIdempotentFile, @@ -128,7 +125,7 @@ const ddbTableNameExpired = generateUniqueName( `${testExpired}-table` ); createIdempotencyResources( - stack, + testStack.stackRef, 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..2d2984ffd1 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.stackRef, runtime, ddbTableNameDefault, makeFunctionIdempotentFile, @@ -81,7 +78,7 @@ const ddbTableNameCustomConfig = generateUniqueName( `${testCustomConfig}-fn` ); createIdempotencyResources( - stack, + testStack.stackRef, runtime, ddbTableNameCustomConfig, makeFunctionIdempotentFile, @@ -104,7 +101,7 @@ const ddbTableNameLambdaHandler = generateUniqueName( `${testLambdaHandler}-table` ); createIdempotencyResources( - stack, + testStack.stackRef, 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); }); From 66dd4d11102751c6a5e95c9c295d0759dab75a8f Mon Sep 17 00:00:00 2001 From: Andrea Amorosi Date: Thu, 27 Jul 2023 16:21:22 +0200 Subject: [PATCH 12/15] tests: move parameters to new testing --- .../tests/e2e/appConfigProvider.class.test.ts | 34 ++++++------ .../tests/e2e/dynamoDBProvider.class.test.ts | 52 +++++++++---------- .../tests/e2e/secretsProvider.class.test.ts | 44 ++++++++-------- .../tests/e2e/ssmProvider.class.test.ts | 32 ++++++------ 4 files changed, 79 insertions(+), 83 deletions(-) diff --git a/packages/parameters/tests/e2e/appConfigProvider.class.test.ts b/packages/parameters/tests/e2e/appConfigProvider.class.test.ts index 2e75f8cc6b..afa0ebc62a 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.stackRef, 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.stackRef, 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.stackRef, application, environment, deploymentStrategy, @@ -223,7 +221,7 @@ describe(`parameters E2E tests (appConfigProvider) for runtime ${runtime}`, () = }); const freeFormYaml = createAppConfigConfigurationProfile({ - stack, + stack: testStack.stackRef, 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.stackRef, 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.stackRef, 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.stackRef).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..bf4a49355e 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.stackRef, 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.stackRef, id: 'Table-get', tableName: tableGet, partitionKey: { @@ -197,7 +195,7 @@ describe(`parameters E2E tests (dynamoDBProvider) for runtime: ${runtime}`, () = }, }); const ddbTableGetMultiple = createDynamoDBTable({ - stack, + stack: testStack.stackRef, id: 'Table-getMultiple', tableName: tableGetMultiple, partitionKey: { @@ -210,7 +208,7 @@ describe(`parameters E2E tests (dynamoDBProvider) for runtime: ${runtime}`, () = }, }); const ddbTableGetCustomKeys = createDynamoDBTable({ - stack, + stack: testStack.stackRef, id: 'Table-getCustomKeys', tableName: tableGetCustomkeys, partitionKey: { @@ -219,7 +217,7 @@ describe(`parameters E2E tests (dynamoDBProvider) for runtime: ${runtime}`, () = }, }); const ddbTabelGetMultipleCustomKeys = createDynamoDBTable({ - stack, + stack: testStack.stackRef, 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.stackRef).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.stackRef, 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.stackRef, id: 'my-param-test2-a', table: ddbTableGetMultiple, item: { @@ -266,7 +264,7 @@ describe(`parameters E2E tests (dynamoDBProvider) for runtime: ${runtime}`, () = }, }); putDynamoDBItem({ - stack, + stack: testStack.stackRef, 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.stackRef, 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.stackRef, id: 'my-param-test4-a', table: ddbTabelGetMultipleCustomKeys, item: { @@ -299,7 +297,7 @@ describe(`parameters E2E tests (dynamoDBProvider) for runtime: ${runtime}`, () = }, }); putDynamoDBItem({ - stack, + stack: testStack.stackRef, 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.stackRef, 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.stackRef, 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.stackRef, id: 'my-param-test7-a', table: ddbTableGetMultiple, item: { @@ -343,7 +341,7 @@ describe(`parameters E2E tests (dynamoDBProvider) for runtime: ${runtime}`, () = }, }); putDynamoDBItem({ - stack, + stack: testStack.stackRef, 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..d37a54d9d0 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.stackRef, 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.stackRef, 'testSecretPlain', { secretName: secretNamePlain, secretStringValue: SecretValue.unsafePlainText('foo'), }); - const secretObject = new Secret(stack, 'testSecretObject', { + const secretObject = new Secret(testStack.stackRef, 'testSecretObject', { secretName: secretNameObject, secretObjectValue: { foo: SecretValue.unsafePlainText('bar'), }, }); - const secretBinary = new Secret(stack, 'testSecretBinary', { + const secretBinary = new Secret(testStack.stackRef, '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.stackRef, + 'testSecretStringCached', + { + secretName: secretNamePlainCached, + secretStringValue: SecretValue.unsafePlainText('foo'), + } + ); const secretStringForceFetch = new Secret( - stack, + testStack.stackRef, '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.stackRef).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..bcff8d0fcf 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.stackRef, 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.stackRef, 'Param-a', { parameterName: paramA, stringValue: paramAValue, }); - const parameterGetB = new StringParameter(stack, 'Param-b', { + const parameterGetB = new StringParameter(testStack.stackRef, 'Param-b', { parameterName: paramB, stringValue: paramBValue, }); const parameterEncryptedA = createSSMSecureString({ - stack, + stack: testStack.stackRef, id: 'Param-encrypted-a', name: paramEncryptedA, value: paramEncryptedAValue, }); const parameterEncryptedB = createSSMSecureString({ - stack, + stack: testStack.stackRef, id: 'Param-encrypted-b', name: paramEncryptedB, value: paramEncryptedBValue, }); // Give the Lambda function access to the SSM parameters - Aspects.of(stack).add( + Aspects.of(testStack.stackRef).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); }); From 0347e96a4930b67b695b7a53a600c374d3ff5a1e Mon Sep 17 00:00:00 2001 From: Andrea Amorosi Date: Thu, 27 Jul 2023 16:32:48 +0200 Subject: [PATCH 13/15] chore: added testing pkg to ci --- .../actions/cached-node-modules/action.yml | 3 ++- layers/package.json | 4 ++++ lerna.json | 1 + package-lock.json | 24 ++++++------------- 4 files changed, 14 insertions(+), 18 deletions(-) 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..c596247709 100644 --- a/layers/package.json +++ b/layers/package.json @@ -35,5 +35,9 @@ "homepage": "https://github.com/aws-powertools/powertools-lambda-typescript#readme", "devDependencies": { "source-map-support": "^0.5.21" + }, + "dependencies": { + "aws-cdk": "^2.88.0", + "aws-cdk-lib": "^2.88.0" } } 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 2c4d02740f..56de9ea6fb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -419,6 +419,10 @@ "layers": { "version": "1.12.1", "license": "MIT-0", + "dependencies": { + "aws-cdk": "^2.88.0", + "aws-cdk-lib": "^2.88.0" + }, "bin": { "layer": "bin/layers.js" }, @@ -6185,9 +6189,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" }, @@ -6542,7 +6546,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": [ @@ -17374,19 +17377,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", From 37518efd60fd538c7b9d821581fab50b9ec30744 Mon Sep 17 00:00:00 2001 From: Andrea Amorosi Date: Thu, 27 Jul 2023 17:44:54 +0200 Subject: [PATCH 14/15] tests: move layers to new testing --- layers/package.json | 4 +- layers/tests/e2e/layerPublisher.test.ts | 64 +- package-lock.json | 742 +++++++++++++++++++++++- packages/testing/package.json | 13 +- packages/testing/src/TestStack.ts | 6 +- 5 files changed, 784 insertions(+), 45 deletions(-) diff --git a/layers/package.json b/layers/package.json index c596247709..ce626f56f8 100644 --- a/layers/package.json +++ b/layers/package.json @@ -34,10 +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" + "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..78873f1bec 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.stackRef, + 'LayerVersionArnReference', + outputs['LatestLayerArn'] + ); + createStackWithLambdaFunction({ + stack: testStack.stackRef, 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/package-lock.json b/package-lock.json index 56de9ea6fb..9e61c13363 100644 --- a/package-lock.json +++ b/package-lock.json @@ -421,15 +421,383 @@ "license": "MIT-0", "dependencies": { "aws-cdk": "^2.88.0", - "aws-cdk-lib": "^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/@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" + } + }, + "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": ">=12" + } + }, + "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" + } + }, + "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" + ], + "engines": { + "node": ">=12" + } + }, + "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": ">=12" + } + }, + "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": ">=12" + } + }, + "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": ">=12" + } + }, + "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": ">=12" + } + }, + "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" + ], + "engines": { + "node": ">=12" + } + }, + "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": ">=12" + } + }, + "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": ">=12" + } + }, + "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" + } + }, + "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" + } + }, + "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" + } + }, + "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" + } + }, + "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, @@ -470,7 +838,6 @@ "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==", - "dev": true, "engines": { "node": ">= 14.15.0" } @@ -17868,9 +18235,376 @@ "name": "@aws-lambda-powertools/testing-utils", "version": "1.12.1", "license": "MIT-0", - "devDependencies": { + "dependencies": { "@aws-cdk/cli-lib-alpha": "^2.88.0-alpha.0", - "aws-cdk-lib": "^2.88.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": { diff --git a/packages/testing/package.json b/packages/testing/package.json index a039363618..375374f9ef 100644 --- a/packages/testing/package.json +++ b/packages/testing/package.json @@ -7,10 +7,6 @@ "url": "https://aws.amazon.com" }, "private": true, - "devDependencies": { - "@aws-cdk/cli-lib-alpha": "^2.88.0-alpha.0", - "aws-cdk-lib": "^2.88.0" - }, "scripts": { "test": "npm run test:unit", "test:unit": "jest --group=unit --detectOpenHandles --coverage --verbose", @@ -45,5 +41,10 @@ "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" -} \ No newline at end of file + "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 index 86d6e9f3fb..f14c09e952 100644 --- a/packages/testing/src/TestStack.ts +++ b/packages/testing/src/TestStack.ts @@ -25,9 +25,9 @@ class TestStack implements ICloudAssemblyDirectoryProducer { */ #cli: AwsCdkCli; - public constructor(stackName: string) { - this.appRef = new App(); - this.stackRef = new Stack(this.appRef, stackName); + public constructor(stackName: string, app?: App, stack?: Stack) { + this.appRef = app ?? new App(); + this.stackRef = stack ?? new Stack(this.appRef, stackName); this.#cli = AwsCdkCli.fromCloudAssemblyDirectoryProducer(this); } From 10a6ca72cef06e1b3bb996c3d1b16c7a88f4a291 Mon Sep 17 00:00:00 2001 From: Andrea Amorosi Date: Fri, 28 Jul 2023 16:04:57 +0200 Subject: [PATCH 15/15] chore: remove ref suffix --- layers/tests/e2e/layerPublisher.test.ts | 4 +-- .../tests/e2e/makeHandlerIdempotent.test.ts | 8 ++--- .../tests/e2e/makeIdempotent.test.ts | 6 ++-- .../tests/e2e/basicFeatures.middy.test.ts | 2 +- .../tests/e2e/childLogger.manual.test.ts | 2 +- .../e2e/logEventEnvVarSetting.middy.test.ts | 2 +- .../tests/e2e/sampleRate.decorator.test.ts | 2 +- .../e2e/basicFeatures.decorators.test.ts | 2 +- .../tests/e2e/basicFeatures.manual.test.ts | 2 +- .../tests/e2e/appConfigProvider.class.test.ts | 14 ++++---- .../tests/e2e/dynamoDBProvider.class.test.ts | 32 +++++++++---------- .../tests/e2e/secretsProvider.class.test.ts | 14 ++++---- .../tests/e2e/ssmProvider.class.test.ts | 12 +++---- packages/testing/src/TestStack.ts | 22 ++++++------- .../tests/e2e/allFeatures.decorator.test.ts | 10 +++--- .../tests/e2e/allFeatures.manual.test.ts | 4 +-- .../tests/e2e/allFeatures.middy.test.ts | 10 +++--- .../tests/e2e/asyncHandler.decorator.test.ts | 6 ++-- 18 files changed, 77 insertions(+), 77 deletions(-) diff --git a/layers/tests/e2e/layerPublisher.test.ts b/layers/tests/e2e/layerPublisher.test.ts index 78873f1bec..7b4bab6988 100644 --- a/layers/tests/e2e/layerPublisher.test.ts +++ b/layers/tests/e2e/layerPublisher.test.ts @@ -87,12 +87,12 @@ describe(`layers E2E tests (LayerPublisherStack) for runtime: ${runtime}`, () => const outputs = await testLayerStack.deploy(); const layerVersion = LayerVersion.fromLayerVersionArn( - testStack.stackRef, + testStack.stack, 'LayerVersionArnReference', outputs['LatestLayerArn'] ); createStackWithLambdaFunction({ - stack: testStack.stackRef, + stack: testStack.stack, functionName: functionName, functionEntry: path.join(__dirname, lambdaFunctionCodeFile), tracing: Tracing.ACTIVE, diff --git a/packages/idempotency/tests/e2e/makeHandlerIdempotent.test.ts b/packages/idempotency/tests/e2e/makeHandlerIdempotent.test.ts index 8f656b10a4..5d4ccd82c7 100644 --- a/packages/idempotency/tests/e2e/makeHandlerIdempotent.test.ts +++ b/packages/idempotency/tests/e2e/makeHandlerIdempotent.test.ts @@ -57,7 +57,7 @@ const ddbTableNameDefault = generateUniqueName( `${testDefault}-table` ); createIdempotencyResources( - testStack.stackRef, + testStack.stack, runtime, ddbTableNameDefault, makeHandlerIdempotentFile, @@ -79,7 +79,7 @@ const ddbTableNameDefaultParallel = generateUniqueName( `${testDefaultParallel}-table` ); createIdempotencyResources( - testStack.stackRef, + testStack.stack, runtime, ddbTableNameDefaultParallel, makeHandlerIdempotentFile, @@ -101,7 +101,7 @@ const ddbTableNameTimeout = generateUniqueName( `${testTimeout}-table` ); createIdempotencyResources( - testStack.stackRef, + testStack.stack, runtime, ddbTableNameTimeout, makeHandlerIdempotentFile, @@ -125,7 +125,7 @@ const ddbTableNameExpired = generateUniqueName( `${testExpired}-table` ); createIdempotencyResources( - testStack.stackRef, + testStack.stack, runtime, ddbTableNameExpired, makeHandlerIdempotentFile, diff --git a/packages/idempotency/tests/e2e/makeIdempotent.test.ts b/packages/idempotency/tests/e2e/makeIdempotent.test.ts index 2d2984ffd1..3feaefb3f1 100644 --- a/packages/idempotency/tests/e2e/makeIdempotent.test.ts +++ b/packages/idempotency/tests/e2e/makeIdempotent.test.ts @@ -56,7 +56,7 @@ const ddbTableNameDefault = generateUniqueName( `${testDefault}-table` ); createIdempotencyResources( - testStack.stackRef, + testStack.stack, runtime, ddbTableNameDefault, makeFunctionIdempotentFile, @@ -78,7 +78,7 @@ const ddbTableNameCustomConfig = generateUniqueName( `${testCustomConfig}-fn` ); createIdempotencyResources( - testStack.stackRef, + testStack.stack, runtime, ddbTableNameCustomConfig, makeFunctionIdempotentFile, @@ -101,7 +101,7 @@ const ddbTableNameLambdaHandler = generateUniqueName( `${testLambdaHandler}-table` ); createIdempotencyResources( - testStack.stackRef, + testStack.stack, runtime, ddbTableNameLambdaHandler, makeFunctionIdempotentFile, diff --git a/packages/logger/tests/e2e/basicFeatures.middy.test.ts b/packages/logger/tests/e2e/basicFeatures.middy.test.ts index 78e0b3a565..971050b5db 100644 --- a/packages/logger/tests/e2e/basicFeatures.middy.test.ts +++ b/packages/logger/tests/e2e/basicFeatures.middy.test.ts @@ -72,7 +72,7 @@ describe(`logger E2E tests basic functionalities (middy) for runtime: ${runtime} beforeAll(async () => { // Create and deploy a stack with AWS CDK createStackWithLambdaFunction({ - stack: testStack.stackRef, + stack: testStack.stack, functionName: functionName, functionEntry: path.join(__dirname, lambdaFunctionCodeFile), environment: { diff --git a/packages/logger/tests/e2e/childLogger.manual.test.ts b/packages/logger/tests/e2e/childLogger.manual.test.ts index 671b1c3fa4..b3ec427f77 100644 --- a/packages/logger/tests/e2e/childLogger.manual.test.ts +++ b/packages/logger/tests/e2e/childLogger.manual.test.ts @@ -65,7 +65,7 @@ describe(`logger E2E tests child logger functionalities (manual) for runtime: ${ beforeAll(async () => { // Create and deploy a stack with AWS CDK createStackWithLambdaFunction({ - stack: testStack.stackRef, + stack: testStack.stack, functionName: functionName, functionEntry: path.join(__dirname, lambdaFunctionCodeFile), environment: { diff --git a/packages/logger/tests/e2e/logEventEnvVarSetting.middy.test.ts b/packages/logger/tests/e2e/logEventEnvVarSetting.middy.test.ts index 79c1b9ae28..9b4e10a727 100644 --- a/packages/logger/tests/e2e/logEventEnvVarSetting.middy.test.ts +++ b/packages/logger/tests/e2e/logEventEnvVarSetting.middy.test.ts @@ -57,7 +57,7 @@ describe(`logger E2E tests log event via env var setting (middy) for runtime: ${ beforeAll(async () => { // Create and deploy a stack with AWS CDK createStackWithLambdaFunction({ - stack: testStack.stackRef, + stack: testStack.stack, functionName: functionName, functionEntry: path.join(__dirname, lambdaFunctionCodeFile), environment: { diff --git a/packages/logger/tests/e2e/sampleRate.decorator.test.ts b/packages/logger/tests/e2e/sampleRate.decorator.test.ts index 80a3b190a5..53f6401aee 100644 --- a/packages/logger/tests/e2e/sampleRate.decorator.test.ts +++ b/packages/logger/tests/e2e/sampleRate.decorator.test.ts @@ -63,7 +63,7 @@ describe(`logger E2E tests sample rate and injectLambdaContext() for runtime: no beforeAll(async () => { // Create and deploy a stack with AWS CDK createStackWithLambdaFunction({ - stack: testStack.stackRef, + stack: testStack.stack, functionName: functionName, functionEntry: path.join(__dirname, lambdaFunctionCodeFile), environment: { diff --git a/packages/metrics/tests/e2e/basicFeatures.decorators.test.ts b/packages/metrics/tests/e2e/basicFeatures.decorators.test.ts index cebbd2f140..e2dbd76c3d 100644 --- a/packages/metrics/tests/e2e/basicFeatures.decorators.test.ts +++ b/packages/metrics/tests/e2e/basicFeatures.decorators.test.ts @@ -75,7 +75,7 @@ describe(`metrics E2E tests (decorator) for runtime: ${runtime}`, () => { beforeAll(async () => { // GIVEN a stack createStackWithLambdaFunction({ - stack: testStack.stackRef, + stack: testStack.stack, functionName: functionName, functionEntry: path.join(__dirname, lambdaFunctionCodeFile), tracing: Tracing.ACTIVE, diff --git a/packages/metrics/tests/e2e/basicFeatures.manual.test.ts b/packages/metrics/tests/e2e/basicFeatures.manual.test.ts index 8ac8af1364..4bde10e7f3 100644 --- a/packages/metrics/tests/e2e/basicFeatures.manual.test.ts +++ b/packages/metrics/tests/e2e/basicFeatures.manual.test.ts @@ -76,7 +76,7 @@ describe(`metrics E2E tests (manual) for runtime: ${runtime}`, () => { beforeAll(async () => { // GIVEN a stack createStackWithLambdaFunction({ - stack: testStack.stackRef, + stack: testStack.stack, functionName: functionName, functionEntry: path.join(__dirname, lambdaFunctionCodeFile), tracing: Tracing.ACTIVE, diff --git a/packages/parameters/tests/e2e/appConfigProvider.class.test.ts b/packages/parameters/tests/e2e/appConfigProvider.class.test.ts index afa0ebc62a..ec662d8bb4 100644 --- a/packages/parameters/tests/e2e/appConfigProvider.class.test.ts +++ b/packages/parameters/tests/e2e/appConfigProvider.class.test.ts @@ -180,7 +180,7 @@ describe(`parameters E2E tests (appConfigProvider) for runtime ${runtime}`, () = beforeAll(async () => { // Create a stack with a Lambda function createStackWithLambdaFunction({ - stack: testStack.stackRef, + stack: testStack.stack, functionName, functionEntry: path.join(__dirname, lambdaFunctionCodeFile), environment: { @@ -200,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: testStack.stackRef, + stack: testStack.stack, applicationName, environmentName, deploymentStrategyName, @@ -208,7 +208,7 @@ describe(`parameters E2E tests (appConfigProvider) for runtime ${runtime}`, () = // Create configuration profiles for tests. const freeFormJson = createAppConfigConfigurationProfile({ - stack: testStack.stackRef, + stack: testStack.stack, application, environment, deploymentStrategy, @@ -221,7 +221,7 @@ describe(`parameters E2E tests (appConfigProvider) for runtime ${runtime}`, () = }); const freeFormYaml = createAppConfigConfigurationProfile({ - stack: testStack.stackRef, + stack: testStack.stack, application, environment, deploymentStrategy, @@ -235,7 +235,7 @@ describe(`parameters E2E tests (appConfigProvider) for runtime ${runtime}`, () = freeFormYaml.node.addDependency(freeFormJson); const freeFormBase64PlainText = createAppConfigConfigurationProfile({ - stack: testStack.stackRef, + stack: testStack.stack, application, environment, deploymentStrategy, @@ -249,7 +249,7 @@ describe(`parameters E2E tests (appConfigProvider) for runtime ${runtime}`, () = freeFormBase64PlainText.node.addDependency(freeFormYaml); const featureFlag = createAppConfigConfigurationProfile({ - stack: testStack.stackRef, + stack: testStack.stack, application, environment, deploymentStrategy, @@ -263,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(testStack.stackRef).add( + Aspects.of(testStack.stack).add( new ResourceAccessGranter([ freeFormJson, freeFormYaml, diff --git a/packages/parameters/tests/e2e/dynamoDBProvider.class.test.ts b/packages/parameters/tests/e2e/dynamoDBProvider.class.test.ts index bf4a49355e..c47a006e30 100644 --- a/packages/parameters/tests/e2e/dynamoDBProvider.class.test.ts +++ b/packages/parameters/tests/e2e/dynamoDBProvider.class.test.ts @@ -166,7 +166,7 @@ describe(`parameters E2E tests (dynamoDBProvider) for runtime: ${runtime}`, () = beforeAll(async () => { // Create a stack with a Lambda function createStackWithLambdaFunction({ - stack: testStack.stackRef, + stack: testStack.stack, functionName, functionEntry: path.join(__dirname, lambdaFunctionCodeFile), environment: { @@ -186,7 +186,7 @@ describe(`parameters E2E tests (dynamoDBProvider) for runtime: ${runtime}`, () = // Create the DynamoDB tables const ddbTableGet = createDynamoDBTable({ - stack: testStack.stackRef, + stack: testStack.stack, id: 'Table-get', tableName: tableGet, partitionKey: { @@ -195,7 +195,7 @@ describe(`parameters E2E tests (dynamoDBProvider) for runtime: ${runtime}`, () = }, }); const ddbTableGetMultiple = createDynamoDBTable({ - stack: testStack.stackRef, + stack: testStack.stack, id: 'Table-getMultiple', tableName: tableGetMultiple, partitionKey: { @@ -208,7 +208,7 @@ describe(`parameters E2E tests (dynamoDBProvider) for runtime: ${runtime}`, () = }, }); const ddbTableGetCustomKeys = createDynamoDBTable({ - stack: testStack.stackRef, + stack: testStack.stack, id: 'Table-getCustomKeys', tableName: tableGetCustomkeys, partitionKey: { @@ -217,7 +217,7 @@ describe(`parameters E2E tests (dynamoDBProvider) for runtime: ${runtime}`, () = }, }); const ddbTabelGetMultipleCustomKeys = createDynamoDBTable({ - stack: testStack.stackRef, + stack: testStack.stack, id: 'Table-getMultipleCustomKeys', tableName: tableGetMultipleCustomkeys, partitionKey: { @@ -231,7 +231,7 @@ describe(`parameters E2E tests (dynamoDBProvider) for runtime: ${runtime}`, () = }); // Give the Lambda access to the DynamoDB tables - Aspects.of(testStack.stackRef).add( + Aspects.of(testStack.stack).add( new ResourceAccessGranter([ ddbTableGet, ddbTableGetMultiple, @@ -243,7 +243,7 @@ describe(`parameters E2E tests (dynamoDBProvider) for runtime: ${runtime}`, () = // Seed tables with test data // Test 1 putDynamoDBItem({ - stack: testStack.stackRef, + stack: testStack.stack, id: 'my-param-test1', table: ddbTableGet, item: { @@ -254,7 +254,7 @@ describe(`parameters E2E tests (dynamoDBProvider) for runtime: ${runtime}`, () = // Test 2 putDynamoDBItem({ - stack: testStack.stackRef, + stack: testStack.stack, id: 'my-param-test2-a', table: ddbTableGetMultiple, item: { @@ -264,7 +264,7 @@ describe(`parameters E2E tests (dynamoDBProvider) for runtime: ${runtime}`, () = }, }); putDynamoDBItem({ - stack: testStack.stackRef, + stack: testStack.stack, id: 'my-param-test2-b', table: ddbTableGetMultiple, item: { @@ -276,7 +276,7 @@ describe(`parameters E2E tests (dynamoDBProvider) for runtime: ${runtime}`, () = // Test 3 putDynamoDBItem({ - stack: testStack.stackRef, + stack: testStack.stack, id: 'my-param-test3', table: ddbTableGetCustomKeys, item: { @@ -287,7 +287,7 @@ describe(`parameters E2E tests (dynamoDBProvider) for runtime: ${runtime}`, () = // Test 4 putDynamoDBItem({ - stack: testStack.stackRef, + stack: testStack.stack, id: 'my-param-test4-a', table: ddbTabelGetMultipleCustomKeys, item: { @@ -297,7 +297,7 @@ describe(`parameters E2E tests (dynamoDBProvider) for runtime: ${runtime}`, () = }, }); putDynamoDBItem({ - stack: testStack.stackRef, + stack: testStack.stack, id: 'my-param-test4-b', table: ddbTabelGetMultipleCustomKeys, item: { @@ -309,7 +309,7 @@ describe(`parameters E2E tests (dynamoDBProvider) for runtime: ${runtime}`, () = // Test 5 putDynamoDBItem({ - stack: testStack.stackRef, + stack: testStack.stack, id: 'my-param-test5', table: ddbTableGet, item: { @@ -320,7 +320,7 @@ describe(`parameters E2E tests (dynamoDBProvider) for runtime: ${runtime}`, () = // Test 6 putDynamoDBItem({ - stack: testStack.stackRef, + stack: testStack.stack, id: 'my-param-test6', table: ddbTableGet, item: { @@ -331,7 +331,7 @@ describe(`parameters E2E tests (dynamoDBProvider) for runtime: ${runtime}`, () = // Test 7 putDynamoDBItem({ - stack: testStack.stackRef, + stack: testStack.stack, id: 'my-param-test7-a', table: ddbTableGetMultiple, item: { @@ -341,7 +341,7 @@ describe(`parameters E2E tests (dynamoDBProvider) for runtime: ${runtime}`, () = }, }); putDynamoDBItem({ - stack: testStack.stackRef, + stack: testStack.stack, id: 'my-param-test7-b', table: ddbTableGetMultiple, item: { diff --git a/packages/parameters/tests/e2e/secretsProvider.class.test.ts b/packages/parameters/tests/e2e/secretsProvider.class.test.ts index d37a54d9d0..d43dd768e5 100644 --- a/packages/parameters/tests/e2e/secretsProvider.class.test.ts +++ b/packages/parameters/tests/e2e/secretsProvider.class.test.ts @@ -106,7 +106,7 @@ 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 createStackWithLambdaFunction({ - stack: testStack.stackRef, + stack: testStack.stack, functionName: functionName, functionEntry: path.join(__dirname, lambdaFunctionCodeFile), tracing: Tracing.ACTIVE, @@ -121,25 +121,25 @@ describe(`parameters E2E tests (SecretsProvider) for runtime: ${runtime}`, () => runtime: runtime, }); - const secretString = new Secret(testStack.stackRef, 'testSecretPlain', { + const secretString = new Secret(testStack.stack, 'testSecretPlain', { secretName: secretNamePlain, secretStringValue: SecretValue.unsafePlainText('foo'), }); - const secretObject = new Secret(testStack.stackRef, 'testSecretObject', { + const secretObject = new Secret(testStack.stack, 'testSecretObject', { secretName: secretNameObject, secretObjectValue: { foo: SecretValue.unsafePlainText('bar'), }, }); - const secretBinary = new Secret(testStack.stackRef, 'testSecretBinary', { + const secretBinary = new Secret(testStack.stack, 'testSecretBinary', { secretName: secretNameBinary, secretStringValue: SecretValue.unsafePlainText('Zm9v'), // 'foo' encoded in base64 }); const secretStringCached = new Secret( - testStack.stackRef, + testStack.stack, 'testSecretStringCached', { secretName: secretNamePlainCached, @@ -148,7 +148,7 @@ describe(`parameters E2E tests (SecretsProvider) for runtime: ${runtime}`, () => ); const secretStringForceFetch = new Secret( - testStack.stackRef, + testStack.stack, 'testSecretStringForceFetch', { secretName: secretNamePlainForceFetch, @@ -157,7 +157,7 @@ describe(`parameters E2E tests (SecretsProvider) for runtime: ${runtime}`, () => ); // add secrets here to grant lambda permisisons to access secrets - Aspects.of(testStack.stackRef).add( + Aspects.of(testStack.stack).add( new ResourceAccessGranter([ secretString, secretObject, diff --git a/packages/parameters/tests/e2e/ssmProvider.class.test.ts b/packages/parameters/tests/e2e/ssmProvider.class.test.ts index bcff8d0fcf..a685a988f5 100644 --- a/packages/parameters/tests/e2e/ssmProvider.class.test.ts +++ b/packages/parameters/tests/e2e/ssmProvider.class.test.ts @@ -139,7 +139,7 @@ describe(`parameters E2E tests (ssmProvider) for runtime: ${runtime}`, () => { beforeAll(async () => { // Create a stack with a Lambda function createStackWithLambdaFunction({ - stack: testStack.stackRef, + stack: testStack.stack, functionName, functionEntry: path.join(__dirname, lambdaFunctionCodeFile), environment: { @@ -155,31 +155,31 @@ describe(`parameters E2E tests (ssmProvider) for runtime: ${runtime}`, () => { }); // Create SSM parameters - const parameterGetA = new StringParameter(testStack.stackRef, 'Param-a', { + const parameterGetA = new StringParameter(testStack.stack, 'Param-a', { parameterName: paramA, stringValue: paramAValue, }); - const parameterGetB = new StringParameter(testStack.stackRef, 'Param-b', { + const parameterGetB = new StringParameter(testStack.stack, 'Param-b', { parameterName: paramB, stringValue: paramBValue, }); const parameterEncryptedA = createSSMSecureString({ - stack: testStack.stackRef, + stack: testStack.stack, id: 'Param-encrypted-a', name: paramEncryptedA, value: paramEncryptedAValue, }); const parameterEncryptedB = createSSMSecureString({ - stack: testStack.stackRef, + stack: testStack.stack, id: 'Param-encrypted-b', name: paramEncryptedB, value: paramEncryptedBValue, }); // Give the Lambda function access to the SSM parameters - Aspects.of(testStack.stackRef).add( + Aspects.of(testStack.stack).add( new ResourceAccessGranter([ parameterGetA, parameterGetB, diff --git a/packages/testing/src/TestStack.ts b/packages/testing/src/TestStack.ts index f14c09e952..8c84e86fb8 100644 --- a/packages/testing/src/TestStack.ts +++ b/packages/testing/src/TestStack.ts @@ -13,12 +13,12 @@ class TestStack implements ICloudAssemblyDirectoryProducer { * Reference to the AWS CDK App object. * @default new App() */ - public appRef: App; + public app: App; /** * Reference to the AWS CDK Stack object. - * @default new Stack(this.appRef, stackName) + * @default new Stack(this.app, stackName) */ - public stackRef: Stack; + public stack: Stack; /** * @internal * Reference to the AWS CDK CLI object. @@ -26,8 +26,8 @@ class TestStack implements ICloudAssemblyDirectoryProducer { #cli: AwsCdkCli; public constructor(stackName: string, app?: App, stack?: Stack) { - this.appRef = app ?? new App(); - this.stackRef = stack ?? new Stack(this.appRef, stackName); + this.app = app ?? new App(); + this.stack = stack ?? new Stack(this.app, stackName); this.#cli = AwsCdkCli.fromCloudAssemblyDirectoryProducer(this); } @@ -40,16 +40,16 @@ class TestStack implements ICloudAssemblyDirectoryProducer { const outputFilePath = join( tmpdir(), 'powertools-e2e-testing', - `${this.stackRef.stackName}.outputs.json` + `${this.stack.stackName}.outputs.json` ); await this.#cli.deploy({ - stacks: [this.stackRef.stackName], + stacks: [this.stack.stackName], requireApproval: RequireApproval.NEVER, outputsFile: outputFilePath, }); return JSON.parse(await readFile(outputFilePath, 'utf-8'))[ - this.stackRef.stackName + this.stack.stackName ]; } @@ -58,7 +58,7 @@ class TestStack implements ICloudAssemblyDirectoryProducer { */ public async destroy(): Promise { await this.#cli.destroy({ - stacks: [this.stackRef.stackName], + stacks: [this.stack.stackName], requireApproval: false, }); } @@ -67,7 +67,7 @@ class TestStack implements ICloudAssemblyDirectoryProducer { * Produce the Cloud Assembly directory. */ public async produce(_context: Record): Promise { - return this.appRef.synth().directory; + return this.app.synth().directory; } /** @@ -75,7 +75,7 @@ class TestStack implements ICloudAssemblyDirectoryProducer { */ public async synth(): Promise { await this.#cli.synth({ - stacks: [this.stackRef.stackName], + stacks: [this.stack.stackName], }); } } diff --git a/packages/tracer/tests/e2e/allFeatures.decorator.test.ts b/packages/tracer/tests/e2e/allFeatures.decorator.test.ts index b1404cf201..a6f9c0911d 100644 --- a/packages/tracer/tests/e2e/allFeatures.decorator.test.ts +++ b/packages/tracer/tests/e2e/allFeatures.decorator.test.ts @@ -127,7 +127,7 @@ describe(`Tracer E2E tests, all features with decorator instantiation for runtim startTime = new Date(); const ddbTableName = stackName + '-table'; - const ddbTable = new Table(testStack.stackRef, 'Table', { + const ddbTable = new Table(testStack.stack, 'Table', { tableName: ddbTableName, partitionKey: { name: 'id', @@ -139,7 +139,7 @@ describe(`Tracer E2E tests, all features with decorator instantiation for runtim const entry = path.join(__dirname, lambdaFunctionCodeFile); const functionWithAllFlagsEnabled = createTracerTestFunction({ - stack: testStack.stackRef, + stack: testStack.stack, functionName: functionNameWithAllFlagsEnabled, entry, expectedServiceName: serviceNameWithAllFlagsEnabled, @@ -155,7 +155,7 @@ describe(`Tracer E2E tests, all features with decorator instantiation for runtim const functionThatDoesNotCapturesErrorAndResponse = createTracerTestFunction({ - stack: testStack.stackRef, + stack: testStack.stack, functionName: functionNameWithNoCaptureErrorOrResponse, entry, expectedServiceName: serviceNameWithNoCaptureErrorOrResponse, @@ -170,7 +170,7 @@ describe(`Tracer E2E tests, all features with decorator instantiation for runtim ddbTable.grantWriteData(functionThatDoesNotCapturesErrorAndResponse); const functionWithTracerDisabled = createTracerTestFunction({ - stack: testStack.stackRef, + stack: testStack.stack, functionName: functionNameWithTracerDisabled, entry, expectedServiceName: serviceNameWithTracerDisabled, @@ -185,7 +185,7 @@ describe(`Tracer E2E tests, all features with decorator instantiation for runtim ddbTable.grantWriteData(functionWithTracerDisabled); const functionWithCaptureResponseFalse = createTracerTestFunction({ - stack: testStack.stackRef, + stack: testStack.stack, functionName: functionNameWithCaptureResponseFalse, handler: 'handlerWithCaptureResponseFalse', entry, diff --git a/packages/tracer/tests/e2e/allFeatures.manual.test.ts b/packages/tracer/tests/e2e/allFeatures.manual.test.ts index ff6f251fb3..9d8cbb7bed 100644 --- a/packages/tracer/tests/e2e/allFeatures.manual.test.ts +++ b/packages/tracer/tests/e2e/allFeatures.manual.test.ts @@ -87,7 +87,7 @@ describe(`Tracer E2E tests, all features with manual instantiation for runtime: POWERTOOLS_TRACE_ENABLED: 'true', }; const testFunction = createTracerTestFunction({ - stack: testStack.stackRef, + stack: testStack.stack, functionName, entry, expectedServiceName, @@ -95,7 +95,7 @@ describe(`Tracer E2E tests, all features with manual instantiation for runtime: runtime, }); - const ddbTable = new Table(testStack.stackRef, 'Table', { + const ddbTable = new Table(testStack.stack, 'Table', { tableName: ddbTableName, partitionKey: { name: 'id', diff --git a/packages/tracer/tests/e2e/allFeatures.middy.test.ts b/packages/tracer/tests/e2e/allFeatures.middy.test.ts index 1d08e6799a..7066a549db 100644 --- a/packages/tracer/tests/e2e/allFeatures.middy.test.ts +++ b/packages/tracer/tests/e2e/allFeatures.middy.test.ts @@ -128,7 +128,7 @@ describe(`Tracer E2E tests, all features with middy instantiation for runtime: $ startTime = new Date(); const ddbTableName = stackName + '-table'; - const ddbTable = new Table(testStack.stackRef, 'Table', { + const ddbTable = new Table(testStack.stack, 'Table', { tableName: ddbTableName, partitionKey: { name: 'id', @@ -140,7 +140,7 @@ describe(`Tracer E2E tests, all features with middy instantiation for runtime: $ const entry = path.join(__dirname, lambdaFunctionCodeFile); const functionWithAllFlagsEnabled = createTracerTestFunction({ - stack: testStack.stackRef, + stack: testStack.stack, functionName: functionNameWithAllFlagsEnabled, entry, expectedServiceName: serviceNameWithAllFlagsEnabled, @@ -156,7 +156,7 @@ describe(`Tracer E2E tests, all features with middy instantiation for runtime: $ const functionThatDoesNotCapturesErrorAndResponse = createTracerTestFunction({ - stack: testStack.stackRef, + stack: testStack.stack, functionName: functionNameWithNoCaptureErrorOrResponse, entry, expectedServiceName: serviceNameWithNoCaptureErrorOrResponse, @@ -171,7 +171,7 @@ describe(`Tracer E2E tests, all features with middy instantiation for runtime: $ ddbTable.grantWriteData(functionThatDoesNotCapturesErrorAndResponse); const functionWithTracerDisabled = createTracerTestFunction({ - stack: testStack.stackRef, + stack: testStack.stack, functionName: functionNameWithTracerDisabled, entry, expectedServiceName: serviceNameWithTracerDisabled, @@ -187,7 +187,7 @@ describe(`Tracer E2E tests, all features with middy instantiation for runtime: $ const functionThatDoesNotCaptureResponseViaMiddlewareOption = createTracerTestFunction({ - stack: testStack.stackRef, + stack: testStack.stack, functionName: functionNameWithNoCaptureResponseViaMiddlewareOption, entry, handler: 'handlerWithNoCaptureResponseViaMiddlewareOption', diff --git a/packages/tracer/tests/e2e/asyncHandler.decorator.test.ts b/packages/tracer/tests/e2e/asyncHandler.decorator.test.ts index d5b6f2fc1e..8d460ee0f1 100644 --- a/packages/tracer/tests/e2e/asyncHandler.decorator.test.ts +++ b/packages/tracer/tests/e2e/asyncHandler.decorator.test.ts @@ -97,7 +97,7 @@ describe(`Tracer E2E tests, asynchronous handler with decorator instantiation fo startTime = new Date(); const ddbTableName = stackName + '-table'; - const ddbTable = new Table(testStack.stackRef, 'Table', { + const ddbTable = new Table(testStack.stack, 'Table', { tableName: ddbTableName, partitionKey: { name: 'id', @@ -109,7 +109,7 @@ describe(`Tracer E2E tests, asynchronous handler with decorator instantiation fo const entry = path.join(__dirname, lambdaFunctionCodeFile); const functionWithAllFlagsEnabled = createTracerTestFunction({ - stack: testStack.stackRef, + stack: testStack.stack, functionName: functionNameWithAllFlagsEnabled, entry, expectedServiceName: serviceNameWithAllFlagsEnabled, @@ -124,7 +124,7 @@ describe(`Tracer E2E tests, asynchronous handler with decorator instantiation fo ddbTable.grantWriteData(functionWithAllFlagsEnabled); const functionWithCustomSubsegmentNameInMethod = createTracerTestFunction({ - stack: testStack.stackRef, + stack: testStack.stack, functionName: functionNameWithCustomSubsegmentNameInMethod, handler: 'handlerWithCustomSubsegmentNameInMethod', entry,