Fix hanging CI tests in test_http_handler.py

- Remove real HTTP call to example.com in test_force_ipv4_transport
  (hangs in CI when network is slow/unavailable)
- Close leaked aiohttp.ClientSession in test_ssl_verification_with_aiohttp_transport
- Add cleanup for transports in test_aiohttp_transport_trust_env_setting
- Add cleanup for handler in test_ssl_security_level
- Add cleanup for transport in test_ssl_context_transport

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
yuneng-jiang
2026-03-14 17:40:33 -07:00
co-authored by Claude Opus 4.6
parent d28e42d7ce
commit b14eadef86
@@ -32,24 +32,25 @@ async def test_ssl_security_level(monkeypatch):
# Create async client with SSL verification disabled to isolate SSL context testing
client = AsyncHTTPHandler()
# Get the transport (should be LiteLLMAiohttpTransport)
transport = client.client._transport
assert isinstance(transport, LiteLLMAiohttpTransport)
try:
# Get the transport (should be LiteLLMAiohttpTransport)
transport = client.client._transport
assert isinstance(transport, LiteLLMAiohttpTransport)
# Get the aiohttp ClientSession
client_session = transport._get_valid_client_session()
# Get the aiohttp ClientSession
client_session = transport._get_valid_client_session()
# Get the connector from the session
connector = client_session.connector
assert isinstance(connector, TCPConnector)
# Get the connector from the session
connector = client_session.connector
assert isinstance(connector, TCPConnector)
# Get the SSL context from the connector
ssl_context = connector._ssl
# Get the SSL context from the connector
ssl_context = connector._ssl
# Verify that the SSL context exists and has the correct cipher string
assert isinstance(ssl_context, ssl.SSLContext)
# Optionally, check the ciphers string if needed
# assert "DEFAULT@SECLEVEL=1" in ssl_context.get_ciphers()
# Verify that the SSL context exists and has the correct cipher string
assert isinstance(ssl_context, ssl.SSLContext)
finally:
await client.close()
finally:
# Restore original setting
litellm.disable_aiohttp_transport = original_disable
@@ -63,15 +64,8 @@ async def test_force_ipv4_transport():
transport = AsyncHTTPHandler._create_async_transport()
# Should get an AsyncHTTPTransport
# Should get an AsyncHTTPTransport (no real HTTP call — avoids CI hangs)
assert isinstance(transport, httpx.AsyncHTTPTransport)
# Verify IPv4 configuration through a request
client = httpx.AsyncClient(transport=transport)
try:
response = await client.get("http://example.com")
assert response.status_code == 200
finally:
await client.aclose()
@pytest.mark.asyncio
@@ -83,13 +77,17 @@ async def test_ssl_context_transport():
transport = AsyncHTTPHandler._create_async_transport(ssl_context=ssl_context)
assert transport is not None
if isinstance(transport, LiteLLMAiohttpTransport):
# Get the client session and verify SSL context is passed through
client_session = transport._get_valid_client_session()
assert isinstance(client_session, ClientSession)
assert isinstance(client_session.connector, TCPConnector)
# Verify the connector has SSL context set by checking if it's using SSL
assert client_session.connector._ssl is not None
try:
if isinstance(transport, LiteLLMAiohttpTransport):
# Get the client session and verify SSL context is passed through
client_session = transport._get_valid_client_session()
assert isinstance(client_session, ClientSession)
assert isinstance(client_session.connector, TCPConnector)
# Verify the connector has SSL context set by checking if it's using SSL
assert client_session.connector._ssl is not None
finally:
if isinstance(transport, LiteLLMAiohttpTransport):
await transport.aclose()
@pytest.mark.asyncio
@@ -130,11 +128,14 @@ async def test_ssl_verification_with_aiohttp_transport():
aiohttp_session = aiohttp.ClientSession(
connector=aiohttp.TCPConnector(ssl=False)
)
aiohttp_connector = aiohttp_session.connector
assert isinstance(aiohttp_connector, aiohttp.TCPConnector)
try:
aiohttp_connector = aiohttp_session.connector
assert isinstance(aiohttp_connector, aiohttp.TCPConnector)
# assert both litellm transport and aiohttp session have ssl_verify=False
assert transport_connector._ssl == aiohttp_connector._ssl
# assert both litellm transport and aiohttp session have ssl_verify=False
assert transport_connector._ssl == aiohttp_connector._ssl
finally:
await aiohttp_session.close()
finally:
# Restore original setting
litellm.disable_aiohttp_transport = original_disable
@@ -220,29 +221,37 @@ async def test_ssl_context_with_shared_session():
@pytest.mark.asyncio
async def test_aiohttp_transport_trust_env_setting(monkeypatch):
"""Test that trust_env setting is properly configured in aiohttp transport"""
# Test 1: Default trust_env behavior
transport = AsyncHTTPHandler._create_aiohttp_transport()
client_session = transport._get_valid_client_session()
# Default should be False (litellm.aiohttp_trust_env default)
default_trust_env = getattr(litellm, 'aiohttp_trust_env', False)
assert client_session._trust_env == default_trust_env
# Test 2: Environment variable override
monkeypatch.setenv("AIOHTTP_TRUST_ENV", "True")
transport_with_env = AsyncHTTPHandler._create_aiohttp_transport()
client_session_with_env = transport_with_env._get_valid_client_session()
# Should be True when environment variable is set
assert client_session_with_env._trust_env is True
# Test 3: Verify environment variable with False value
monkeypatch.setenv("AIOHTTP_TRUST_ENV", "False")
transport_with_false_env = AsyncHTTPHandler._create_aiohttp_transport()
client_session_with_false_env = transport_with_false_env._get_valid_client_session()
# Should respect the litellm.aiohttp_trust_env setting when env var is False
assert client_session_with_false_env._trust_env == default_trust_env
transports = []
try:
# Test 1: Default trust_env behavior
transport = AsyncHTTPHandler._create_aiohttp_transport()
transports.append(transport)
client_session = transport._get_valid_client_session()
# Default should be False (litellm.aiohttp_trust_env default)
default_trust_env = getattr(litellm, 'aiohttp_trust_env', False)
assert client_session._trust_env == default_trust_env
# Test 2: Environment variable override
monkeypatch.setenv("AIOHTTP_TRUST_ENV", "True")
transport_with_env = AsyncHTTPHandler._create_aiohttp_transport()
transports.append(transport_with_env)
client_session_with_env = transport_with_env._get_valid_client_session()
# Should be True when environment variable is set
assert client_session_with_env._trust_env is True
# Test 3: Verify environment variable with False value
monkeypatch.setenv("AIOHTTP_TRUST_ENV", "False")
transport_with_false_env = AsyncHTTPHandler._create_aiohttp_transport()
transports.append(transport_with_false_env)
client_session_with_false_env = transport_with_false_env._get_valid_client_session()
# Should respect the litellm.aiohttp_trust_env setting when env var is False
assert client_session_with_false_env._trust_env == default_trust_env
finally:
for t in transports:
await t.aclose()
def test_get_ssl_configuration():