Skip to content

Commit d6aae13

Browse files
flochazdreamorosiijemmysaragerion
authored
chore: run e2e tests on demand (#441)
Co-authored-by: Andrea Amorosi <[email protected]> Co-authored-by: ijemmy <[email protected]> Co-authored-by: Sara Gerion <[email protected]>
1 parent c06fbd4 commit d6aae13

20 files changed

+250
-99
lines changed

Diff for: .github/workflows/on-merge-to-main.yml

-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ on:
77
jobs:
88
publish:
99
runs-on: ubuntu-latest
10-
1110
steps:
1211
- name: "Checkout"
1312
uses: actions/checkout@v2

Diff for: .github/workflows/run-e2e-tests.yml

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
name: run-e2e-tests
2+
on:
3+
workflow_dispatch: {}
4+
jobs:
5+
run:
6+
runs-on: ubuntu-latest
7+
permissions:
8+
id-token: write # needed to interact with GitHub's OIDC Token endpoint.
9+
contents: read
10+
steps:
11+
- name: "Checkout"
12+
uses: actions/checkout@v2
13+
#########################
14+
# Release new version
15+
#########################
16+
- name: "Use NodeJS 14"
17+
uses: actions/setup-node@v2
18+
with:
19+
node-version: '14'
20+
- name: Install packages
21+
run: |
22+
npm ci
23+
npm run lerna-ci
24+
- name: Configure AWS credentials
25+
uses: aws-actions/[email protected]
26+
with:
27+
role-to-assume: ${{ secrets.AWS_ROLE_ARN_TO_ASSUME }}
28+
aws-region: eu-west-1
29+
- name: Run integration tests
30+
run: npm run lerna-test:e2e

Diff for: CONTRIBUTING.md

+90
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,96 @@ You can build and start a local docs website by running these two commands.
5959
* `npm run docs-buildDockerImage` OR `docker build -t squidfunk/mkdocs-material ./docs/`
6060
* `npm run docs-runLocalDocker` OR `docker run --rm -it -p 8000:8000 -v ${PWD}:/docs squidfunk/mkdocs-material`
6161

62+
### Tests
63+
64+
Tests are under `tests` folder of each modules and split into two categories: unit tests and e2e (end-to-end) tests.
65+
66+
You can run each group separately or all together thanks to [jest-runner-groups](https://www.npmjs.com/package/jest-runner-groups).
67+
68+
Unit tests, under `tests/unit` folder are standard [Jest](https://jestjs.io) tests.
69+
70+
End-to-end tests, under `tests/e2e` folder, will test the module features by deploying AWS Lambda functions into your AWS Account. We use [aws-cdk](https://docs.aws.amazon.com/cdk/v1/guide/getting_started.html) v1 library (not v2 due to [this cdk issue](https://github.com/aws/aws-cdk/issues/18211)) for Typescript for creating infrastructure, and [aws-sdk-js v2](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/) for invoking the functions and assert on the expected behaviors. All steps are also executed by Jest.
71+
72+
73+
Running end-to-end tests will deploy AWS resources. You will need an AWS account and the tests might incur costs. The cost from **some services** are covered by the [AWS Free Tier](https://aws.amazon.com/free/?all-free-tier.sort-by=item.additionalFields.SortRank&all-free-tier.sort-order=asc&awsf.Free%20Tier%20Types=*all&awsf.Free%20Tier%20Categories=*all) but not all of them. If you don't have an AWS Account follow [these instructions to create one](https://aws.amazon.com/premiumsupport/knowledge-center/create-and-activate-aws-account/).
74+
75+
When contributing to this repository, these end-to-end tests are run by the maintainers before merging a PR.
76+
77+
78+
**Unit tests**
79+
80+
**Write**
81+
82+
As mentioned before, tests are split into groups thanks to [jest-runner-groups](https://www.npmjs.com/package/jest-runner-groups) and therefore each test needs to be tagged properly by adding the following comments in the header of your unit test file:
83+
84+
```typescript
85+
/**
86+
* Tests metrics
87+
*
88+
* @group unit/<YOUR CATEGORY>/<YOUR SUB CATEGORY>
89+
*/
90+
```
91+
92+
**Run**
93+
94+
To run unit tests you can either use
95+
* npm task `lerna-test:unit` (`npm run lerna-test:unit`) in root folder to run them all
96+
* npm task `test:e2e` (`npm run test:unit`) in module folder (for example: `packages/metrics`) to run the module specific one
97+
* jest directly `npx jest --group=unit` in module folder to run the module specific one (You can run selective tests by restricting the group to the one you want. For instance `npx jest --group=unit/metrics/class`)
98+
99+
**e2e tests**
100+
101+
**Write**
102+
103+
As mentioned in the previous section, tests are split into groups thanks to [jest-runner-groups](https://www.npmjs.com/package/jest-runner-groups) and therefore each test needs to be tagged properly by adding the following comments in the header of your unit test file:
104+
105+
```typescript
106+
/**
107+
* Tests data lake catalog
108+
*
109+
* @group e2e/<YOUR CATEGORY>/<YOUR SUB CATEGORY>
110+
*/
111+
```
112+
113+
See `metrics/tests/e2e/decorator.test.ts` as an example.
114+
115+
116+
**Run**
117+
118+
To run e2e tests you can either use
119+
* npm task `lerna-test:e2e` (`npm run lerna-test:e2e`) in root folder
120+
* npm task `test:e2e` (`npm run test:e2e`) in module folder (for example: `packages/metrics`) to run the module specific one
121+
* jest directly `npx jest --group=e2e` in module folder. (You can run selective tests by restricting the group to the one you want. For instance `npx jest --group=e2e/metrics/decorator`)
122+
123+
Two important env variable can be used:
124+
* `AWS_PROFILE` to use the right AWS credentials
125+
* `DISABLE_TEARDOWN` if you don't want your stack to be destroyed at the end of the test (useful in dev mode when iterating over your code).
126+
127+
Example: `DISABLE_TEARDOWN=true AWS_PROFILE=dev-account npx jest --group=e2e/metrics/decorator`
128+
129+
**Automate**
130+
131+
You can run the end-to-end tests automatically on your forked project by following these steps:
132+
1. Create an IAM role in your target AWS account, with the least amount of privilege.
133+
134+
As mentioned above in this page, we are leveraging CDK to deploy and consequently clean-up resources on AWS. Therefore to run those tests through Github actions you will need to grant specific permissions to your workflow.
135+
136+
We recommend following [Amazon IAM best practices](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html) for the AWS credentials used in GitHub Actions workflows, including:
137+
* Do not store credentials in your repository's code.
138+
* [Grant least privilege](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege) to the credentials used in GitHub Actions workflows. Grant only the permissions required to perform the actions in your GitHub Actions workflows.
139+
* [Monitor the activity](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#keep-a-log) of the credentials used in GitHub Actions workflows.
140+
141+
For an example of how to create a role in CDK, you can look at [@pahud/cdk-github-oidc](https://constructs.dev/packages/@pahud/cdk-github-oidc) construct.
142+
143+
More information about:
144+
145+
- [Github OpenID Connect](https://github.blog/changelog/2021-10-27-github-actions-secure-cloud-deployments-with-openid-connect/
146+
- ["Configure AWS Credentials" Action For GitHub Actions](https://github.com/aws-actions/configure-aws-credentials/)
147+
2. Add your new role into your [Github fork secrets](https://docs.github.com/en/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository) with name `AWS_ROLE_ARN_TO_ASSUME`.
148+
3. In your forked repository, go to the "Actions" tabs, select the `run-e2e-tests` workflow.
149+
4. In the run-e2e-tests workflow page, select "Run workflow" and run it on the desired branch.
150+
151+
> :warning: **Don't automatically run end-to-end tests on branch push or PRs**. A malicious attacker can submit a pull request to attack your AWS account. Ideally, use a blank account without any important workload/data, and limit `AWS_ROLE_ARN_TO_ASSUME` permission to least minimum privilege.
62152
### Conventions
63153

64154
Category | Convention

Diff for: package.json

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
"package": "npm run package",
1515
"lerna-ci": "lerna exec -- npm ci",
1616
"lerna-test": "lerna exec -- npm run test",
17+
"lerna-test:e2e": "lerna exec -- npm run test:e2e",
1718
"lerna-package": "lerna exec -- npm run package",
1819
"lerna-build": "lerna exec -- tsc",
1920
"lerna-lint": "lerna exec -- eslint \"./{src,tests}/**/*.ts ./src/*.ts\"",

Diff for: packages/commons/package.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@
1111
},
1212
"scripts": {
1313
"commit": "commit",
14-
"test": "jest --detectOpenHandles --coverage --verbose",
14+
"test": "npm run test:unit",
15+
"test:unit": "jest --group=unit --detectOpenHandles --coverage --verbose",
16+
"test:e2e": "echo 'Not Applicable'",
1517
"watch": "jest --watch",
1618
"build": "tsc",
1719
"lint": "eslint --ext .ts --fix --no-error-on-unmatched-pattern src tests",

Diff for: packages/logger/jest.config.js

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ module.exports = {
33
name: 'AWS Lambda Powertools utility: LOGGER',
44
color: 'cyan',
55
},
6+
'runner': 'groups',
67
'preset': 'ts-jest',
78
'transform': {
89
'^.+\\.ts?$': 'ts-jest',

Diff for: packages/logger/package-lock.json

+21
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: packages/logger/package.json

+4-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@
1111
},
1212
"scripts": {
1313
"commit": "commit",
14-
"test": "jest --detectOpenHandles --coverage --verbose",
14+
"test": "npm run test:unit",
15+
"test:unit": "jest --group=unit --detectOpenHandles --coverage --verbose",
16+
"test:e2e": "jest --group=e2e",
1517
"watch": "jest --watch",
1618
"build": "tsc",
1719
"lint": "eslint --ext .ts --fix --no-error-on-unmatched-pattern src tests",
@@ -53,6 +55,7 @@
5355
"eslint-import-resolver-typescript": "^2.5.0",
5456
"eslint-plugin-import": "^2.25.3",
5557
"jest": "^27.0.4",
58+
"jest-runner-groups": "^2.1.0",
5659
"ts-jest": "^27.0.3",
5760
"ts-node": "^10.0.0",
5861
"typescript": "^4.1.3"

Diff for: packages/logger/tests/unit/Logger.test.ts

+6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
/**
2+
* Test Logger class
3+
*
4+
* @group unit/logger/all
5+
*/
6+
17
import { context as dummyContext } from '../../../../tests/resources/contexts/hello-world';
28
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
39
// @ts-ignore

Diff for: packages/logger/tests/unit/config/EnvironmentVariablesService.test.ts

+6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
/**
2+
* Test Logger EnvironmentVariablesService class
3+
*
4+
* @group unit/logger/all
5+
*/
6+
17
import { EnvironmentVariablesService } from '../../../src/config';
28

39
describe('Class: EnvironmentVariablesService', () => {

Diff for: packages/logger/tests/unit/formatter/PowertoolLogFormatter.test.ts

+6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
/**
2+
* Test Logger formatter
3+
*
4+
* @group unit/logger/all
5+
*/
6+
17
import { AssertionError, strictEqual } from 'assert';
28
import { PowertoolLogFormatter } from '../../../src/formatter';
39
import { UnformattedAttributes } from '../../../src/types';

Diff for: packages/logger/tests/unit/helpers.test.ts

+6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
/**
2+
* Test Logger helpers
3+
*
4+
* @group unit/logger/all
5+
*/
6+
17
import { ConfigServiceInterface, EnvironmentVariablesService } from '../../src/config';
28
import { LogFormatter, PowertoolLogFormatter } from '../../src/formatter';
39
import { LoggerOptions } from '../../src/types';

Diff for: packages/logger/tests/unit/middleware/middy.test.ts

+6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
/**
2+
* Test Logger middleware
3+
*
4+
* @group unit/logger/all
5+
*/
6+
17
import { EnvironmentVariablesService } from '../../../src/config';
28
import { injectLambdaContext } from '../../../src/middleware/middy';
39
import { Logger } from './../../../src';

Diff for: packages/metrics/package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
},
1212
"scripts": {
1313
"commit": "commit",
14-
"test": "jest --group=unit --detectOpenHandles --coverage --verbose",
14+
"test": "npm run test:unit",
15+
"test:unit": "jest --group=unit --detectOpenHandles --coverage --verbose",
1516
"test:e2e": "jest --group=e2e",
1617
"watch": "jest --group=unit --watch ",
1718
"build": "tsc",

Diff for: packages/metrics/tests/e2e/decorator.test.MyFunction.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const singleMetricName = process.env.EXPECTED_SINGLE_METRIC_NAME ?? 'MySingleMet
1414
const singleMetricUnit = (process.env.EXPECTED_SINGLE_METRIC_UNIT as MetricUnits) ?? MetricUnits.Percent;
1515
const singleMetricValue = process.env.EXPECTED_SINGLE_METRIC_VALUE ?? '2';
1616

17-
const metrics = new Metrics({ namespace: namespace, service: serviceName });
17+
const metrics = new Metrics({ namespace: namespace, serviceName: serviceName });
1818

1919
class Lambda implements LambdaInterface {
2020

0 commit comments

Comments
 (0)