Skip to content

Commit f557193

Browse files
authored
add loading test script (#98)
Add loading test script, it uses locust library issue: https://issues.redhat.com/browse/AAP-47222 Signed-off-by: Djebran Lezzoum <[email protected]>
1 parent a80466a commit f557193

File tree

4 files changed

+551
-1
lines changed

4 files changed

+551
-1
lines changed

Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,3 +235,6 @@ all: setup build build-custom
235235
@echo "All build steps completed successfully."
236236
@printf "To run the container, use: $(RED)make run$(NC)\n"
237237
@printf "To tag and push the container to quay.io, use: $(RED)make tag-and-push$(NC)\n"
238+
239+
load-test:
240+
uv run locust -f scripts/loading_test.py -t 120 --users 10 --spawn-rate 10 -H http://localhost:8321

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,5 @@ dependencies = [
2222
dev = [
2323
"cachetools>=6.1.0",
2424
"kubernetes>=33.1.0",
25+
"locust>=2.39.1",
2526
]

scripts/loading_test.py

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import json
2+
from locust import task, constant, FastHttpUser
3+
import time
4+
5+
PROVIDER = "my_rhoai_dev"
6+
MODEL_ID = "granite-3.3-8b-instruct"
7+
8+
prompt = "what is AAP ?"
9+
10+
query_data = dict(
11+
query=prompt,
12+
model=MODEL_ID,
13+
provider=PROVIDER,
14+
)
15+
16+
expected_text = "Ansible Automation Platform"
17+
18+
headers = {"Content-Type": "application/json"}
19+
20+
21+
def get_response_chuncks_text_from_stream(response):
22+
chuncks_text = ""
23+
stream = getattr(response, "stream", None)
24+
if not stream:
25+
raise ValueError("response has no stream attribute")
26+
27+
chuncks_bytes = bytearray()
28+
while True:
29+
try:
30+
chunck = stream.next()
31+
chuncks_bytes += chunck
32+
# wait for data to be ready before reading next
33+
time.sleep(5)
34+
except StopIteration:
35+
stream.release()
36+
break
37+
38+
chuncks_string = chuncks_bytes.decode("utf-8")
39+
for http_chunk in chuncks_string.split("\n"):
40+
if http_chunk:
41+
if http_chunk.startswith("data: "):
42+
chuck_data = json.loads(http_chunk.strip("data: "))
43+
if chuck_data.get("event", "") == "token":
44+
token = chuck_data.get("data", {}).get("token", "")
45+
chuncks_text += token
46+
47+
return chuncks_text
48+
49+
50+
class ChatTesting(FastHttpUser):
51+
wait_time = constant(30)
52+
53+
@task
54+
def chat(self):
55+
with self.client.post(
56+
"/v1/streaming_query",
57+
data=json.dumps(query_data),
58+
headers=headers,
59+
stream=True,
60+
catch_response=True,
61+
) as response:
62+
response.raise_for_status()
63+
text = get_response_chuncks_text_from_stream(response)
64+
if expected_text not in text:
65+
response.failure(
66+
f"expected '{expected_text}' not in response text '{text}'"
67+
)
68+
else:
69+
response.success()
70+
71+
72+
# command line
73+
# uv run locust -f scripts/loading_test.py -t 120 --headless --users 10 --spawn-rate 10 -H http://localhost:8321
74+
75+
# web
76+
# uv run locust -f scripts/loading_test.py -t 120 --users 10 --spawn-rate 10 -H http://localhost:8321

0 commit comments

Comments
 (0)