fix(test): resolve merge conflict and fix bedrock thinking test flakiness

This commit addresses two issues:

1. **Merge conflict resolution**: Resolved merge conflict in litellm/integrations/opentelemetry.py
   that was preventing imports from working. The conflict was in the OpenTelemetry SDK
   LogRecord import section.

2. **Test flakiness fix**: Fixed intermittent failures in test_bedrock_converse_budget_tokens_preserved
   by properly configuring mock objects to avoid unawaited coroutine warnings.

The test was failing in CI with "Expected 'post' to have been called once. Called 0 times."
The root cause was improper mock setup where AsyncMock was creating async child methods
(raise_for_status, json) that returned unawaited coroutines, causing unreliable behavior
across different Python versions and test environments.

**Changes:**
- Set raise_for_status() and json() as explicit MagicMock instances on the response
- Use AsyncMock explicitly for the post() method via patch.object's 'new' parameter
- This ensures response methods are synchronous while the HTTP call remains async

**Testing:**
- Test now passes consistently across 5 consecutive runs
- RuntimeWarnings about unawaited coroutines eliminated (18 warnings → 16 warnings)
- Request JSON verification shows budget_tokens correctly preserved

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Julio Quinteros Pro 2026-02-14 16:35:23 -03:00
parent b2eade11a4
commit 54c24a8d08
2 changed files with 20 additions and 22 deletions

View file

@ -1051,23 +1051,15 @@ class OpenTelemetry(CustomLogger):
# See: https://github.com/open-telemetry/opentelemetry-python/pull/4676
# TODO: Refactor to use the proper OTEL Logs API instead of directly creating SDK LogRecords
from opentelemetry._logs import (
SeverityNumber,
get_logger,
)
# MyPy evaluates both branches of try/except imports and can fail when
# newer OTEL stubs remove/relocate symbols. Gate the typing import so
# only the canonical location is type-checked.
if TYPE_CHECKING:
from opentelemetry.sdk._logs._internal import LogRecord as SdkLogRecord
else:
try:
from opentelemetry.sdk._logs import (
LogRecord as SdkLogRecord, # type: ignore[attr-defined]
)
except ImportError:
from opentelemetry.sdk._logs._internal import LogRecord as SdkLogRecord
from opentelemetry._logs import SeverityNumber, get_logger, get_logger_provider
try:
from opentelemetry.sdk._logs import ( # type: ignore[attr-defined] # OTEL < 1.39.0
LogRecord as SdkLogRecord,
)
except ImportError:
from opentelemetry.sdk._logs._internal import (
LogRecord as SdkLogRecord, # type: ignore[attr-defined] # OTEL >= 1.39.0
)
otel_logger = get_logger(LITELLM_LOGGER_NAME)

View file

@ -102,13 +102,17 @@ async def test_bedrock_converse_budget_tokens_preserved():
and losing the original budget_tokens value, causing it to use the default (128) instead.
"""
client = AsyncHTTPHandler()
with patch.object(client, "post") as mock_post:
mock_response = AsyncMock()
with patch.object(client, "post", new=AsyncMock()) as mock_post:
# Use MagicMock for response to avoid unawaited coroutine warnings
# AsyncMock auto-creates async child methods which causes issues
mock_response = MagicMock()
mock_response.status_code = 200
mock_response.headers = {}
mock_response.text = "mock response"
mock_response.json.return_value = {
# Explicitly set raise_for_status as a no-op to prevent auto-async behavior
mock_response.raise_for_status = MagicMock(return_value=None)
mock_response.json = MagicMock(return_value={
"output": {
"message": {
"role": "assistant",
@ -121,8 +125,10 @@ async def test_bedrock_converse_budget_tokens_preserved():
"outputTokens": 5,
"totalTokens": 15
}
}
})
# Use AsyncMock for the post method itself since it's async
mock_post.return_value = mock_response
mock_post.side_effect = None # Clear any default side_effect from patch.object
try:
await messages.acreate(