mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-09 03:18:44 +00:00
test(health_check): cover probe tool-strip under tests/test_litellm
tests/litellm_utils_tests is not run by make test-unit or the codecov job, so the regression added there reported 0% patch coverage. Moved it to tests/test_litellm/proxy/test_health_check_max_tokens.py, the unit suite where _update_litellm_params_for_health_check is already exercised, and reverted the litellm_utils copy
This commit is contained in:
parent
6483335df0
commit
fe09af7ccf
2 changed files with 52 additions and 56 deletions
|
|
@ -447,62 +447,6 @@ def test_update_litellm_params_for_health_check():
|
|||
)
|
||||
|
||||
|
||||
def test_health_check_strips_tool_config_from_probe():
|
||||
"""
|
||||
Regression for #31008: health probes must not carry tool configuration.
|
||||
|
||||
OpenRouter server tools configured via `extra_body.tools` (e.g.
|
||||
`openrouter:web_search`) made the trivial probe 500. `tools`/`tool_choice`
|
||||
are stripped from both the top level and `extra_body`, while other
|
||||
`extra_body` fields (e.g. provider routing) are preserved, and the caller's
|
||||
params are never mutated.
|
||||
"""
|
||||
from litellm.proxy.health_check import _update_litellm_params_for_health_check
|
||||
|
||||
extra_body = {
|
||||
"tools": [{"type": "openrouter:web_search"}],
|
||||
"tool_choice": "auto",
|
||||
"provider": {"order": ["OpenAI"]},
|
||||
}
|
||||
litellm_params = {
|
||||
"model": "openrouter/openai/gpt-4o-mini",
|
||||
"api_key": "fake_key",
|
||||
"tools": [{"type": "function", "function": {"name": "f"}}],
|
||||
"tool_choice": "auto",
|
||||
"extra_body": extra_body,
|
||||
}
|
||||
|
||||
updated = _update_litellm_params_for_health_check({}, litellm_params)
|
||||
|
||||
# probe is stripped of all tool config, top-level and nested
|
||||
assert "tools" not in updated and "tool_choice" not in updated
|
||||
assert "tools" not in updated["extra_body"]
|
||||
assert "tool_choice" not in updated["extra_body"]
|
||||
assert updated["extra_body"]["provider"] == {"order": ["OpenAI"]}
|
||||
assert isinstance(updated["messages"], list)
|
||||
|
||||
# caller's params are not mutated: a fresh object, no probe fields leaked in,
|
||||
# tool config intact both top-level and nested
|
||||
assert updated is not litellm_params
|
||||
assert "messages" not in litellm_params
|
||||
assert "tools" in litellm_params and "tool_choice" in litellm_params
|
||||
assert extra_body["tools"] == [{"type": "openrouter:web_search"}]
|
||||
assert extra_body["tool_choice"] == "auto"
|
||||
assert updated["extra_body"] is not extra_body
|
||||
|
||||
|
||||
def test_health_check_probe_without_extra_body_does_not_crash():
|
||||
"""A deployment with no `extra_body` must still build a valid probe."""
|
||||
from litellm.proxy.health_check import _update_litellm_params_for_health_check
|
||||
|
||||
updated = _update_litellm_params_for_health_check(
|
||||
{}, {"model": "openai/gpt-4o-mini", "api_key": "fake_key"}
|
||||
)
|
||||
|
||||
assert "extra_body" not in updated
|
||||
assert isinstance(updated["messages"], list)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_perform_health_check_filters_by_model_id():
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -516,3 +516,55 @@ def test_autodetected_embedding_skips_reasoning_effort():
|
|||
|
||||
assert "reasoning_effort" not in updated
|
||||
assert "max_tokens" not in updated
|
||||
|
||||
|
||||
def test_health_check_strips_tool_config_from_probe():
|
||||
"""
|
||||
Regression for #31008: health probes must not carry tool configuration.
|
||||
|
||||
OpenRouter server tools configured via `extra_body.tools` (e.g.
|
||||
`openrouter:web_search`) made the trivial probe 500. `tools`/`tool_choice`
|
||||
are stripped from both the top level and `extra_body`, while other
|
||||
`extra_body` fields (e.g. provider routing) are preserved, and the caller's
|
||||
params are never mutated.
|
||||
"""
|
||||
extra_body = {
|
||||
"tools": [{"type": "openrouter:web_search"}],
|
||||
"tool_choice": "auto",
|
||||
"provider": {"order": ["OpenAI"]},
|
||||
}
|
||||
litellm_params = {
|
||||
"model": "openrouter/openai/gpt-4o-mini",
|
||||
"api_key": "fake_key",
|
||||
"tools": [{"type": "function", "function": {"name": "f"}}],
|
||||
"tool_choice": "auto",
|
||||
"extra_body": extra_body,
|
||||
}
|
||||
|
||||
updated = _update_litellm_params_for_health_check({}, litellm_params)
|
||||
|
||||
# probe is stripped of all tool config, top-level and nested
|
||||
assert "tools" not in updated and "tool_choice" not in updated
|
||||
assert "tools" not in updated["extra_body"]
|
||||
assert "tool_choice" not in updated["extra_body"]
|
||||
assert updated["extra_body"]["provider"] == {"order": ["OpenAI"]}
|
||||
assert isinstance(updated["messages"], list)
|
||||
|
||||
# caller's params are not mutated: a fresh object, no probe fields leaked in,
|
||||
# tool config intact both top-level and nested
|
||||
assert updated is not litellm_params
|
||||
assert "messages" not in litellm_params
|
||||
assert "tools" in litellm_params and "tool_choice" in litellm_params
|
||||
assert extra_body["tools"] == [{"type": "openrouter:web_search"}]
|
||||
assert extra_body["tool_choice"] == "auto"
|
||||
assert updated["extra_body"] is not extra_body
|
||||
|
||||
|
||||
def test_health_check_probe_without_extra_body_does_not_crash():
|
||||
"""A deployment with no `extra_body` must still build a valid probe."""
|
||||
updated = _update_litellm_params_for_health_check(
|
||||
{}, {"model": "openai/gpt-4o-mini", "api_key": "fake_key"}
|
||||
)
|
||||
|
||||
assert "extra_body" not in updated
|
||||
assert isinstance(updated["messages"], list)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue