mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-24 00:52:24 +00:00
test(realtime): drop legacy InvalidStatusCode tests and pin websockets imports (#42624)
The two redaction tests raised the deprecated InvalidStatusCode, which the websockets 15 asyncio client never raises, and asserted the raw 403 close code that the handshake refusal path replaced with 1008. The refusal path builds its close reason from the status code alone, so there is no secret to redact there, and the handshake refusal tests already cover the error event and the 1008 close. Those refusal tests only passed when run after a sibling test had imported websockets.asyncio.client, since websockets lazy-loads its exceptions submodule. Importing InvalidStatus, Response, and Headers from their own submodules makes them pass in any order. Co-authored-by: mateo-berri <277851410+mateo-berri@users.noreply.github.com>
This commit is contained in:
parent
b4ccb5b747
commit
38f0eb876b
3 changed files with 9 additions and 63 deletions
|
|
@ -21,7 +21,9 @@ class _RecordingClientWebSocket:
|
|||
|
||||
@pytest.mark.asyncio
|
||||
async def test_async_realtime_upstream_handshake_refusal_sends_error_event_then_policy_close():
|
||||
import websockets
|
||||
from websockets.datastructures import Headers
|
||||
from websockets.exceptions import InvalidStatus
|
||||
from websockets.http11 import Response
|
||||
|
||||
from litellm.llms.azure.realtime.handler import AzureOpenAIRealtime
|
||||
from litellm.types.realtime import RealtimeErrorEvent
|
||||
|
|
@ -32,9 +34,7 @@ async def test_async_realtime_upstream_handshake_refusal_sends_error_event_then_
|
|||
dummy_websocket = _RecordingClientWebSocket()
|
||||
dummy_logging_obj = MagicMock()
|
||||
|
||||
refused = websockets.exceptions.InvalidStatus(
|
||||
websockets.http11.Response(401, "Unauthorized", websockets.datastructures.Headers())
|
||||
)
|
||||
refused = InvalidStatus(Response(401, "Unauthorized", Headers()))
|
||||
|
||||
with patch("websockets.connect", side_effect=refused):
|
||||
await handler.async_realtime( # pyright: ignore[reportUnknownMemberType] # handler's websocket param is a Protocol here but the mock connect type is incomplete
|
||||
|
|
|
|||
|
|
@ -422,7 +422,9 @@ async def test_async_realtime_ws_url_has_no_ssl():
|
|||
async def test_async_realtime_upstream_handshake_refusal_sends_error_event_then_policy_close():
|
||||
from typing import cast
|
||||
|
||||
import websockets
|
||||
from websockets.datastructures import Headers
|
||||
from websockets.exceptions import InvalidStatus
|
||||
from websockets.http11 import Response
|
||||
|
||||
from litellm.llms.openai.realtime.handler import OpenAIRealtime
|
||||
from litellm.types.realtime import RealtimeErrorEvent
|
||||
|
|
@ -445,9 +447,7 @@ async def test_async_realtime_upstream_handshake_refusal_sends_error_event_then_
|
|||
dummy_websocket = RecordingClientWebSocket()
|
||||
dummy_logging_obj = MagicMock()
|
||||
|
||||
refused = websockets.exceptions.InvalidStatus(
|
||||
websockets.http11.Response(401, "Unauthorized", websockets.datastructures.Headers())
|
||||
)
|
||||
refused = InvalidStatus(Response(401, "Unauthorized", Headers()))
|
||||
|
||||
with patch("websockets.connect", side_effect=refused):
|
||||
await handler.async_realtime( # pyright: ignore[reportUnknownMemberType] # handler's websocket param is Any
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
Tests for _redact_string usage in error/logging paths.
|
||||
|
||||
Covers actual execution of redaction in:
|
||||
- WebSocket close reasons in realtime handlers (openai, azure, bedrock)
|
||||
- WebSocket close reasons in realtime handlers (openai, bedrock)
|
||||
- Gemini RAG ingestion x-goog-api-key header usage
|
||||
- Traceback redaction pattern used in proxy streaming
|
||||
- Router fallback-failure traceback redaction
|
||||
|
|
@ -72,25 +72,6 @@ class TestOpenAIRealtimeRedaction:
|
|||
api_key="test-key",
|
||||
)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_invalid_status_code_redacts_reason(self):
|
||||
import websockets.exceptions
|
||||
|
||||
from litellm.llms.openai.realtime.handler import OpenAIRealtime
|
||||
|
||||
handler = OpenAIRealtime()
|
||||
exc = websockets.exceptions.InvalidStatusCode(403, None)
|
||||
exc.status_code = 403
|
||||
|
||||
kwargs = self._call_kwargs()
|
||||
mock_ws = kwargs["websocket"]
|
||||
p1, p2, p3 = self._make_patches(handler)
|
||||
with p1, p2, p3, patch("websockets.connect", side_effect=exc):
|
||||
await handler.async_realtime(**kwargs)
|
||||
|
||||
mock_ws.close.assert_called_once()
|
||||
assert mock_ws.close.call_args[1]["code"] == 403
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_generic_exception_redacts_reason(self):
|
||||
from litellm.llms.openai.realtime.handler import OpenAIRealtime
|
||||
|
|
@ -111,41 +92,6 @@ class TestOpenAIRealtimeRedaction:
|
|||
assert "sk-1234567890abcdefghij" not in mock_ws.close.call_args[1]["reason"]
|
||||
|
||||
|
||||
class TestAzureRealtimeRedaction:
|
||||
"""Test that Azure realtime handler redacts secrets in websocket close reasons."""
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_invalid_status_code_redacts_reason(self):
|
||||
import websockets.exceptions
|
||||
|
||||
from litellm.llms.azure.realtime.handler import AzureOpenAIRealtime
|
||||
|
||||
handler = AzureOpenAIRealtime()
|
||||
mock_ws = AsyncMock()
|
||||
exc = websockets.exceptions.InvalidStatusCode(403, None)
|
||||
exc.status_code = 403
|
||||
|
||||
with (
|
||||
patch.object(
|
||||
handler,
|
||||
"_construct_url",
|
||||
return_value="wss://test.openai.azure.com/openai/realtime",
|
||||
),
|
||||
patch("websockets.connect", side_effect=exc),
|
||||
):
|
||||
await handler.async_realtime(
|
||||
model="gpt-4",
|
||||
websocket=mock_ws,
|
||||
logging_obj=MagicMock(),
|
||||
api_base="https://test.openai.azure.com/",
|
||||
api_key="test-key",
|
||||
api_version="2024-10-01-preview",
|
||||
)
|
||||
|
||||
mock_ws.close.assert_called_once()
|
||||
assert mock_ws.close.call_args[1]["code"] == 403
|
||||
|
||||
|
||||
class TestBedrockRealtimeRedaction:
|
||||
"""Test that _redact_string produces safe close reasons for Bedrock-style errors."""
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue