"""Locust load profile for the LegacyHUB hybrid search API. Run: pip install locust locust -f scripts/locustfile_search.py \ --host http://localhost:8000 \ --users 50 --spawn-rate 5 --run-time 5m Or headless with HTML report: locust -f scripts/locustfile_search.py --host http://localhost:8000 \ --headless --users 100 --spawn-rate 10 --run-time 10m \ --html load_search.html """ from __future__ import annotations import random from locust import HttpUser, between, task QUERIES = [ "ГОСТ 21.501-93 рабочие чертежи", "класс бетона B25", "регламент технического обслуживания", "контроль качества сварных соединений", "схема электропитания корпус 3", "журнал ремонтов узлов", "правила производства земляных работ", "акты приемки скрытых работ", "fundament concrete grade", "maintenance schedule appendix", ] MODES = ["hybrid", "hybrid", "hybrid", "lexical", "semantic"] class SearchUser(HttpUser): wait_time = between(0.5, 2.5) api_prefix = "/api/v1" @task(8) def hybrid_search(self): body = { "query": random.choice(QUERIES), "limit": random.choice([5, 10, 20]), "filters": { "document_id": None, "source_path": None, "block_type": None, "min_ocr_confidence": None, }, "search_mode": random.choice(MODES), } with self.client.post( f"{self.api_prefix}/search", json=body, name="POST /search", catch_response=True, ) as res: if res.status_code != 200: res.failure(f"HTTP {res.status_code}: {res.text[:120]}") return data = res.json() if not data.get("results"): res.failure("empty results") @task(1) def health(self): self.client.get(f"{self.api_prefix}/health", name="GET /health")