uodate test load
parent
3223a95f3e
commit
f79684d769
|
|
@ -0,0 +1,116 @@
|
||||||
|
# Load Testing Documentation for C Programming Learning Management System
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
This document describes how to perform load testing on the C Programming Learning Management System to ensure it can handle at least 50 concurrent students accessing the application.
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Python 3.7+
|
||||||
|
- Locust (installed via pip)
|
||||||
|
- The LMS application running on your local machine or a test server
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
|
||||||
|
### 1. Install Locust
|
||||||
|
```bash
|
||||||
|
pip install locust
|
||||||
|
```
|
||||||
|
|
||||||
|
Alternatively, install from the requirements file in the test directory:
|
||||||
|
```bash
|
||||||
|
cd /path/to/lms-c/test
|
||||||
|
pip install -r requirements.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Ensure the LMS Application is Running
|
||||||
|
Start your LMS application:
|
||||||
|
```bash
|
||||||
|
cd /path/to/lms-c
|
||||||
|
./start.sh
|
||||||
|
```
|
||||||
|
Or if running directly:
|
||||||
|
```bash
|
||||||
|
python app.py
|
||||||
|
```
|
||||||
|
|
||||||
|
By default, the application runs on `http://localhost:5000`.
|
||||||
|
|
||||||
|
## Running the Load Test
|
||||||
|
|
||||||
|
### Basic Load Test
|
||||||
|
To run a load test simulating 50 users with a hatch rate of 2 users per second:
|
||||||
|
```bash
|
||||||
|
cd /path/to/lms-c/test
|
||||||
|
locust -f load_test.py --host=http://localhost:5000
|
||||||
|
```
|
||||||
|
|
||||||
|
Then open your browser and go to `http://localhost:8089` to configure the load test.
|
||||||
|
|
||||||
|
### Command Line Load Test
|
||||||
|
To run the load test directly from the command line without the web interface:
|
||||||
|
```bash
|
||||||
|
locust -f load_test.py --host=http://localhost:5000 --users=50 --spawn-rate=2 --run-time=5m --headless
|
||||||
|
```
|
||||||
|
|
||||||
|
This command will:
|
||||||
|
- Simulate 50 users (`--users=50`)
|
||||||
|
- Spawn 2 users per second (`--spawn-rate=2`)
|
||||||
|
- Run for 5 minutes (`--run-time=5m`)
|
||||||
|
- Run in headless mode without the web interface (`--headless`)
|
||||||
|
|
||||||
|
## Test Scenarios
|
||||||
|
|
||||||
|
The load test script simulates the following student behaviors:
|
||||||
|
|
||||||
|
1. **Viewing the homepage** (30% of requests) - Students browsing available lessons
|
||||||
|
2. **Viewing lesson pages** (40% of requests) - Students reading lesson content
|
||||||
|
3. **Compiling code** (20% of requests) - Students submitting C code for compilation
|
||||||
|
4. **Logging in** (10% of requests) - Students authenticating with tokens
|
||||||
|
5. **Validating tokens** (10% of requests) - Students validating their access tokens
|
||||||
|
6. **Tracking progress** (10% of requests) - Students saving their lesson progress
|
||||||
|
|
||||||
|
## Monitoring and Metrics
|
||||||
|
|
||||||
|
During the load test, Locust provides the following metrics:
|
||||||
|
|
||||||
|
- **Users**: Number of concurrent users
|
||||||
|
- **Failures**: Number of failed requests
|
||||||
|
- **Requests per second**: Average request rate
|
||||||
|
- **Average response time**: Mean response time across all requests
|
||||||
|
- **95th percentile response time**: Response time below which 95% of requests complete
|
||||||
|
- **99th percentile response time**: Response time below which 99% of requests complete
|
||||||
|
- **Total requests**: Total number of requests made during the test
|
||||||
|
|
||||||
|
## Performance Benchmarks
|
||||||
|
|
||||||
|
For the application to be considered capable of handling 50 students simultaneously, it should meet these benchmarks:
|
||||||
|
|
||||||
|
- Less than 1% failure rate
|
||||||
|
- Average response time under 2 seconds
|
||||||
|
- 95th percentile response time under 5 seconds
|
||||||
|
- No significant degradation in performance as user count increases
|
||||||
|
|
||||||
|
## Customizing the Load Test
|
||||||
|
|
||||||
|
You can modify the `load_test.py` file to adjust:
|
||||||
|
|
||||||
|
- The number of users simulated
|
||||||
|
- The distribution of different types of requests
|
||||||
|
- The wait time between requests
|
||||||
|
- The sample code used for compilation tests
|
||||||
|
- The tokens used for authentication
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Common Issues:
|
||||||
|
|
||||||
|
1. **Connection Refused**: Ensure the LMS application is running on the specified host/port
|
||||||
|
2. **High Failure Rate**: Check application logs for errors during the load test
|
||||||
|
3. **Memory Issues**: Monitor system resources during the test
|
||||||
|
4. **GCC Compilation Errors**: The application compiles C code, which may consume resources
|
||||||
|
|
||||||
|
### Resource Monitoring:
|
||||||
|
Consider monitoring system resources (CPU, memory, disk I/O) during the test using tools like `htop`, `iostat`, or `vmstat`.
|
||||||
|
|
||||||
|
## Conclusion
|
||||||
|
|
||||||
|
This load testing setup allows you to verify that the C Programming Learning Management System can handle at least 50 concurrent students. Regular load testing should be performed, especially after major updates, to ensure the application continues to meet performance requirements.
|
||||||
|
|
@ -0,0 +1,145 @@
|
||||||
|
"""
|
||||||
|
Load testing script for C Programming Learning Management System
|
||||||
|
Using Locust to simulate 50+ concurrent students accessing the application
|
||||||
|
"""
|
||||||
|
|
||||||
|
from locust import HttpUser, TaskSet, task, between
|
||||||
|
import random
|
||||||
|
import json
|
||||||
|
|
||||||
|
|
||||||
|
class StudentBehavior(TaskSet):
|
||||||
|
"""
|
||||||
|
Define the behavior of a student using the LMS
|
||||||
|
"""
|
||||||
|
|
||||||
|
def on_start(self):
|
||||||
|
"""Initialize the user session - potentially with a valid token"""
|
||||||
|
self.token = None
|
||||||
|
self.student_name = None
|
||||||
|
self.current_lesson = None
|
||||||
|
self.lessons = []
|
||||||
|
|
||||||
|
# Get available lessons
|
||||||
|
response = self.client.get("/")
|
||||||
|
if response.status_code == 200:
|
||||||
|
# In a real scenario, we would parse the response to get lesson names
|
||||||
|
# For now, we'll use a predefined list of possible lessons
|
||||||
|
self.lessons = [
|
||||||
|
"variables.md", "loops.md", "functions.md",
|
||||||
|
"arrays.md", "pointers.md", "structures.md"
|
||||||
|
]
|
||||||
|
|
||||||
|
@task(3)
|
||||||
|
def view_homepage(self):
|
||||||
|
"""View the main page with all lessons"""
|
||||||
|
self.client.get("/")
|
||||||
|
|
||||||
|
@task(4)
|
||||||
|
def view_lesson(self):
|
||||||
|
"""View a random lesson page"""
|
||||||
|
if self.lessons:
|
||||||
|
lesson = random.choice(self.lessons)
|
||||||
|
self.client.get(f"/lesson/{lesson}")
|
||||||
|
|
||||||
|
@task(2)
|
||||||
|
def compile_code(self):
|
||||||
|
"""Submit code for compilation (simulating exercise completion)"""
|
||||||
|
sample_codes = [
|
||||||
|
'''#include <stdio.h>
|
||||||
|
int main() {
|
||||||
|
printf("Hello, World!\\n");
|
||||||
|
return 0;
|
||||||
|
}''',
|
||||||
|
'''#include <stdio.h>
|
||||||
|
int main() {
|
||||||
|
int a = 5, b = 10;
|
||||||
|
printf("Sum: %d\\n", a + b);
|
||||||
|
return 0;
|
||||||
|
}''',
|
||||||
|
'''#include <stdio.h>
|
||||||
|
int main() {
|
||||||
|
for(int i = 0; i < 5; i++) {
|
||||||
|
printf("Count: %d\\n", i);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}'''
|
||||||
|
]
|
||||||
|
|
||||||
|
code = random.choice(sample_codes)
|
||||||
|
|
||||||
|
response = self.client.post(
|
||||||
|
"/compile",
|
||||||
|
json={"code": code},
|
||||||
|
headers={"Content-Type": "application/json"}
|
||||||
|
)
|
||||||
|
|
||||||
|
@task(1)
|
||||||
|
def login(self):
|
||||||
|
"""Attempt to log in with a token"""
|
||||||
|
# Using a random token for testing - in a real scenario,
|
||||||
|
# we would use valid tokens from a pool
|
||||||
|
tokens_pool = [
|
||||||
|
"STUDENT001", "STUDENT002", "STUDENT003", "STUDENT004", "STUDENT005",
|
||||||
|
"STUDENT006", "STUDENT007", "STUDENT008", "STUDENT009", "STUDENT010"
|
||||||
|
]
|
||||||
|
|
||||||
|
token = random.choice(tokens_pool)
|
||||||
|
|
||||||
|
response = self.client.post(
|
||||||
|
"/login",
|
||||||
|
json={"token": token},
|
||||||
|
headers={"Content-Type": "application/json"}
|
||||||
|
)
|
||||||
|
|
||||||
|
if response.status_code == 200:
|
||||||
|
try:
|
||||||
|
data = response.json()
|
||||||
|
if data.get("success"):
|
||||||
|
self.token = token
|
||||||
|
self.student_name = data.get("student_name")
|
||||||
|
except json.JSONDecodeError:
|
||||||
|
pass # Handle non-JSON responses
|
||||||
|
|
||||||
|
@task(1)
|
||||||
|
def validate_token(self):
|
||||||
|
"""Validate a token"""
|
||||||
|
tokens_pool = [
|
||||||
|
"STUDENT001", "STUDENT002", "STUDENT003", "STUDENT004", "STUDENT005",
|
||||||
|
"STUDENT006", "STUDENT007", "STUDENT008", "STUDENT009", "STUDENT010"
|
||||||
|
]
|
||||||
|
|
||||||
|
token = random.choice(tokens_pool)
|
||||||
|
|
||||||
|
response = self.client.post(
|
||||||
|
"/validate-token",
|
||||||
|
json={"token": token},
|
||||||
|
headers={"Content-Type": "application/json"}
|
||||||
|
)
|
||||||
|
|
||||||
|
@task(1)
|
||||||
|
def track_progress(self):
|
||||||
|
"""Track progress for a lesson (only if logged in)"""
|
||||||
|
if self.token and self.lessons:
|
||||||
|
lesson_name = random.choice(self.lessons).replace('.md', '')
|
||||||
|
|
||||||
|
response = self.client.post(
|
||||||
|
"/track-progress",
|
||||||
|
json={
|
||||||
|
"token": self.token,
|
||||||
|
"lesson_name": lesson_name,
|
||||||
|
"status": "completed"
|
||||||
|
},
|
||||||
|
headers={"Content-Type": "application/json"}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class WebsiteUser(HttpUser):
|
||||||
|
"""
|
||||||
|
Main user class for the load test
|
||||||
|
"""
|
||||||
|
tasks = [StudentBehavior]
|
||||||
|
wait_time = between(1, 5) # Wait between 1-5 seconds between requests
|
||||||
|
|
||||||
|
# Host where the application is running
|
||||||
|
host = "http://localhost:5000"
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
locust==2.24.1
|
||||||
Loading…
Reference in New Issue