Files
2026-07-13 13:22:34 +08:00

106 lines
3.7 KiB
Python

from unittest import mock
import pytest
from mlflow.gateway.providers.utils import (
SUPPORTED_ACCEPT_ENCODING,
_aiohttp_post,
proxy_root_url,
rename_payload_keys,
)
from tests.gateway.tools import MockAsyncResponse, mock_http_client
def test_rename_payload_keys():
payload = {"old_key1": "value1", "old_key2": "value2", "old_key3": None, "old_key4": []}
mapping = {"old_key1": "new_key1", "old_key2": "new_key2"}
expected = {"new_key1": "value1", "new_key2": "value2", "old_key3": None, "old_key4": []}
assert rename_payload_keys(payload, mapping) == expected
@pytest.mark.parametrize(
("payload", "mapping", "expected"),
[
(
{"old_key1": "value1", "old_key2": None, "old_key3": "value3"},
{"old_key1": "new_key1", "old_key3": "new_key3"},
{"new_key1": "value1", "old_key2": None, "new_key3": "value3"},
),
(
{"old_key1": None, "old_key2": "value2", "old_key3": []},
{"old_key1": "new_key1", "old_key3": "new_key3"},
{"new_key1": None, "old_key2": "value2", "new_key3": []},
),
(
{"old_key1": "value1", "old_key2": "value2"},
{"old_key1": "new_key1", "old_key3": "new_key3"},
{"new_key1": "value1", "old_key2": "value2"},
),
],
)
def test_rename_payload_keys_parameterized(payload, mapping, expected):
assert rename_payload_keys(payload, mapping) == expected
@pytest.mark.asyncio
async def test_aiohttp_post_includes_supported_accept_encoding():
mock_client = mock_http_client(MockAsyncResponse({}))
with mock.patch("aiohttp.ClientSession", return_value=mock_client) as mock_session_cls:
async with _aiohttp_post(
headers={"Authorization": "Bearer key"},
base_url="https://api.example.com",
path="/v1/chat",
payload={"model": "x"},
):
pass
mock_session_cls.assert_called_once()
call_headers = mock_session_cls.call_args.kwargs["headers"]
assert call_headers.get("Accept-Encoding") == SUPPORTED_ACCEPT_ENCODING
@pytest.mark.asyncio
async def test_aiohttp_post_uses_timeout_from_env_var(monkeypatch):
monkeypatch.setenv("MLFLOW_GATEWAY_ROUTE_TIMEOUT_SECONDS", "2")
mock_client = mock_http_client(MockAsyncResponse({}))
with mock.patch("aiohttp.ClientSession", return_value=mock_client):
async with _aiohttp_post(
headers={"Authorization": "Bearer key"},
base_url="https://api.example.com",
path="/v1/chat",
payload={"model": "x"},
):
pass
mock_client.post.assert_called_once()
assert mock_client.post.call_args.kwargs["timeout"].total == 2
@pytest.mark.asyncio
async def test_aiohttp_post_sets_read_bufsize_for_large_sse_lines():
mock_client = mock_http_client(MockAsyncResponse({}))
with mock.patch("aiohttp.ClientSession", return_value=mock_client) as mock_session_cls:
async with _aiohttp_post(
headers={"Authorization": "Bearer key"},
base_url="https://api.example.com",
path="/v1/chat",
payload={"model": "x"},
):
pass
assert mock_session_cls.call_args.kwargs["read_bufsize"] == 2**20
@pytest.mark.parametrize(
("base_url", "expected"),
[
("https://api.anthropic.com/v1", "https://api.anthropic.com"),
("https://api.openai.com/v1", "https://api.openai.com"),
("https://api.groq.com/openai/v1", "https://api.groq.com/openai"),
("https://api.example.com/v1/", "https://api.example.com"),
],
)
def test_proxy_root_url(base_url, expected):
assert proxy_root_url(base_url) == expected