mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 23:41:08 +02:00
The pre-launch consolidation collapsed 17+ per-product backends into
the single Hono/Bun process at apps/api. That makes apps/api the
single point of failure for every authenticated module call the
unified Mana web app makes — a missing index, a hot-path allocation
in auth middleware, or rate-limiter contention degrades all 16
modules at once. The other scripts in load-tests/ already cover
mana-auth, mana-sync, mana-llm and the SvelteKit frontends, but
apps/api itself was unmeasured. This is that missing piece.
What it tests
-------------
A weighted mixed workload that walks the full middleware stack
(CORS → request logger → rate limit → auth → router → handler)
plus a representative range of handler shapes:
25% GET /health (no auth, baseline)
20% GET /api/v1/moodlit/presets (auth + in-memory return)
15% GET /api/v1/chat/models (auth + DB read)
20% POST /api/v1/calendar/events/expand (auth + Zod + RRULE compute)
12% POST /api/v1/todo/compute/next-occurrence
(auth + Zod + rrule lib)
8% POST /api/v1/todo/compute/validate (auth + Zod + validation)
Deliberately no write endpoints — those would conflate write
amplification with API-server cost. The compute routes here all run
in <50ms warm; what we're measuring is the overhead the unified
server adds on top of pure handler work.
Per-route-class p95 budgets via tags:
health < 100ms
authed_get < 300ms
authed_post < 500ms
global p95 < 500ms, p99 < 2s
Application-level error rate (4xx + 5xx + check failures) must stay
under 1% — exit code 1 otherwise, so it's CI-gateable.
Auth setup
----------
apps/api requires JWT on every /api/* route. setup() acquires a
token once before VUs start hammering and shares it for the run.
Three sources tried in order:
1. $MANA_API_TOKEN (CI passes a pre-minted token)
2. login at $TEST_EMAIL / $TEST_PASSWORD
3. register a fresh account on the fly
Bails with a clear error message if all three fail.
Load profile
------------
4 minute total: 30s warmup → 2m sustained @ 50 VUs → 1m peak @ 100 VUs
→ 30s cooldown. Override with --vus / --duration as usual.
Closes item #23 in docs/REFACTORING_AUDIT_2026_04.md.
Follow-ups not in this commit:
- Wire into .github/workflows/daily-tests.yml (requires standing
up the apps/api stack in the runner — bigger lift, separate PR)
- Per-module thresholds once we have a few real runs and know
where the natural baseline sits
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
79 lines
2.5 KiB
Markdown
79 lines
2.5 KiB
Markdown
# Load Tests
|
|
|
|
k6-basierte Load Tests fuer die Mana-Infrastruktur.
|
|
|
|
## Setup
|
|
|
|
```bash
|
|
# k6 installieren (macOS)
|
|
brew install k6
|
|
|
|
# WebSocket-Extension (fuer Sync-Tests)
|
|
# k6 hat WebSocket-Support eingebaut
|
|
```
|
|
|
|
## Tests ausfuehren
|
|
|
|
```bash
|
|
# Gegen lokale Umgebung
|
|
k6 run load-tests/web-apps.js
|
|
k6 run load-tests/auth-api.js
|
|
k6 run load-tests/api.js
|
|
k6 run load-tests/sync-websocket.js
|
|
k6 run load-tests/llm-ollama.js
|
|
|
|
# api.js braucht ein gültiges JWT — entweder via $MANA_API_TOKEN
|
|
# oder es loggt sich mit den TEST_EMAIL/TEST_PASSWORD env vars ein
|
|
# (default: loadtest-api@mana.test / LoadTestApi123!).
|
|
k6 run -e MANA_API_TOKEN=eyJhbGc... load-tests/api.js
|
|
|
|
# Gegen Produktion (vorsichtig!)
|
|
k6 run -e BASE_URL=https://mana.how load-tests/web-apps.js
|
|
|
|
# Mit mehr/weniger Last
|
|
k6 run --vus 100 --duration 5m load-tests/web-apps.js
|
|
|
|
# JSON-Output fuer Grafana
|
|
k6 run --out json=results.json load-tests/web-apps.js
|
|
```
|
|
|
|
## Test-Szenarien
|
|
|
|
| Script | Ziel | Default VUs | Dauer |
|
|
|--------|------|-------------|-------|
|
|
| `web-apps.js` | SvelteKit Frontends (HTML-Responses) | 10→50→10 | 5 min |
|
|
| `auth-api.js` | Login, Register, Token Validation | 5→20→5 | 4 min |
|
|
| `api.js` | Unified `apps/api` Hono server (16 Module) — gemixte Workload mit Auth, Compute & Validation | 10→50→100→0 | 4 min |
|
|
| `sync-websocket.js` | mana-sync WebSocket Connections | 10→30→10 | 5 min |
|
|
| `llm-ollama.js` | Ollama Chat Completions | 1→3→1 | 3 min |
|
|
|
|
### `api.js` Thresholds
|
|
|
|
Pro Route-Klasse hat das Script eigene p95-Budgets über `tags`:
|
|
|
|
| Klasse | Endpoints | p95-Budget |
|
|
|--------|-----------|------------|
|
|
| `health` | `GET /health` | < 100ms |
|
|
| `authed_get` | `GET /api/v1/moodlit/presets`, `GET /api/v1/chat/models` | < 300ms |
|
|
| `authed_post` | `POST /api/v1/calendar/events/expand`, `POST /api/v1/todo/compute/*` | < 500ms |
|
|
| Global | alle Requests aggregiert | p95 < 500ms, p99 < 2s |
|
|
|
|
Application-level error rate (4xx + 5xx + Check-Failures) muss unter
|
|
1% bleiben, sonst exit-code 1 → CI-Build bricht.
|
|
|
|
## Metriken interpretieren
|
|
|
|
| Metrik | Gut | Akzeptabel | Schlecht |
|
|
|--------|-----|-----------|---------|
|
|
| http_req_duration (p95) | < 200ms | < 1s | > 2s |
|
|
| http_req_failed | 0% | < 1% | > 5% |
|
|
| ws_connecting (p95) | < 100ms | < 500ms | > 1s |
|
|
| iterations | Steigend | Stabil | Fallend |
|
|
|
|
## Monitoring waehrend Tests
|
|
|
|
Grafana-Dashboard auf http://localhost:8080 (oder https://grafana.mana.how) beobachten:
|
|
- Container CPU/RAM (cAdvisor)
|
|
- PostgreSQL Connections
|
|
- Redis Commands/sec
|
|
- Netzwerk-Throughput
|