Skip to content

Commit

Permalink
Chore: Load Tests run in CI (#324)
Browse files Browse the repository at this point in the history
# Problem

We want to run the k6 tests in CI so that they also function as
semi-integration test system.

Closes: #317

# Solution

- Added a workflow for the k6 tests
- Disabled one test I didn't want to get working without additional
work. So added an issue for that:
#344
  • Loading branch information
wilwade authored Aug 6, 2024
1 parent eeb345f commit ff4539b
Show file tree
Hide file tree
Showing 34 changed files with 2,566 additions and 107 deletions.
106 changes: 106 additions & 0 deletions .github/workflows/load-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
name: Load Tests

on:
pull_request:
branches:
- main
push:
branches:
- main

jobs:
determine-service-matrix:
runs-on: ubuntu-latest
outputs:
services: ${{ steps.determine-matrix.outputs.changes }}
steps:
- name: Check Out Repo
uses: actions/checkout@v4
- uses: dorny/paths-filter@v3
id: determine-matrix
with:
# Note, 'common' is for future use--when code is factored out into common libraries,
# but it's set up here so that the workflow logic could be tested with it present
filters: |
common:
- '*'
- '.github/**'
account:
- '*'
- '.github/**'
- 'services/account/**'
graph:
- '*'
- '.github/**'
- 'services/graph/**'
content-publishing:
- '*'
- '.github/**'
- 'services/content-publishing/**'
content-watcher:
- '*'
- '.github/**'
- 'services/content-watcher/**'
build:
name: '[${{ matrix.service }}] Load Test'
runs-on: ubuntu-latest
needs: determine-service-matrix
strategy:
fail-fast: false
matrix:
service: ${{ fromJson(needs.determine-service-matrix.outputs.services) }}
exclude:
- service: common
steps:
- uses: actions/checkout@v4

- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
registry-url: 'https://registry.npmjs.org'
cache-dependency-path: tools/ci-k6/package-lock.json
- name: Install dependencies
working-directory: tools/ci-k6
run: npm ci

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{secrets.DOCKERHUB_USERNAME}}
password: ${{secrets.DOCKERHUB_TOKEN}}

- name: Start Frequency
run: |
docker compose -f docker-compose.yaml -f docker-compose-k6.${{ matrix.service }}.yaml up -d frequency
sleep 5
- name: Generate Provider and Capacity
working-directory: tools/ci-k6
run: npm run main

# Just start the services we need...
- name: Start All Services
run: docker compose -f docker-compose.yaml -f docker-compose-k6.${{ matrix.service }}.yaml up -d

- name: Wait for API to be ready
uses: cygnetdigital/[email protected]
with:
url: 'http://localhost:3000/readyz'
responseCode: '200'
timeout: 120000
interval: 2000

- name: Setup K6
uses: grafana/setup-k6-action@v1
- name: Run k6 Tests
run: |
for test_file in services/${{ matrix.service }}/k6-test/*.k6.js; do
k6 run --no-color --quiet --no-usage-report "$test_file" || exit 1
done
- name: Stop Docker Compose
if: always()
run: docker compose -f docker-compose.yaml -f docker-compose-k6.${{ matrix.service }}.yaml down
71 changes: 71 additions & 0 deletions docker-compose-k6.account.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# yaml-language-server: $schema=https://raw.githubusercontent.com/compose-spec/compose-spec/master/schema/compose-spec.json

services:
account-service-api:
pull_policy: never
build:
context: .
dockerfile: ./Docker/Dockerfile.account
command: ['api']
ports:
- 3000:3000
volumes: !reset []
depends_on: !override
redis:
condition: service_started
ipfs:
condition: service_healthy
account-service-webhook:
condition: service_healthy
environment:
PROVIDER_BASE_URL: 'http://account-service-webhook:3001/webhooks/account-service'
WEBHOOK_BASE_URL: 'http://account-service-webhook:3001/webhooks'

account-service-worker:
pull_policy: never
build:
context: .
dockerfile: ./Docker/Dockerfile.account
command: ['worker']
volumes: !reset []
depends_on: !override
- redis
- ipfs
environment:
PROVIDER_BASE_URL: 'http://account-service-webhook:3001/webhooks/account-service'
WEBHOOK_BASE_URL: 'http://account-service-webhook:3001/webhooks'

account-service-webhook:
image: rust:1.80.0
volumes:
- ./services/account/rust-webhook-server:/app
ports:
- '3001:3001'
command: sh -c "cd /app && cargo run"
healthcheck:
test: ['CMD', 'curl', '-f', 'http://127.0.0.1:3001/webhooks/health']
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
networks:
- amplica-gateway

gateway-base:
profiles:
- skip
content-publishing-service-worker:
profiles:
- skip
content-publishing-service-api:
profiles:
- skip
content-watcher-service:
profiles:
- skip
graph-service-api:
profiles:
- skip
graph-service-worker:
profiles:
- skip
45 changes: 45 additions & 0 deletions docker-compose-k6.content-publishing.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# yaml-language-server: $schema=https://raw.githubusercontent.com/compose-spec/compose-spec/master/schema/compose-spec.json

services:
content-publishing-service-api:
pull_policy: never
build:
context: .
dockerfile: ./Docker/Dockerfile.content-publishing
command: ['api']
ports:
- 3000:3000
volumes: !reset []
depends_on: !override
- redis
- ipfs

content-publishing-service-worker:
pull_policy: never
build:
context: .
dockerfile: ./Docker/Dockerfile.content-publishing
command: ['worker']
volumes: !reset []
depends_on: !override
- redis
- ipfs

gateway-base:
profiles:
- skip
account-service-worker:
profiles:
- skip
account-service-api:
profiles:
- skip
content-watcher-service:
profiles:
- skip
graph-service-api:
profiles:
- skip
graph-service-worker:
profiles:
- skip
36 changes: 36 additions & 0 deletions docker-compose-k6.content-watcher.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# yaml-language-server: $schema=https://raw.githubusercontent.com/compose-spec/compose-spec/master/schema/compose-spec.json

services:
content-watcher-service:
pull_policy: never
build:
context: .
dockerfile: ./Docker/Dockerfile.content-watcher
ports:
- 3000:3000
volumes: !reset []
depends_on: !override
- redis
- ipfs

gateway-base:
profiles:
- skip
content-publishing-service-worker:
profiles:
- skip
content-publishing-service-api:
profiles:
- skip
account-service-worker:
profiles:
- skip
account-service-api:
profiles:
- skip
graph-service-api:
profiles:
- skip
graph-service-worker:
profiles:
- skip
43 changes: 43 additions & 0 deletions docker-compose-k6.graph.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# yaml-language-server: $schema=https://raw.githubusercontent.com/compose-spec/compose-spec/master/schema/compose-spec.json

services:
graph-service-api:
pull_policy: never
build:
context: .
dockerfile: ./Docker/Dockerfile.graph
command: ['api']
ports:
- 3000:3000
volumes: !reset []
depends_on: !override
- redis

graph-service-worker:
pull_policy: never
build:
context: .
dockerfile: ./Docker/Dockerfile.graph
command: ['worker']
volumes: !reset []
depends_on: !override
- redis

gateway-base:
profiles:
- skip
content-publishing-service-worker:
profiles:
- skip
content-publishing-service-api:
profiles:
- skip
content-watcher-service:
profiles:
- skip
account-service-api:
profiles:
- skip
account-service-worker:
profiles:
- skip
5 changes: 2 additions & 3 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# yaml-language-server: $schema=https://raw.githubusercontent.com/compose-spec/compose-spec/master/schema/compose-spec.json
x-common-environment: &common-environment
FREQUENCY_URL: ${FREQUENCY_URL:-ws://frequency:9944}
FREQUENCY_HTTP_URL: ${FREQUENCY_HTTP_URL:-http://localhost:9944}
Expand Down Expand Up @@ -55,7 +56,7 @@ services:
- redis_data:/data/redis

frequency:
image: dsnp/instant-seal-node-with-deployed-schemas:latest
image: frequencychain/standalone-node:v1.13.0-rc3
# We need to specify the platform because it's the only image
# built by Frequency at the moment, and auto-pull won't work otherwise
platform: linux/amd64
Expand Down Expand Up @@ -159,7 +160,6 @@ services:
- graph_node_cache:/app/services/graph/node_modules
depends_on:
- redis
- ipfs
- gateway-base
networks:
- amplica-gateway
Expand All @@ -174,7 +174,6 @@ services:
- graph_node_cache:/app/services/graph/node_modules
depends_on:
- redis
- ipfs
- gateway-base
networks:
- amplica-gateway
Expand Down
2 changes: 1 addition & 1 deletion services/account/docs/account_service_arch.drawio
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<mxCell id="34" value="" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="280" y="330" width="390" height="330" as="geometry" />
</mxCell>
<mxCell id="35" value="GET/api/health" style="endArrow=classic;html=1;rounded=0;fillColor=#d5e8d4;strokeColor=#82b366;strokeWidth=3;exitX=0.996;exitY=0.17;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0;entryY=0.172;entryDx=0;entryDy=0;entryPerimeter=0;" parent="1" source="45" target="41" edge="1">
<mxCell id="35" value="GET/healthz" style="endArrow=classic;html=1;rounded=0;fillColor=#d5e8d4;strokeColor=#82b366;strokeWidth=3;exitX=0.996;exitY=0.17;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0;entryY=0.172;entryDx=0;entryDy=0;entryPerimeter=0;" parent="1" source="45" target="41" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="-260" y="400" as="sourcePoint" />
<mxPoint x="-140" y="400" as="targetPoint" />
Expand Down
12 changes: 9 additions & 3 deletions services/account/k6-test/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Generated k6 script

The `account-service-load.js` file contains most of the Swagger/OpenAPI specification and you can customize it to your needs.
The `health-check.js` file contains a simple health check script that can be used to check the health of the service.
The `account-service-load.k6.js` file contains most of the Swagger/OpenAPI specification and you can customize it to your needs.
The `health-check.k6.js` file contains a simple health check script that can be used to check the health of the service.

Global header variables are defined at the top of the file, like `api_key`. Each path in the specification is converted into a [group](https://docs.k6.io/docs/tags-and-groups) in k6 and each group contains all the request methods related to that path. Path and query parameters are extracted from the specification and put at the start of the group. The URL is constructed from the base URL plus path and query.

Expand All @@ -22,5 +22,11 @@ To run the script, you need to have k6 installed. You can download it from [here
To run the script, execute the following command:

```bash
k6 run health-check.js
k6 run health-check.k6.js
```

## Generating Test Data

So that k6 doesn't have to interact with the chain, we can generate data sepatately and then use it for the tests.

`npm run generate:signup` for example will re-generate the `signups.gen.js` file with 100 generated valid signup payloads.
Loading

0 comments on commit ff4539b

Please sign in to comment.