Skip to content
Open
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
node_modules/
build/
dist/
e2e/generated
52 changes: 52 additions & 0 deletions e2e/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# GCM Synthetics e2e testing

This folder contains a test runner for local changes to any of the packages distributed under `@google-cloud/synthetics-sdk-nodejs`, as well as continuous validation against already distributed packages. These scenarios are all ran within synthetics that target GCFv2's, with passing / failing correctness measured using alert policies, all spun up using terraform in a GCP project.

### tl;dr of how this folder works...
* A script (`./e2e/generate_test_servers.sh`) is used to generate code that is valid when deploying against GCFv2, and uses package distributions local to the repository, as well as versions distributed on npm.
* Cloud build is used to
* (a) Spin up "golden" synthetics against different versions of each distributed synthetics-sdk packages, and creates alerts against them to ensure that they continue to work.
* (b) Spin up temporary synthetics against local versions of the syntehtics-sdk packages, runs tests against them to ensure they work correctly, and tears down the infrastructure.

### Prerequisite Project Setup

The following GCS buckets need to exist on your project to persist information about terraform resources

```bash
$ gsutil mb gs://synthetics-sdk-golden-tf
$ gsutil mb gs://synthetics-sdk-testing-tf
$ gsutil versioning set on gs://synthetics-sdk-testing-tf
$ gsutil versioning set on gs://synthetics-sdk-golden-tf
```

The following permissions need to be provided to the cloud build service account
```
$ gcloud projects add-iam-policy-binding $PROJECT_ID --member serviceAccount:$CLOUDBUILD_SA --role roles/editor
$ gcloud functions add-iam-policy-binding local-cloud-build --member serviceAccount:$CLOUDBUILD_SA --role=roles/cloudfunctions.invoker
```

A notification channel should be created that will be used for when golden and test synthetics fail or pass(incorrectly).

### Running "locally" on Cloud Build

All scenarios should be ran from the root of the repository.

Managing "golden" synthetics.

```
# Turns up
$ NOTIFICATION_CHANNEL=<<alerts when golden fails>>
$ gcloud builds submit --region=us-central1 --config ./e2e/cloudbuild-golden.yaml --substitutions=_NOTIFICATION_CHANNEL="${NOTIFICATION_CHANNEL}" .
# Turns down
$ gcloud builds submit --region=us-central1 --config ./e2e/cloudbuild-local-cleanup.yaml --substitutions=_WORKSPACE_ID="golden-prod" .
```


```
# Spins up synthetics against local versions of synthetics-sdk packages,
# ensures they pass / fail as expected, and turns them down.
$ gcloud builds submit --region=us-central1 --config ./e2e/cloudbuild-local-test.yaml .

# Spins up permanent synthetics w/ alerts
$ gcloud builds submit --region=us-central1 --config ./e2e/cloudbuild-golden.yaml .
```
35 changes: 35 additions & 0 deletions e2e/cloudbuild-golden.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Copyright 2023 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

steps:
- name: node:16-alpine
id: build
script: |
set -x
apk add zip jq coreutils findutils
npm run generate_test_servers

- id: 'terraform setup'
name: 'hashicorp/terraform:1.0.0'
env:
- 'PROJECT_ID=$PROJECT_ID'
- 'NOTIFICATION_CHANNEL=$_NOTIFICATION_CHANNEL'
automapSubstitutions: true
script: |
cd e2e/golden_synthetics
echo "here is a log"
terraform init -reconfigure
terraform workspace select golden-prod || terraform workspace new golden-prod
terraform plan -var project_id=$PROJECT_ID -var notification_channel=$NOTIFICATION_CHANNEL
#terraform apply -auto-approve -var project_id=$PROJECT_ID -var notification_channel=$NOTIFICATION_CHANNEL
35 changes: 35 additions & 0 deletions e2e/cloudbuild-golden2.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Copyright 2023 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

steps:
- name: node:16-alpine
id: build
script: |
set -x
apk add zip jq coreutils findutils
npm run generate_test_servers

- id: 'terraform setup'
name: 'hashicorp/terraform:1.0.0'
env:
- 'PROJECT_ID=$PROJECT_ID'
- 'NOTIFICATION_CHANNEL=$_NOTIFICATION_CHANNEL'
- 'SERVICE_ACCOUNT=$_SERVICE_ACCOUNT'
automapSubstitutions: true
script: |
cd e2e/golden_synthetics
terraform init -reconfigure
terraform workspace select golden-prod || terraform workspace new golden-prod
terraform plan -var project_id=$PROJECT_ID -var notification_channel=$NOTIFICATION_CHANNEL -var service_account=$SERVICE_ACCOUNT
terraform apply -auto-approve -var project_id=$PROJECT_ID -var notification_channel=$NOTIFICATION_CHANNEL -var service_account=$SERVICE_ACCOUNT
31 changes: 31 additions & 0 deletions e2e/cloudbuild-local-cleanup.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Copyright 2023 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

steps:
- name: node:16-alpine
id: build
script: |
set -x
apk add zip jq coreutils findutils
npm run generate_test_servers
- name: 'hashicorp/terraform:1.0.0'
id: 'terraform teardown'
env:
- 'PROJECT_ID=$PROJECT_ID'
- 'WORKSPACE_ID=$_WORKSPACE_ID'
script: |
cd e2e/golden_synthetics
terraform init -reconfigure
terraform workspace select $WORKSPACE_ID
terraform destroy -auto-approve -var project_id=$PROJECT_ID
36 changes: 36 additions & 0 deletions e2e/cloudbuild-local-test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Copyright 2023 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

steps:
- name: node:16-alpine
id: build
script: |
set -x
apk add zip jq coreutils findutils
npm run generate_test_servers

- id: 'terraform setup'
name: 'hashicorp/terraform:1.0.0'
env:
- 'PROJECT_ID=$PROJECT_ID'
- 'BUILD_ID=$BUILD_ID'
- 'NOTIFICATION_CHANNEL=$_NOTIFICATION_CHANNEL'
automapSubstitutions: true
script: |
cd e2e/test_synthetics
WORKSPACE_ID=${BUILD_ID:0:7}
terraform init -reconfigure
terraform workspace new $WORKSPACE_ID
terraform plan -var project_id=$PROJECT_ID
terraform apply -auto-approve -var project_id=$PROJECT_ID -var notification_channel=$NOTIFICATION_CHANNEL
50 changes: 50 additions & 0 deletions e2e/cloudbuild-pr-open.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Copyright 2023 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

steps:
- name: node:16-alpine
id: build
script: |
set -x
apk add zip jq coreutils findutils
npm run generate_test_servers

- id: 'terraform setup'
name: 'hashicorp/terraform:1.0.0'
env:
- 'PROJECT_ID=$PROJECT_ID'
- 'BUILD_ID=$BUILD_ID'
script: |
cd e2e/test_synthetics
WORKSPACE_ID=${BUILD_ID:0:7}
terraform init -reconfigure
terraform workspace new $WORKSPACE_ID
terraform plan -var project_id=$PROJECT_ID
terraform apply -auto-approve -var project_id=$PROJECT_ID

- name: node:16-alpine
id: 'run tests'
script: |
# This step waits for alerts to fire / not fire.
sleep 600
- name: 'hashicorp/terraform:1.0.0'
id: 'terraform teardown'
env:
- 'PROJECT_ID=$PROJECT_ID'
- 'BUILD_ID=$BUILD_ID'
script: |
cd e2e/test_synthetics
WORKSPACE_ID=${BUILD_ID:0:7}
terraform workspace select $WORKSPACE_ID
terraform destroy -auto-approve -var project_id=$PROJECT_ID
74 changes: 74 additions & 0 deletions e2e/generate_test_servers.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Copyright 2023 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

npm install

synthetics_sdk_api_pack_file=$(npm pack --workspace @google-cloud/synthetics-sdk-api --pack-destination e2e)
synthetics_sdk_mocha_pack_file=$(npm pack --workspace @google-cloud/synthetics-sdk-mocha --pack-destination e2e)

cd e2e

# For each directory under ./e2e/test_servers...
# Create a directory under ./e2e/generated
# Copy the test server to that directory
# Copy the packed synthetic sdk to the directory
# If a given sdk is a dependency, set package.json to use the packed sdk
for d in $(find ./test_servers/ -mindepth 2 -maxdepth 2 -type d -printf '%P\n' -o -type l -printf '%P\n'); do
generated_dir="./generated/local/${d}"
echo Generating ${generated_dir}
mkdir -p ${generated_dir}
cp -r ./test_servers/${d}/* ${generated_dir}
cp ${synthetics_sdk_api_pack_file} ${generated_dir}
cp ${synthetics_sdk_mocha_pack_file} ${generated_dir}
sed -i '/synthetics-sdk-api/c\\"@google-cloud\/synthetics-sdk-api\": \"'${synthetics_sdk_api_pack_file}'\"' ${generated_dir}/package.json
sed -i '/synthetics-sdk-mocha/c\\"@google-cloud\/synthetics-sdk-mocha\": \"'${synthetics_sdk_mocha_pack_file}'\"' ${generated_dir}/package.json
done

# For each directory under ./e2e/test_servers/synthetics-sdk-api
# For each distributed version of @google-cloud/synthetics-sdk-api
# Create a directory under ./e2e/generated/synthetics-sdk-api-<<version>>
# Copy the test_server to that directory
# Update the sdk dependency, set package.json to use the version of the sdk
for d in $(find ./test_servers/synthetics-sdk-api/ -mindepth 1 -maxdepth 1 -type d -printf '%P\n' -o -type l -printf '%P\n'); do
for v in $(npm view @google-cloud/synthetics-sdk-api versions --json | jq -r 'if type == "string" then [.] else . end' | jq -r '.[]'); do
generated_dir="./generated/synthetics-sdk-api/synthetics-sdk-api-${v}/${d}"
echo Generating ${generated_dir}
mkdir -p ${generated_dir}
cp -r ./test_servers/synthetics-sdk-api/${d}/* ${generated_dir}
sed -i '/synthetics-sdk-api/c\\"@google-cloud\/synthetics-sdk-api\": \"'^${v}'\"' ${generated_dir}/package.json
done
done

# For each directory under ./e2e/test_servers/synthetics-sdk-mocha
# For each distributed version of @google-cloud/synthetics-sdk-mocha
# Create a directory under ./e2e/generated/synthetics-sdk-mocha-<<version>>
# Copy the test_server to that directory
# Update the sdk dependency, set package.json to use the version of the sdk
for d in $(find ./test_servers/synthetics-sdk-mocha/ -mindepth 1 -maxdepth 1 -type d -printf '%P\n' -o -type l -printf '%P\n'); do
for v in $(npm view @google-cloud/synthetics-sdk-mocha versions --json | jq -r 'if type == "string" then [.] else . end' | jq -r '.[]'); do
generated_dir="./generated/synthetics-sdk-mocha/synthetics-sdk-mocha-${v}/${d}"
echo Generating ${generated_dir}
mkdir -p ${generated_dir}
cp -r ./test_servers/synthetics-sdk-mocha/${d}/* ${generated_dir}
sed -i '/synthetics-sdk-mocha/c\\"@google-cloud\/synthetics-sdk-mocha\": \"'^${v}'\"' ${generated_dir}/package.json
done
done

# Zip each generated directory so that it can be deployed on GCF
for d in $(find ./generated/ -mindepth 3 -maxdepth 3 -type d); do
echo zipping ${d}
cd ${d}
zip -qr gcf-source *
cd -
done
Loading