GitHub Actions
Clean sync from GitHub - no large files in history
1390f29
Raw History Blame Contribute Delete
2.27 kB
"""
Unit tests for observability/analytics.py::get_verified_trace_cost().
Covers the retry/poll semantics: LangFuse computes cost server-side,
asynchronously, after ingestion, so a freshly-flushed trace may briefly
report $0.00 before the real cost is available.
"""
from unittest.mock import Mock
import pytest
from observability.analytics import get_verified_trace_cost
def _trace_reader_returning(costs):
"""Mock TraceReader whose get_trace_by_id() yields total_cost from `costs` in order."""
reader = Mock()
trace_sequence = [Mock(total_cost=cost) if cost is not None else None for cost in costs]
reader.get_trace_by_id.side_effect = trace_sequence
return reader
class TestGetVerifiedTraceCost:
def test_returns_immediately_on_nonzero_cost(self):
reader = _trace_reader_returning([0.0118901])
cost = get_verified_trace_cost("trace-1", max_attempts=5, delay_seconds=0, trace_reader=reader)
assert cost == 0.0118901
assert reader.get_trace_by_id.call_count == 1
def test_retries_while_cost_is_zero_then_succeeds(self):
reader = _trace_reader_returning([0.0, 0.0, 0.004])
cost = get_verified_trace_cost("trace-1", max_attempts=5, delay_seconds=0, trace_reader=reader)
assert cost == 0.004
assert reader.get_trace_by_id.call_count == 3
def test_returns_zero_after_exhausting_attempts(self):
reader = _trace_reader_returning([0.0, 0.0, 0.0])
cost = get_verified_trace_cost("trace-1", max_attempts=3, delay_seconds=0, trace_reader=reader)
assert cost == 0.0
assert reader.get_trace_by_id.call_count == 3
def test_returns_none_when_trace_never_found(self):
reader = _trace_reader_returning([None, None])
cost = get_verified_trace_cost("trace-1", max_attempts=2, delay_seconds=0, trace_reader=reader)
assert cost is None
assert reader.get_trace_by_id.call_count == 2
def test_never_raises_on_lookup_exception(self):
reader = Mock()
reader.get_trace_by_id.side_effect = Exception("network error")
cost = get_verified_trace_cost("trace-1", max_attempts=2, delay_seconds=0, trace_reader=reader)
assert cost is None
assert reader.get_trace_by_id.call_count == 2