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
6.9 KiB
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
-
Install k6:
# macOS brew install k6 # Linux sudo apt-get install k6 # Windows (using Chocolatey) choco install k6 -
Set up environment:
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:
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:
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:
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
# 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
# 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
# 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
-
Response Time (p95): 95th percentile response time
- ✅ Pass: < 500ms
- ❌ Fail: >= 500ms
-
Error Rate: Percentage of failed requests
- ✅ Pass: < 1%
- ❌ Fail: >= 1%
-
Throughput: Requests per second
- ✅ Pass: > 100 req/s for API, > 50 req/s for pages
- ❌ Fail: Below threshold
-
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
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_URLis correct - Verify firewall settings
High Error Rate
Error: http_req_failed > 1%
Possible Causes:
- Server overload (reduce VUs)
- Database connection issues
- Authentication failures
- Network issues
Debug:
# 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:
- Unoptimized database queries
- Missing indexes
- Large payloads
- Server resource constraints
Next Steps:
- Review database queries
- Check caching strategies
- Optimize images/assets
- 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
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