Complete 6 Sprint 1 stories for Epic 1 web migration infrastructure. Portfolio Collection: - Add 7 fields: title, slug, url, image, description, websiteType, tags - Configure R2 storage and authenticated access control Categories Collection: - Add nameEn, order, textColor, backgroundColor fields - Add color picker UI configuration Posts Collection: - Add excerpt with 200 char limit and ogImage for social sharing - Add showInFooter checkbox and status select (draft/review/published) Role-Based Access Control: - Add role field to Users collection (admin/editor) - Create adminOnly and authenticated access functions - Apply access rules to Portfolio, Categories, Posts, Users collections Audit Logging System (NFR9): - Create Audit collection with timestamps for 90-day retention - Add auditLogger utility for login/logout/content change tracking - Add auditChange and auditGlobalChange hooks to all collections and globals - Add cleanupAuditLogs job with 90-day retention policy Load Testing Framework (NFR4): - Add k6 load testing with 3 scripts: public-browsing, admin-operations, api-performance - Configure targets: p95 < 500ms, error rate < 1%, 100 concurrent users - Add verification script and comprehensive documentation Other Changes: - Remove unused Form blocks - Add Header/Footer audit hooks - Regenerate Payload TypeScript types
295 lines
6.9 KiB
Markdown
295 lines
6.9 KiB
Markdown
# K6 Load Testing Framework
|
|
|
|
## Overview
|
|
|
|
This directory contains load testing scripts for the Enchun CMS backend using k6. The tests are designed to validate the non-functional requirement NFR4:
|
|
|
|
- **Target:** p95 response time < 500ms
|
|
- **Error rate:** < 1%
|
|
- **Concurrent users:** 100
|
|
|
|
## Prerequisites
|
|
|
|
1. **Install k6:**
|
|
```bash
|
|
# macOS
|
|
brew install k6
|
|
|
|
# Linux
|
|
sudo apt-get install k6
|
|
|
|
# Windows (using Chocolatey)
|
|
choco install k6
|
|
```
|
|
|
|
2. **Set up environment:**
|
|
```bash
|
|
cp .env.example .env.k6
|
|
# Edit .env.k6 with your test environment credentials
|
|
```
|
|
|
|
## Test Scripts
|
|
|
|
### 1. Public Browsing Test (`public-browsing.js`)
|
|
|
|
Simulates 100 concurrent users browsing public pages:
|
|
- Homepage
|
|
- About page
|
|
- Solutions page
|
|
- Portfolio list
|
|
- Blog list
|
|
- Contact page
|
|
|
|
**Run:**
|
|
```bash
|
|
k6 run --env BASE_URL=http://localhost:3000 tests/k6/public-browsing.js
|
|
```
|
|
|
|
**Expected Results:**
|
|
- p95 response time < 500ms
|
|
- Error rate < 1%
|
|
- 100 concurrent users sustained for 2 minutes
|
|
|
|
### 2. Admin Operations Test (`admin-operations.js`)
|
|
|
|
Simulates 20 concurrent admin users performing:
|
|
- Login
|
|
- List pages/posts
|
|
- Create/edit content
|
|
- Delete content
|
|
|
|
**Run:**
|
|
```bash
|
|
k6 run --env BASE_URL=http://localhost:3000 \
|
|
--env ADMIN_EMAIL=admin@example.com \
|
|
--env ADMIN_PASSWORD=password123 \
|
|
tests/k6/admin-operations.js
|
|
```
|
|
|
|
**Expected Results:**
|
|
- p95 response time < 500ms
|
|
- Error rate < 1%
|
|
- 20 concurrent users sustained for 3 minutes
|
|
|
|
### 3. API Performance Test (`api-performance.js`)
|
|
|
|
Tests specific API endpoints:
|
|
- GraphQL API queries
|
|
- REST API endpoints
|
|
- Global API endpoint
|
|
|
|
**Run:**
|
|
```bash
|
|
k6 run --env BASE_URL=http://localhost:3000 tests/k6/api-performance.js
|
|
```
|
|
|
|
**Expected Results:**
|
|
- p95 response time < 300ms (faster for API)
|
|
- Error rate < 0.5%
|
|
- Throughput > 100 requests/second
|
|
|
|
## Configuration
|
|
|
|
### Environment Variables
|
|
|
|
| Variable | Description | Default | Required |
|
|
|----------|-------------|---------|----------|
|
|
| `BASE_URL` | Target server URL | `http://localhost:3000` | Yes |
|
|
| `ADMIN_EMAIL` | Admin user email | - | For admin tests |
|
|
| `ADMIN_PASSWORD` | Admin user password | - | For admin tests |
|
|
| `VUS` | Number of virtual users | Varies per test | No |
|
|
| `DURATION` | Test duration | Varies per test | No |
|
|
|
|
### Load Profiles
|
|
|
|
Each test uses different load profiles:
|
|
|
|
| Test | Virtual Users | Duration | Ramp Up |
|
|
|------|--------------|----------|---------|
|
|
| Public Browsing | 100 | 2m | 30s |
|
|
| Admin Operations | 20 | 3m | 30s |
|
|
| API Performance | 50 | 5m | 1m |
|
|
|
|
## Running Tests
|
|
|
|
### Run Single Test
|
|
|
|
```bash
|
|
# Basic run
|
|
k6 run tests/k6/public-browsing.js
|
|
|
|
# With custom environment
|
|
k6 run --env BASE_URL=https://staging.enchun.tw tests/k6/public-browsing.js
|
|
|
|
# With custom stages
|
|
k6 run --env STAGED_USERS=200 --env STAGED_DURATION=10m tests/k6/public-browsing.js
|
|
```
|
|
|
|
### Run All Tests
|
|
|
|
```bash
|
|
# Using the npm script
|
|
pnpm test:load
|
|
|
|
# Or manually
|
|
k6 run tests/k6/public-browsing.js
|
|
k6 run tests/k6/admin-operations.js
|
|
k6 run tests/k6/api-performance.js
|
|
```
|
|
|
|
### Run with Output Options
|
|
|
|
```bash
|
|
# Generate JSON report
|
|
k6 run --out json=results.json tests/k6/public-browsing.js
|
|
|
|
# Generate HTML report (requires k6-reporter)
|
|
k6 run --out json=results.json tests/k6/public-browsing.js
|
|
k6-reporter results.json --output results.html
|
|
```
|
|
|
|
## Interpreting Results
|
|
|
|
### Key Metrics
|
|
|
|
1. **Response Time (p95):** 95th percentile response time
|
|
- ✅ Pass: < 500ms
|
|
- ❌ Fail: >= 500ms
|
|
|
|
2. **Error Rate:** Percentage of failed requests
|
|
- ✅ Pass: < 1%
|
|
- ❌ Fail: >= 1%
|
|
|
|
3. **Throughput:** Requests per second
|
|
- ✅ Pass: > 100 req/s for API, > 50 req/s for pages
|
|
- ❌ Fail: Below threshold
|
|
|
|
4. **Virtual Users (VUs):** Active concurrent users
|
|
- Should sustain target VUs for the full duration
|
|
|
|
### Example Output
|
|
|
|
```
|
|
✓ Status is 200
|
|
✓ Response time < 500ms
|
|
✓ Page content loaded
|
|
|
|
checks.........................: 100.0% ✓ 12000 ✗ 0
|
|
data_received..................: 15 MB 125 kB/s
|
|
data_sent......................: 2.1 MB 18 kB/s
|
|
http_req_blocked...............: avg=1.2ms min=0.5µs med=1µs max=125ms
|
|
http_req_connecting............: avg=500µs min=0s med=0s max=45ms
|
|
http_req_duration..............: avg=185.3ms min=45ms med=150ms max=850ms p(95)=420ms
|
|
http_req_failed................: 0.00% ✓ 0 ✗ 12000
|
|
http_req_receiving.............: avg=15ms min=10µs med=50µs max=250ms
|
|
http_req_sending...............: avg=50µs min=5µs med=20µs max=5ms
|
|
http_req_tls_handshaking.......: avg=0s min=0s med=0s max=0s
|
|
http_req_waiting...............: avg=170ms min=40ms med=140ms max=800ms
|
|
http_reqs......................: 12000 100 req/s
|
|
iteration_duration.............: avg=5.2s min=1.2s med=5s max=12s
|
|
iterations.....................: 2400 20 /s
|
|
vus............................: 100 min=100 max=100
|
|
vus_max........................: 100 min=100 max=100
|
|
```
|
|
|
|
## CI/CD Integration
|
|
|
|
### GitHub Actions
|
|
|
|
```yaml
|
|
name: Load Tests
|
|
on:
|
|
schedule:
|
|
- cron: '0 2 * * *' # Daily at 2 AM
|
|
workflow_dispatch:
|
|
|
|
jobs:
|
|
k6:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v3
|
|
- uses: grafana/k6-action@v0.3.1
|
|
with:
|
|
filename: tests/k6/public-browsing.js
|
|
env:
|
|
BASE_URL: ${{ secrets.STAGING_URL }}
|
|
```
|
|
|
|
## Troubleshooting
|
|
|
|
### Connection Refused
|
|
|
|
**Error:** `connect attempt failed`
|
|
|
|
**Solution:**
|
|
- Ensure the backend server is running
|
|
- Check `BASE_URL` is correct
|
|
- Verify firewall settings
|
|
|
|
### High Error Rate
|
|
|
|
**Error:** `http_req_failed > 1%`
|
|
|
|
**Possible Causes:**
|
|
1. Server overload (reduce VUs)
|
|
2. Database connection issues
|
|
3. Authentication failures
|
|
4. Network issues
|
|
|
|
**Debug:**
|
|
```bash
|
|
# Run with fewer users
|
|
k6 run --env STAGED_USERS=10 tests/k6/public-browsing.js
|
|
|
|
# Check server logs
|
|
pnpm dev
|
|
# In another terminal, watch logs while tests run
|
|
```
|
|
|
|
### Slow Response Times
|
|
|
|
**Error:** `p(95) >= 500ms`
|
|
|
|
**Possible Causes:**
|
|
1. Unoptimized database queries
|
|
2. Missing indexes
|
|
3. Large payloads
|
|
4. Server resource constraints
|
|
|
|
**Next Steps:**
|
|
1. Review database queries
|
|
2. Check caching strategies
|
|
3. Optimize images/assets
|
|
4. Scale server resources
|
|
|
|
## Performance Baseline
|
|
|
|
Initial baseline (to be established):
|
|
|
|
| Test | p95 (ms) | Error Rate | Throughput |
|
|
|------|----------|------------|------------|
|
|
| Public Browsing | TBD | TBD | TBD |
|
|
| Admin Operations | TBD | TBD | TBD |
|
|
| API Performance | TBD | TBD | TBD |
|
|
|
|
Update this table after first test run to establish baseline.
|
|
|
|
## Resources
|
|
|
|
- [k6 Documentation](https://k6.io/docs/)
|
|
- [k6 Metrics](https://k6.io/docs/using-k6/metrics/)
|
|
- [Payload CMS Performance](https://payloadcms.com/docs/admin/configuration)
|
|
- [Web Vitals](https://web.dev/vitals/)
|
|
|
|
## Maintenance
|
|
|
|
- Review and update test scenarios quarterly
|
|
- Adjust load profiles based on real traffic patterns
|
|
- Update thresholds based on business requirements
|
|
- Add new tests for new features
|
|
|
|
---
|
|
|
|
**Last Updated:** 2025-01-31
|
|
**Owner:** QA Team
|