From 3f85e73b182360f30447fd44da121247b3611bd6 Mon Sep 17 00:00:00 2001 From: shin-bot-litellm Date: Sat, 31 Jan 2026 22:57:44 +0000 Subject: [PATCH] litellm_fix_mapped_tests_core: disable aiohttp transport in tests ## Problem Tests using @respx.mock were hitting real APIs because respx only intercepts httpx requests, but litellm uses aiohttp transport by default. Tests affected: - test_send_email_missing_api_key - test_send_email_multiple_recipients (resend & sendgrid) - test_search_uses_registry_credentials - test_vector_store_create_with_simple_provider_name - test_image_edit_merges_headers_and_extra_headers ## Solution 1. Add disable_aiohttp_transport fixture (autouse=True) to test files that use respx mocking. This forces httpx transport so respx works. 2. Clear client cache in fixture to prevent reuse of old clients. 3. Fix isinstance checks in vector store tests to use type name comparison (avoids module identity issues from sys.path.insert). ## Regression PR #19829 (commit f95572e3ed) added @respx.mock but didn't account for aiohttp transport bypassing respx interception. --- .../send_emails/test_resend_email.py | 25 +++++++++++++++++++ .../send_emails/test_sendgrid_email.py | 25 +++++++++++++++++++ tests/test_litellm/test_main.py | 21 ++++++++++++++++ ...test_vector_store_create_provider_logic.py | 19 +++++++------- .../test_vector_store_registry.py | 21 ++++++++++++++++ 5 files changed, 102 insertions(+), 9 deletions(-) diff --git a/tests/test_litellm/enterprise/enterprise_callbacks/send_emails/test_resend_email.py b/tests/test_litellm/enterprise/enterprise_callbacks/send_emails/test_resend_email.py index 8db6d98f13..1a9bb04dd6 100644 --- a/tests/test_litellm/enterprise/enterprise_callbacks/send_emails/test_resend_email.py +++ b/tests/test_litellm/enterprise/enterprise_callbacks/send_emails/test_resend_email.py @@ -9,6 +9,7 @@ sys.path.insert(0, os.path.abspath("../../..")) +import litellm from litellm_enterprise.enterprise_callbacks.send_emails.resend_email import ( ResendEmailLogger, ) @@ -16,6 +17,30 @@ # Test file for Resend email integration +@pytest.fixture(autouse=True) +def disable_aiohttp_transport(): + """ + Disable aiohttp transport so respx can intercept httpx requests. + Also clear the client cache to ensure fresh clients are created. + """ + # Disable aiohttp transport so respx can intercept requests + original_value = getattr(litellm, "disable_aiohttp_transport", None) + litellm.disable_aiohttp_transport = True + + # Clear the client cache to ensure we don't reuse old clients + cache = getattr(litellm, "in_memory_llm_clients_cache", None) + if cache is not None: + cache.flush_cache() + + yield + + # Restore original value + if original_value is not None: + litellm.disable_aiohttp_transport = original_value + elif hasattr(litellm, "disable_aiohttp_transport"): + delattr(litellm, "disable_aiohttp_transport") + + @pytest.fixture def mock_env_vars(): with mock.patch.dict(os.environ, {"RESEND_API_KEY": "test_api_key"}): diff --git a/tests/test_litellm/enterprise/enterprise_callbacks/send_emails/test_sendgrid_email.py b/tests/test_litellm/enterprise/enterprise_callbacks/send_emails/test_sendgrid_email.py index 836b717bd6..9709118323 100644 --- a/tests/test_litellm/enterprise/enterprise_callbacks/send_emails/test_sendgrid_email.py +++ b/tests/test_litellm/enterprise/enterprise_callbacks/send_emails/test_sendgrid_email.py @@ -9,11 +9,36 @@ sys.path.insert(0, os.path.abspath("../../..")) +import litellm from litellm_enterprise.enterprise_callbacks.send_emails.sendgrid_email import ( SendGridEmailLogger, ) +@pytest.fixture(autouse=True) +def disable_aiohttp_transport(): + """ + Disable aiohttp transport so respx can intercept httpx requests. + Also clear the client cache to ensure fresh clients are created. + """ + # Disable aiohttp transport so respx can intercept requests + original_value = getattr(litellm, "disable_aiohttp_transport", None) + litellm.disable_aiohttp_transport = True + + # Clear the client cache to ensure we don't reuse old clients + cache = getattr(litellm, "in_memory_llm_clients_cache", None) + if cache is not None: + cache.flush_cache() + + yield + + # Restore original value + if original_value is not None: + litellm.disable_aiohttp_transport = original_value + elif hasattr(litellm, "disable_aiohttp_transport"): + delattr(litellm, "disable_aiohttp_transport") + + @pytest.fixture def mock_env_vars(): # Store original values diff --git a/tests/test_litellm/test_main.py b/tests/test_litellm/test_main.py index 80fd9f6129..f32f454eb0 100644 --- a/tests/test_litellm/test_main.py +++ b/tests/test_litellm/test_main.py @@ -18,6 +18,27 @@ from litellm import main as litellm_main +@pytest.fixture(autouse=True) +def disable_aiohttp_transport(): + """ + Disable aiohttp transport so respx can intercept httpx requests. + Also clear the client cache to ensure fresh clients are created. + """ + original_value = getattr(litellm, "disable_aiohttp_transport", None) + litellm.disable_aiohttp_transport = True + + cache = getattr(litellm, "in_memory_llm_clients_cache", None) + if cache is not None: + cache.flush_cache() + + yield + + if original_value is not None: + litellm.disable_aiohttp_transport = original_value + elif hasattr(litellm, "disable_aiohttp_transport"): + delattr(litellm, "disable_aiohttp_transport") + + @pytest.fixture(autouse=True) def add_api_keys_to_env(monkeypatch): monkeypatch.setenv("ANTHROPIC_API_KEY", "sk-ant-api03-1234567890") diff --git a/tests/test_litellm/vector_stores/test_vector_store_create_provider_logic.py b/tests/test_litellm/vector_stores/test_vector_store_create_provider_logic.py index cca20847f1..08da9b9807 100644 --- a/tests/test_litellm/vector_stores/test_vector_store_create_provider_logic.py +++ b/tests/test_litellm/vector_stores/test_vector_store_create_provider_logic.py @@ -51,9 +51,10 @@ def test_vector_store_create_with_simple_provider_name(): ) assert vector_store_provider_config is not None, "Should return a config for OpenAI" - assert isinstance( - vector_store_provider_config, OpenAIVectorStoreConfig - ), "Should return OpenAIVectorStoreConfig for OpenAI provider" + # Use type name check instead of isinstance to avoid module identity issues + # caused by sys.path manipulation in test setup + assert type(vector_store_provider_config).__name__ == "OpenAIVectorStoreConfig", \ + f"Should return OpenAIVectorStoreConfig for OpenAI provider, got {type(vector_store_provider_config).__name__}" print("✅ Test passed: Simple provider name 'openai' handled correctly") @@ -97,9 +98,9 @@ def test_vector_store_create_with_provider_api_type(): ) assert vector_store_provider_config is not None, "Should return a config for Vertex AI" - assert isinstance( - vector_store_provider_config, VertexVectorStoreConfig - ), "Should return VertexVectorStoreConfig for vertex_ai provider with rag_api" + # Use type name check instead of isinstance to avoid module identity issues + assert type(vector_store_provider_config).__name__ == "VertexVectorStoreConfig", \ + f"Should return VertexVectorStoreConfig for vertex_ai provider with rag_api, got {type(vector_store_provider_config).__name__}" print("✅ Test passed: Provider with api_type 'vertex_ai/rag_api' handled correctly") @@ -134,9 +135,9 @@ def test_vector_store_create_with_ragflow_provider(): ) assert vector_store_provider_config is not None, "Should return a config for RAGFlow" - assert isinstance( - vector_store_provider_config, RAGFlowVectorStoreConfig - ), "Should return RAGFlowVectorStoreConfig for RAGFlow provider" + # Use type name check instead of isinstance to avoid module identity issues + assert type(vector_store_provider_config).__name__ == "RAGFlowVectorStoreConfig", \ + f"Should return RAGFlowVectorStoreConfig for RAGFlow provider, got {type(vector_store_provider_config).__name__}" print("✅ Test passed: RAGFlow provider handled correctly") diff --git a/tests/test_litellm/vector_stores/test_vector_store_registry.py b/tests/test_litellm/vector_stores/test_vector_store_registry.py index a3af476bc7..98127efc9e 100644 --- a/tests/test_litellm/vector_stores/test_vector_store_registry.py +++ b/tests/test_litellm/vector_stores/test_vector_store_registry.py @@ -21,6 +21,27 @@ from litellm.vector_stores.vector_store_registry import VectorStoreRegistry +@pytest.fixture(autouse=True) +def disable_aiohttp_transport(): + """ + Disable aiohttp transport so respx can intercept httpx requests. + Also clear the client cache to ensure fresh clients are created. + """ + original_value = getattr(litellm, "disable_aiohttp_transport", None) + litellm.disable_aiohttp_transport = True + + cache = getattr(litellm, "in_memory_llm_clients_cache", None) + if cache is not None: + cache.flush_cache() + + yield + + if original_value is not None: + litellm.disable_aiohttp_transport = original_value + elif hasattr(litellm, "disable_aiohttp_transport"): + delattr(litellm, "disable_aiohttp_transport") + + def test_get_credentials_for_vector_store(): """Test that get_credentials_for_vector_store returns correct credentials""" # Create test vector stores