129 lines
3.7 KiB
Python
129 lines
3.7 KiB
Python
"""
|
|
Tests for Deployment Module - Langfuse Client.
|
|
|
|
Tests observability and tracing functionality.
|
|
"""
|
|
|
|
import pytest
|
|
from unittest.mock import patch
|
|
|
|
from src.deployment.langfuse_client import (
|
|
LangfuseClient,
|
|
TraceData,
|
|
SpanData,
|
|
TraceStatus,
|
|
get_langfuse
|
|
)
|
|
|
|
|
|
class TestLangfuseClient:
|
|
"""Tests for LangfuseClient."""
|
|
|
|
@pytest.fixture
|
|
def client(self):
|
|
"""Create Langfuse client."""
|
|
return LangfuseClient()
|
|
|
|
def test_create_trace(self, client):
|
|
"""Test trace creation."""
|
|
trace_id = client.create_trace(
|
|
name="test_trace",
|
|
tenant_id="tenant-001"
|
|
)
|
|
|
|
assert trace_id.startswith("trace-")
|
|
assert len(trace_id) == 22 # trace- + 16 hex chars
|
|
|
|
def test_trace_metadata(self, client):
|
|
"""Test trace with metadata."""
|
|
trace_id = client.create_trace(
|
|
name="test_trace",
|
|
tenant_id="tenant-001",
|
|
metadata={"ticket_id": "TKT-001"}
|
|
)
|
|
|
|
assert trace_id is not None
|
|
|
|
def test_start_span(self, client):
|
|
"""Test span creation."""
|
|
trace_id = client.create_trace("test", "tenant-001")
|
|
span_id = client.start_span(
|
|
trace_id=trace_id,
|
|
name="test_span",
|
|
input_data="test input"
|
|
)
|
|
|
|
assert span_id.startswith("span-")
|
|
|
|
def test_end_span(self, client):
|
|
"""Test ending a span."""
|
|
trace_id = client.create_trace("test", "tenant-001")
|
|
span_id = client.start_span(trace_id, "test_span")
|
|
|
|
client.end_span(
|
|
span_id=span_id,
|
|
output_data="test output",
|
|
status=TraceStatus.COMPLETED
|
|
)
|
|
|
|
# Span should be removed from active spans
|
|
assert span_id not in client._active_spans
|
|
|
|
def test_end_trace(self, client):
|
|
"""Test ending a trace."""
|
|
trace_id = client.create_trace(
|
|
name="test_trace",
|
|
tenant_id="tenant-001"
|
|
)
|
|
|
|
result = client.end_trace(trace_id, TraceStatus.COMPLETED)
|
|
|
|
assert result is not None
|
|
assert result.status == TraceStatus.COMPLETED
|
|
assert result.total_duration_ms >= 0
|
|
|
|
def test_trace_context_manager(self, client):
|
|
"""Test trace context manager."""
|
|
with client.trace("test_op", "tenant-001") as trace_id:
|
|
assert trace_id.startswith("trace-")
|
|
|
|
# Trace should be completed
|
|
assert trace_id not in client._active_traces
|
|
|
|
def test_span_context_manager(self, client):
|
|
"""Test span context manager."""
|
|
trace_id = client.create_trace("test", "tenant-001")
|
|
|
|
with client.span(trace_id, "test_span", "input") as span_id:
|
|
assert span_id.startswith("span-")
|
|
|
|
# Span should be completed
|
|
assert span_id not in client._active_spans
|
|
|
|
def test_get_metrics(self, client):
|
|
"""Test metrics retrieval."""
|
|
metrics = client.get_metrics()
|
|
|
|
assert "active_traces" in metrics
|
|
assert "active_spans" in metrics
|
|
assert "langfuse_enabled" in metrics
|
|
|
|
def test_fallback_mode(self, client):
|
|
"""Test fallback when Langfuse not configured."""
|
|
# Default client should be in fallback mode
|
|
assert client._enabled is False
|
|
|
|
|
|
class TestLangfuseSingleton:
|
|
"""Tests for singleton."""
|
|
|
|
def test_singleton(self):
|
|
"""Test singleton returns same instance."""
|
|
import src.deployment.langfuse_client as module
|
|
module._langfuse = None
|
|
|
|
l1 = get_langfuse()
|
|
l2 = get_langfuse()
|
|
|
|
assert l1 is l2
|