22# SPDX-License-Identifier: Apache-2.0
33
44from unittest import TestCase
5- from unittest .mock import MagicMock
5+ from unittest .mock import MagicMock , patch
66
77from amazon .opentelemetry .distro .exporter .otlp .aws .traces .otlp_aws_span_exporter import OTLPAwsSpanExporter
8+ from opentelemetry .exporter .otlp .proto .http .trace_exporter import OTLPSpanExporter
89from opentelemetry .sdk ._logs import LoggerProvider
10+ from opentelemetry .sdk .trace import ReadableSpan
11+ from opentelemetry .sdk .trace .export import SpanExportResult
912
1013
1114class TestOTLPAwsSpanExporter (TestCase ):
@@ -27,3 +30,162 @@ def test_init_without_logger_provider(self):
2730
2831 self .assertIsNone (exporter ._logger_provider )
2932 self .assertEqual (exporter ._aws_region , "us-west-2" )
33+ self .assertIsNone (exporter ._llo_handler )
34+
35+ @patch ("amazon.opentelemetry.distro.exporter.otlp.aws.traces.otlp_aws_span_exporter.is_agent_observability_enabled" )
36+ def test_ensure_llo_handler_when_disabled (self , mock_is_enabled ):
37+ # Test _ensure_llo_handler when agent observability is disabled
38+ mock_is_enabled .return_value = False
39+ endpoint = "https://xray.us-east-1.amazonaws.com/v1/traces"
40+
41+ exporter = OTLPAwsSpanExporter (endpoint = endpoint )
42+ result = exporter ._ensure_llo_handler ()
43+
44+ self .assertFalse (result )
45+ self .assertIsNone (exporter ._llo_handler )
46+ mock_is_enabled .assert_called_once ()
47+
48+ @patch ("amazon.opentelemetry.distro.exporter.otlp.aws.traces.otlp_aws_span_exporter.get_logger_provider" )
49+ @patch ("amazon.opentelemetry.distro.exporter.otlp.aws.traces.otlp_aws_span_exporter.is_agent_observability_enabled" )
50+ @patch ("amazon.opentelemetry.distro.exporter.otlp.aws.traces.otlp_aws_span_exporter.LLOHandler" )
51+ def test_ensure_llo_handler_lazy_initialization (
52+ self , mock_llo_handler_class , mock_is_enabled , mock_get_logger_provider
53+ ):
54+ # Test lazy initialization of LLO handler when enabled
55+ mock_is_enabled .return_value = True
56+ mock_logger_provider = MagicMock (spec = LoggerProvider )
57+ mock_get_logger_provider .return_value = mock_logger_provider
58+ mock_llo_handler = MagicMock ()
59+ mock_llo_handler_class .return_value = mock_llo_handler
60+
61+ endpoint = "https://xray.us-east-1.amazonaws.com/v1/traces"
62+ exporter = OTLPAwsSpanExporter (endpoint = endpoint )
63+
64+ # First call should initialize
65+ result = exporter ._ensure_llo_handler ()
66+
67+ self .assertTrue (result )
68+ self .assertEqual (exporter ._llo_handler , mock_llo_handler )
69+ mock_llo_handler_class .assert_called_once_with (mock_logger_provider )
70+ mock_get_logger_provider .assert_called_once ()
71+
72+ # Second call should not re-initialize
73+ mock_llo_handler_class .reset_mock ()
74+ mock_get_logger_provider .reset_mock ()
75+
76+ result = exporter ._ensure_llo_handler ()
77+
78+ self .assertTrue (result )
79+ mock_llo_handler_class .assert_not_called ()
80+ mock_get_logger_provider .assert_not_called ()
81+
82+ @patch ("amazon.opentelemetry.distro.exporter.otlp.aws.traces.otlp_aws_span_exporter.get_logger_provider" )
83+ @patch ("amazon.opentelemetry.distro.exporter.otlp.aws.traces.otlp_aws_span_exporter.is_agent_observability_enabled" )
84+ def test_ensure_llo_handler_with_existing_logger_provider (self , mock_is_enabled , mock_get_logger_provider ):
85+ # Test when logger_provider is already provided
86+ mock_is_enabled .return_value = True
87+ mock_logger_provider = MagicMock (spec = LoggerProvider )
88+
89+ endpoint = "https://xray.us-east-1.amazonaws.com/v1/traces"
90+ exporter = OTLPAwsSpanExporter (endpoint = endpoint , logger_provider = mock_logger_provider )
91+
92+ with patch (
93+ "amazon.opentelemetry.distro.exporter.otlp.aws.traces.otlp_aws_span_exporter.LLOHandler"
94+ ) as mock_llo_handler_class :
95+ mock_llo_handler = MagicMock ()
96+ mock_llo_handler_class .return_value = mock_llo_handler
97+
98+ result = exporter ._ensure_llo_handler ()
99+
100+ self .assertTrue (result )
101+ self .assertEqual (exporter ._llo_handler , mock_llo_handler )
102+ mock_llo_handler_class .assert_called_once_with (mock_logger_provider )
103+ mock_get_logger_provider .assert_not_called ()
104+
105+ @patch ("amazon.opentelemetry.distro.exporter.otlp.aws.traces.otlp_aws_span_exporter.get_logger_provider" )
106+ @patch ("amazon.opentelemetry.distro.exporter.otlp.aws.traces.otlp_aws_span_exporter.is_agent_observability_enabled" )
107+ def test_ensure_llo_handler_get_logger_provider_fails (self , mock_is_enabled , mock_get_logger_provider ):
108+ # Test when get_logger_provider raises exception
109+ mock_is_enabled .return_value = True
110+ mock_get_logger_provider .side_effect = Exception ("Failed to get logger provider" )
111+
112+ endpoint = "https://xray.us-east-1.amazonaws.com/v1/traces"
113+ exporter = OTLPAwsSpanExporter (endpoint = endpoint )
114+
115+ result = exporter ._ensure_llo_handler ()
116+
117+ self .assertFalse (result )
118+ self .assertIsNone (exporter ._llo_handler )
119+
120+ @patch ("amazon.opentelemetry.distro.exporter.otlp.aws.traces.otlp_aws_span_exporter.is_agent_observability_enabled" )
121+ def test_export_with_llo_disabled (self , mock_is_enabled ):
122+ # Test export when LLO is disabled
123+ mock_is_enabled .return_value = False
124+ endpoint = "https://xray.us-east-1.amazonaws.com/v1/traces"
125+
126+ exporter = OTLPAwsSpanExporter (endpoint = endpoint )
127+
128+ # Mock the parent class export method
129+ with patch .object (OTLPSpanExporter , "export" ) as mock_parent_export :
130+ mock_parent_export .return_value = SpanExportResult .SUCCESS
131+
132+ spans = [MagicMock (spec = ReadableSpan ), MagicMock (spec = ReadableSpan )]
133+ result = exporter .export (spans )
134+
135+ self .assertEqual (result , SpanExportResult .SUCCESS )
136+ mock_parent_export .assert_called_once_with (spans )
137+ self .assertIsNone (exporter ._llo_handler )
138+
139+ @patch ("amazon.opentelemetry.distro.exporter.otlp.aws.traces.otlp_aws_span_exporter.is_agent_observability_enabled" )
140+ @patch ("amazon.opentelemetry.distro.exporter.otlp.aws.traces.otlp_aws_span_exporter.get_logger_provider" )
141+ @patch ("amazon.opentelemetry.distro.exporter.otlp.aws.traces.otlp_aws_span_exporter.LLOHandler" )
142+ def test_export_with_llo_enabled (self , mock_llo_handler_class , mock_get_logger_provider , mock_is_enabled ):
143+ # Test export when LLO is enabled and successfully processes spans
144+ mock_is_enabled .return_value = True
145+ mock_logger_provider = MagicMock (spec = LoggerProvider )
146+ mock_get_logger_provider .return_value = mock_logger_provider
147+
148+ mock_llo_handler = MagicMock ()
149+ mock_llo_handler_class .return_value = mock_llo_handler
150+
151+ endpoint = "https://xray.us-east-1.amazonaws.com/v1/traces"
152+ exporter = OTLPAwsSpanExporter (endpoint = endpoint )
153+
154+ # Mock spans and processed spans
155+ original_spans = [MagicMock (spec = ReadableSpan ), MagicMock (spec = ReadableSpan )]
156+ processed_spans = [MagicMock (spec = ReadableSpan ), MagicMock (spec = ReadableSpan )]
157+ mock_llo_handler .process_spans .return_value = processed_spans
158+
159+ # Mock the parent class export method
160+ with patch .object (OTLPSpanExporter , "export" ) as mock_parent_export :
161+ mock_parent_export .return_value = SpanExportResult .SUCCESS
162+
163+ result = exporter .export (original_spans )
164+
165+ self .assertEqual (result , SpanExportResult .SUCCESS )
166+ mock_llo_handler .process_spans .assert_called_once_with (original_spans )
167+ mock_parent_export .assert_called_once_with (processed_spans )
168+
169+ @patch ("amazon.opentelemetry.distro.exporter.otlp.aws.traces.otlp_aws_span_exporter.is_agent_observability_enabled" )
170+ @patch ("amazon.opentelemetry.distro.exporter.otlp.aws.traces.otlp_aws_span_exporter.get_logger_provider" )
171+ @patch ("amazon.opentelemetry.distro.exporter.otlp.aws.traces.otlp_aws_span_exporter.LLOHandler" )
172+ def test_export_with_llo_processing_failure (
173+ self , mock_llo_handler_class , mock_get_logger_provider , mock_is_enabled
174+ ):
175+ # Test export when LLO processing fails
176+ mock_is_enabled .return_value = True
177+ mock_logger_provider = MagicMock (spec = LoggerProvider )
178+ mock_get_logger_provider .return_value = mock_logger_provider
179+
180+ mock_llo_handler = MagicMock ()
181+ mock_llo_handler_class .return_value = mock_llo_handler
182+ mock_llo_handler .process_spans .side_effect = Exception ("LLO processing failed" )
183+
184+ endpoint = "https://xray.us-east-1.amazonaws.com/v1/traces"
185+ exporter = OTLPAwsSpanExporter (endpoint = endpoint )
186+
187+ spans = [MagicMock (spec = ReadableSpan ), MagicMock (spec = ReadableSpan )]
188+
189+ result = exporter .export (spans )
190+
191+ self .assertEqual (result , SpanExportResult .FAILURE )
0 commit comments