Spaces:
Paused
Paused
| """Tests for the optional Langfuse trace exporter (ADR-0019). | |
| All offline: the `langfuse` SDK is stubbed so we exercise enable-detection and the | |
| export path without the real dependency, and confirm export is a safe no-op when | |
| disabled and never raises. | |
| """ | |
| from __future__ import annotations | |
| import importlib.machinery | |
| import importlib.util | |
| import sys | |
| import types | |
| from auralynq.telemetry.langfuse_export import export_trace, langfuse_enabled | |
| from auralynq.telemetry.tracing import Trace | |
| def _trace() -> Trace: | |
| t = Trace(trace_id="t-test") | |
| with t.span("planner", q="x"): | |
| pass | |
| with t.span("synthesizer", provider="extractive"): | |
| pass | |
| return t | |
| def test_disabled_without_keys(monkeypatch): | |
| monkeypatch.setenv("LANGFUSE_PUBLIC_KEY", "") | |
| monkeypatch.setenv("LANGFUSE_SECRET_KEY", "") | |
| from auralynq.config import reload_settings | |
| reload_settings() | |
| assert langfuse_enabled() is False | |
| # export is a no-op (returns False), never raises | |
| assert export_trace(_trace(), question="q", answer="a") is False | |
| def _install_fake_langfuse(monkeypatch, recorder): | |
| fake = types.ModuleType("langfuse") | |
| fake.__spec__ = importlib.machinery.ModuleSpec("langfuse", loader=None) | |
| class _Span: | |
| def span(self, **kw): | |
| recorder["spans"].append(kw) | |
| return self | |
| class _Trace(_Span): | |
| pass | |
| class _Langfuse: | |
| def __init__(self, **kw): | |
| recorder["init"] = kw | |
| def trace(self, **kw): | |
| recorder["trace"] = kw | |
| return _Trace() | |
| def flush(self): | |
| recorder["flushed"] = True | |
| fake.Langfuse = _Langfuse | |
| monkeypatch.setitem(sys.modules, "langfuse", fake) | |
| def test_enabled_and_exports_with_keys_and_sdk(monkeypatch): | |
| monkeypatch.setenv("LANGFUSE_PUBLIC_KEY", "pk-test") | |
| monkeypatch.setenv("LANGFUSE_SECRET_KEY", "sk-test") | |
| from auralynq.config import reload_settings | |
| reload_settings() | |
| rec = {"spans": []} | |
| _install_fake_langfuse(monkeypatch, rec) | |
| # reset the cached client so it picks up the stub + keys | |
| from auralynq.telemetry import langfuse_export as lx | |
| lx._client.cache_clear() | |
| assert langfuse_enabled() is True | |
| ok = export_trace( | |
| _trace(), | |
| question="What is the capital of France?", | |
| answer="Paris [1]", | |
| metadata={"route": "fast"}, | |
| ) | |
| assert ok is True | |
| assert rec["trace"]["input"] == {"question": "What is the capital of France?"} | |
| assert rec["trace"]["output"] == {"answer": "Paris [1]"} | |
| assert [s["name"] for s in rec["spans"]] == ["planner", "synthesizer"] | |
| assert rec.get("flushed") is True | |
| lx._client.cache_clear() | |
| def test_export_never_raises_on_sdk_error(monkeypatch): | |
| monkeypatch.setenv("LANGFUSE_PUBLIC_KEY", "pk-test") | |
| monkeypatch.setenv("LANGFUSE_SECRET_KEY", "sk-test") | |
| from auralynq.config import reload_settings | |
| reload_settings() | |
| fake = types.ModuleType("langfuse") | |
| fake.__spec__ = importlib.machinery.ModuleSpec("langfuse", loader=None) | |
| class _Boom: | |
| def __init__(self, **kw): | |
| raise RuntimeError("network down") | |
| fake.Langfuse = _Boom | |
| monkeypatch.setitem(sys.modules, "langfuse", fake) | |
| from auralynq.telemetry import langfuse_export as lx | |
| lx._client.cache_clear() | |
| # must swallow the error and return False, not propagate | |
| assert export_trace(_trace(), question="q", answer="a") is False | |
| lx._client.cache_clear() | |