# 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