Skip to content

Commit 073df4e

Browse files
lucas-tuckerLucas TuckerYuhanLiu11
authored
[Router][CI/CD and misc.] Add RoundRobinRouter logic testing (#639)
* added basic unit test for RoundRobinRouter route_request logic Signed-off-by: Lucas Tucker <[email protected]> * address gemini concerns Signed-off-by: Lucas Tucker <[email protected]> --------- Signed-off-by: Lucas Tucker <[email protected]> Co-authored-by: Lucas Tucker <[email protected]> Co-authored-by: Yuhan Liu <[email protected]>
1 parent a4de81a commit 073df4e

File tree

1 file changed

+74
-0
lines changed

1 file changed

+74
-0
lines changed

src/tests/test_roundrobin_router.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import random
2+
from typing import Dict, List, Tuple
3+
4+
from vllm_router.routers.routing_logic import RoundRobinRouter
5+
6+
7+
class EndpointInfo:
8+
def __init__(self, url: str):
9+
self.url = url
10+
11+
12+
class RequestStats:
13+
def __init__(self, qps: float):
14+
self.qps = qps
15+
16+
17+
class Request:
18+
def __init__(self, headers: Dict[str, str]):
19+
self.headers = headers
20+
21+
22+
class EngineStats:
23+
def __init__(self):
24+
return
25+
26+
27+
def generate_request_args(
28+
num_endpoints: int, qps_range: int = 0
29+
) -> Tuple[List[EndpointInfo], Dict[str, EngineStats], Dict[str, RequestStats]]:
30+
endpoints = [
31+
EndpointInfo(
32+
url=f"{endpoint_index}",
33+
)
34+
for endpoint_index in range(num_endpoints)
35+
]
36+
engine_stats = {
37+
f"{endpoint_index}": EngineStats() for endpoint_index in range(num_endpoints)
38+
}
39+
request_stats = {
40+
f"{endpoint_index}": RequestStats(qps=random.uniform(0, qps_range))
41+
for endpoint_index in range(num_endpoints)
42+
}
43+
return endpoints, engine_stats, request_stats
44+
45+
46+
def generate_request(request_type="http") -> Request:
47+
return Request({"type": request_type})
48+
49+
50+
def test_roundrobin_logic(
51+
dynamic_discoveries: int = 10, max_endpoints: int = 1000, max_requests: int = 10000
52+
):
53+
"""
54+
Ensure that all active urls have roughly same number of requests (difference at most 1)
55+
"""
56+
router = RoundRobinRouter()
57+
58+
def _fixed_router_check(num_endpoints: int, num_requests: int) -> bool:
59+
# Make num_requests requests to the router and check even output distribution
60+
endpoints, engine_stats, request_stats = generate_request_args(num_endpoints)
61+
output_distribution = {}
62+
for request_idx in range(num_requests):
63+
request = generate_request()
64+
url = router.route_request(endpoints, engine_stats, request_stats, request)
65+
output_distribution[url] = output_distribution.get(url, 0) + 1
66+
request_counts = output_distribution.values()
67+
return max(request_counts) - min(request_counts) <= 1
68+
69+
for _ in range(dynamic_discoveries):
70+
num_endpoints = random.randint(1, max_endpoints)
71+
num_requests = random.randint(1, max_requests)
72+
# Perform router check
73+
res = _fixed_router_check(num_endpoints, num_requests)
74+
assert res

0 commit comments

Comments
 (0)