88
99from microsoft_agents_a365 .observability .core .exporters .enriching_span_processor import (
1010 _EnrichingBatchSpanProcessor ,
11- _span_enrichers ,
11+ get_span_enricher ,
1212 register_span_enricher ,
1313 unregister_span_enricher ,
1414)
@@ -18,58 +18,66 @@ class TestSpanEnricherRegistry(unittest.TestCase):
1818 """Test suite for span enricher registration functions."""
1919
2020 def setUp (self ):
21- """Clear enrichers before each test."""
22- _span_enrichers . clear ()
21+ """Ensure clean state before each test."""
22+ unregister_span_enricher ()
2323
2424 def tearDown (self ):
25- """Clear enrichers after each test."""
26- _span_enrichers . clear ()
25+ """Clean up after each test."""
26+ unregister_span_enricher ()
2727
2828 def test_register_and_unregister_enricher (self ):
29- """Test that enrichers can be registered and unregistered."""
29+ """Test that enricher can be registered and unregistered."""
3030
31- # Define a simple enricher
3231 def my_enricher (span ):
3332 return span
3433
35- # Register
36- register_span_enricher (my_enricher )
37- self .assertIn (my_enricher , _span_enrichers )
38- self .assertEqual (len (_span_enrichers ), 1 )
34+ # Initially no enricher
35+ self .assertIsNone (get_span_enricher ())
3936
40- # Duplicate registration should not add again
37+ # Register
4138 register_span_enricher (my_enricher )
42- self .assertEqual (len ( _span_enrichers ), 1 )
39+ self .assertEqual (get_span_enricher ( ), my_enricher )
4340
4441 # Unregister
45- unregister_span_enricher (my_enricher )
46- self .assertNotIn (my_enricher , _span_enrichers )
47- self .assertEqual (len (_span_enrichers ), 0 )
42+ unregister_span_enricher ()
43+ self .assertIsNone (get_span_enricher ())
4844
49- def test_unregister_nonexistent_enricher_does_not_raise (self ):
50- """Test that unregistering a non-existent enricher doesn't raise an error ."""
45+ def test_register_second_enricher_raises_error (self ):
46+ """Test that registering a second enricher raises RuntimeError ."""
5147
52- def my_enricher (span ):
48+ def enricher_one (span ):
5349 return span
5450
51+ def enricher_two (span ):
52+ return span
53+
54+ register_span_enricher (enricher_one )
55+
56+ with self .assertRaises (RuntimeError ) as context :
57+ register_span_enricher (enricher_two )
58+
59+ self .assertIn ("already registered" , str (context .exception ))
60+
61+ def test_unregister_when_none_registered_is_safe (self ):
62+ """Test that unregistering when no enricher is registered doesn't raise."""
5563 # Should not raise
56- unregister_span_enricher (my_enricher )
57- self .assertEqual ( len ( _span_enrichers ), 0 )
64+ unregister_span_enricher ()
65+ self .assertIsNone ( get_span_enricher () )
5866
5967
6068class TestEnrichingBatchSpanProcessor (unittest .TestCase ):
6169 """Test suite for _EnrichingBatchSpanProcessor."""
6270
6371 def setUp (self ):
64- """Clear enrichers before each test."""
65- _span_enrichers . clear ()
72+ """Ensure clean state before each test."""
73+ unregister_span_enricher ()
6674
6775 def tearDown (self ):
68- """Clear enrichers after each test."""
69- _span_enrichers . clear ()
76+ """Clean up after each test."""
77+ unregister_span_enricher ()
7078
71- def test_on_end_applies_enrichers_to_span (self ):
72- """Test that on_end applies all registered enrichers to the span."""
79+ def test_on_end_applies_enricher_to_span (self ):
80+ """Test that on_end applies the registered enricher to the span."""
7381 # Create processor with a mock exporter
7482 mock_exporter = Mock ()
7583 processor = _EnrichingBatchSpanProcessor (mock_exporter )
@@ -103,23 +111,14 @@ def enricher(span):
103111 processor .shutdown ()
104112
105113 def test_on_end_continues_if_enricher_raises_exception (self ):
106- """Test that on_end continues processing even if an enricher raises an exception."""
114+ """Test that on_end continues processing even if enricher raises an exception."""
107115 mock_exporter = Mock ()
108116 processor = _EnrichingBatchSpanProcessor (mock_exporter )
109117
110- # Track which enrichers were called
111- called_enrichers = []
112-
113118 def failing_enricher (span ):
114- called_enrichers .append ("failing" )
115119 raise ValueError ("Enricher failed!" )
116120
117- def succeeding_enricher (span ):
118- called_enrichers .append ("succeeding" )
119- return span
120-
121121 register_span_enricher (failing_enricher )
122- register_span_enricher (succeeding_enricher )
123122
124123 # Create a mock span
125124 original_span = Mock (name = "original_span" )
@@ -130,9 +129,22 @@ def succeeding_enricher(span):
130129 # Should not raise despite failing enricher
131130 processor .on_end (original_span )
132131
133- # Verify both enrichers were called (failing one didn't stop the chain)
134- self .assertIn ("failing" , called_enrichers )
135- self .assertIn ("succeeding" , called_enrichers )
132+ # Cleanup
133+ processor .shutdown ()
134+
135+ def test_on_end_works_without_enricher (self ):
136+ """Test that on_end works when no enricher is registered."""
137+ mock_exporter = Mock ()
138+ processor = _EnrichingBatchSpanProcessor (mock_exporter )
139+
140+ # Create a mock span (no enricher registered)
141+ original_span = Mock (name = "original_span" )
142+ original_span .context = Mock ()
143+ original_span .context .trace_id = 123
144+ original_span .context .span_id = 456
145+
146+ # Should not raise
147+ processor .on_end (original_span )
136148
137149 # Cleanup
138150 processor .shutdown ()
0 commit comments