-
Notifications
You must be signed in to change notification settings - Fork 34
Expand file tree
/
Copy pathconftest.py
More file actions
74 lines (59 loc) · 2.77 KB
/
Copy pathconftest.py
File metadata and controls
74 lines (59 loc) · 2.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
"""Fixtures for telemetry integration tests."""
import os
from pathlib import Path
from unittest.mock import patch
import pytest
from dotenv import load_dotenv
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import SimpleSpanProcessor
from opentelemetry.sdk.trace.export.in_memory_span_exporter import InMemorySpanExporter
from sap_cloud_sdk.aicore import set_aicore_config
from sap_cloud_sdk.core.telemetry.auto_instrument import auto_instrument
from sap_cloud_sdk.core.telemetry.genai_attribute_transformer import (
GenAIAttributeTransformer,
)
_env_file = Path(__file__).parent.parent.parent.parent.parent / ".env_integration_tests"
if _env_file.exists():
load_dotenv(_env_file, override=True)
@pytest.fixture(scope="session")
def memory_exporter() -> InMemorySpanExporter:
"""Initialize auto_instrument once per session and inject an in-memory exporter.
Uses OTEL_TRACES_EXPORTER=console so Traceloop.init runs for real without
needing a real collector endpoint. A second SimpleSpanProcessor backed by
InMemorySpanExporter is added afterward for test assertions on raw spans.
"""
raw_exporter = InMemorySpanExporter()
with patch.dict(os.environ, {"OTEL_TRACES_EXPORTER": "console"}, clear=False):
auto_instrument(disable_batch=True)
provider = trace.get_tracer_provider()
assert isinstance(provider, TracerProvider)
provider.add_span_processor(SimpleSpanProcessor(raw_exporter))
return raw_exporter
@pytest.fixture(scope="session")
def transforming_exporter(memory_exporter: InMemorySpanExporter) -> InMemorySpanExporter:
"""Inject a second in-memory exporter wrapped in GenAIAttributeTransformer.
Used by traceloop.feature tests to assert on transformer output
(gen_ai.* attributes present, llm.usage.* and traceloop.* absent).
"""
transformed_sink = InMemorySpanExporter()
provider = trace.get_tracer_provider()
assert isinstance(provider, TracerProvider)
provider.add_span_processor(
SimpleSpanProcessor(GenAIAttributeTransformer(transformed_sink))
)
return transformed_sink
@pytest.fixture(autouse=True)
def clear_spans(memory_exporter: InMemorySpanExporter, transforming_exporter: InMemorySpanExporter):
"""Clear both exporters before each test so spans don't bleed between scenarios."""
memory_exporter.clear()
transforming_exporter.clear()
@pytest.fixture(scope="session")
def aicore_configured():
"""Call set_aicore_config() once per session.
Skips if AICORE_BASE_URL is absent — tests depending on this fixture are
skipped automatically.
"""
if not os.environ.get("AICORE_BASE_URL"):
pytest.skip("AICORE_BASE_URL not set — skipping AI Core integration tests")
set_aicore_config()