From 1cd866d42970f2b892ee698505404a69ddaf7970 Mon Sep 17 00:00:00 2001 From: Sara Date: Tue, 22 Oct 2024 02:22:10 +1100 Subject: [PATCH] Run k6 after staging deployments (#4991) * Add workflow for running k6 on live urls * Use generic service_url variable for frontend scenarios * Set testing variables in workflow * Remove JS template string syntax from Python template string * Fix missing k6 envvar option for signing secret * Add step to trigger load test with staging deploy * Remove testing input overrides * Update .github/workflows/ci_cd.yml Co-authored-by: Sara * Add comment Signed-off-by: Olga Bulat --------- Signed-off-by: Olga Bulat Co-authored-by: Olga Bulat --- .github/workflows/ci_cd.yml | 23 ++++++++- .github/workflows/k6.yml | 66 ++++++++++++++++++++++++ docker/dev_env/Dockerfile | 2 + packages/js/k6/justfile | 5 ++ packages/js/k6/src/frontend/constants.ts | 2 +- 5 files changed, 95 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/k6.yml diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index 4a01e3d5637..b074bd1b804 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -708,7 +708,7 @@ jobs: - name: Run k6 frontend all against local Nuxt run: | just k6 frontend all \ - -e FRONTEND_URL=http://127.0.0.1:8443/ \ + -e service_url=http://127.0.0.1:8443/ \ -e text_summary=/tmp/k6-summary.txt - name: Upload artifacts @@ -739,7 +739,7 @@ jobs: ## Latest k6 run output[^update] ``` - ${summary} + {summary} ``` [^update]: This comment will automatically update with new output each time k6 runs for this PR @@ -1312,6 +1312,25 @@ jobs: wait_time: 60 # check every minute max_time: 1800 # allow up to 30 minutes for a deployment + - name: Trigger staging k6 load test + uses: convictional/trigger-workflow-and-wait@v1.6.5 + with: + owner: WordPress + repo: openverse + token: ${{ secrets.ACCESS_TOKEN }} + workflow_file_name: k6.yml + wait_interval: 60 + # TODO: Set to true once we see that this test is stable, and we can fail the deployment if it fails. + # @see https://github.com/WordPress/openverse/pull/4991 + propagate_failure: false + client_payload: | + { + "namespace": "frontend", + "scenario": "all", + "service_url": "https://staging.openverse.org/", + "report": true + } + deploy-api: name: Deploy staging API runs-on: ubuntu-latest diff --git a/.github/workflows/k6.yml b/.github/workflows/k6.yml new file mode 100644 index 00000000000..faf4e3fe0b3 --- /dev/null +++ b/.github/workflows/k6.yml @@ -0,0 +1,66 @@ +name: Run k6 scenario + +on: + workflow_dispatch: + inputs: + namespace: + description: '"namespace" of the k6 test scenario to run.' + required: true + type: choice + # frontend is the only one so far, but we will add API back to the k6 tests at some point + options: + - frontend + scenario: + description: "The k6 scenario to run; availability differs per namespace. Run `ov j packages/js/k6/ls` for a list of all k6 scenarios for each namespace." + required: true + type: string + service_url: + description: "The service against which to run the k6 scenario." + required: true + type: string + report: + description: "Whether to report the run results to Grafana Cloud k6" + required: false + type: boolean + default: false + +run-name: k6 run ${{ inputs.namespace }} ${{ inputs.scenario }} ${{ inputs.service_url }} report=${{ inputs.report }} + +# Disallow running multiple load tests at once against the same service +concurrency: ${{ github.workflow }}-${{ inputs.service_url }} + +jobs: + run-k6: + name: "Run k6 ${{ inputs.namespace }} ${{ inputs.scenario }} ${{ inputs.service_url }} report=${{ inputs.report }}" + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup CI env + uses: ./.github/actions/setup-env + with: + setup_python: false + install_recipe: node-install + + - name: Setup k6 + uses: grafana/setup-k6-action@v1 + + - name: k6 run ${{ inputs.namespace }} ${{ inputs.scenario }} ${{ inputs.service_url }} + env: + K6_CLOUD_TOKEN: ${{ secrets.GC_K6_TOKEN }} + K6_SIGNING_SECRET: ${{ secrets.K6_SIGNING_SECRET }} + run: | + just k6 ${{ inputs.namespace }} ${{ inputs.scenario }} \ + ${{ inputs.report && '-o cloud' || ''}} \ + -e signing_secret="$K6_SIGNING_SECRET" \ + -e service_url=${{ inputs.service_url }} \ + -e text_summary=/tmp/k6-summary.txt + + - name: Upload artifacts + if: always() + uses: actions/upload-artifact@v4 + with: + name: k6-output + path: /tmp/k6-summary.txt diff --git a/docker/dev_env/Dockerfile b/docker/dev_env/Dockerfile index 6d4c9ac8767..20c124c7e15 100644 --- a/docker/dev_env/Dockerfile +++ b/docker/dev_env/Dockerfile @@ -31,6 +31,7 @@ ENV PATH="${PNPM_BIN}:${N_PREFIX}/bin:${PDM_PYTHONS}:${HOME}/.local/bin:${PATH}" # - just: command runner # - jq: JSON processor # - which: locate a program file in `PATH` +# - tree: list files in a tree # - python*: required by some Python libraries for compilation during installation # - libffi*: required for the Python package cffi # - pipx: Python CLI app installer @@ -58,6 +59,7 @@ RUN mkdir /pipx \ just \ jq \ which \ + tree \ xdg-utils \ nodejs npm \ python3.12 python3.12-devel pipx \ diff --git a/packages/js/k6/justfile b/packages/js/k6/justfile index a4758069ece..6d8a75d5198 100644 --- a/packages/js/k6/justfile +++ b/packages/js/k6/justfile @@ -4,3 +4,8 @@ run namespace scenario *extra_args: #! /usr/bin/env bash pnpm run build --input src/{{ namespace }}/{{ scenario }}.test.ts k6 run "${@:3}" ./dist/{{ namespace }}/{{ scenario }}.test.js + +# List namespaces and scenarios +@ls: + echo "Openverse k6 namespaces and scenarios" + tree src -P '*.test.ts' --noreport | cut -c 5- | sed 's/\.test\.ts//' diff --git a/packages/js/k6/src/frontend/constants.ts b/packages/js/k6/src/frontend/constants.ts index 7f5a29615e4..1617e49c041 100644 --- a/packages/js/k6/src/frontend/constants.ts +++ b/packages/js/k6/src/frontend/constants.ts @@ -1,3 +1,3 @@ export const PROJECT_ID = 3713375 // Default to location of `ov j p frontend prod` -export const FRONTEND_URL = __ENV.FRONTEND_URL || "http://127.0.0.1:8443/" +export const FRONTEND_URL = __ENV.service_url || "http://127.0.0.1:8443/"