Fix Langfuse test isolation to prevent flaky failures

Fixes test_log_langfuse_v2_handles_null_usage_values flaky test failure
by properly cleaning up sys.modules['langfuse'] in tearDown.

Changes:
- Store original langfuse module in setUp before mocking
- Restore original or remove mock in tearDown to prevent state pollution
- Remove invalid print_verbose parameter from log_event_on_langfuse

Root Cause:
The tearDown method was not cleaning up sys.modules['langfuse'] after
each test, causing mock state to leak between tests. This caused
intermittent failures in CI, especially when tests run in parallel or
in different orders.

Impact:
This test has a long history of flakiness with multiple attempted fixes
(#20475, #17599, #17594, #17591, #17588). The missing sys.modules cleanup
was the underlying issue causing continued failures despite those patches.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Julio Quinteros Pro 2026-02-14 16:04:08 -03:00
parent b2eade11a4
commit 9672a1f015

View file

@ -32,6 +32,9 @@ class TestLangfuseUsageDetails(unittest.TestCase):
)
self.env_patcher.start()
# Store original langfuse module if it exists for cleanup
self._original_langfuse_module = sys.modules.get("langfuse")
# Create mock objects
self.mock_langfuse_client = MagicMock()
# Mock the client attribute to prevent errors during logger initialization
@ -39,7 +42,7 @@ class TestLangfuseUsageDetails(unittest.TestCase):
self.mock_langfuse_trace = MagicMock()
self.mock_langfuse_generation = MagicMock()
self.mock_langfuse_generation.trace_id = "test-trace-id"
# Mock span method for trace (used by log_provider_specific_information_as_span and _log_guardrail_information_as_span)
self.mock_langfuse_span = MagicMock()
self.mock_langfuse_span.end = MagicMock()
@ -109,7 +112,6 @@ class TestLangfuseUsageDetails(unittest.TestCase):
response_obj=response_obj,
level=level,
litellm_call_id=kwargs.get("litellm_call_id", None),
print_verbose=True, # Add the missing parameter
)
# Bind the method to the instance
@ -127,6 +129,12 @@ class TestLangfuseUsageDetails(unittest.TestCase):
self.env_patcher.stop()
self.langfuse_module_patcher.stop()
# Restore original langfuse module or remove mock to prevent test pollution
if self._original_langfuse_module is not None:
sys.modules["langfuse"] = self._original_langfuse_module
elif "langfuse" in sys.modules:
del sys.modules["langfuse"]
def test_langfuse_usage_details_type(self):
"""Test that LangfuseUsageDetails TypedDict is properly defined with the correct fields"""
# Create an instance of LangfuseUsageDetails