From 0ff2152d9aebb0851cd9e66f0fd207b85f81fc14 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 4 Aug 2026 01:09:59 +0000 Subject: [PATCH] test: assert rendered log messages where call sites now log lazily --- .../test_mcp_client.py | 2 +- .../integrations/newrelic/test_newrelic.py | 5 ++-- .../test_anthropic_cache_control_hook.py | 6 +++-- .../llms/azure/test_azure_common_utils.py | 2 +- .../mcp_server/test_mcp_server.py | 20 +++++++--------- .../mcp_server/test_rest_endpoints.py | 24 +++++++++++++++---- .../proxy/auth/test_auth_checks.py | 3 ++- .../proxy/auth/test_model_checks_fallbacks.py | 5 ++-- .../test_team_endpoints.py | 2 +- 9 files changed, 44 insertions(+), 25 deletions(-) diff --git a/tests/test_litellm/experimental_mcp_client/test_mcp_client.py b/tests/test_litellm/experimental_mcp_client/test_mcp_client.py index c97856598f1..15b1e27d058 100644 --- a/tests/test_litellm/experimental_mcp_client/test_mcp_client.py +++ b/tests/test_litellm/experimental_mcp_client/test_mcp_client.py @@ -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 diff --git a/tests/test_litellm/integrations/newrelic/test_newrelic.py b/tests/test_litellm/integrations/newrelic/test_newrelic.py index 541b271cb77..52836020411 100644 --- a/tests/test_litellm/integrations/newrelic/test_newrelic.py +++ b/tests/test_litellm/integrations/newrelic/test_newrelic.py @@ -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 # --------------------------------------------------------------------------- diff --git a/tests/test_litellm/integrations/test_anthropic_cache_control_hook.py b/tests/test_litellm/integrations/test_anthropic_cache_control_hook.py index d94f0d5f47e..88d14940b74 100644 --- a/tests/test_litellm/integrations/test_anthropic_cache_control_hook.py +++ b/tests/test_litellm/integrations/test_anthropic_cache_control_hook.py @@ -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 diff --git a/tests/test_litellm/llms/azure/test_azure_common_utils.py b/tests/test_litellm/llms/azure/test_azure_common_utils.py index c5d4bd044cc..85db11fdb24 100644 --- a/tests/test_litellm/llms/azure/test_azure_common_utils.py +++ b/tests/test_litellm/llms/azure/test_azure_common_utils.py @@ -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: " + "Azure AD token provider returned non-string value: %s", int ) diff --git a/tests/test_litellm/proxy/_experimental/mcp_server/test_mcp_server.py b/tests/test_litellm/proxy/_experimental/mcp_server/test_mcp_server.py index 3a84428add1..44ca32fd4f8 100644 --- a/tests/test_litellm/proxy/_experimental/mcp_server/test_mcp_server.py +++ b/tests/test_litellm/proxy/_experimental/mcp_server/test_mcp_server.py @@ -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 diff --git a/tests/test_litellm/proxy/_experimental/mcp_server/test_rest_endpoints.py b/tests/test_litellm/proxy/_experimental/mcp_server/test_rest_endpoints.py index 329b6d5c45d..2ce02a2a179 100644 --- a/tests/test_litellm/proxy/_experimental/mcp_server/test_rest_endpoints.py +++ b/tests/test_litellm/proxy/_experimental/mcp_server/test_rest_endpoints.py @@ -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): diff --git a/tests/test_litellm/proxy/auth/test_auth_checks.py b/tests/test_litellm/proxy/auth/test_auth_checks.py index f5aa695cb78..822a6d83f64 100644 --- a/tests/test_litellm/proxy/auth/test_auth_checks.py +++ b/tests/test_litellm/proxy/auth/test_auth_checks.py @@ -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 diff --git a/tests/test_litellm/proxy/auth/test_model_checks_fallbacks.py b/tests/test_litellm/proxy/auth/test_model_checks_fallbacks.py index f3bd1742827..526e401b975 100644 --- a/tests/test_litellm/proxy/auth/test_model_checks_fallbacks.py +++ b/tests/test_litellm/proxy/auth/test_model_checks_fallbacks.py @@ -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 ) diff --git a/tests/test_litellm/proxy/management_endpoints/test_team_endpoints.py b/tests/test_litellm/proxy/management_endpoints/test_team_endpoints.py index 0de2c1ac71d..8cc6e2a6767 100644 --- a/tests/test_litellm/proxy/management_endpoints/test_team_endpoints.py +++ b/tests/test_litellm/proxy/management_endpoints/test_team_endpoints.py @@ -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