From e775a6f0fec1e99b647ba460b58046c741ef555d Mon Sep 17 00:00:00 2001 From: Yamac Ay Date: Fri, 25 Sep 2026 14:04:59 +0200 Subject: [PATCH] tests & small name -> configurationName fix --- litellm/llms/sap/chat/transformation.py | 6 ++-- .../llms/sap/chat/test_sap_transformation.py | 35 ++++++++++++------- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/litellm/llms/sap/chat/transformation.py b/litellm/llms/sap/chat/transformation.py index a2f08f58c09..9ad1971c380 100755 --- a/litellm/llms/sap/chat/transformation.py +++ b/litellm/llms/sap/chat/transformation.py @@ -197,9 +197,9 @@ class GenAIHubOrchestrationConfig(OpenAIGPTConfig): litellm.module_level_client.get( f"{self.base_url}/lm/deployments", headers=self.headers, - params={ + params={ # mutable-ok: one-shot query-params dict passed directly to httpx, not stored "scenarioId": "orchestration", - "executableIds": ["orchestration"], + "executableIds": ["orchestration"], # mutable-ok: list literal required by httpx multi-value param serialization "status": "RUNNING", }, ) @@ -208,7 +208,7 @@ class GenAIHubOrchestrationConfig(OpenAIGPTConfig): ) candidates: Final[list[tuple[str, str, str]]] = sorted( ( - (dep["deploymentUrl"], dep["createdAt"], dep.get("name", "")) + (dep["deploymentUrl"], dep["createdAt"], dep.get("configurationName", "")) for dep in resources if dep.get("deploymentUrl") ), diff --git a/tests/unit/llms/sap/chat/test_sap_transformation.py b/tests/unit/llms/sap/chat/test_sap_transformation.py index 4e1c8fd7298..d7cd27eb71f 100644 --- a/tests/unit/llms/sap/chat/test_sap_transformation.py +++ b/tests/unit/llms/sap/chat/test_sap_transformation.py @@ -658,29 +658,25 @@ def _make_config(): def _mock_client(*names: str): - """Fake httpx client that returns deployment/config payloads for given names.""" + """Fake httpx client returning a /lm/deployments response for the given deployment names. + + The backend filters by scenarioId/executableIds/status, so there is no + second call to /lm/configurations; the mock only needs one response shape. + """ resources = [ { "scenarioId": "orchestration", "configurationId": f"cfg-{n}", "deploymentUrl": f"https://deploy-{n}.sap.com", "createdAt": f"2024-01-{i + 1:02d}T00:00:00Z", + "configurationName": n, } for i, n in enumerate(names) ] - configs = {f"cfg-{n}": {"executableId": "orchestration", "name": n} for n in names} - - def fake_get(url, headers=None): - resp = MagicMock() - if "/lm/deployments" in url: - resp.json.return_value = {"resources": resources} - else: - cfg_id = url.split("/")[-1] - resp.json.return_value = configs.get(cfg_id, {}) - return resp - + resp = MagicMock() + resp.json.return_value = {"resources": resources} client = MagicMock() - client.get.side_effect = fake_get + client.get.return_value = resp return client @@ -716,6 +712,19 @@ class TestDeploymentResolution: cfg._resolve_deployment_url() assert "No orchestration deployment found" in str(exc.value) + def test_query_params_sent_to_backend(self): + """The whole point of this refactor: filtering must happen server-side.""" + cfg = _make_config() + mock = _mock_client("orch-a") + with patch("litellm.module_level_client", mock): # test-quality-ok: patching the HTTP client at the litellm transport boundary + cfg._resolve_deployment_url() + _, kwargs = mock.get.call_args + assert kwargs["params"] == { + "scenarioId": "orchestration", + "executableIds": ["orchestration"], + "status": "RUNNING", + } + class TestGetCompleteUrl: def test_optional_params_used_first(self):