From 9e92fadacf935b7f7712b21f9b3067f46a43813d Mon Sep 17 00:00:00 2001 From: "devin-ai-integration[bot]" <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Tue, 22 Sep 2026 11:02:42 -0700 Subject: [PATCH] test(proxy): give every ui settings endpoint test a fresh settings store (#42430) * test(proxy): give every ui settings endpoint test a fresh settings store Under xdist the module-scoped reload in tests/test_litellm/conftest.py is skipped, so a health endpoint test's lifespan startup leaves proxy_server.general_settings bound to the ProxyConfig singleton's SettingsStore for the rest of the worker. Every /get or /update ui_settings call in test_proxy_setting_endpoints.py then writes into that shared store, and since get_ui_settings merges proxy_config.settings over the stored row, a leaked team_admin_editable_team_fields: [] from the PTU round-trip test beat the mocked DB row in test_get_reports_the_stored_list_and_advertises_supported_fields. An autouse fixture now binds both proxy_config.settings and general_settings to a fresh store for each test in the file, and a regression pair checks a runtime-flag write lands in the store the endpoint reads and does not survive into the next test. * test(proxy): assert ui settings isolation through the endpoints Replace the fixture-structure assertions with a parametrized GET/PATCH round trip on /get/ui_settings and /update/ui_settings that fails whenever one case's PATCH leaks into the next case's GET. --------- Co-authored-by: mateo-berri <277851410+mateo-berri@users.noreply.github.com> --- .../test_proxy_setting_endpoints.py | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/tests/test_litellm/proxy/ui_crud_endpoints/test_proxy_setting_endpoints.py b/tests/test_litellm/proxy/ui_crud_endpoints/test_proxy_setting_endpoints.py index 9ba4975cb19..f40848bc38b 100644 --- a/tests/test_litellm/proxy/ui_crud_endpoints/test_proxy_setting_endpoints.py +++ b/tests/test_litellm/proxy/ui_crud_endpoints/test_proxy_setting_endpoints.py @@ -1,5 +1,6 @@ import json import os +from typing import Final import pytest from fastapi.testclient import TestClient @@ -90,6 +91,16 @@ def mock_auth(): app.dependency_overrides.pop(user_api_key_auth, None) +@pytest.fixture(autouse=True) +def fresh_settings_store(monkeypatch: pytest.MonkeyPatch) -> None: + from litellm.proxy import proxy_server + from litellm.proxy.config_resolvers.settings_store import SettingsStore + + store: Final = SettingsStore("general_settings") + monkeypatch.setattr(proxy_server.proxy_config, "settings", store) + monkeypatch.setattr(proxy_server, "general_settings", store) + + class TestProxySettingEndpoints: def test_get_internal_user_settings(self, mock_proxy_config, mock_auth): """Test getting the internal user settings""" @@ -3881,6 +3892,31 @@ class TestTeamAdminEditableTeamFieldsSetting: assert "tpm_limit" in field_schema["items"]["enum"] assert "projects" in field_schema["items"]["enum"] + @pytest.mark.parametrize(("stored", "patched"), [(["tpm_limit"], []), (["rpm_limit"], ["max_budget"])]) + def test_get_reports_its_own_db_row_whatever_an_earlier_test_patched(self, monkeypatch, stored, patched): + """A booted proxy keeps its runtime settings in one shared store. Each case PATCHes a list into + that store, so whichever case ran second used to read the other's list instead of its own DB row.""" + from unittest.mock import AsyncMock, MagicMock + + from litellm.proxy import proxy_server + + mock_prisma = self._as_proxy_admin(monkeypatch) + mock_db_record = MagicMock() + mock_db_record.ui_settings = {"team_admin_editable_team_fields": stored} + mock_prisma.db.litellm_uisettings.find_unique = AsyncMock(return_value=mock_db_record) + monkeypatch.setattr("litellm.proxy.proxy_server.general_settings", {}) + + try: + fetched = client.get("/get/ui_settings") + proxy_server._bind_general_settings_store(proxy_server.proxy_config.settings) + response = client.patch("/update/ui_settings", json={"team_admin_editable_team_fields": patched}) + finally: + app.dependency_overrides.clear() + + assert fetched.json()["values"]["team_admin_editable_team_fields"] == stored + assert response.status_code == 200 + assert proxy_server.general_settings["team_admin_editable_team_fields"] == patched + class TestSyncUiSettingsToGeneralSettings: """The DB re-read each pod runs on startup and on every config reload.""" @@ -3975,3 +4011,4 @@ class TestSyncUiSettingsToGeneralSettings: assert general_settings["forward_client_headers_to_llm_api"] is False assert general_settings.source("forward_client_headers_to_llm_api") == "config" +