test: fix stale and state-leaking tests red on scheduled CircleCI (#43266)

test_update_config_success_callback_normalization replaced
proxy_server.proxy_logging_obj with a MagicMock and never restored it.
Since the proxy unit tests joined tests/unit (#42903), 14 JWT mapping,
end-user and MCP tests on the same xdist worker awaited that mock and
failed. The test now uses monkeypatch.

test_prometheus_logging_callbacks set verbose_logger to DEBUG and
litellm.set_verbose at import, so every worker in the unit job ran with
DEBUG on. That broke caplog equality in the JEV classifier test, the
vertex streaming memory ratio, and four event-loop lag checks. The
module-level setup is removed; nothing in the file depended on it.

#43081 removed the OCR harness modules but left them in the
importability parametrize list.

test_get_model_info_bedrock_region reassigned litellm.model_cost and set
LITELLM_LOCAL_MODEL_COST_MAP without restoring either, and never cleared
the get_model_info caches, so it failed whenever an earlier test had
looked up the regional model. It now uses monkeypatch and invalidates
the caches; the local_testing isolation fixture also invalidates them
after restoring model_cost.

The Windows job hit CircleCI's 10 minute no-output limit while cargo
compiles the Rust crates inside uv sync and uv build. Those two steps now
allow 30 minutes of silence.
This commit is contained in:
yuneng-jiang 2026-09-25 19:10:20 -07:00 • committed by GitHub
parent 1a58162630
commit 7fc2206171
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 17 additions and 20 deletions

View file

@ -323,6 +323,7 @@ jobs:
CHOCOLATEY_CONFIRM_ALL: "true"
- run:
name: Install Dependencies
no_output_timeout: 30m
environment:
UV_HTTP_TIMEOUT: "300"
command: |
@ -381,6 +382,7 @@ jobs:
uv run --no-sync python -m pytest tests/windows_tests/ -v
- run:
name: Guard against MAX_PATH-busting packaged wheel paths
no_output_timeout: 30m
environment:
UV_HTTP_TIMEOUT: "300"
command: |

View file

@ -19,6 +19,7 @@ import pytest
import litellm
from litellm.litellm_core_utils.logging_worker import GLOBAL_LOGGING_WORKER
from litellm.utils import _invalidate_model_cost_lowercase_map
# ``litellm.model_cost`` is loaded at import time from the URL pinned to ``main``
# (``LITELLM_MODEL_COST_MAP_URL``). The in-tree backup ships with this branch
@ -232,6 +233,7 @@ def isolate_litellm_state():
for attr, original_value in original_state.items():
if hasattr(litellm, attr):
setattr(litellm, attr, original_value)
_invalidate_model_cost_lowercase_map()
@pytest.fixture(scope="module", autouse=True)

View file

@ -9,6 +9,7 @@ import pytest
import litellm
from litellm import get_model_info
from litellm.utils import _invalidate_model_cost_lowercase_map
from unittest.mock import MagicMock, patch
@ -74,15 +75,15 @@ def test_get_model_info_ollama_chat():
assert mock_client.call_args.kwargs["json"]["name"] == "unknown-model"
def test_get_model_info_bedrock_region():
os.environ["LITELLM_LOCAL_MODEL_COST_MAP"] = "True"
litellm.model_cost = litellm.get_model_cost_map(url="")
args = {
"model": "us.anthropic.claude-haiku-4-5-20251001-v1:0",
"custom_llm_provider": "bedrock",
def test_get_model_info_bedrock_region(monkeypatch):
regional_model = "us.anthropic.claude-haiku-4-5-20251001-v1:0"
monkeypatch.setenv("LITELLM_LOCAL_MODEL_COST_MAP", "True")
model_cost_without_regional_entry = {
key: value for key, value in litellm.get_model_cost_map(url="").items() if key != regional_model
}
litellm.model_cost.pop("us.anthropic.claude-haiku-4-5-20251001-v1:0", None)
info = litellm.get_model_info(**args)
monkeypatch.setattr(litellm, "model_cost", model_cost_without_regional_entry)
_invalidate_model_cost_lowercase_map()
info = litellm.get_model_info(model=regional_model, custom_llm_provider="bedrock")
print("info", info)
assert info["key"] == "anthropic.claude-haiku-4-5-20251001-v1:0"
assert info["litellm_provider"] == "bedrock_converse"

View file

@ -36,8 +36,6 @@ def _case(module: str = "tests.example") -> HarnessCase:
@pytest.mark.parametrize(
"module",
[
"tests.rust-python-harness.strategies.e2e_parity.sdk.ocr.test_sdk_parity",
"tests.rust-python-harness.strategies.trace_parity.sdk.ocr.case",
"tests.rust-python-harness.strategies.trace_parity.sdk.messages.case",
"tests.rust-python-harness.strategies.trace_parity.sdk.chat_completions.case",
"tests.rust-python-harness.strategies.trace_parity.sdk.transcription.case",

View file

@ -1,7 +1,6 @@
import asyncio
import logging
from datetime import datetime, timedelta, timezone
from unittest.mock import MagicMock, call, patch
@ -9,7 +8,6 @@ import pytest
from prometheus_client import REGISTRY
import litellm
from litellm._logging import verbose_logger
from litellm.types.utils import (
StandardLoggingHiddenParams,
StandardLoggingMetadata,
@ -27,10 +25,6 @@ except Exception:
PrometheusLogger = None
from litellm.proxy._types import UserAPIKeyAuth
verbose_logger.setLevel(logging.DEBUG)
litellm.set_verbose = True
@pytest.fixture
def prometheus_logger() -> PrometheusLogger:

View file

@ -2979,7 +2979,7 @@ async def test_get_config_callbacks_environment_variables(client_no_auth):
@pytest.mark.asyncio
async def test_update_config_success_callback_normalization():
async def test_update_config_success_callback_normalization(monkeypatch):
"""
Ensure success_callback values are normalized to lowercase when updating config.
This prevents delete_callback (which searches lowercase) from failing on mixed case inputs like 'SQS'.
@ -2987,7 +2987,7 @@ async def test_update_config_success_callback_normalization():
import litellm.proxy.proxy_server as proxy_server
from litellm.proxy._types import ConfigYAML
setattr(proxy_server, "proxy_logging_obj", MagicMock())
monkeypatch.setattr(proxy_server, "proxy_logging_obj", MagicMock())
existing_litellm_settings = {"success_callback": ["langfuse"]}
@ -3013,7 +3013,7 @@ async def test_update_config_success_callback_normalization():
self.db.litellm_config.find_first = AsyncMock(side_effect=fake_find_first)
self.db.litellm_config.upsert = AsyncMock(side_effect=fake_upsert)
setattr(proxy_server, "prisma_client", MockPrisma())
monkeypatch.setattr(proxy_server, "prisma_client", MockPrisma())
class MockProxyConfig:
async def add_deployment(self, prisma_client=None, proxy_logging_obj=None): # noqa: F811 # pytest fixture, not a redefinition
@ -3022,7 +3022,7 @@ async def test_update_config_success_callback_normalization():
def reject_config_owned_writes(self, *, section_name, changed_keys):
return None
setattr(proxy_server, "proxy_config", MockProxyConfig())
monkeypatch.setattr(proxy_server, "proxy_config", MockProxyConfig())
config_update = ConfigYAML(litellm_settings={"success_callback": ["SQS", "sQs"]})
from litellm.proxy._types import LitellmUserRoles, UserAPIKeyAuth