@@ -86,58 +86,81 @@ def _make_histogram_data_point(name, unit="s"):
8686
8787class TestLoggerMetricExporter :
8888 def test_export_counter_returns_success (self , logger ):
89+ # Arrange
8990 exporter = LoggerMetricExporter (logger )
91+ # Act
9092 result = exporter .export (_make_counter_data_point ("my.metric" , 42 ))
93+ # Assert
9194 assert result == MetricExportResult .SUCCESS
9295
9396 def test_export_counter_logs_value (self , logger ):
97+ # Arrange
9498 exporter = LoggerMetricExporter (logger )
99+ # Act
95100 exporter .export (_make_counter_data_point ("my.metric" , 7 , attributes = {"a" : "b" }))
101+ # Assert
96102 logger .info .assert_called ()
97103 call_args = logger .info .call_args [0 ]
98104 assert "my.metric" in call_args [1 ]
99105
100106 def test_export_counter_no_attributes (self , logger ):
107+ # Arrange
101108 exporter = LoggerMetricExporter (logger )
109+ # Act
102110 result = exporter .export (
103111 _make_counter_data_point ("my.metric" , 1 , attributes = None )
104112 )
113+ # Assert
105114 assert result == MetricExportResult .SUCCESS
106115
107116 def test_export_histogram_returns_success (self , logger ):
117+ # Arrange
108118 exporter = LoggerMetricExporter (logger )
119+ # Act
109120 result = exporter .export (_make_histogram_data_point ("my.histogram" ))
121+ # Assert
110122 assert result == MetricExportResult .SUCCESS
111123
112124 def test_export_histogram_logs_bucket_info (self , logger ):
125+ # Arrange
113126 exporter = LoggerMetricExporter (logger )
127+ # Act
114128 exporter .export (_make_histogram_data_point ("my.histogram" ))
129+ # Assert
115130 logger .info .assert_called ()
116131 call_args = logger .info .call_args [0 ]
117132 assert "my.histogram" in call_args [1 ]
118133
119134 def test_export_empty_metrics_data (self , logger ):
135+ # Arrange
120136 metrics_data = MagicMock ()
121137 metrics_data .resource_metrics = []
122138 exporter = LoggerMetricExporter (logger )
139+ # Act
123140 result = exporter .export (metrics_data )
141+ # Assert
124142 assert result == MetricExportResult .SUCCESS
125143 logger .debug .assert_not_called ()
126144
127145 def test_export_returns_failure_on_exception (self , logger ):
146+ # Arrange
128147 metrics_data = MagicMock ()
129148 metrics_data .resource_metrics .__iter__ = MagicMock (
130149 side_effect = RuntimeError ("boom" )
131150 )
132151 exporter = LoggerMetricExporter (logger )
152+ # Act
133153 result = exporter .export (metrics_data )
154+ # Assert
134155 assert result == MetricExportResult .FAILURE
135156 logger .error .assert_called ()
136157
137158 def test_shutdown_does_not_raise (self , logger ):
159+ # Arrange / Act / Assert
138160 LoggerMetricExporter (logger ).shutdown ()
139161
140162 def test_force_flush_returns_true (self , logger ):
163+ # Arrange / Act / Assert
141164 assert LoggerMetricExporter (logger ).force_flush () is True
142165
143166
@@ -164,20 +187,27 @@ def _make_service(logger, monkeypatch, extra_exporters=None):
164187
165188class TestObservabilityService :
166189 def test_counters_are_created (self , logger , monkeypatch ):
190+ # Arrange / Act
167191 svc = _make_service (logger , monkeypatch )
192+ # Assert
168193 assert svc .event_count_counter is not None
169194 assert svc .event_bytes_counter is not None
170195
171196 def test_meter_is_available (self , logger , monkeypatch ):
197+ # Arrange / Act
172198 svc = _make_service (logger , monkeypatch )
199+ # Assert
173200 assert svc ._meter is not None
174201
175202 def test_extra_exporter_is_added (self , logger , monkeypatch ):
203+ # Arrange
176204 extra = MagicMock ()
205+ # Act / Assert
177206 _make_service (logger , monkeypatch , extra_exporters = [extra ])
178207 # No assertion needed beyond not raising; the exporter is wrapped internally
179208
180209 def test_missing_ta_name_logs_warning (self , logger , monkeypatch ):
210+ # Arrange
181211 monkeypatch .setattr (
182212 "solnlib.observability.ObservabilityService._create_otlp_exporter" ,
183213 lambda self : None ,
@@ -186,13 +216,16 @@ def test_missing_ta_name_logs_warning(self, logger, monkeypatch):
186216 "solnlib.observability.ObservabilityService._read_ta_info" ,
187217 lambda self : (None , None ),
188218 )
219+ # Act
189220 svc = ObservabilityService (modinput_type = "test-input" , logger = logger )
221+ # Assert
190222 assert svc ._meter is None
191223 logger .warning .assert_called ()
192224
193225 def test_register_instrument_returns_none_when_meter_missing (
194226 self , logger , monkeypatch
195227 ):
228+ # Arrange
196229 monkeypatch .setattr (
197230 "solnlib.observability.ObservabilityService._create_otlp_exporter" ,
198231 lambda self : None ,
@@ -202,17 +235,23 @@ def test_register_instrument_returns_none_when_meter_missing(
202235 lambda self : (None , None ),
203236 )
204237 svc = ObservabilityService (modinput_type = "test-input" , logger = logger )
238+ # Act
205239 result = svc .register_instrument (lambda m : m .create_counter ("x" ))
240+ # Assert
206241 assert result is None
207242
208243 def test_register_instrument_calls_callback (self , logger , monkeypatch ):
244+ # Arrange
209245 svc = _make_service (logger , monkeypatch )
210246 callback = MagicMock (return_value = "instrument" )
247+ # Act
211248 result = svc .register_instrument (callback )
249+ # Assert
212250 callback .assert_called_once_with (svc ._meter )
213251 assert result == "instrument"
214252
215253 def test_read_ta_info_returns_values (self , logger , monkeypatch ):
254+ # Arrange
216255 monkeypatch .setattr (
217256 "solnlib.observability.get_conf_stanzas" ,
218257 lambda conf , ** kwargs : {
@@ -224,10 +263,13 @@ def test_read_ta_info_returns_values(self, logger, monkeypatch):
224263 "solnlib.observability.ObservabilityService._create_otlp_exporter" ,
225264 lambda self : None ,
226265 )
266+ # Act
227267 svc = ObservabilityService (modinput_type = "test-input" , logger = logger )
268+ # Assert
228269 assert svc ._meter is not None
229270
230271 def test_read_ta_info_handles_exception (self , logger , monkeypatch ):
272+ # Arrange
231273 monkeypatch .setattr (
232274 "solnlib.observability.ObservabilityService._create_otlp_exporter" ,
233275 lambda self : None ,
@@ -236,50 +278,63 @@ def test_read_ta_info_handles_exception(self, logger, monkeypatch):
236278 "solnlib.observability.get_conf_stanzas" ,
237279 MagicMock (side_effect = Exception ("no btool" )),
238280 )
281+ # Act
239282 svc = ObservabilityService (modinput_type = "test-input" , logger = logger )
283+ # Assert
240284 assert svc ._meter is None
241285
242286 def test_resolve_otlp_port_from_env (self , logger , monkeypatch ):
287+ # Arrange
243288 monkeypatch .setenv ("SPOTLIGHT_OTEL_RECEIVER_PORT" , "4317" )
244289 svc = _make_service (logger , monkeypatch )
290+ # Act / Assert
245291 assert svc ._resolve_otlp_port () == "4317"
246292
247293 def test_resolve_otlp_port_falls_back_to_ipc (self , logger , monkeypatch ):
294+ # Arrange
248295 monkeypatch .delenv ("SPOTLIGHT_OTEL_RECEIVER_PORT" , raising = False )
249296 monkeypatch .setattr (
250297 "solnlib.observability.ObservabilityService._discover_otlp_port_via_ipc_broker" ,
251298 lambda self : "9999" ,
252299 )
253300 svc = _make_service (logger , monkeypatch )
301+ # Act / Assert
254302 assert svc ._resolve_otlp_port () == "9999"
255303
256304 def test_get_ipc_broker_port_returns_none_on_error (self , logger , monkeypatch ):
305+ # Arrange
257306 monkeypatch .setattr (
258307 "solnlib.observability.get_conf_stanzas" ,
259308 MagicMock (side_effect = Exception ("fail" )),
260309 )
261310 svc = _make_service (logger , monkeypatch )
311+ # Act / Assert
262312 assert svc ._get_ipc_broker_port () is None
263313
264314 def test_get_ipc_broker_port_returns_port (self , logger , monkeypatch ):
315+ # Arrange
265316 monkeypatch .setattr (
266317 "solnlib.observability.get_conf_stanzas" ,
267318 lambda conf , ** kwargs : {"ipc_broker" : {"port" : "8088" }},
268319 )
269320 svc = _make_service (logger , monkeypatch )
321+ # Act / Assert
270322 assert svc ._get_ipc_broker_port () == 8088
271323
272324 def test_discover_otlp_port_returns_none_when_ipc_port_missing (
273325 self , logger , monkeypatch
274326 ):
327+ # Arrange
275328 monkeypatch .setattr (
276329 "solnlib.observability.ObservabilityService._get_ipc_broker_port" ,
277330 lambda self : None ,
278331 )
279332 svc = _make_service (logger , monkeypatch )
333+ # Act / Assert
280334 assert svc ._discover_otlp_port_via_ipc_broker () is None
281335
282336 def test_discover_otlp_port_returns_none_on_http_error (self , logger , monkeypatch ):
337+ # Arrange
283338 monkeypatch .setattr (
284339 "solnlib.observability.ObservabilityService._get_ipc_broker_port" ,
285340 lambda self : 8088 ,
@@ -289,11 +344,13 @@ def test_discover_otlp_port_returns_none_on_http_error(self, logger, monkeypatch
289344 MagicMock (side_effect = Exception ("connection refused" )),
290345 )
291346 svc = _make_service (logger , monkeypatch )
347+ # Act / Assert
292348 assert svc ._discover_otlp_port_via_ipc_broker () is None
293349
294350 def test_discover_otlp_port_returns_none_on_unsuccessful_response (
295351 self , logger , monkeypatch
296352 ):
353+ # Arrange
297354 monkeypatch .setattr (
298355 "solnlib.observability.ObservabilityService._get_ipc_broker_port" ,
299356 lambda self : 8088 ,
@@ -304,9 +361,11 @@ def test_discover_otlp_port_returns_none_on_unsuccessful_response(
304361 mock_resp .read .return_value = b'{"success": false}'
305362 monkeypatch .setattr ("urllib.request.urlopen" , lambda * a , ** kw : mock_resp )
306363 svc = _make_service (logger , monkeypatch )
364+ # Act / Assert
307365 assert svc ._discover_otlp_port_via_ipc_broker () is None
308366
309367 def test_discover_otlp_port_returns_port_on_success (self , logger , monkeypatch ):
368+ # Arrange
310369 monkeypatch .setattr (
311370 "solnlib.observability.ObservabilityService._get_ipc_broker_port" ,
312371 lambda self : 8088 ,
@@ -317,24 +376,30 @@ def test_discover_otlp_port_returns_port_on_success(self, logger, monkeypatch):
317376 mock_resp .read .return_value = b'{"success": true, "port": 4317}'
318377 monkeypatch .setattr ("urllib.request.urlopen" , lambda * a , ** kw : mock_resp )
319378 svc = _make_service (logger , monkeypatch )
379+ # Act / Assert
320380 assert svc ._discover_otlp_port_via_ipc_broker () == "4317"
321381
322382 def test_create_otlp_exporter_returns_none_when_no_port (self , logger , monkeypatch ):
383+ # Arrange
323384 monkeypatch .delenv ("SPOTLIGHT_OTEL_RECEIVER_PORT" , raising = False )
324385 monkeypatch .setattr (
325386 "solnlib.observability.ObservabilityService._discover_otlp_port_via_ipc_broker" ,
326387 lambda self : None ,
327388 )
328389 svc = _make_service (logger , monkeypatch )
329- # Call the real _create_otlp_exporter now (not patched)
390+ # Act — call the real _create_otlp_exporter (not patched)
330391 result = ObservabilityService ._create_otlp_exporter (svc )
392+ # Assert
331393 assert result is None
332394
333395 def test_create_otlp_exporter_returns_none_when_cert_missing (
334396 self , logger , monkeypatch , tmp_path
335397 ):
398+ # Arrange
336399 monkeypatch .setenv ("SPOTLIGHT_OTEL_RECEIVER_PORT" , "4317" )
337400 monkeypatch .setenv ("SPLUNK_HOME" , str (tmp_path ))
338401 svc = _make_service (logger , monkeypatch )
402+ # Act
339403 result = ObservabilityService ._create_otlp_exporter (svc )
404+ # Assert
340405 assert result is None
0 commit comments