# 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
