1313# limitations under the License.
1414from unittest import TestCase , mock
1515
16- from pika .adapters import BlockingConnection
17- from pika .adapters .blocking_connection import _QueueConsumerGeneratorInfo
16+ from pika .adapters import BaseConnection , BlockingConnection
17+ from pika .adapters .blocking_connection import (
18+ BlockingChannel ,
19+ _QueueConsumerGeneratorInfo ,
20+ )
1821from pika .channel import Channel
22+ from pika .connection import Connection
1923from wrapt import BoundFunctionWrapper
2024
2125from opentelemetry .instrumentation .pika import PikaInstrumentor
3135
3236class TestPika (TestCase ):
3337 def setUp (self ) -> None :
38+ self .blocking_channel = mock .MagicMock (spec = BlockingChannel )
3439 self .channel = mock .MagicMock (spec = Channel )
3540 consumer_info = mock .MagicMock ()
3641 callback_attr = PikaInstrumentor .CONSUMER_CALLBACK_ATTR
3742 setattr (consumer_info , callback_attr , mock .MagicMock ())
38- self .channel ._consumer_infos = {"consumer-tag" : consumer_info }
43+ self .blocking_channel ._consumer_infos = {"consumer-tag" : consumer_info }
44+ self .channel ._consumers = {"consumer-tag" : consumer_info }
3945 self .mock_callback = mock .MagicMock ()
4046
4147 def test_instrument_api (self ) -> None :
@@ -44,6 +50,10 @@ def test_instrument_api(self) -> None:
4450 self .assertTrue (
4551 isinstance (BlockingConnection .channel , BoundFunctionWrapper )
4652 )
53+ self .assertTrue (isinstance (Connection .channel , BoundFunctionWrapper ))
54+ self .assertTrue (
55+ isinstance (BaseConnection .channel , BoundFunctionWrapper )
56+ )
4757 self .assertTrue (
4858 isinstance (
4959 _QueueConsumerGeneratorInfo .__init__ , BoundFunctionWrapper
@@ -56,6 +66,10 @@ def test_instrument_api(self) -> None:
5666 self .assertFalse (
5767 isinstance (BlockingConnection .channel , BoundFunctionWrapper )
5868 )
69+ self .assertFalse (isinstance (Connection .channel , BoundFunctionWrapper ))
70+ self .assertFalse (
71+ isinstance (BaseConnection .channel , BoundFunctionWrapper )
72+ )
5973 self .assertFalse (
6074 isinstance (
6175 _QueueConsumerGeneratorInfo .__init__ , BoundFunctionWrapper
@@ -69,24 +83,47 @@ def test_instrument_api(self) -> None:
6983 "opentelemetry.instrumentation.pika.PikaInstrumentor._decorate_basic_consume"
7084 )
7185 @mock .patch (
72- "opentelemetry.instrumentation.pika.PikaInstrumentor._instrument_blocking_channel_consumers"
86+ "opentelemetry.instrumentation.pika.PikaInstrumentor._instrument_channel_consumers"
87+ )
88+ def test_instrument_blocking_channel (
89+ self ,
90+ instrument_channel_consumers : mock .MagicMock ,
91+ instrument_basic_consume : mock .MagicMock ,
92+ instrument_channel_functions : mock .MagicMock ,
93+ ):
94+ PikaInstrumentor .instrument_channel (channel = self .blocking_channel )
95+ assert hasattr (
96+ self .blocking_channel , "_is_instrumented_by_opentelemetry"
97+ ), "channel is not marked as instrumented!"
98+ instrument_channel_consumers .assert_called_once ()
99+ instrument_basic_consume .assert_called_once ()
100+ instrument_channel_functions .assert_called_once ()
101+
102+ @mock .patch (
103+ "opentelemetry.instrumentation.pika.PikaInstrumentor._instrument_channel_functions"
104+ )
105+ @mock .patch (
106+ "opentelemetry.instrumentation.pika.PikaInstrumentor._decorate_basic_consume"
107+ )
108+ @mock .patch (
109+ "opentelemetry.instrumentation.pika.PikaInstrumentor._instrument_channel_consumers"
73110 )
74111 def test_instrument_channel (
75112 self ,
76- instrument_blocking_channel_consumers : mock .MagicMock ,
113+ instrument_channel_consumers : mock .MagicMock ,
77114 instrument_basic_consume : mock .MagicMock ,
78115 instrument_channel_functions : mock .MagicMock ,
79116 ):
80117 PikaInstrumentor .instrument_channel (channel = self .channel )
81118 assert hasattr (
82119 self .channel , "_is_instrumented_by_opentelemetry"
83120 ), "channel is not marked as instrumented!"
84- instrument_blocking_channel_consumers .assert_called_once ()
121+ instrument_channel_consumers .assert_called_once ()
85122 instrument_basic_consume .assert_called_once ()
86123 instrument_channel_functions .assert_called_once ()
87124
88125 @mock .patch ("opentelemetry.instrumentation.pika.utils._decorate_callback" )
89- def test_instrument_consumers (
126+ def test_instrument_consumers_on_blocking_channel (
90127 self , decorate_callback : mock .MagicMock
91128 ) -> None :
92129 tracer = mock .MagicMock (spec = Tracer )
@@ -95,23 +132,63 @@ def test_instrument_consumers(
95132 mock .call (
96133 getattr (value , callback_attr ), tracer , key , dummy_callback
97134 )
98- for key , value in self .channel ._consumer_infos .items ()
135+ for key , value in self .blocking_channel ._consumer_infos .items ()
99136 ]
100- PikaInstrumentor ._instrument_blocking_channel_consumers (
101- self .channel , tracer
137+ PikaInstrumentor ._instrument_channel_consumers (
138+ self .blocking_channel , tracer
102139 )
103140 decorate_callback .assert_has_calls (
104141 calls = expected_decoration_calls , any_order = True
105142 )
106143 assert all (
107144 hasattr (callback , "_original_callback" )
108- for callback in self .channel ._consumer_infos .values ()
145+ for callback in self .blocking_channel ._consumer_infos .values ()
146+ )
147+
148+ @mock .patch ("opentelemetry.instrumentation.pika.utils._decorate_callback" )
149+ def test_instrument_consumers_on_channel (
150+ self , decorate_callback : mock .MagicMock
151+ ) -> None :
152+ tracer = mock .MagicMock (spec = Tracer )
153+ callback_attr = PikaInstrumentor .CONSUMER_CALLBACK_ATTR
154+ expected_decoration_calls = [
155+ mock .call (
156+ getattr (value , callback_attr ), tracer , key , dummy_callback
157+ )
158+ for key , value in self .channel ._consumers .items ()
159+ ]
160+ PikaInstrumentor ._instrument_channel_consumers (self .channel , tracer )
161+ decorate_callback .assert_has_calls (
162+ calls = expected_decoration_calls , any_order = True
163+ )
164+ assert all (
165+ hasattr (callback , "_original_callback" )
166+ for callback in self .channel ._consumers .values ()
109167 )
110168
111169 @mock .patch (
112170 "opentelemetry.instrumentation.pika.utils._decorate_basic_publish"
113171 )
114- def test_instrument_basic_publish (
172+ def test_instrument_basic_publish_on_blocking_channel (
173+ self , decorate_basic_publish : mock .MagicMock
174+ ) -> None :
175+ tracer = mock .MagicMock (spec = Tracer )
176+ original_function = self .blocking_channel .basic_publish
177+ PikaInstrumentor ._instrument_basic_publish (
178+ self .blocking_channel , tracer
179+ )
180+ decorate_basic_publish .assert_called_once_with (
181+ original_function , self .blocking_channel , tracer , dummy_callback
182+ )
183+ self .assertEqual (
184+ self .blocking_channel .basic_publish ,
185+ decorate_basic_publish .return_value ,
186+ )
187+
188+ @mock .patch (
189+ "opentelemetry.instrumentation.pika.utils._decorate_basic_publish"
190+ )
191+ def test_instrument_basic_publish_on_channel (
115192 self , decorate_basic_publish : mock .MagicMock
116193 ) -> None :
117194 tracer = mock .MagicMock (spec = Tracer )
@@ -141,6 +218,17 @@ def test_instrument_queue_consumer_generator(self) -> None:
141218 isinstance (generator_info .pending_events , ReadyMessagesDequeProxy )
142219 )
143220
221+ def test_uninstrument_blocking_channel_functions (self ) -> None :
222+ original_function = self .blocking_channel .basic_publish
223+ self .blocking_channel .basic_publish = mock .MagicMock ()
224+ self .blocking_channel .basic_publish ._original_function = (
225+ original_function
226+ )
227+ PikaInstrumentor ._uninstrument_channel_functions (self .blocking_channel )
228+ self .assertEqual (
229+ self .blocking_channel .basic_publish , original_function
230+ )
231+
144232 def test_uninstrument_channel_functions (self ) -> None :
145233 original_function = self .channel .basic_publish
146234 self .channel .basic_publish = mock .MagicMock ()
0 commit comments