feat(load-test): replace k6 with locust for ongoing continuous testing and web GUI
This commit is contained in:
72
scripts/locustfile.py
Normal file
72
scripts/locustfile.py
Normal 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}")
|
||||
|
||||
Reference in New Issue
Block a user