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

Release/2024-11-06 #393

Merged
merged 26 commits into from
Nov 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
b512cda
[feature/PI-575-remove_implicit_ok] remove implicit ok
jaklinger Oct 31, 2024
a90ae92
[feature/PI-293-e2e_with_apigee] e2e with apigee
jaklinger Oct 31, 2024
c184d90
[feature/PI-591-better_postman] better postman
jaklinger Nov 4, 2024
f2a0642
Update dependencies in README
jameslinnell Oct 31, 2024
efa8916
Add delete scenario to smoke tests
jameslinnell Nov 4, 2024
10a1e89
Add Status and DELETE Product to smoke tests
jameslinnell Nov 4, 2024
3bd2bb4
Add MhsMessageSet create to smoke tests
jameslinnell Nov 4, 2024
84c6db4
[release/2024-11-06] create release
jaklinger Nov 6, 2024
4f5bdfc
Merge branch 'feature/PI-593-readme_update' into release/2024-11-06
jaklinger Nov 6, 2024
c125647
Merge branch 'feature/PI-594-some_more_smoke_tests' into release/2024…
jaklinger Nov 6, 2024
29f6cdd
Merge branch 'feature/PI-575-remove_implicit_ok' into release/2024-11-06
jaklinger Nov 6, 2024
3246fa8
Add a search Results wrapper
jameslinnell Oct 30, 2024
6f37cb9
Remove classmethod from Searchresponse
jameslinnell Nov 1, 2024
ee112c3
Fix product_name
jameslinnell Nov 5, 2024
dcd2fe0
Merge branch 'feature/PI-558-search_wrapper' into release/2024-11-06
jaklinger Nov 6, 2024
6e78307
Merge branch 'feature/PI-591-better_postman' into release/2024-11-06
jaklinger Nov 6, 2024
9e15a73
Fix destroy script
jameslinnell Nov 7, 2024
d6d6d39
Remove Location from searchCPMProducts
jameslinnell Nov 7, 2024
acae57d
Add delete to smoke tests
jameslinnell Nov 7, 2024
8962c09
Workflow test
jameslinnell Nov 7, 2024
c935b21
Destroy workflow on close PR
jameslinnell Nov 7, 2024
59a73bf
Use dev env
jameslinnell Nov 7, 2024
a5a81e7
Destroy workflow on close PR
jameslinnell Nov 7, 2024
50e6a6c
Destroy workflow on close PR
jameslinnell Nov 7, 2024
18a72bc
Merge branch 'feature/PI-601-workspace_destruction' into release/2024…
jameslinnell Nov 8, 2024
d658f03
Add Destroy workflow to changelog
jameslinnell Nov 8, 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
50 changes: 50 additions & 0 deletions .github/workflows/on-pr-close.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: "Workflow: PR Close"

permissions:
id-token: write
contents: read
actions: write

env:
TF_CLI_ARGS: -no-color
CI_ROLE_NAME: ${{ secrets.CI_ROLE_NAME }}
BRANCH_NAME: ${{ github.event.pull_request.head.ref }}

on:
pull_request:
types: [closed]

jobs:
parse-secrets:
runs-on: [self-hosted, ci]
steps:
- id: parse-secrets
run: |
echo "::add-mask::${{ secrets.CI_ROLE_NAME }}"

build-base:
runs-on: [self-hosted, ci]
needs: [parse-secrets]
steps:
- uses: actions/checkout@v4
with:
ref: ${{ env.BRANCH_NAME }}
- uses: ./.github/actions/make/
with:
command: build
save-to-cache: "true"
restore-from-cache: "false"

destroy-pr-workspaces:
runs-on: [self-hosted, ci]
needs: [parse-secrets, build-base]
steps:
- uses: actions/checkout@v4
with:
ref: ${{ env.BRANCH_NAME }}
fetch-depth: 0
- name: Remove PR workspaces
uses: ./.github/actions/make/
with:
command: destroy--redundant-workspaces BRANCH_NAME=origin/${{ env.BRANCH_NAME }} DESTROY_ALL_COMMITS_ON_BRANCH=true KILL_ALL=true TF_CLI_ARGS=${{ env.TF_CLI_ARGS }}
requires-aws: true
9 changes: 8 additions & 1 deletion .github/workflows/pull-requests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ jobs:
test--unit,
test--feature--local,
terraform-head-build,
apigee--attach-product,
]
runs-on: [self-hosted, ci]
strategy:
Expand Down Expand Up @@ -276,7 +277,13 @@ jobs:
requires-aws: true

apigee--detach-product:
needs: [build-head, test--smoke, apigee--attach-product]
needs:
[
build-head,
test--smoke,
apigee--attach-product,
test--feature--integration,
]
runs-on: [self-hosted, ci]
if: ${{ needs.apigee--attach-product.result == 'success' }}
steps:
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ dist
openapi

postman-collection.json
postman-environment.json
token_cache.json
cpm.cdx.json

Expand Down
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# Changelog

## 2024-11-06
- [PI-593] Readme updates
- [PI-594] More smoke tests
- [PI-575] Remove implicit OK from responses
- [PI-558] Add search wrapper
- [PI-591] Better postman
- [PI-293] E2E tests with apigee
- [PI-601] Destroy workspaces on PR close

## 2024-11-05
- [PI-585] PR/release CI builds in dev

Expand Down
69 changes: 61 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,12 @@
3. [AWS SSO Setup](#aws-sso-setup)
4. [Other helpful commands](#other-helpful-commands)
2. [Tests](#tests)
3. [Workflow](#workflow)
4. [Swagger](#swagger)
5. [ETL](#etl)
3. [pytest tests](#pytest-tests)
4. [End-to-End feature tests](#end-to-end-feature-tests)
5. [Generate the Feature Test Postman collection](#generate-the-feature-test-postman-collection)
6. [Workflow](#workflow)
7. [Swagger](#swagger)
8. [ETL](#etl)

---

Expand All @@ -22,16 +25,20 @@

We use `asdf` to fetch the required versions of prerequisite libraries instead of your system's default version. To get it up and running go to https://asdf-vm.com/guide/getting-started.html. You can check it installed properly by using the command `asdf --version`.

If you are using `pyenv` (you can check by typing `pyenv` and seeing whether it returns a nice list of commands) then you should run:

```
pyenv install $(cat .python-version)
```
However, you will also need to install the `docker engine` separately

Additionally you will need `wget` (doing `which wget` will return blank if not installed). Please Google "how to install wget on my operating system", if you don't already have this installed.

Update any dependencies on your system as required.

Otherwise `asdf` should do the work for you.

### Useful tools

`VScode` is useful and we have a workspace file setup to allow easy integration

`Postman` &/or `Newman` Feature tests create a postman.collection which can be used for manual testing.

### Project build

Do `make build` every time you would like to pick up and install new local/project dependencies and artifacts. This will always detect changes to:
Expand Down Expand Up @@ -220,6 +227,52 @@ The VSCode settings for "Run and Debug" are also set up to run these tests if yo
`make test--sds--matrix` is used for testing responses match in SDS FHIR between CPM and LDAP. You must provide `SDS_PROD_APIKEY` and `SDS_DEV_APIKEY`. There are 3 optional variables `USE_CPM_PROD`, defaults to `FALSE`, `COMPARISON_ENV`, defaults to `local` and `TEST_COUNT`, defaults to `10` and is the number of requests to make.
Add `PYTEST_FLAGS='-sv'`.

### End-to-End feature tests

The Feature tests use `behave` (rather than `pytest`) to execute cucumber/gherkin-style end-to-end tests of specific features, in principle
giving full end-to-end test coverage for API operations.

Executing feature tests locally will give you a good idea whether you have implemented a well-behaved feature whilst in development (i.e. no need to redeploy whilst developing).

Executing feature tests in integration mode will then give you confidence that the feature is ready to deploy in production, but has a much slower development cycle as it will need a full redeploy after codebase or infrastructure changes are implemented.

#### Local

To execute the feature tests entirely locally (executing lambdas directly, and otherwise mocking databases and responses to a high standard) you can do:

```shell
make test--feature-local
```

If you would like to pass `behave` flags, e.g. to \[stop after the first failure\]:

```shell
make test--feature-local BEHAVE_FLAGS="--stop"
```

#### Integration

To execute the feature tests across the entire stack (including Apigee and AWS) you can do

```shell
make test--feature-integration
```

### Generate the Feature Test Postman collection

Our [end-to-end feature tests](#end-to-end-feature-tests) also generate working Postman collections. To generate the Postman collection quickly, without Apigee credentials, you can run the local feature tests. If you would like the Apigee
credentials generating then you should run the integration feature tests. The generated files are:

- `src/api/tests/feature_tests/postman-collection.json`
- `src/api/tests/feature_tests/postman-environment.json`

You can drag and drop `postman-collection.json` into the `Collections` tab on Postman,
and `postman-environment.json` on to the `Environments` tab (remember to activate it). If you generated these
with the local feature tests, then you will need to manually update the Apigee `baseUrl` and `apiKey` fields
in the environment (but these are filled out already if generated with the integration feature tests).

💡 **The feature tests are only guaranteed to work out-of-the-box with an empty database**

## Workflow

In order to create new branches, use the commands listed below. Note that the commands will throw an error if
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2024.11.05
2024.11.06
7 changes: 7 additions & 0 deletions changelog/2024-11-06.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
- [PI-593] Readme updates
- [PI-594] More smoke tests
- [PI-575] Remove implicit OK from responses
- [PI-558] Add search wrapper
- [PI-591] Better postman
- [PI-293] E2E tests with apigee
- [PI-601] Destroy workspaces on PR close
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "connecting-party-manager"
version = "2024.11.05"
version = "2024.11.06"
description = "Repository for the Connecting Party Manager API and related services"
authors = ["NHS England"]
license = "LICENSE.md"
Expand Down
2 changes: 1 addition & 1 deletion scripts/builder/build.mk
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ POSTMAN_COLLECTION = $(CURDIR)/src/api/tests/feature_tests/postman-collection.js
TOOL_VERSIONS_COPY = $(TIMESTAMP_DIR)/tool-versions.copy
POETRY_LOCK = $(CURDIR)/poetry.lock
INIT_TIMESTAMP = $(CURDIR)/.timestamp/init.timestamp
SRC_FILES = $(shell find src -type f -name "*.py" -not -path "*/test_*" -not -path "*/fhir/r4/strict_models.py" -not -path "*/fhir/r4/models.py")
SRC_FILES = $(shell find src -type f -name "*.py" -not -path "*/feature_tests/*" -not -path "*/test_*" -not -path "*/fhir/r4/strict_models.py" -not -path "*/fhir/r4/models.py")
THIRD_PARTY_DIST = $(CURDIR)/src/layers/third_party/dist
SWAGGER_DIST = $(CURDIR)/infrastructure/swagger/dist
SWAGGER_PUBLIC = $(SWAGGER_DIST)/public/swagger.yaml
Expand Down
31 changes: 20 additions & 11 deletions scripts/infrastructure/apigee.mk
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@
APIGEE_CONFIG_PATH = $(CURDIR)/infrastructure/apigee
APIGEE_TIMESTAMP = $(TIMESTAMP_DIR)/.apigee.stamp
PROXYGEN_TIMESTAMP = $(TIMESTAMP_DIR)/.proxygen.stamp
PROXYGEN_PRODUCT_TIMESTAMP = $(TIMESTAMP_DIR)/.proxygen-product.stamp

SWAGGER_APIGEE = $(SWAGGER_DIST)/apigee/swagger.yaml
WORKSPACE_OUTPUT_JSON = $(CURDIR)/infrastructure/terraform/per_workspace/output.json
ENVIRONMENT_MAPPING_YAML = $(CURDIR)/infrastructure/apigee/environment_mapping.yaml
STAGE_MAPPING_YAML = $(CURDIR)/infrastructure/apigee/stage_mapping.yaml

apigee--deploy: $(PROXYGEN_TIMESTAMP)
apigee--deploy: aws--login $(PROXYGEN_TIMESTAMP)


apigee--delete: aws--login
Expand All @@ -26,15 +27,7 @@ apigee--delete: aws--login
apigee--clean:
[[ -f $(PROXYGEN_TIMESTAMP) ]] && rm $(PROXYGEN_TIMESTAMP) || :

apigee--attach-product: aws--login
WORKSPACE_OUTPUT_JSON=$(WORKSPACE_OUTPUT_JSON) \
ENVIRONMENT_MAPPING_YAML=$(ENVIRONMENT_MAPPING_YAML) \
STAGE_MAPPING_YAML=$(STAGE_MAPPING_YAML) \
APIGEE_CONFIG_PATH=$(APIGEE_CONFIG_PATH) \
AWS_ACCESS_KEY_ID=$(AWS_ACCESS_KEY_ID) \
AWS_SECRET_ACCESS_KEY=$(AWS_SECRET_ACCESS_KEY) \
AWS_SESSION_TOKEN=$(AWS_SESSION_TOKEN) \
bash $(PATH_TO_INFRASTRUCTURE)/apigee/apigee.sh attach_product $(PERSISTENT_ENVIRONMENT_BUILD)
apigee--attach-product: aws--login $(PROXYGEN_PRODUCT_TIMESTAMP)

apigee--detach-product: aws--login
WORKSPACE_OUTPUT_JSON=$(WORKSPACE_OUTPUT_JSON) \
Expand All @@ -45,8 +38,10 @@ apigee--detach-product: aws--login
AWS_SECRET_ACCESS_KEY=$(AWS_SECRET_ACCESS_KEY) \
AWS_SESSION_TOKEN=$(AWS_SESSION_TOKEN) \
bash $(PATH_TO_INFRASTRUCTURE)/apigee/apigee.sh detach_product $(PERSISTENT_ENVIRONMENT_BUILD)
[[ -f $(PROXYGEN_PRODUCT_TIMESTAMP) ]] && rm $(PROXYGEN_PRODUCT_TIMESTAMP) || :

$(PROXYGEN_TIMESTAMP): aws--login $(SWAGGER_APIGEE) $(WORKSPACE_OUTPUT_JSON)

$(PROXYGEN_TIMESTAMP): $(SWAGGER_APIGEE) $(WORKSPACE_OUTPUT_JSON)
[[ -f $(PROXYGEN_TIMESTAMP) ]] && rm $(PROXYGEN_TIMESTAMP) || :

WORKSPACE_OUTPUT_JSON=$(WORKSPACE_OUTPUT_JSON) \
Expand All @@ -60,3 +55,17 @@ $(PROXYGEN_TIMESTAMP): aws--login $(SWAGGER_APIGEE) $(WORKSPACE_OUTPUT_JSON)
bash $(PATH_TO_INFRASTRUCTURE)/apigee/proxygen.sh generate_proxy $(PERSISTENT_ENVIRONMENT_BUILD)

touch $(PROXYGEN_TIMESTAMP)


$(PROXYGEN_PRODUCT_TIMESTAMP): $(PROXYGEN_TIMESTAMP)
[[ -f $(PROXYGEN_PRODUCT_TIMESTAMP) ]] && rm $(PROXYGEN_PRODUCT_TIMESTAMP) || :

WORKSPACE_OUTPUT_JSON=$(WORKSPACE_OUTPUT_JSON) \
ENVIRONMENT_MAPPING_YAML=$(ENVIRONMENT_MAPPING_YAML) \
STAGE_MAPPING_YAML=$(STAGE_MAPPING_YAML) \
APIGEE_CONFIG_PATH=$(APIGEE_CONFIG_PATH) \
AWS_ACCESS_KEY_ID=$(AWS_ACCESS_KEY_ID) \
AWS_SECRET_ACCESS_KEY=$(AWS_SECRET_ACCESS_KEY) \
AWS_SESSION_TOKEN=$(AWS_SESSION_TOKEN) \
bash $(PATH_TO_INFRASTRUCTURE)/apigee/apigee.sh attach_product $(PERSISTENT_ENVIRONMENT_BUILD)
touch $(PROXYGEN_PRODUCT_TIMESTAMP)
10 changes: 2 additions & 8 deletions scripts/infrastructure/apigee/apigee.sh
Original file line number Diff line number Diff line change
Expand Up @@ -146,17 +146,14 @@ function attach_product(){

token=$(echo "$token_response" | jq -r '.pytest_nhsd_apim_token')
url=https://api.enterprise.apigee.com/v1/organizations/$_org_name/developers/$email_that_owns_app/apps/$app_name/keys/$client_id
echo "$url"

add_product_response=$(curl -X POST \
add_product_response=$(curl --retry 100 -sS -X POST \
$url \
-H "Authorization: Bearer $token" \
-H "Content-type:application/json" \
-d "{\"apiProducts\": [\"$_product_name\"]}")

status=$(echo "$add_product_response" | jq -r '.status')
echo "$status"

if [ -z "$status" ] || [ "$status" != "approved" ]; then
echo "Failed to add product to the app"
echo "Response: $add_product_response"
Expand Down Expand Up @@ -232,17 +229,14 @@ function detach_product(){

token=$(echo "$token_response" | jq -r '.pytest_nhsd_apim_token')
url=https://api.enterprise.apigee.com/v1/organizations/$_org_name/developers/$email_that_owns_app/apps/$app_name/keys/$client_id/apiproducts/$_product_name
echo "$url"

detach_product_response=$(curl -X DELETE \
detach_product_response=$(curl -sS -X DELETE \
$url \
-H "Authorization: Bearer $token" \
-H "Content-type:application/json" \
-d "{\"apiProducts\": [\"$_product_name\"]}")

status=$(echo "$detach_product_response" | jq -r '.status')
echo "$status"

if [ -z "$status" ] || [ "$status" != "approved" ]; then
echo "Failed to remove product from the app"
echo "Response: $detach_product_response"
Expand Down
1 change: 0 additions & 1 deletion scripts/infrastructure/apigee/proxygen.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ PATH_TO_HERE="scripts/infrastructure/apigee"
APIGEE_DEPLOYMENT_ROLE="NHSDeploymentRole"
API_NAME="connecting-party-manager"
PERSISTENT_ENVIRONMENT_BUILD="${2:-false}"
echo "PERSISTENT_ENVIRONMENT_BUILD is: $PERSISTENT_ENVIRONMENT_BUILD"


if [[ -z ${WORKSPACE_OUTPUT_JSON} ]]; then
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,11 @@ function _destroy_redundant_workspaces() {
workspaces=$(aws s3 ls "$bucket" --no-paginate | awk '{print $NF}' | sed 's:/$::')

# get JIRA ID from branch name
ENVIRONMENT="dev"
if [[ $BRANCH_NAME =~ feature\/(PI-[0-9]+)[-_] ]]; then
workspace_id="${BASH_REMATCH[1]}"
ENVIRONMENT="ref"
elif [[ $BRANCH_NAME == *release/* ]]; then
workspace_id="${BRANCH_NAME##*release/}"
ENVIRONMENT="dev"
fi
echo "The workspace ID is: $workspace_id"
echo "Destroying workspaces in: $ENVIRONMENT"
Expand Down
3 changes: 2 additions & 1 deletion scripts/test/test.mk
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ USE_CPM_PROD ?= FALSE
TEST_COUNT =
COMPARISON_ENV ?= local
RUN_SPEEDTEST = ?= FALSE
PROXYGEN_PRODUCT_TIMESTAMP = $(TIMESTAMP_DIR)/.proxygen-product.stamp

_pytest:
AWS_DEFAULT_REGION=$(AWS_DEFAULT_REGION) AWS_ACCESS_KEY_ID=$(AWS_ACCESS_KEY_ID) AWS_SECRET_ACCESS_KEY=$(AWS_SECRET_ACCESS_KEY) AWS_SESSION_TOKEN=$(AWS_SESSION_TOKEN) poetry run python -m pytest $(PYTEST_FLAGS) $(_INTERNAL_FLAGS) $(_CACHE_CLEAR)
Expand All @@ -32,7 +33,7 @@ test--smoke: aws--login ## Run end-to-end smoke tests (pytest)
test--%--rerun: ## Rerun failed integration or unit (pytest) tests
$(MAKE) test--$* _INTERNAL_FLAGS="--last-failed --last-failed-no-failures none" _CACHE_CLEAR=$(_CACHE_CLEAR)

test--feature--integration: aws--login ## Run integration feature (gherkin) tests
test--feature--integration: aws--login $(PROXYGEN_PRODUCT_TIMESTAMP) ## Run integration feature (gherkin) tests
$(MAKE) _behave _INTERNAL_FLAGS="--define='test_mode=integration' $(_INTERNAL_FLAGS)" AWS_ACCESS_KEY_ID=$(AWS_ACCESS_KEY_ID) AWS_SECRET_ACCESS_KEY=$(AWS_SECRET_ACCESS_KEY) AWS_SESSION_TOKEN=$(AWS_SESSION_TOKEN)

test--feature--local: _behave ## Run local feature (gherkin) tests
Expand Down
2 changes: 0 additions & 2 deletions src/api/createCpmProduct/tests/test_index.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ def test_index(version):
"Content-Length": str(len(expected_body)),
"Content-Type": "application/json",
"Version": version,
"Location": "FOO",
},
}
_response_assertions(
Expand Down Expand Up @@ -149,7 +148,6 @@ def test_index_no_such_product_team(version):
"Content-Length": str(len(expected_result)),
"Content-Type": "application/json",
"Version": version,
"Location": None,
},
}
_response_assertions(
Expand Down
3 changes: 0 additions & 3 deletions src/api/createProductTeam/tests/v1/test_index_v1.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ def test_index(version):
"Content-Length": str(len(expected_body)),
"Content-Type": "application/json",
"Version": version,
"Location": None,
},
}
_response_assertions(
Expand Down Expand Up @@ -107,7 +106,6 @@ def test_index_bad_payload(version):
"Content-Length": str(len(expected_body)),
"Content-Type": "application/json",
"Version": version,
"Location": None,
},
}
_response_assertions(
Expand Down Expand Up @@ -158,7 +156,6 @@ def test_index(version):
"Content-Length": str(len(expected_body)),
"Content-Type": "application/json",
"Version": version,
"Location": None,
},
}
_response_assertions(
Expand Down
Loading
Loading