11import asyncio
22from unittest import mock
3-
3+
44import pytest
55from asyncpg import Connection , Record , cursor
6-
6+
77try :
88 # wrapt 2.0.0+
99 from wrapt import BaseObjectProxy # pylint: disable=no-name-in-module
1010except ImportError :
1111 from wrapt import ObjectProxy as BaseObjectProxy
12-
12+
1313from opentelemetry import trace as trace_api
1414from opentelemetry .instrumentation .asyncpg import AsyncPGInstrumentor
1515from opentelemetry .test .test_base import TestBase
16-
17-
16+
17+
1818class TestAsyncPGInstrumentation (TestBase ):
1919 def test_duplicated_instrumentation_can_be_uninstrumented (self ):
2020 AsyncPGInstrumentor ().instrument ()
@@ -26,15 +26,15 @@ def test_duplicated_instrumentation_can_be_uninstrumented(self):
2626 self .assertFalse (
2727 hasattr (method , "_opentelemetry_ext_asyncpg_applied" )
2828 )
29-
29+
3030 def test_duplicated_instrumentation_works (self ):
3131 first = AsyncPGInstrumentor ()
3232 first .instrument ()
3333 second = AsyncPGInstrumentor ()
3434 second .instrument ()
3535 self .assertIsNotNone (first ._tracer )
3636 self .assertIsNotNone (second ._tracer )
37-
37+
3838 def test_duplicated_uninstrumentation (self ):
3939 AsyncPGInstrumentor ().instrument ()
4040 AsyncPGInstrumentor ().uninstrument ()
@@ -45,7 +45,7 @@ def test_duplicated_uninstrumentation(self):
4545 self .assertFalse (
4646 hasattr (method , "_opentelemetry_ext_asyncpg_applied" )
4747 )
48-
48+
4949 def test_cursor_instrumentation (self ):
5050 def assert_wrapped (assert_fnc ):
5151 for cls , methods in [
@@ -58,106 +58,108 @@ def assert_wrapped(assert_fnc):
5858 isinstance (method , BaseObjectProxy ),
5959 f"{ method } isinstance { type (method )} " ,
6060 )
61-
61+
6262 assert_wrapped (self .assertFalse )
6363 AsyncPGInstrumentor ().instrument ()
6464 assert_wrapped (self .assertTrue )
6565 AsyncPGInstrumentor ().uninstrument ()
6666 assert_wrapped (self .assertFalse )
67-
67+
6868 def test_cursor_span_creation (self ):
6969 """Test the cursor wrapper if it creates spans correctly."""
70-
70+
7171 # Mock out all interaction with postgres
7272 async def bind_mock (* args , ** kwargs ):
7373 return []
74-
74+
7575 async def exec_mock (* args , ** kwargs ):
7676 return [], None , True
77-
77+
7878 conn = mock .Mock ()
7979 conn .is_closed = lambda : False
80-
80+
8181 conn ._protocol = mock .Mock ()
8282 conn ._protocol .bind = bind_mock
8383 conn ._protocol .execute = exec_mock
8484 conn ._protocol .bind_execute = exec_mock
8585 conn ._protocol .close_portal = bind_mock
86-
86+
8787 state = mock .Mock ()
8888 state .closed = False
89-
89+
9090 apg = AsyncPGInstrumentor ()
9191 apg .instrument (tracer_provider = self .tracer_provider )
92-
92+
9393 # init the cursor and fetch a single record
9494 crs = cursor .Cursor (conn , "SELECT * FROM test" , state , [], Record )
9595 asyncio .run (crs ._init (1 ))
9696 asyncio .run (crs .fetch (1 ))
97-
97+
9898 spans = self .memory_exporter .get_finished_spans ()
9999 self .assertEqual (len (spans ), 1 )
100100 self .assertEqual (spans [0 ].name , "CURSOR: SELECT" )
101101 self .assertTrue (spans [0 ].status .is_ok )
102-
102+
103103 # Now test that the StopAsyncIteration of the cursor does not get recorded as an ERROR
104104 crs_iter = cursor .CursorIterator (
105105 conn , "SELECT * FROM test" , state , [], Record , 1 , 1
106106 )
107-
107+
108108 with pytest .raises (StopAsyncIteration ):
109109 asyncio .run (crs_iter .__anext__ ())
110-
110+
111111 spans = self .memory_exporter .get_finished_spans ()
112112 self .assertEqual (len (spans ), 2 )
113113 self .assertEqual ([span .status .is_ok for span in spans ], [True , True ])
114-
114+
115115 def test_no_op_tracer_provider (self ):
116116 AsyncPGInstrumentor ().uninstrument ()
117117 AsyncPGInstrumentor ().instrument (
118118 tracer_provider = trace_api .NoOpTracerProvider ()
119119 )
120-
120+
121121 # Mock out all interaction with postgres
122122 async def bind_mock (* args , ** kwargs ):
123123 return []
124-
124+
125125 async def exec_mock (* args , ** kwargs ):
126126 return [], None , True
127-
127+
128128 conn = mock .Mock ()
129129 conn .is_closed = lambda : False
130-
130+
131131 conn ._protocol = mock .Mock ()
132132 conn ._protocol .bind = bind_mock
133133 conn ._protocol .execute = exec_mock
134134 conn ._protocol .bind_execute = exec_mock
135135 conn ._protocol .close_portal = bind_mock
136-
136+
137137 state = mock .Mock ()
138138 state .closed = False
139-
139+
140140 # init the cursor and fetch a single record
141141 crs = cursor .Cursor (conn , "SELECT * FROM test" , state , [], Record )
142142 asyncio .run (crs ._init (1 ))
143143 asyncio .run (crs .fetch (1 ))
144-
144+
145145 spans = self .memory_exporter .get_finished_spans ()
146- def test_capture_connection_cleanup_false (self ):
146+ self .assertEqual (len (spans ), 0 )
147+
148+ def test_capture_connection_cleanup_false (self ):
147149 """Test that cleanup queries are not traced when capture_connection_cleanup=False."""
148150 AsyncPGInstrumentor ().uninstrument ()
149151 apg = AsyncPGInstrumentor (capture_connection_cleanup = False )
150152 apg .instrument (tracer_provider = self .tracer_provider )
151-
153+
152154 async def mock_execute (* args , ** kwargs ):
153155 return None
154-
156+
155157 conn = mock .Mock ()
156158 conn ._params = mock .Mock ()
157159 conn ._params .database = "testdb"
158160 conn ._params .user = "testuser"
159161 conn ._addr = ("localhost" , 5432 )
160-
162+
161163 for cleanup_query in [
162164 "SELECT pg_advisory_unlock_all()" ,
163165 "CLOSE ALL" ,
@@ -167,7 +169,7 @@ async def mock_execute(*args, **kwargs):
167169 asyncio .run (
168170 apg ._do_execute (mock_execute , conn , (cleanup_query ,), {})
169171 )
170-
172+
171173 spans = self .memory_exporter .get_finished_spans ()
172174 self .assertEqual (len (spans ), 0 )
173- self . assertEqual ( len ( spans ), 0 )
175+
0 commit comments