1- from unittest .mock import MagicMock
1+ import hashlib
2+ from unittest .mock import AsyncMock , MagicMock
23
34import pytest
5+ from aiohttp import web
6+ from fastapi import FastAPI
47
58from vllm_router .service_discovery import StaticServiceDiscovery
69
710
811def test_init_when_static_backend_health_checks_calls_start_health_checks (
12+ mock_app : FastAPI ,
913 monkeypatch : pytest .MonkeyPatch ,
1014) -> None :
1115 start_health_check_mock = MagicMock ()
@@ -14,7 +18,7 @@ def test_init_when_static_backend_health_checks_calls_start_health_checks(
1418 start_health_check_mock ,
1519 )
1620 discovery_instance = StaticServiceDiscovery (
17- None ,
21+ mock_app ,
1822 [],
1923 [],
2024 None ,
@@ -28,6 +32,7 @@ def test_init_when_static_backend_health_checks_calls_start_health_checks(
2832
2933
3034def test_init_when_endpoint_health_check_disabled_does_not_call_start_health_checks (
35+ mock_app : FastAPI ,
3136 monkeypatch : pytest .MonkeyPatch ,
3237) -> None :
3338 start_health_check_mock = MagicMock ()
@@ -36,7 +41,7 @@ def test_init_when_endpoint_health_check_disabled_does_not_call_start_health_che
3641 start_health_check_mock ,
3742 )
3843 discovery_instance = StaticServiceDiscovery (
39- None ,
44+ mock_app ,
4045 [],
4146 [],
4247 None ,
@@ -49,31 +54,39 @@ def test_init_when_endpoint_health_check_disabled_does_not_call_start_health_che
4954 discovery_instance .start_health_check_task .assert_not_called ()
5055
5156
52- def test_get_unhealthy_endpoint_hashes_when_only_healthy_models_exist_does_not_return_unhealthy_endpoint_hashes (
53- monkeypatch : pytest .MonkeyPatch ,
57+ @pytest .mark .asyncio
58+ async def test_get_unhealthy_endpoint_hashes_when_only_healthy_models_exist_does_not_return_unhealthy_endpoint_hashes (
59+ make_mock_engine , mock_app
5460) -> None :
55- monkeypatch .setattr ("vllm_router.utils.is_model_healthy" , lambda * _ : True )
61+ mock_response = AsyncMock (return_value = web .json_response (status = 200 ))
62+ base_url = await make_mock_engine ({"/v1/chat/completions" : mock_response })
63+
5664 discovery_instance = StaticServiceDiscovery (
57- None ,
58- ["http://localhost.com" ],
65+ mock_app ,
66+ [base_url ],
5967 ["llama3" ],
6068 None ,
6169 None ,
6270 ["chat" ],
63- static_backend_health_checks = True ,
71+ static_backend_health_checks = False ,
6472 prefill_model_labels = None ,
6573 decode_model_labels = None ,
6674 )
67- assert discovery_instance .get_unhealthy_endpoint_hashes () == []
75+ assert await discovery_instance .get_unhealthy_endpoint_hashes () == []
6876
6977
70- def test_get_unhealthy_endpoint_hashes_when_unhealthy_model_exist_returns_unhealthy_endpoint_hash (
71- monkeypatch : pytest .MonkeyPatch ,
78+ @pytest .mark .asyncio
79+ async def test_get_unhealthy_endpoint_hashes_when_unhealthy_model_exist_returns_unhealthy_endpoint_hash (
80+ make_mock_engine ,
81+ mock_app ,
7282) -> None :
73- monkeypatch .setattr ("vllm_router.utils.is_model_healthy" , lambda * _ : False )
83+ mock_response = AsyncMock (return_value = web .json_response (status = 500 ))
84+ base_url = await make_mock_engine ({"/v1/chat/completions" : mock_response })
85+ expected_hash = hashlib .md5 (f"{ base_url } llama3" .encode ()).hexdigest ()
86+
7487 discovery_instance = StaticServiceDiscovery (
75- None ,
76- ["http://localhost.com" ],
88+ mock_app ,
89+ [base_url ],
7790 ["llama3" ],
7891 None ,
7992 None ,
@@ -82,23 +95,33 @@ def test_get_unhealthy_endpoint_hashes_when_unhealthy_model_exist_returns_unheal
8295 prefill_model_labels = None ,
8396 decode_model_labels = None ,
8497 )
85- assert discovery_instance .get_unhealthy_endpoint_hashes () == [
86- "ee7d421a744e07595b70f98c11be93e7"
87- ]
98+ assert await discovery_instance .get_unhealthy_endpoint_hashes () == [expected_hash ]
8899
89100
90- def test_get_unhealthy_endpoint_hashes_when_healthy_and_unhealthy_models_exist_returns_only_unhealthy_endpoint_hash (
91- monkeypatch : pytest .MonkeyPatch ,
101+ @pytest .mark .asyncio
102+ async def test_get_unhealthy_endpoint_hashes_when_healthy_and_unhealthy_models_exist_returns_only_unhealthy_endpoint_hash (
103+ make_mock_engine ,
104+ mock_app ,
92105) -> None :
93106 unhealthy_model = "bge-m3"
107+ mock_response = AsyncMock (return_value = web .json_response (status = 500 ))
108+
109+ async def mock_mixed_chat_response (request : web .Request ) -> web .Response :
110+ data = await request .json ()
111+ status = 500 if data .get ("model" ) == unhealthy_model else 200
112+ return web .json_response (status = status )
113+
114+ base_url = await make_mock_engine (
115+ {
116+ "/v1/chat/completions" : mock_mixed_chat_response ,
117+ "/v1/embeddings" : mock_response ,
118+ }
119+ )
120+ expected_hash = hashlib .md5 (f"{ base_url } { unhealthy_model } " .encode ()).hexdigest ()
94121
95- def mock_is_model_healthy (url : str , model : str , model_type : str ) -> bool :
96- return model != unhealthy_model
97-
98- monkeypatch .setattr ("vllm_router.utils.is_model_healthy" , mock_is_model_healthy )
99122 discovery_instance = StaticServiceDiscovery (
100- None ,
101- ["http://localhost.com" , "http://10.123.112.412" ],
123+ mock_app ,
124+ [base_url , base_url ],
102125 ["llama3" , unhealthy_model ],
103126 None ,
104127 None ,
@@ -107,12 +130,11 @@ def mock_is_model_healthy(url: str, model: str, model_type: str) -> bool:
107130 prefill_model_labels = None ,
108131 decode_model_labels = None ,
109132 )
110- assert discovery_instance .get_unhealthy_endpoint_hashes () == [
111- "01e1b07eca36d39acacd55a33272a225"
112- ]
133+ assert await discovery_instance .get_unhealthy_endpoint_hashes () == [expected_hash ]
113134
114135
115136def test_get_endpoint_info_when_model_endpoint_hash_is_in_unhealthy_endpoint_does_not_return_endpoint (
137+ mock_app : FastAPI ,
116138 monkeypatch : pytest .MonkeyPatch ,
117139) -> None :
118140 unhealthy_model = "mistral"
@@ -121,7 +143,7 @@ def mock_get_model_endpoint_hash(url: str, model: str) -> str:
121143 return "some-hash" if model == unhealthy_model else "other-hash"
122144
123145 discovery_instance = StaticServiceDiscovery (
124- None ,
146+ mock_app ,
125147 ["http://localhost.com" , "http://10.123.112.412" ],
126148 ["llama3" , unhealthy_model ],
127149 None ,
0 commit comments