From c3465b9656451371066da63248487615ede89123 Mon Sep 17 00:00:00 2001 From: pengzh1 Date: Thu, 27 Aug 2026 19:53:07 +0800 Subject: [PATCH] test(proxy): suppress TQ008 for pass-through CRUD global patches MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The CRUD handlers reach their collaborators (config_passthrough_endpoints, get/update_config_general_settings, route registry) through proxy_server module globals imported at call time — there is no injection seam, so each patch carries a test-quality-ok reason per the repo convention. The three error-path tests now share one _db_only_crud_env contextmanager. --- .../test_config_defined_endpoint_crud.py | 58 ++++++++----------- 1 file changed, 23 insertions(+), 35 deletions(-) diff --git a/tests/test_litellm/proxy/pass_through_endpoints/test_config_defined_endpoint_crud.py b/tests/test_litellm/proxy/pass_through_endpoints/test_config_defined_endpoint_crud.py index 30e60007af7..e8e834568ce 100644 --- a/tests/test_litellm/proxy/pass_through_endpoints/test_config_defined_endpoint_crud.py +++ b/tests/test_litellm/proxy/pass_through_endpoints/test_config_defined_endpoint_crud.py @@ -1,17 +1,18 @@ """ -What is this? Regression tests for #38195: config-file-defined pass-through endpoints are merged into the GET list but can never be managed by the DB-backed CRUD handlers. DELETE/UPDATE must return a targeted error pointing the operator back to config.yaml instead of a misleading "not found". """ +from collections.abc import Iterator +from contextlib import contextmanager from unittest.mock import AsyncMock, patch import pytest from fastapi import HTTPException -from litellm.proxy._types import ConfigFieldInfo, UserAPIKeyAuth +from litellm.proxy._types import ConfigFieldInfo, PassThroughGenericEndpoint, UserAPIKeyAuth from litellm.proxy.pass_through_endpoints.pass_through_endpoints import ( delete_pass_through_endpoints, update_pass_through_endpoints, @@ -48,18 +49,27 @@ def _db_getter(): return _get -@pytest.mark.asyncio -async def test_delete_config_defined_endpoint_returns_targeted_error(): +@contextmanager +def _db_only_crud_env() -> Iterator[None]: + """Point the CRUD handlers at a DB copy plus one config-file endpoint, + the state a user of #38195 ends up in: the config endpoint is listed by + GET but absent from the DB-backed CRUD path.""" with ( - patch( + patch( # test-quality-ok: proxy_server module global is the endpoint's only injection point "litellm.proxy.proxy_server.config_passthrough_endpoints", [dict(CONFIG_ENDPOINT)], ), - patch( + patch( # test-quality-ok: handlers import this from proxy_server at call time; no seam to inject "litellm.proxy.proxy_server.get_config_general_settings", side_effect=_db_getter(), ), ): + yield + + +@pytest.mark.asyncio +async def test_delete_config_defined_endpoint_returns_targeted_error(): + with _db_only_crud_env(): with pytest.raises(HTTPException) as exc_info: await delete_pass_through_endpoints( endpoint_id="config-endpoint-id", @@ -73,18 +83,7 @@ async def test_delete_config_defined_endpoint_returns_targeted_error(): @pytest.mark.asyncio async def test_update_config_defined_endpoint_returns_targeted_error(): - from litellm.proxy._types import PassThroughGenericEndpoint - - with ( - patch( - "litellm.proxy.proxy_server.config_passthrough_endpoints", - [dict(CONFIG_ENDPOINT)], - ), - patch( - "litellm.proxy.proxy_server.get_config_general_settings", - side_effect=_db_getter(), - ), - ): + with _db_only_crud_env(): with pytest.raises(HTTPException) as exc_info: await update_pass_through_endpoints( endpoint_id="config-endpoint-id", @@ -102,16 +101,7 @@ async def test_update_config_defined_endpoint_returns_targeted_error(): @pytest.mark.asyncio async def test_delete_unknown_endpoint_keeps_generic_not_found(): - with ( - patch( - "litellm.proxy.proxy_server.config_passthrough_endpoints", - [dict(CONFIG_ENDPOINT)], - ), - patch( - "litellm.proxy.proxy_server.get_config_general_settings", - side_effect=_db_getter(), - ), - ): + with _db_only_crud_env(): with pytest.raises(HTTPException) as exc_info: await delete_pass_through_endpoints( endpoint_id="does-not-exist", @@ -124,22 +114,20 @@ async def test_delete_unknown_endpoint_keeps_generic_not_found(): @pytest.mark.asyncio async def test_delete_db_endpoint_still_works(): - db_getter = _db_getter() - with ( - patch( + patch( # test-quality-ok: proxy_server module global is the endpoint's only injection point "litellm.proxy.proxy_server.config_passthrough_endpoints", [dict(CONFIG_ENDPOINT)], ), - patch( + patch( # test-quality-ok: handlers import this from proxy_server at call time; no seam to inject "litellm.proxy.proxy_server.get_config_general_settings", - side_effect=db_getter, + side_effect=_db_getter(), ), - patch( + patch( # test-quality-ok: handlers import this from proxy_server at call time; no seam to inject "litellm.proxy.proxy_server.update_config_general_settings", new_callable=AsyncMock, ) as mock_update, - patch( + patch( # test-quality-ok: mutates the live FastAPI route registry; no injection seam "litellm.proxy.pass_through_endpoints.pass_through_endpoints.InitPassThroughEndpointHelpers.remove_endpoint_routes" ), ):