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

feat: add integration tests #69

Merged
merged 32 commits into from
Feb 21, 2024
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
3537795
feat: add integration tests
vincentsarago Sep 5, 2023
f1c1d1f
add eoapi-cdk upgrade command and pip cache
emileten Sep 6, 2023
aab0acb
test commit, to revert
emileten Sep 6, 2023
d9749de
Revert "test commit, to revert"
emileten Sep 6, 2023
1300c4e
update workflow
emileten Sep 11, 2023
c47f6d6
update workflow to run when release happens, move tests here
emileten Sep 11, 2023
a63c909
instead of cloning the eoapi-template repo, copy the code here so tha…
emileten Sep 21, 2023
6ebc271
trailing wsp
emileten Sep 21, 2023
80f03ba
run action with push to try
emileten Sep 21, 2023
4ff82c2
move the trigger of integration tests to distribute, right before rel…
emileten Sep 27, 2023
eb20644
feat!: custom runtime for bootstrapper and custom runtimes from Docke…
emileten Oct 5, 2023
385ab1b
fix a couple bugs found in the first changes
emileten Oct 10, 2023
dbcada8
avoid maintaining custom interfaces for configurable lambda propertie…
emileten Oct 12, 2023
7573398
expose bootstrapper props in pgstacdatabase construct constructor
emileten Oct 12, 2023
926a6a1
merge database and boostrapper files to solve casting bug
emileten Oct 17, 2023
f725f28
bump and harmonize pypgstac to 0.7.10 across apps
emileten Oct 27, 2023
f48e334
bump cachetools
emileten Oct 27, 2023
7b62f2a
some changes to allow for less security
emileten Oct 27, 2023
7c75981
bump python to 3.11
emileten Oct 31, 2023
ccfce6b
change base image for bootstrapper to use python 311
emileten Oct 31, 2023
a7aea2b
fix linting issues
emileten Oct 31, 2023
9e886a2
Merge branch 'feat/custom-runtimes' into feat/add-integration-tests
emileten Oct 31, 2023
b973fbc
Merge branch 'main' into feat/add-integration-tests
emileten Feb 19, 2024
64e67b7
move integration tests to step before release, improve naming of work…
emileten Feb 19, 2024
c7904ef
lint
vincentsarago Feb 20, 2024
92b4bf9
fix moto requirement
vincentsarago Feb 20, 2024
97b5a32
test to fix deployment : try adding s3 endpoint and force allow publi…
emileten Feb 21, 2024
4ede0a5
lint and make lambda functions more configurable
emileten Feb 21, 2024
b4de035
moving deploy to a separate workflow
emileten Feb 21, 2024
92cec0d
remove useless dependencies in deployment tests, turn on pull request…
emileten Feb 21, 2024
b4fe0f6
when tearing down the infrastructure, synthesize the cloud formation …
emileten Feb 21, 2024
b08e8b3
update readmes and revive the artifact download in python distribution
emileten Feb 21, 2024
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
81 changes: 78 additions & 3 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,30 @@ on:
required: false
DS_RELEASE_BOT_PRIVATE_KEY:
required: false

AWS_DEFAULT_REGION_DEPLOY:
required: false
AWS_ACCESS_KEY_ID_DEPLOY:
required: false
AWS_SECRET_ACCESS_KEY_DEPLOY:
required: false
AWS_ACCOUNT_ID:
required: false
jobs:
build_and_package:
name: Build and package
runs-on: ubuntu-latest
timeout-minutes: 60
env:
AWS_DEFAULT_REGION: ${{ secrets.AWS_DEFAULT_REGION_DEPLOY }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID_DEPLOY }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY_DEPLOY }}
AWS_DEFAULT_ACCOUNT: ${{ secrets.AWS_ACCOUNT_ID }}
steps:
- uses: actions/checkout@v3

- uses: actions/setup-node@v3
with:
node-version: 16
node-version: 18
cache: "npm"

- name: Install Dependencies
Expand Down Expand Up @@ -65,8 +78,70 @@ jobs:
app_id: ${{ secrets.DS_RELEASE_BOT_ID }}
private_key: ${{ secrets.DS_RELEASE_BOT_PRIVATE_KEY }}

- name: Maybe Release 🚀
- name: Check release
id: check_release
if: ${{ inputs.release }}
run: |
SHOULD_RELEASE=false
npm run semantic-release --dry-run > check_release_output.txt
if grep -q "Published release" check_release_output.txt; then
echo "SHOULD_RELEASE=true" >> $GITHUB_OUTPUT
else
echo "SHOULD_RELEASE=false" >> $GITHUB_OUTPUT
fi

- name: Install deployment environment
if: "${{ inputs.release && steps.check_release.outputs.SHOULD_RELEASE }}"
id: install_deploy_env
run: |
# install deployment environment with eoapi-cdk from build
python -m venv .deployment_venv
source .deployment_venv/bin/activate
pip install dist/python/*.gz
cd integration_tests/cdk
pip install -r requirements.txt
npm install
deactivate
cd -


- name: Deploy test stack
if: "${{ inputs.release && steps.check_release.outputs.SHOULD_RELEASE }}"
id: deploy_step
run: |
source .deployment_venv/bin/activate

# synthesize the stack
cd integration_tests/cdk
npx cdk synth --debug --all --require-approval never

# deploy the stack and grab URLs for testing
npx cdk deploy --ci --all --require-approval never
echo "ingestor_url=$(aws cloudformation describe-stacks --stack-name eoapi-cdk-integration-test-pgSTAC-infra --query "Stacks[0].Outputs[?starts_with(OutputKey, 'stacingestor')].OutputValue | [0]" --output text)" >> $GITHUB_OUTPUT
echo "stac_api_url=$(aws cloudformation describe-stacks --stack-name eoapi-cdk-integration-test-pgSTAC-infra --query "Stacks[0].Outputs[?starts_with(OutputKey, 'pgstacapi')].OutputValue | [0]" --output text)" >> $GITHUB_OUTPUT
echo "titiler_pgstac_api_url=$(aws cloudformation describe-stacks --stack-name eoapi-cdk-integration-test-pgSTAC-infra --query "Stacks[0].Outputs[?starts_with(OutputKey, 'titilerpgstac')].OutputValue | [0]" --output text)" >> $GITHUB_OUTPUT
deactivate
cd -

- name: Tear down any infrastructure
if: always()
run: |
cd integration_tests/cdk
# run this only if we find a 'cdk.out' directory, which means there might be things to tear down
if [ -d "cdk.out" ]; then
cd -
source .deployment_venv/bin/activate
cd integration_tests/cdk
# see https://github.com/aws/aws-cdk/issues/24946
rm -f cdk.out/synth.lock
npx cdk destroy --ci --all --force
fi


# run if the previous step set SHOULD_RELEASE to true
- name: Maybe Release 🚀
# only run if the previous step set SHOULD_RELEASE to true
if: "${{ inputs.release && steps.check_release.outputs.SHOULD_RELEASE }}"
run: |
npm run semantic-release
env:
Expand Down
17 changes: 17 additions & 0 deletions .github/workflows/build_and_release.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: Build & try to release

on:
push:

jobs:
package:
uses: ./.github/workflows/build.yaml
with:
release: true
secrets:
DS_RELEASE_BOT_ID: ${{ secrets.DS_RELEASE_BOT_ID }}
DS_RELEASE_BOT_PRIVATE_KEY: ${{ secrets.DS_RELEASE_BOT_PRIVATE_KEY }}
AWS_DEFAULT_REGION_DEPLOY: ${{ secrets.AWS_DEFAULT_REGION_DEPLOY }}
AWS_ACCESS_KEY_ID_DEPLOY: ${{ secrets.AWS_ACCESS_KEY_ID_DEPLOY }}
AWS_SECRET_ACCESS_KEY_DEPLOY: ${{ secrets.AWS_SECRET_ACCESS_KEY_DEPLOY }}
AWS_ACCOUNT_ID: ${{ secrets.AWS_ACCOUNT_ID }}
5 changes: 0 additions & 5 deletions .github/workflows/distribute.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,6 @@ jobs:
runs-on: ubuntu-latest
needs: package
steps:
- uses: actions/download-artifact@v3
with:
name: python
path: dist

- run: pip install twine

- run: twine upload dist/*
Expand Down
13 changes: 0 additions & 13 deletions .github/workflows/test.yaml

This file was deleted.

3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,6 @@ docs
__pycache__
.venv
.tox
tests/*.egg*
tests/*venv*
tests/__pycache__
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,6 @@ Versioning is automatically handled via [Conventional Commits](https://www.conve
_Warning_: If you rebase `main`, you must ensure that the commits referenced by tags point to commits that are within the `main` branch. If a commit references a commit that is no longer on the `main` branch, Semantic Release will fail to detect the correct version of the project. [More information](https://github.com/semantic-release/semantic-release/issues/1121#issuecomment-517945233).


## Tests

Each new release triggers an integration test against a running deployment that uses the newly releases constructs. See the corresponding [github workflow](https://github.com/developmentseed/eoapi-cdk/blob/main/.github/workflows/deploy.yaml) and the [tests definition](https://github.com/developmentseed/eoapi-cdk/blob/main/tests).
57 changes: 57 additions & 0 deletions integration_tests/cdk/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
This is a non-forked version of [eoapi-template](https://github.com/developmentseed/eoapi-template).

# Deployment CDK code for eoapi-cdk integration tests

This is a wrapper CDK code that provides the `eoapi-cdk` deployment to run integration tests on the latest releases of the `eoapi-cdk` constructs.

## Requirements

- python
- docker
- node
- AWS credentials environment variables configured to point to an account.
- **Optional** a `config.yaml` file to override the default deployment settings defined in `config.py`.

## Installation

Install python dependencies with

```
python -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt
```

Install the latest `eoapi-cdk` either from PyPI:

```
pip install eoapi-cdk
```

Or alternatively, compile and package from the root of this repository to get the python version of the constructs locally.

Also install node dependencies with

```
npm install
```

Verify that the `cdk` CLI is available. Since `aws-cdk` is installed as a local dependency, you can use the `npx` node package runner tool, that comes with `npm`.

```
npx cdk --version
```

## Deployment

First, synthesize the app

```
npx cdk synth --all
```

Then, deploy

```
npx cdk deploy --all --require-approval never
```
17 changes: 17 additions & 0 deletions integration_tests/cdk/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from aws_cdk import App

from config import build_app_config
from eoapi_template import pgStacInfra, vpc

app = App()

app_config = build_app_config()

vpc_stack = vpc.VpcStack(scope=app, app_config=app_config)

pgstac_infra_stack = pgStacInfra.pgStacInfraStack(
scope=app,
vpc=vpc_stack.vpc,
app_config=app_config,
)
app.synth()
32 changes: 32 additions & 0 deletions integration_tests/cdk/cdk.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"app": "python3 app.py",
"watch": {
"include": [
"**"
],
"exclude": [
"README.md",
"cdk*.json",
"requirements*.txt",
"source.bat",
"**/*.pyc",
"**/*.tmp",
"**/__pycache__",
"tests",
"scripts",
"*venv"
]
},
"context": {
"@aws-cdk/aws-apigateway:usagePlanKeyOrderInsensitiveId": true,
"@aws-cdk/core:stackRelativeExports": true,
"@aws-cdk/aws-rds:lowercaseDbIdentifier": true,
"@aws-cdk/aws-lambda:recognizeVersionProps": true,
"@aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2_2021": true,
"@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true,
"@aws-cdk/core:target-partitions": [
"aws",
"aws-cn"
]
}
}
58 changes: 58 additions & 0 deletions integration_tests/cdk/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
from typing import Dict

import pydantic
import yaml
from pydantic_core.core_schema import FieldValidationInfo
from pydantic_settings import BaseSettings, SettingsConfigDict


class AppConfig(BaseSettings):
model_config = SettingsConfigDict(
env_file=".env"
)
aws_default_account: str = pydantic.Field(
description="AWS account ID"
)
project_id: str = pydantic.Field(
description="Project ID", default="eoapi-cdk"
)
stage: str = pydantic.Field(description="Stage of deployment", default="test")
# because of its validator, `tags` should always come after `project_id` and `stage`
tags: Dict[str, str] | None = pydantic.Field(
description="""Tags to apply to resources. If none provided,
will default to the defaults defined in `default_tags`.
Note that if tags are passed to the CDK CLI via `--tags`,
they will override any tags defined here.""",
default=None,
)
db_instance_type: str = pydantic.Field(
description="Database instance type", default="t3.micro"
)
db_allocated_storage: int = pydantic.Field(
description="Allocated storage for the database", default=5
)

@pydantic.field_validator("tags")
def default_tags(cls, v, info: FieldValidationInfo):
return v or {"project_id": info.data["project_id"], "stage": info.data["stage"]}

def build_service_name(self, service_id: str) -> str:
return f"{self.project_id}-{self.stage}-{service_id}"


def build_app_config() -> AppConfig:
"""Builds the AppConfig object from config.yaml file if exists,
otherwise use defaults"""
try:
with open("config.yaml") as f:
print("Loading config from config.yaml")
app_config = yaml.safe_load(f)
app_config = (
{} if app_config is None else app_config
) # if config is empty, set it to an empty dict
app_config = AppConfig(**app_config)
except FileNotFoundError:
# if no config at the expected path, using defaults
app_config = AppConfig()

return app_config
Empty file.
Loading
Loading