feat(load-tests): add K6 load testing suite for critical API paths

K6 scripts for 4 critical paths:
- Auth (100 VU): login, register, profile
- Listings (500 VU): search with filters, detail view
- Search (200 VU): full-text + geo search
- Payments (50 VU): create payment, list transactions

SLA thresholds: p50<200ms, p95<500ms, p99<1s, error<1%.
CI: manual workflow_dispatch with suite selector.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
Ho Ngoc Hai
2026-04-09 08:41:15 +07:00
parent ffb6179b65
commit a8e1a438b9
7 changed files with 663 additions and 0 deletions

102
.github/workflows/load-test.yml vendored Normal file
View File

@@ -0,0 +1,102 @@
name: Load Tests (K6)
on:
workflow_dispatch:
inputs:
suite:
description: 'Test suite to run'
required: true
default: 'all'
type: choice
options:
- all
- auth
- listings
- search
- payments
concurrency:
group: load-test-${{ github.ref }}
cancel-in-progress: true
jobs:
load-test:
name: K6 Load Test — ${{ inputs.suite }}
runs-on: ubuntu-latest
timeout-minutes: 20
services:
postgres:
image: postgis/postgis:16-3.4
env:
POSTGRES_DB: goodgo_test
POSTGRES_USER: goodgo
POSTGRES_PASSWORD: goodgo_test_secret
ports:
- 5432:5432
options: >-
--health-cmd "pg_isready -U goodgo -d goodgo_test"
--health-interval 10s
--health-timeout 5s
--health-retries 5
env:
DATABASE_URL: postgresql://goodgo:goodgo_test_secret@localhost:5432/goodgo_test
NODE_ENV: test
JWT_SECRET: load-test-jwt-secret-key
JWT_REFRESH_SECRET: load-test-refresh-secret-key
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install K6
run: |
sudo gpg -k
sudo gpg --no-default-keyring --keyring /usr/share/keyrings/k6-archive-keyring.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D68
echo "deb [signed-by=/usr/share/keyrings/k6-archive-keyring.gpg] https://dl.k6.io/deb stable main" | sudo tee /etc/apt/sources.list.d/k6.list
sudo apt-get update
sudo apt-get install k6
- name: Install pnpm
uses: pnpm/action-setup@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Run database migrations
run: pnpm db:migrate:deploy
- name: Build and start API
run: |
pnpm --filter @goodgo/api run build
pnpm --filter @goodgo/api run start &
sleep 10
- name: Run load tests
run: |
mkdir -p results
if [ "${{ inputs.suite }}" = "all" ]; then
for f in load-tests/scripts/*.js; do
name=$(basename "$f" .js)
echo "=== Running $name ==="
k6 run --out json="results/${name}.json" "$f" || true
done
else
k6 run --out json="results/${{ inputs.suite }}.json" \
"load-tests/scripts/${{ inputs.suite }}.js"
fi
- name: Upload results
if: ${{ !cancelled() }}
uses: actions/upload-artifact@v4
with:
name: k6-results-${{ inputs.suite }}
path: results/
retention-days: 30