Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert manual integration tests to pytest tests #148

Merged
merged 4 commits into from
Sep 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -132,4 +132,7 @@ dmypy.json
.DS_Store

# VSCode
.vscode/
.vscode/

# PyCharm
.idea/
7 changes: 5 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,16 @@ update: install # update all python dependencies
pipenv update --dev

## ---- Test commands ---- ##
test: # run tests and print coverage report
pipenv run coverage run --source=lambdas -m pytest -vv
test: # Run tests and print a coverage report
pipenv run coverage run --source=lambdas -m pytest -vv -m "not integration"
pipenv run coverage report -m

coveralls: test
pipenv run coverage lcov -o ./coverage/lcov.info

test-integration:
pipenv run pytest -vv -s -m "integration"
jonavellecuerdo marked this conversation as resolved.
Show resolved Hide resolved

## ---- Code quality and safety commands ###

# linting commands
Expand Down
76 changes: 24 additions & 52 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,88 +29,60 @@ Required env variables:
- `WORKSPACE=dev`: env for local development, set by Terraform in AWS environments.
- `SENTRY_DSN`: only needed in production.

### To verify local changes in Dev1
### Integration Tests for Dev1

- Ensure your aws cli is configured with credentials for the Dev1 account.
- Ensure you have the above env variables set in your .env, matching those in our Dev1 environment.
- Add the following to your .env: `LAMBDA_FUNCTION_URL=<the Dev1 lambda function URL>`
- Publish the lambda function:
Some minimal integration tests are provided for checking the deployed webhook handling lambda, defined as `integration` type pytest tests. These tests check the following:
* lambda function URL is operational
* `GET` and `POST` requests are received
* deployed lambda has adequate permissions to communicate with S3, StepFunctions, etc.

```bash
make publish-dev
make update-lambda-dev
```
Other notes about tests:
* tests are limited to `Dev1` environment
* AWS `AWSAdministratorAccess` role credentials must be set on developer machine
* environment variable `WORKSPACE=dev` must be set
* no other environment variables are required, these are all retrieved from deployed context

#### GET request example
#### Steps to run integration tests
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use numbering to enumerate these steps? I think it would help with the readability! :)


- Send a GET request with challenge phrase to the lambda function URL:
1. Update docker image to ensure local changes are deployed to `Dev1`:

```bash
pipenv run python -c "from lambdas.helpers import send_get_to_lambda_function_url; print(send_get_to_lambda_function_url('your challenge phrase'))"
```

Observe output: `your challenge phrase`

#### POST request examples

- Send a POST request mimicking a webhook POST (not a POD or TIMDEX export job)

```bash
pipenv run python -c "from lambdas.helpers import send_post_to_lambda_function_url, SAMPLE_WEBHOOK_POST_BODY; print(send_post_to_lambda_function_url(SAMPLE_WEBHOOK_POST_BODY))"
```

Observe output: `Webhook POST request received and validated, no action taken.`

- Send a POST request mimicking a POD export job webhook
_Note_: sending a request that mimics a POD export JOB_END will trigger the entire POD workflow, which is fine _in Dev1 only_ for testing.

Add the following to your .env:
- `VALID_POD_EXPORT_DATE=<the date of a POD export with files in the Dev1 S3 export bucket, in "YYYY-MM-DD" format>` Note: if it's been a while since the last POD export from Alma sandbox, there may be no files in the Dev1 S3 export bucket and you may need to run the publishing job from the sandbox.

```bash
pipenv run python -c "from lambdas.helpers import send_post_to_lambda_function_url, SAMPLE_POD_EXPORT_JOB_END_WEBHOOK_POST_BODY; print(send_post_to_lambda_function_url(SAMPLE_POD_EXPORT_JOB_END_WEBHOOK_POST_BODY))"
```

Observe output: `Webhook POST request received and validated, PPOD pipeline initiated.` and then check the Dev1 ppod state machine logs to confirm the entire process ran!

- Send a POST request mimicking a TIMDEX export job webhook
_Note_: sending a request that mimics a TIMDEX export JOB_END will trigger the entire TIMDEX workflow, which is fine _in Dev1 only_ for testing.

Add the following to your .env:
- `VALID_TIMDEX_EXPORT_DATE=<the date of a TIMDEX export with files in the Dev1 S3 export bucket, in "YYYY-MM-DD" format>` Note: if it's been a while since the last TIMDEX export from Alma sandbox, there may be no files in the Dev1 S3 export bucket and you may need to run the publishing job from the sandbox.
```shell
make publish-dev
make update-lambda-dev
```

```bash
pipenv run python -c "from lambdas.helpers import send_post_to_lambda_function_url, SAMPLE_TIMDEX_EXPORT_JOB_END_WEBHOOK_POST_BODY; print(send_post_to_lambda_function_url(SAMPLE_TIMDEX_EXPORT_JOB_END_WEBHOOK_POST_BODY))"
```
2. Run tests against deployed assets:

Observe output: `Webhook POST request received and validated, TIMDEX pipeline initiated.` and then check the Dev1 timdex state machine logs to confirm the entire process ran!
```shell
make test-integration
```

## Running locally with Docker
jonavellecuerdo marked this conversation as resolved.
Show resolved Hide resolved

Note: this is only useful for validating exceptions and error states, as success states require calling other AWS services for which we do not currently support local emulation.

<https://docs.aws.amazon.com/lambda/latest/dg/images-test.html>

### Build the container
1. Build the container:

```bash
make dist-dev
```

### Run the default handler for the container
2. Run the default handler for the container

```bash
docker run -p 9000:8080 alma-webhook-lambdas-dev:latest
```

Depending on what you're testing, you may need to pass `-e WORKSPACE=dev` and/or other environment variables as options to the `docker run` command.

### POST to the container
3. POST to the container

```bash
curl -XPOST "http://localhost:9000/2015-03-31/functions/function/invocations" -d "{}"
```

### Observe output
4. Observe output

Running the above with no env variables passed should result in an exception.
37 changes: 0 additions & 37 deletions lambdas/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,43 +5,6 @@

import requests

SAMPLE_WEBHOOK_POST_BODY = {
"action": "JOB_END",
"job_instance": {
"name": "Not a POD export job",
},
}

SAMPLE_POD_EXPORT_JOB_END_WEBHOOK_POST_BODY = {
"action": "JOB_END",
"job_instance": {
"name": os.getenv("ALMA_POD_EXPORT_JOB_NAME", "PPOD Export"),
"end_time": os.getenv("VALID_POD_EXPORT_DATE", "2022-05-23"),
"status": {"value": "COMPLETED_SUCCESS"},
"counter": [
{
"type": {"value": "label.new.records", "desc": "New Records"},
"value": "1",
},
],
},
}

SAMPLE_TIMDEX_EXPORT_JOB_END_WEBHOOK_POST_BODY = {
"action": "JOB_END",
"job_instance": {
"name": "Publishing Platform Job TIMDEX EXPORT to Dev1 DAILY",
"status": {"value": "COMPLETED_SUCCESS"},
"end_time": os.getenv("VALID_TIMDEX_EXPORT_DATE", "2022-10-24"),
"counter": [
{
"type": {"value": "label.new.records", "desc": "New Records"},
"value": "1",
},
],
},
}


def generate_signature(message_body: dict) -> str:
secret = os.environ["ALMA_CHALLENGE_SECRET"]
Expand Down
7 changes: 6 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ exclude = ["tests/"]

[tool.pytest.ini_options]
log_level = "INFO"
markers = [
"unit: unit tests",
"integration: integration tests"
]

[tool.ruff]
target-version = "py311"
Expand All @@ -25,7 +29,8 @@ ignore = [
# project-specific
"D100",
"D103",
"D104"
"D104",
"G002"
]

# allow autofix behavior for specified rules
Expand Down
Loading
Loading