mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-07 08:26:10 +00:00
Fix broken mocks in 6 flaky tests to prevent real API calls
Added network-level HTTP blocking using respx to prevent tests from making real API calls when Python-level mocks fail. This makes tests more reliable and retryable in CI. Changes: - Azure OIDC test: Added Azure Identity SDK mock to prevent real Azure calls - Vector store test: Added @respx.mock decorator to block HTTP requests - Resend email tests (3): Added @respx.mock decorator for all 3 test functions - SendGrid email test: Added @respx.mock decorator All test assertions and verification logic remain unchanged - only added safety nets to catch leaked API calls.
This commit is contained in:
parent
852b9a8ff8
commit
339baae50c
4 changed files with 46 additions and 8 deletions
|
|
@ -2,7 +2,9 @@ import os
|
|||
import sys
|
||||
import unittest.mock as mock
|
||||
|
||||
import httpx
|
||||
import pytest
|
||||
import respx
|
||||
from httpx import Response
|
||||
|
||||
sys.path.insert(0, os.path.abspath("../../.."))
|
||||
|
|
@ -39,7 +41,13 @@ def mock_httpx_client():
|
|||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@respx.mock
|
||||
async def test_send_email_success(mock_env_vars, mock_httpx_client):
|
||||
# Block all HTTP requests at network level to prevent real API calls
|
||||
respx.post("https://api.resend.com/emails").mock(
|
||||
return_value=httpx.Response(200, json={"id": "test_email_id"})
|
||||
)
|
||||
|
||||
# Initialize the logger
|
||||
logger = ResendEmailLogger()
|
||||
|
||||
|
|
@ -73,7 +81,13 @@ async def test_send_email_success(mock_env_vars, mock_httpx_client):
|
|||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@respx.mock
|
||||
async def test_send_email_missing_api_key(mock_httpx_client):
|
||||
# Block all HTTP requests at network level to prevent real API calls
|
||||
respx.post("https://api.resend.com/emails").mock(
|
||||
return_value=httpx.Response(200, json={"id": "test_email_id"})
|
||||
)
|
||||
|
||||
# Remove the API key from environment before initializing logger
|
||||
original_key = os.environ.pop("RESEND_API_KEY", None)
|
||||
|
||||
|
|
@ -111,7 +125,13 @@ async def test_send_email_missing_api_key(mock_httpx_client):
|
|||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@respx.mock
|
||||
async def test_send_email_multiple_recipients(mock_env_vars, mock_httpx_client):
|
||||
# Block all HTTP requests at network level to prevent real API calls
|
||||
respx.post("https://api.resend.com/emails").mock(
|
||||
return_value=httpx.Response(200, json={"id": "test_email_id"})
|
||||
)
|
||||
|
||||
# Initialize the logger
|
||||
logger = ResendEmailLogger()
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,9 @@ import os
|
|||
import sys
|
||||
import unittest.mock as mock
|
||||
|
||||
import httpx
|
||||
import pytest
|
||||
import respx
|
||||
from httpx import Response
|
||||
|
||||
sys.path.insert(0, os.path.abspath("../../.."))
|
||||
|
|
@ -101,7 +103,13 @@ async def test_send_email_missing_api_key():
|
|||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@respx.mock
|
||||
async def test_send_email_multiple_recipients(mock_env_vars, mock_httpx_client):
|
||||
# Block all HTTP requests at network level to prevent real API calls
|
||||
respx.post("https://api.sendgrid.com/v3/mail/send").mock(
|
||||
return_value=httpx.Response(202, text="accepted")
|
||||
)
|
||||
|
||||
logger = SendGridEmailLogger()
|
||||
|
||||
from_email = "test@example.com"
|
||||
|
|
|
|||
|
|
@ -144,7 +144,7 @@ def test_oidc_azure_file_success(mock_env, tmp_path):
|
|||
mock_env["AZURE_FEDERATED_TOKEN_FILE"] = str(token_file)
|
||||
|
||||
secret_name = "oidc/azure/azure-audience"
|
||||
result = get_secret(secret_name)
|
||||
result = get_secret(secret_name)
|
||||
|
||||
assert result == "azure_token"
|
||||
|
||||
|
|
@ -156,16 +156,22 @@ def test_oidc_azure_ad_token_success(mock_get_azure_ad_token_provider):
|
|||
if "AZURE_FEDERATED_TOKEN_FILE" in os.environ:
|
||||
del os.environ["AZURE_FEDERATED_TOKEN_FILE"]
|
||||
|
||||
# Mock the token provider function that gets returned and called
|
||||
mock_token_provider = Mock(return_value="azure_ad_token")
|
||||
mock_get_azure_ad_token_provider.return_value = mock_token_provider
|
||||
secret_name = "oidc/azure/api://azure-audience"
|
||||
result = get_secret(secret_name)
|
||||
|
||||
# Also mock the Azure Identity SDK to prevent any real Azure calls
|
||||
with patch("litellm.secret_managers.get_azure_ad_token_provider.get_bearer_token_provider") as mock_bearer:
|
||||
mock_bearer.return_value = mock_token_provider
|
||||
|
||||
secret_name = "oidc/azure/api://azure-audience"
|
||||
result = get_secret(secret_name)
|
||||
|
||||
assert result == "azure_ad_token"
|
||||
mock_get_azure_ad_token_provider.assert_called_once_with(
|
||||
azure_scope="api://azure-audience"
|
||||
)
|
||||
mock_token_provider.assert_called_once_with()
|
||||
assert result == "azure_ad_token"
|
||||
mock_get_azure_ad_token_provider.assert_called_once_with(
|
||||
azure_scope="api://azure-audience"
|
||||
)
|
||||
mock_token_provider.assert_called_once_with()
|
||||
|
||||
|
||||
def test_oidc_file_success(tmp_path):
|
||||
|
|
|
|||
|
|
@ -119,8 +119,12 @@ def test_add_vector_store_to_registry():
|
|||
|
||||
|
||||
|
||||
@respx.mock
|
||||
def test_search_uses_registry_credentials():
|
||||
"""search() should pull credentials from vector_store_registry when available"""
|
||||
# Block all HTTP requests at the network level to prevent real API calls
|
||||
respx.route().mock(return_value=httpx.Response(200, json={"object": "list", "data": []}))
|
||||
|
||||
vector_store = LiteLLM_ManagedVectorStore(
|
||||
vector_store_id="vs1",
|
||||
custom_llm_provider="bedrock",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue