Files
2026-07-13 13:17:40 +08:00

106 lines
2.8 KiB
Python

from locust.env import Environment
from locust.stats import stats_printer, stats_history, print_stats
import gevent
from typing import Dict, Any
import logging
from locust.log import setup_logging
from .load_test import LLMUser, events, collect_metrics
from .configs import LoadTestConfig
class LLMLoadTester:
"""
Usage Example:
```python
config = LoadTestConfig(
host="http://localhost:8000",
provider="vllm",
model="meta-llama/Meta-Llama-3.1-8B-Instruct",
api_key="NONE",
prompt_tokens=550,
max_tokens=150,
users=128,
run_time="1m",
summary_file="./vllm.csv"
)
tester = LLMLoadTester(config)
results = tester.run()
```
"""
def __init__(self, config: LoadTestConfig):
self.config = config
def _setup_environment(self) -> Environment:
setup_logging("INFO", None)
# Setup Environment and Runner
env = Environment(
user_classes=[LLMUser],
host=self.config.host,
reset_stats=self.config.reset_stats,
events=events,
)
env.parsed_options = self.config.to_namespace()
return env
def run(self) -> Dict[str, Any]:
try:
# Setup environment
env = self._setup_environment()
env.create_local_runner()
# Log test start
logging.info(f"Starting test with {self.config.users} users")
# Create greenlets for stats
stats_printer_greenlet = gevent.spawn(stats_printer(env.stats))
stats_history_greenlet = gevent.spawn(stats_history, env.runner)
# Start the test
env.runner.start(
user_count=self.config.users,
spawn_rate=self.config.users,
)
# Run for specified duration
gevent.sleep(self._parse_time(self.config.run_time))
# Stop the test
env.runner.quit()
entries = collect_metrics(env)
# Wait for greenlets
env.runner.greenlet.join()
stats_printer_greenlet.kill()
stats_history_greenlet.kill()
# Print final stats
print_stats(env.stats)
return entries
except Exception as e:
logging.error(f"Test failed: {str(e)}")
raise
@staticmethod
def _parse_time(time_str: str) -> int:
"""Convert time string (e.g., '30s', '1m', '1h') to seconds"""
unit = time_str[-1]
value = int(time_str[:-1])
if unit == "s":
return value
elif unit == "m":
return value * 60
elif unit == "h":
return value * 3600
else:
raise ValueError(f"Invalid time unit: {unit}")