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>
This commit is contained in:
devin-ai-integration[bot] 2026-09-22 11:02:42 -07:00 • committed by GitHub
parent ded69f8d03
commit 9e92fadacf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -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"