11 KiB
Load Test untuk Elemes LMS
Load test ini menggunakan Locust untuk mensimulasikan traffic pengguna pada LMS Elemes (Sinau-C).
⚠️ Penting: Keamanan Data Siswa
Load test ini menggunakan token siswa test yang ditunjuk khusus untuk testing:
Student Test Tokens (rows 40-72 di tokens_siswa.csv):
- CC90965E (ACHMAD RAFFY IRSYAD RAMADHAN)
- F84E3336 (AHMAD GHAUZAN AZRIL IRAWAN)
- D78F6DBD (AINI BINTANG PRAMESWARI)
- ... dan 30 siswa lainnya sampai SATRIYO WICAKSONO
Teacher Token:
- 141214 (Anggoro Dwi - untuk view-only operations)
Token-token ini aman untuk testing karena:
- ✅ Bukan siswa aktif yang sedang belajar
- ✅ Progress mereka bisa di-reset dengan mudah
- ✅ Teacher token hanya untuk read-only operations
- ✅ Semua write operations (track-progress) menggunakan test student tokens
Struktur File
test-load/
├── locustfile.py # Script load test utama
├── requirements.txt # Dependencies Python
└── README.md # Dokumentasi ini
Instalasi
1. Buat Virtual Environment (Opsional tapi Direkomendasikan)
cd test-load
python3 -m venv venv
source venv/bin/activate # Linux/Mac
# atau
venv\Scripts\activate # Windows
2. Install Dependencies
pip install -r requirements.txt
Cara Menjalankan
🚀 Quick Start (Menggunakan Script Helper)
Cara termudah untuk menjalankan load test adalah menggunakan script run.sh yang sudah menyertakan setup venv otomatis:
cd test-load
# Test API (Flask backend :5000)
./run.sh
# Test Frontend (SvelteKit :3000) - HTML pages
./run.sh frontend
# Test Full Stack (Frontend + API via proxy)
./run.sh fullstack
# Jalankan headless mode (default: 50 users, 5 spawn rate, 60 detik)
./run.sh headless
# Custom parameters
./run.sh headless -u 100 -r 10 -t 5m
./run.sh headless frontend -u 200 -r 20 -t 300s
# Hapus virtual environment
./run.sh clean
Mode Web UI (Interaktif)
# Menggunakan script helper (recommended)
# Test API only (Flask backend :5000)
./run.sh
# Test Frontend only (SvelteKit :3000) - loads HTML pages
./run.sh frontend
# Test Full Stack (Frontend proxies /api to Flask)
./run.sh fullstack
# Atau manual dengan venv
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
# API testing
locust -f locustfile.py --host=http://localhost:5000
# Frontend testing
locust -f locustfile.py --host=http://localhost:3000
Kemudian buka browser di: http://localhost:8089
Di Web UI, Anda bisa:
- Set jumlah user (Total Users)
- Set spawn rate (user per detik)
- Start, Stop, dan Edit load test secara real-time
- Melihat grafik response time, requests/detik, failures
Mode Headless (CLI/Scripted)
# Menggunakan script helper
# Test API
./run.sh headless -u 100 -r 10 -t 300s
# Test Frontend (HTML pages)
./run.sh headless frontend -u 100 -r 10 -t 5m
# Test Full Stack
./run.sh headless fullstack -u 200 -r 20 -t 10m
# Atau manual
source venv/bin/activate
# API testing (Flask :5000)
locust -f locustfile.py --host=http://localhost:5000 --headless -u 100 -r 10 -t 300s
# Frontend testing (SvelteKit :3000)
locust -f locustfile.py --host=http://localhost:3000 --headless -u 100 -r 10 -t 300s
Mode Distributed (Multi-Machine)
Untuk load test skala besar:
# Master node
locust -f locustfile.py --headless -u 1000 -r 100 --master
# Worker node 1
locust -f locustfile.py --worker --master-host=192.168.1.100
# Worker node 2
locust -f locustfile.py --worker --master-host=192.168.1.100
Parameter CLI
| Parameter | Deskripsi | Contoh |
|---|---|---|
-u |
Total jumlah user simulasi | -u 100 |
-r |
Spawn rate (user per detik) | -r 10 |
-t |
Durasi test | -t 300s, -t 5m, -t 1h |
--host |
Target URL | --host=http://localhost:5000 |
--headless |
Jalankan tanpa UI | --headless |
--html |
Export hasil ke HTML | --html=report.html |
User Classes
Load test ini memiliki 4 kelas user:
1. FrontendUser (Weight: 5)
Mensimulasikan user yang browsing halaman web frontend:
- Load homepage (/)
- Load lesson pages (/lesson/[slug])
- Load progress page (/progress)
- Load static assets (CSS, JS, manifest)
Weight 5 = Testing beban pada SvelteKit frontend
2. StudentUser (Weight: 8)
Mensimulasikan siswa yang berinteraksi dengan API:
- Login dengan token
- Melihat daftar pelajaran (API)
- Membuka konten lesson (API)
- Compile kode C
- Validate token
- Logout
Weight 8 = 40% traffic adalah siswa (API)
3. TeacherUser (Weight: 2)
Mensimulasikan guru yang berinteraksi dengan API:
- Login dengan token guru
- Melihat progress report (API)
- Export CSV progress
- Membuka lesson untuk review
- Validate token
Weight 2 = 10% traffic adalah guru (API)
4. APIStressTest (Weight: 1)
Stress test endpoint API spesifik:
/api/compile- Code compilation/api/lesson/[slug].json- Lesson content/api/validate-token- Token validation/api/lessons- Lessons list
Weight 1 = 5% traffic adalah stress test API
Endpoint yang Diuji
Frontend (SvelteKit :3000)
| Endpoint | Method | Fungsi | User Class |
|---|---|---|---|
/ |
GET | Homepage (lesson grid) | FrontendUser |
/lesson/[slug] |
GET | Lesson page | FrontendUser |
/progress |
GET | Progress report page | FrontendUser |
/_app/immutable/* |
GET | Static JS/CSS assets | FrontendUser |
/manifest.json |
GET | PWA manifest | FrontendUser |
/circuitjs1/circuitjs.html |
GET | Circuit simulator | FrontendUser |
Backend API (Flask :5000)
| Endpoint | Method | Fungsi | User Class |
|---|---|---|---|
/api/login |
POST | Login dengan token | Student, Teacher |
/api/logout |
POST | Logout | Student |
/api/validate-token |
POST | Validasi token | Student, Teacher, Stress |
/api/lessons |
GET | Daftar pelajaran | Student, Teacher, Stress |
/api/lesson/<slug>.json |
GET | Konten lesson | Student, Teacher, Stress |
/api/compile |
POST | Compile & run kode | Student, Stress |
/api/progress-report.json |
GET | Progress report | Teacher |
/api/progress-report/export-csv |
GET | Export CSV | Teacher |
Contoh Skenario Testing
1. Load Test Ringan (Development)
# API only
./run.sh headless -u 20 -r 2 -t 60s
# Frontend
./run.sh headless frontend -u 20 -r 2 -t 60s
2. Load Test Sedang (Staging)
# API only
./run.sh headless -u 100 -r 10 -t 300s
# Full Stack (Frontend + API)
./run.sh headless fullstack -u 100 -r 10 -t 300s
3. Load Test Berat (Production Capacity Test)
# API only
./run.sh headless -u 500 -r 50 -t 600s
# Frontend
./run.sh headless frontend -u 500 -r 50 -t 600s
4. Stress Test (Find Breaking Point)
./run.sh headless fullstack -u 1000 -r 100 -t 300s
5. Endurance Test (Stability Test)
./run.sh headless fullstack -u 50 -r 5 -t 2h
6. Frontend Page Load Test
# Test HTML page rendering + static assets
./run.sh headless frontend -u 100 -r 10 -t 5m
Metrik yang Dipantau
Di Web UI
- RPS: Requests per second
- Average Response Time: Rata-rata waktu response
- Median Response Time: Response time median
- 95th Percentile: 95% request lebih cepat dari nilai ini
- Failures: Jumlah request gagal
Log Console
- Slow requests (>1 detik)
- Total requests
- Failure rate (%)
- Average response time
Threshold Performance
Berikut threshold yang direkomendasikan untuk LMS:
| Metrik | Target | Warning | Critical |
|---|---|---|---|
| Avg Response Time | <200ms | 200-500ms | >500ms |
| 95th Percentile | <500ms | 500-1000ms | >1000ms |
| Failure Rate | <0.1% | 0.1-1% | >1% |
| RPS Capacity | >100 | 50-100 | <50 |
Export Hasil
HTML Report
locust -f locustfile.py --host=http://localhost:5000 --headless -u 100 -r 10 -t 300s --html=report.html
CSV Statistics
locust -f locustfile.py --host=http://localhost:5000 --headless -u 100 -r 10 -t 300s --csv=results
Output:
results_requests.csvresults_failures.csvresults_stats.csvresults_history.csv
JSON (via events)
Tambahkan ke locustfile.py:
@events.test_stop.add_listener
def on_test_stop(environment, **kwargs):
import json
stats = {
'total_requests': environment.stats.total.num_requests,
'failures': environment.stats.total.num_failures,
'avg_response_time': environment.stats.total.avg_response_time,
}
with open('results.json', 'w') as f:
json.dump(stats, f)
Troubleshooting
User Count Tidak Sesuai (Misal: Set 50, Yang Muncul 19)
Penyebab:
- User class gagal start - Task error atau on_start error
- Host tidak reachable - Server target belum running
- Weight distribution - Locust mendistribusikan user berdasarkan weight
Solusi:
-
Periksa log console untuk error messages:
./run.sh 2>&1 | grep -i error -
Pastikan server target running:
# Untuk API testing (:5000) curl http://localhost:5000/api/lessons # Untuk Frontend testing (:3000) curl http://localhost:3000/ -
Gunakan mode yang sesuai:
# API only - jangan gunakan frontend user ./run.sh headless -u 50 -r 5 # Frontend only ./run.sh headless frontend -u 50 -r 5 # Full stack (recommended) ./run.sh headless fullstack -u 50 -r 5 -
Cek user count di log:
✅ Spawning complete: 50 users active -
Disable user class yang tidak perlu dengan edit weight di
locustfile.py:class FrontendUser(HttpUser): weight = 0 # Disable
Error: "Connection refused"
Pastikan backend/frontend berjalan:
# API (Flask)
cd elemes
python app.py
# Frontend (SvelteKit)
cd elemes/frontend
npm run dev
Response time sangat tinggi
Kemungkinan penyebab:
- Backend overload (kurangi user count)
- Network latency (jalankan load test di network yang sama)
- Database/file I/O bottleneck (periksa logs Flask)
High failure rate
Periksa:
- Token guru valid di
tokens_siswa.csv - Content folder ada dan berisi file .md
- Flask logs untuk error detail
FrontendUser tidak muncul di panel
Jika testing di :5000 (API), FrontendUser otomatis disabled karena halaman web tidak ada di Flask backend. Gunakan :3000 untuk frontend testing.
Tips
- Mulai kecil: Mulai dengan 10-20 user, naikkan bertahap
- Monitor resources: Gunakan
htop,docker statssaat testing - Test di staging: Jangan test load tinggi langsung di production
- Baseline first: Jalankan test sekali untuk dapat baseline metrics
- Compare runs: Simpan hasil untuk perbandingan setelah perubahan code
Integrasi CI/CD
GitHub Actions Example
name: Load Test
on: [push]
jobs:
load-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Install dependencies
run: |
cd test-load
pip install -r requirements.txt
- name: Run load test
run: |
cd test-load
locust -f locustfile.py --host=http://localhost:5000 \
--headless -u 50 -r 5 -t 60s --fail-on-ratio=0.01