From 51aaf1768030747fe5cf86c16f23ee2e64ec1a13 Mon Sep 17 00:00:00 2001 From: mayuriphad Date: Wed, 7 Oct 2026 08:44:31 +0530 Subject: [PATCH] test(proxy): cover litellm_proxy wildcard model discovery end to end --- tests/unit/proxy/auth/test_model_checks.py | 54 +++++++++++++++++++--- 1 file changed, 47 insertions(+), 7 deletions(-) diff --git a/tests/unit/proxy/auth/test_model_checks.py b/tests/unit/proxy/auth/test_model_checks.py index 74c872d429f..88c2d9c684a 100644 --- a/tests/unit/proxy/auth/test_model_checks.py +++ b/tests/unit/proxy/auth/test_model_checks.py @@ -968,14 +968,11 @@ def test_get_complete_model_list_sentinel_only_grants_nothing(): def test_get_provider_models_admits_providers_without_a_static_catalog(): - """litellm_proxy and hosted_vllm have no entry in litellm.models_by_provider - (their model list only exists behind the provider's own endpoint), so the - static-dict gate must not reject them before endpoint discovery runs. + """Providers without a static model list are no longer rejected up front. - Regression check only, not a discovery test: with check_provider_endpoint - left at its default (off), get_valid_models never reaches the network and - falls back to models_by_provider.get(provider, []) -- an empty list, not - None. Before the fix, the gate itself returned None for these providers. + With endpoint discovery off, get_valid_models falls back to the (empty) + static list, so the result is [] rather than None. Before the fix this + returned None and the wildcard was never expanded. """ import litellm from litellm.proxy.auth.model_checks import get_provider_models @@ -996,6 +993,49 @@ def test_get_provider_models_admits_providers_without_a_static_catalog(): assert result == [] +def test_get_complete_model_list_discovers_litellm_proxy_wildcard_models(monkeypatch): + """A litellm_proxy/* deployment lists the upstream proxy's models when endpoint discovery is on.""" + import litellm + from litellm import Router + from litellm.llms.openai.chat.gpt_transformation import OpenAIGPTConfig + from litellm.proxy.auth.model_checks import get_complete_model_list + + monkeypatch.setattr(litellm, "check_provider_endpoint", True) + captured = {} + + def fake_get_models(self, api_key=None, api_base=None): + captured["api_key"] = api_key + captured["api_base"] = api_base + return ["gpt-4o", "claude-sonnet"] + + monkeypatch.setattr(OpenAIGPTConfig, "get_models", fake_get_models) + + router = Router( + model_list=[ + { + "model_name": "litellm_proxy/*", + "litellm_params": { + "model": "litellm_proxy/*", + "api_base": "http://upstream:4000", + "api_key": "sk-upstream", + }, + } + ] + ) + result = get_complete_model_list( + key_models=[], + team_models=[], + proxy_model_list=["litellm_proxy/*"], + user_model=None, + infer_model_from_keys=False, + llm_router=router, + ) + + assert captured == {"api_key": "sk-upstream", "api_base": "http://upstream:4000"} + assert "litellm_proxy/gpt-4o" in result + assert "litellm_proxy/claude-sonnet" in result + + def test_get_provider_models_returns_none_for_an_unknown_provider(): from litellm.proxy.auth.model_checks import get_provider_models