feat(load-test): replace k6 with locust for ongoing continuous testing and web GUI

This commit is contained in:
2026-09-22 17:20:04 +03:30
parent 98fa1f6441
commit 081abdeb11
6 changed files with 191 additions and 139 deletions

72
scripts/locustfile.py Normal file
View File

@@ -0,0 +1,72 @@
import os
import random
import time
import uuid
from locust import FastHttpUser, task, between, events
# Configuration defaults with environment variable overrides
MIN_WAIT = float(os.getenv("LOCUST_MIN_WAIT", "0.001"))
MAX_WAIT = float(os.getenv("LOCUST_MAX_WAIT", "0.010"))
TREAT_429_AS_SUCCESS = os.getenv("TREAT_429_AS_SUCCESS", "false").lower() in ("true", "1", "yes")
# Valid Radio Access Types supported by the pipeline validation layer
VALID_RATS = [1, 6, 9]
# Service types
SERVICE_TYPES = ["4G_DATA", "5G_DATA", "VOICE", "SMS"]
class CDRLoadUser(FastHttpUser):
"""
High-performance Locust user for generating and ingesting Telecom CDR records.
Uses FastHttpUser (geventhttpclient) for maximum throughput with minimal CPU overhead.
Runs continuously until manually stopped in the Web GUI or terminal.
"""
# Low wait time between iterations to maintain continuous traffic flow
wait_time = between(MIN_WAIT, MAX_WAIT)
@task
def ingest_cdr(self) -> None:
"""
Generates a valid CDR payload and posts it to the raw CDR ingestion endpoint.
"""
now = int(time.time())
raw_id = f"locust-{uuid.uuid4().hex}"
payload = {
"raw_id": raw_id,
"src_ip": "10.240.12.1",
"device_id": "310410998877665",
"caller_num": "+14155552671",
"svc": random.choice(SERVICE_TYPES),
"up_bytes": random.randint(512, 8192),
"down_bytes": random.randint(1024, 32768),
"rat": random.choice(VALID_RATS),
"lac": "4021",
"ci": "8812",
"epoch_start": now,
"epoch_end": now + 300,
}
with self.client.post(
"/api/v1/cdr/raw",
json=payload,
name="/api/v1/cdr/raw",
catch_response=True,
) as response:
if response.status_code == 202:
response.success()
elif response.status_code == 429:
# 429 indicates bounded queue saturation (graceful backpressure)
if TREAT_429_AS_SUCCESS:
response.success()
else:
response.failure("429 Too Many Requests (Queue Backpressure)")
elif response.status_code == 503:
response.failure("503 Service Unavailable (Kafka Broker Failure)")
elif response.status_code == 400:
response.failure(f"400 Bad Request: {response.text}")
else:
response.failure(f"Unexpected HTTP {response.status_code}: {response.text}")