add tests and grafana dashboard
This commit is contained in:
174
k6/README.md
Normal file
174
k6/README.md
Normal file
@@ -0,0 +1,174 @@
|
||||
# k6 Load Tests for Cart API
|
||||
|
||||
This directory contains a k6 script (`cart_load_test.js`) to stress and observe the cart actor HTTP API.
|
||||
|
||||
## Contents
|
||||
|
||||
- `cart_load_test.js` – primary k6 scenario script
|
||||
- `README.md` – this file
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Node not required (k6 runs standalone)
|
||||
- k6 installed (>= v0.43 recommended)
|
||||
- Prometheus + Grafana (optional) if you want to correlate with the dashboard you generated
|
||||
- A running cart service exposing HTTP endpoints at (default) `http://localhost:8080/cart`
|
||||
|
||||
## Endpoints Exercised
|
||||
|
||||
The script exercises (per iteration):
|
||||
|
||||
1. `GET /cart/` – ensure / fetch cart state (creates cart if missing; sets `cartid` & `cartowner` cookies)
|
||||
2. `POST /cart/` – add item mutation (random SKU & quantity)
|
||||
3. `GET /cart/` – fetch after mutations
|
||||
4. `GET /cart/checkout` – occasionally (~2% of iterations) to simulate checkout start
|
||||
|
||||
You can extend it easily to hit deliveries, quantity changes, or removal endpoints.
|
||||
|
||||
## Environment Variables
|
||||
|
||||
| Variable | Purpose | Default |
|
||||
|-----------------|----------------------------------------------|-------------------------|
|
||||
| `BASE_URL` | Base URL root (either host or host/cart) | `http://localhost:8080/cart` |
|
||||
| `VUS` | VUs for steady_mutations scenario | `20` |
|
||||
| `DURATION` | Duration for steady_mutations scenario | `5m` |
|
||||
| `RAMP_TARGET` | Peak VUs for ramp_up scenario | `50` |
|
||||
|
||||
You can also disable one scenario by editing `options.scenarios` inside the script.
|
||||
|
||||
Example run:
|
||||
|
||||
```bash
|
||||
k6 run \
|
||||
-e BASE_URL=https://cart.prod.example.com/cart \
|
||||
-e VUS=40 \
|
||||
-e DURATION=10m \
|
||||
-e RAMP_TARGET=120 \
|
||||
k6/cart_load_test.js
|
||||
```
|
||||
|
||||
## Metrics (Custom)
|
||||
|
||||
The script defines additional k6 metrics:
|
||||
|
||||
- `cart_add_item_duration` (Trend) – latency of POST add item
|
||||
- `cart_fetch_duration` (Trend) – latency of GET cart state
|
||||
- `cart_checkout_duration` (Trend) – latency of checkout
|
||||
- `cart_items_added` (Counter) – successful add item operations
|
||||
- `cart_checkout_calls` (Counter) – successful checkout calls
|
||||
|
||||
Thresholds (in `options.thresholds`) enforce basic SLO:
|
||||
- Mutation failure rate < 2%
|
||||
- p90 mutation latency < 800 ms
|
||||
- p99 overall HTTP latency < 1500 ms
|
||||
|
||||
Adjust thresholds to your environment if they trigger prematurely.
|
||||
|
||||
## Cookies & Stickiness
|
||||
|
||||
The script preserves:
|
||||
- `cartid` – cart identity (server sets expiry separately)
|
||||
- `cartowner` – owning host for sticky routing
|
||||
|
||||
If your load balancer or ingress enforces affinity based on these cookies, traffic will naturally concentrate on the originally claimed host for each cart under test.
|
||||
|
||||
## SKU Set
|
||||
|
||||
SKUs used (randomly selected each mutation):
|
||||
|
||||
```
|
||||
778290 778345 778317 778277 778267 778376 778244 778384
|
||||
778365 778377 778255 778286 778246 778270 778266 778285
|
||||
778329 778425 778407 778418 778430 778469 778358 778351
|
||||
778319 778307 778278 778251 778253 778261 778263 778273
|
||||
778281 778294 778297 778302
|
||||
```
|
||||
|
||||
To add/remove SKUs, edit the `SKUS` array. Keeping it non-empty and moderately sized helps randomization.
|
||||
|
||||
## Extending the Script
|
||||
|
||||
### Add Quantity Change
|
||||
|
||||
```js
|
||||
function changeQuantity(itemId, newQty) {
|
||||
const payload = JSON.stringify({ Id: itemId, Qty: newQty });
|
||||
http.put(baseUrl() + '/', payload, { headers: headers() });
|
||||
}
|
||||
```
|
||||
|
||||
### Remove Item
|
||||
|
||||
```js
|
||||
function removeItem(itemId) {
|
||||
http.del(baseUrl() + '/' + itemId, null, { headers: headers() });
|
||||
}
|
||||
```
|
||||
|
||||
### Add Delivery
|
||||
|
||||
```js
|
||||
function addDelivery(itemIds) {
|
||||
const payload = JSON.stringify({ provider: "POSTNORD", items: itemIds });
|
||||
http.post(baseUrl() + '/delivery', payload, { headers: headers() });
|
||||
}
|
||||
```
|
||||
|
||||
You can integrate these into the iteration loop with probabilities.
|
||||
|
||||
## Output Summary
|
||||
|
||||
`handleSummary` outputs a JSON summary to stdout:
|
||||
- Average & p95 mutation latencies (if present)
|
||||
- Fetch p95
|
||||
- Checkout count
|
||||
- Check statuses
|
||||
|
||||
Redirect or parse that output for CI pipelines.
|
||||
|
||||
## Running in CI
|
||||
|
||||
Use shorter durations (e.g. `DURATION=2m VUS=10`) to keep builds fast. Fail build on threshold breaches:
|
||||
|
||||
```bash
|
||||
k6 run -e BASE_URL=$TARGET -e VUS=10 -e DURATION=2m k6/cart_load_test.js || exit 1
|
||||
```
|
||||
|
||||
## Correlating with Prometheus / Grafana
|
||||
|
||||
During load, observe:
|
||||
- `cart_mutations_total` growth and latency histograms
|
||||
- Event log write rate (`cart_event_log_appends_total`)
|
||||
- Pool usage (`cart_grain_pool_usage`) and spawn rate (`cart_grain_spawned_total`)
|
||||
- Failure counters (`cart_mutation_failures_total`) ensure they remain low
|
||||
|
||||
If mutation latency spikes without high error rate, inspect external dependencies (e.g., product fetcher or Klarna endpoints).
|
||||
|
||||
## Common Tuning Tips
|
||||
|
||||
| Symptom | Potential Adjustment |
|
||||
|------------------------------------|---------------------------------------------------|
|
||||
| High latency p99 | Increase CPU/memory, optimize mutation handlers |
|
||||
| Pool at capacity | Raise pool size argument or TTL |
|
||||
| Frequent cart eviction mid-test | Confirm TTL is sliding (now 2h on mutation) |
|
||||
| High replay duration | Consider snapshot + truncate event logs |
|
||||
| Uneven host load | Verify `cartowner` cookie is respected upstream |
|
||||
|
||||
## Safety / Load Guardrails
|
||||
|
||||
- Start with low VUs (5–10) and short duration.
|
||||
- Scale incrementally to find saturation points.
|
||||
- If using production endpoints, coordinate off-peak runs.
|
||||
|
||||
## License / Attribution
|
||||
|
||||
This test script is tailored for your internal cart actor system; adapt freely. k6 is open-source (AGPL v3). Ensure compliance if redistributing.
|
||||
|
||||
---
|
||||
|
||||
Feel free to request:
|
||||
- A variant script for spike tests
|
||||
- WebSocket / long poll integration (if added later)
|
||||
- Synthetic error injection harness
|
||||
|
||||
Happy load testing!
|
||||
Reference in New Issue
Block a user