mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-13 23:11:40 +00:00
test: assert rendered log messages where call sites now log lazily
This commit is contained in:
parent
b248f7b39d
commit
0ff2152d9a
9 changed files with 44 additions and 25 deletions
|
|
@ -554,7 +554,7 @@ class TestMCPClientResolvedAuth:
|
|||
|
||||
def _all_logged_messages(mock_logger):
|
||||
return " ".join(
|
||||
str(call.args[0])
|
||||
str(call.args[0]) % tuple(call.args[1:]) if len(call.args) > 1 else str(call.args[0])
|
||||
for level in ("info", "debug", "warning", "error", "exception")
|
||||
for call in getattr(mock_logger, level).call_args_list
|
||||
if call.args
|
||||
|
|
|
|||
|
|
@ -268,8 +268,9 @@ class TestParseBoolEnv:
|
|||
assert mock_warn.call_count == 2
|
||||
# Warning should mention the variable name and the raw value
|
||||
for call in mock_warn.call_args_list:
|
||||
assert "MY_VAR" in call.args[0]
|
||||
assert repr(raw) in call.args[0]
|
||||
rendered = call.args[0] % call.args[1:]
|
||||
assert "MY_VAR" in rendered
|
||||
assert repr(raw) in rendered
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -339,7 +339,8 @@ async def test_anthropic_cache_control_hook_out_of_bounds_logging():
|
|||
|
||||
# Verify that warning was called with the expected message
|
||||
mock_logger.warning.assert_called_once()
|
||||
warning_call = mock_logger.warning.call_args[0][0]
|
||||
warning_args = mock_logger.warning.call_args[0]
|
||||
warning_call = warning_args[0] % warning_args[1:]
|
||||
|
||||
# Check that the warning message contains the expected information
|
||||
assert "AnthropicCacheControlHook: Provided index 10 is out of bounds" in warning_call
|
||||
|
|
@ -405,7 +406,8 @@ async def test_anthropic_cache_control_hook_negative_out_of_bounds_logging():
|
|||
|
||||
# Verify that warning was called with the expected message
|
||||
mock_logger.warning.assert_called_once()
|
||||
warning_call = mock_logger.warning.call_args[0][0]
|
||||
warning_args = mock_logger.warning.call_args[0]
|
||||
warning_call = warning_args[0] % warning_args[1:]
|
||||
|
||||
# Check that the warning message contains the original negative index
|
||||
assert "AnthropicCacheControlHook: Provided index -5 is out of bounds" in warning_call
|
||||
|
|
|
|||
|
|
@ -1430,7 +1430,7 @@ def test_token_provider_returns_non_string(setup_mocks):
|
|||
|
||||
# Verify the error was logged
|
||||
setup_mocks["logger"].error.assert_any_call(
|
||||
"Azure AD token provider returned non-string value: <class 'int'>"
|
||||
"Azure AD token provider returned non-string value: %s", int
|
||||
)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1106,12 +1106,12 @@ async def test_get_tools_from_mcp_servers_continues_when_one_server_fails():
|
|||
assert result.outcomes["failing"].tag == "internal"
|
||||
|
||||
# Verify failure logging
|
||||
mock_logger.exception.assert_any_call(
|
||||
"Error getting tools from server failing_server: Server connection failed"
|
||||
)
|
||||
rendered_exceptions = [c.args[0] % c.args[1:] for c in mock_logger.exception.call_args_list]
|
||||
assert "Error getting tools from server failing_server: Server connection failed" in rendered_exceptions
|
||||
|
||||
# Verify success logging
|
||||
mock_logger.info.assert_any_call("Successfully fetched 1 tools total from all MCP servers")
|
||||
rendered_infos = [c.args[0] % c.args[1:] for c in mock_logger.info.call_args_list]
|
||||
assert "Successfully fetched 1 tools total from all MCP servers" in rendered_infos
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
|
|
@ -1201,15 +1201,13 @@ async def test_get_tools_from_mcp_servers_handles_all_servers_failing():
|
|||
assert result.outcomes["failing2"].tag == "internal"
|
||||
|
||||
# Verify failure logging for both servers
|
||||
mock_logger.exception.assert_any_call(
|
||||
"Error getting tools from server failing_server1: Server failing_server1 connection failed"
|
||||
)
|
||||
mock_logger.exception.assert_any_call(
|
||||
"Error getting tools from server failing_server2: Server failing_server2 connection failed"
|
||||
)
|
||||
rendered_exceptions = [c.args[0] % c.args[1:] for c in mock_logger.exception.call_args_list]
|
||||
assert "Error getting tools from server failing_server1: Server failing_server1 connection failed" in rendered_exceptions
|
||||
assert "Error getting tools from server failing_server2: Server failing_server2 connection failed" in rendered_exceptions
|
||||
|
||||
# Verify total logging
|
||||
mock_logger.info.assert_any_call("Successfully fetched 0 tools total from all MCP servers")
|
||||
rendered_infos = [c.args[0] % c.args[1:] for c in mock_logger.info.call_args_list]
|
||||
assert "Successfully fetched 0 tools total from all MCP servers" in rendered_infos
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
|
|
|
|||
|
|
@ -2048,9 +2048,17 @@ class TestCallToolRestAPI:
|
|||
assert exc_info.value.headers.get("www-authenticate") == challenge
|
||||
# The expected caller-must-reauth signal is logged once, at info, and never at error, so
|
||||
# error-rate alerts do not fire on normal pass-through re-authentication.
|
||||
error_messages = [str(c.args[0]) for c in mock_logger.error.call_args_list if c.args]
|
||||
error_messages = [
|
||||
str(c.args[0]) % c.args[1:] if len(c.args) > 1 else str(c.args[0])
|
||||
for c in mock_logger.error.call_args_list
|
||||
if c.args
|
||||
]
|
||||
assert not any("MCP tool call" in m for m in error_messages)
|
||||
info_messages = [str(c.args[0]) for c in mock_logger.info.call_args_list if c.args]
|
||||
info_messages = [
|
||||
str(c.args[0]) % c.args[1:] if len(c.args) > 1 else str(c.args[0])
|
||||
for c in mock_logger.info.call_args_list
|
||||
if c.args
|
||||
]
|
||||
assert sum(str(upstream_status) in m for m in info_messages) == 1
|
||||
|
||||
async def test_local_permission_denial_keeps_error_level_logging(self, monkeypatch):
|
||||
|
|
@ -2112,9 +2120,17 @@ class TestCallToolRestAPI:
|
|||
await rest_endpoints.call_tool_rest_api(request, user_api_key_dict=UserAPIKeyAuth())
|
||||
|
||||
assert exc_info.value.status_code == 403
|
||||
error_messages = [str(c.args[0]) for c in mock_logger.error.call_args_list if c.args]
|
||||
error_messages = [
|
||||
str(c.args[0]) % c.args[1:] if len(c.args) > 1 else str(c.args[0])
|
||||
for c in mock_logger.error.call_args_list
|
||||
if c.args
|
||||
]
|
||||
assert any("HTTPException in MCP tool call" in m for m in error_messages)
|
||||
info_messages = [str(c.args[0]) for c in mock_logger.info.call_args_list if c.args]
|
||||
info_messages = [
|
||||
str(c.args[0]) % c.args[1:] if len(c.args) > 1 else str(c.args[0])
|
||||
for c in mock_logger.info.call_args_list
|
||||
if c.args
|
||||
]
|
||||
assert not any("relaying upstream" in m for m in info_messages)
|
||||
|
||||
async def test_success_logging_cancellation_propagates(self, monkeypatch):
|
||||
|
|
|
|||
|
|
@ -1167,7 +1167,8 @@ def test_log_budget_lookup_failure_dry_run():
|
|||
err = Exception("column 'policies' does not exist in prisma schema")
|
||||
_log_budget_lookup_failure("user", err)
|
||||
mock_logger.error.assert_called_once()
|
||||
call_msg = mock_logger.error.call_args[0][0]
|
||||
error_args = mock_logger.error.call_args[0]
|
||||
call_msg = error_args[0] % error_args[1:]
|
||||
assert "user" in call_msg
|
||||
assert "cache will not be populated" in call_msg
|
||||
assert "policies" in call_msg or "prisma" in call_msg
|
||||
|
|
|
|||
|
|
@ -150,7 +150,7 @@ def test_invalid_fallback_type_returns_empty_list():
|
|||
)
|
||||
|
||||
assert result == []
|
||||
mock_logger.warning.assert_called_once_with("Unknown fallback_type: invalid")
|
||||
mock_logger.warning.assert_called_once_with("Unknown fallback_type: %s", "invalid")
|
||||
|
||||
|
||||
def test_exception_handling_returns_empty_list():
|
||||
|
|
@ -171,7 +171,8 @@ def test_exception_handling_returns_empty_list():
|
|||
|
||||
assert result == []
|
||||
mock_logger.error.assert_called_once()
|
||||
error_call_args = mock_logger.error.call_args[0][0]
|
||||
error_args = mock_logger.error.call_args[0]
|
||||
error_call_args = error_args[0] % error_args[1:]
|
||||
assert (
|
||||
"Error getting fallbacks for model claude-4-sonnet" in error_call_args
|
||||
)
|
||||
|
|
|
|||
|
|
@ -984,7 +984,7 @@ async def test_add_team_member_budget_table_exception_handling():
|
|||
|
||||
# Verify the error was logged
|
||||
mock_logger.info.assert_called_once_with(
|
||||
"Team member budget table not found, passed team_member_budget_id=nonexistent-budget-456"
|
||||
"Team member budget table not found, passed team_member_budget_id=%s", "nonexistent-budget-456"
|
||||
)
|
||||
|
||||
# Verify database call was attempted
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue