Skip to content

Commit 9c1a370

Browse files
committed
feat: unit tests
1 parent 372e1a5 commit 9c1a370

1 file changed

Lines changed: 30 additions & 9 deletions

File tree

tests/core/unit/telemetry/test_auto_instrument.py

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ def mock_traceloop_components():
1313
with ExitStack() as stack:
1414
mocks = {
1515
'traceloop': stack.enter_context(patch('sap_cloud_sdk.core.telemetry.auto_instrument.Traceloop')),
16-
'exporter': stack.enter_context(patch('sap_cloud_sdk.core.telemetry.auto_instrument.OTLPSpanExporter')),
16+
'grpc_exporter': stack.enter_context(patch('opentelemetry.exporter.otlp.proto.grpc.trace_exporter.OTLPSpanExporter')),
17+
'http_exporter': stack.enter_context(patch('opentelemetry.exporter.otlp.proto.http.trace_exporter.OTLPSpanExporter')),
1718
'console_exporter': stack.enter_context(patch('sap_cloud_sdk.core.telemetry.auto_instrument.ConsoleSpanExporter')),
1819
'transformer': stack.enter_context(patch('sap_cloud_sdk.core.telemetry.auto_instrument.GenAIAttributeTransformer')),
1920
'create_resource': stack.enter_context(patch('sap_cloud_sdk.core.telemetry.auto_instrument.create_resource_attributes_from_env')),
@@ -48,8 +49,8 @@ def test_auto_instrument_appends_v1_traces_to_endpoint(self, mock_traceloop_comp
4849
with patch.dict('os.environ', {'OTEL_EXPORTER_OTLP_ENDPOINT': 'http://localhost:4317'}, clear=True):
4950
auto_instrument()
5051

51-
# Verify exporter was called with /v1/traces appended
52-
mock_traceloop_components['exporter'].assert_called_once_with(
52+
# Verify exporter was called with /v1/traces appended (grpc by default)
53+
mock_traceloop_components['grpc_exporter'].assert_called_once_with(
5354
endpoint='http://localhost:4317/v1/traces'
5455
)
5556

@@ -61,8 +62,8 @@ def test_auto_instrument_preserves_existing_v1_traces(self, mock_traceloop_compo
6162
with patch.dict('os.environ', {'OTEL_EXPORTER_OTLP_ENDPOINT': 'http://localhost:4317/v1/traces'}, clear=True):
6263
auto_instrument()
6364

64-
# Verify exporter was called with original endpoint
65-
mock_traceloop_components['exporter'].assert_called_once_with(
65+
# Verify exporter was called with original endpoint (grpc by default)
66+
mock_traceloop_components['grpc_exporter'].assert_called_once_with(
6667
endpoint='http://localhost:4317/v1/traces'
6768
)
6869

@@ -110,11 +111,29 @@ def test_auto_instrument_with_trailing_slash(self, mock_traceloop_components):
110111
with patch.dict('os.environ', {'OTEL_EXPORTER_OTLP_ENDPOINT': 'http://localhost:4317/'}, clear=True):
111112
auto_instrument()
112113

113-
# Verify trailing slash is removed before appending /v1/traces
114-
mock_traceloop_components['exporter'].assert_called_once_with(
114+
# Verify trailing slash is removed before appending /v1/traces (grpc by default)
115+
mock_traceloop_components['grpc_exporter'].assert_called_once_with(
115116
endpoint='http://localhost:4317/v1/traces'
116117
)
117118

119+
def test_auto_instrument_with_http_protobuf_protocol(self, mock_traceloop_components):
120+
"""Test that auto_instrument uses HTTP exporter when OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf."""
121+
mock_traceloop_components['get_app_name'].return_value = 'test-app'
122+
mock_traceloop_components['create_resource'].return_value = {}
123+
124+
with patch.dict('os.environ', {
125+
'OTEL_EXPORTER_OTLP_ENDPOINT': 'http://localhost:4318',
126+
'OTEL_EXPORTER_OTLP_PROTOCOL': 'http/protobuf'
127+
}, clear=True):
128+
auto_instrument()
129+
130+
# Verify HTTP exporter was called with /v1/traces appended
131+
mock_traceloop_components['http_exporter'].assert_called_once_with(
132+
endpoint='http://localhost:4318/v1/traces'
133+
)
134+
# Verify gRPC exporter was not called
135+
mock_traceloop_components['grpc_exporter'].assert_not_called()
136+
118137
def test_auto_instrument_passes_transformer_to_traceloop(self, mock_traceloop_components):
119138
"""Test that auto_instrument passes the GenAIAttributeTransformer as exporter to Traceloop."""
120139
mock_traceloop_components['get_app_name'].return_value = 'test-app'
@@ -155,7 +174,8 @@ def test_auto_instrument_with_console_exporter(self, mock_traceloop_components):
155174
auto_instrument()
156175

157176
mock_traceloop_components['console_exporter'].assert_called_once_with()
158-
mock_traceloop_components['exporter'].assert_not_called()
177+
mock_traceloop_components['grpc_exporter'].assert_not_called()
178+
mock_traceloop_components['http_exporter'].assert_not_called()
159179
mock_traceloop_components['traceloop'].init.assert_called_once()
160180

161181
def test_auto_instrument_console_exporter_case_insensitive(self, mock_traceloop_components):
@@ -182,7 +202,8 @@ def test_auto_instrument_console_wins_when_both_set(self, mock_traceloop_compone
182202
auto_instrument()
183203

184204
mock_traceloop_components['console_exporter'].assert_called_once_with()
185-
mock_traceloop_components['exporter'].assert_not_called()
205+
mock_traceloop_components['grpc_exporter'].assert_not_called()
206+
mock_traceloop_components['http_exporter'].assert_not_called()
186207

187208
def test_auto_instrument_console_wraps_with_transformer(self, mock_traceloop_components):
188209
"""Test that ConsoleSpanExporter is wrapped with GenAIAttributeTransformer."""

0 commit comments

Comments
 (0)