Files
website-enchun-mgr/apps/backend/tests/k6
pkupuk 7fd73e0e3d Implement Sprint 1 stories: collections, RBAC, audit logging, load testing
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
2026-01-31 17:20:35 +08:00
..

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:

    # macOS
    brew install k6
    
    # Linux
    sudo apt-get install k6
    
    # Windows (using Chocolatey)
    choco install k6
    
  2. 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

  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

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:

# 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

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