Skip to content

Commit 413c98e

Browse files
rite7shxrmx
andauthored
test(mysql): provide concrete DBAPI connection attributes in mocks (#4116)
* test(mysql): provide concrete DBAPI connection attributes in mocks * test(mysql): pass concrete attributes via MagicMock helpers * test(mysql): refactor mocks and remove redundant attribute assignments * changelog: add mysql test mock fix entry * test(mysql): refactor SQL commenter mocks into helper * test(mysql): refactor SQL commenter mocks into helper - Introduce make_mysql_commenter_mocks helper - Remove duplicated MagicMock setup - Preserve test assertions and behavior - Improve readability and maintainability * test(mysql): use concrete DBAPI connection attributes in mocks to fix attribute type warnings * Update instrumentation/opentelemetry-instrumentation-mysql/tests/test_mysql_integration.py --------- Co-authored-by: Riccardo Magliocchetti <riccardo.magliocchetti@gmail.com>
1 parent 87b20ab commit 413c98e

2 files changed

Lines changed: 63 additions & 90 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
5959
([#4139](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4139))
6060

6161
### Fixed
62-
62+
- `opentelemetry-instrumentation-mysql`: Refactor MySQL integration test mocks to use concrete DBAPI connection attributes, reducing noisy attribute type warnings.
63+
([#4116](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4116))
6364
- `opentelemetry-instrumentation-cassandra`: Use `_instruments_any` instead of `_instruments` for driver dependencies so that having either `cassandra-driver` or `scylla-driver` installed is sufficient
6465
([#4182](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4182))
6566
- `opentelemetry-instrumentation-asyncpg`: Hydrate span attributes before creation so samplers can filter on database details

instrumentation/opentelemetry-instrumentation-mysql/tests/test_mysql_integration.py

Lines changed: 61 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,50 @@ def connect_and_execute_query():
3535
return cnx, query
3636

3737

38+
def make_mysql_connection_mock():
39+
cnx = mock.MagicMock()
40+
cnx.database = "test"
41+
cnx.server_host = "localhost"
42+
cnx.server_port = 3306
43+
44+
cursor = mock.MagicMock()
45+
cursor._cnx = cnx
46+
47+
cnx.cursor.return_value = cursor
48+
return cnx
49+
50+
51+
def make_mysql_commenter_mocks(client_version="foobaz"):
52+
"""Create mock objects for MySQL connector with SQL commenter support.
53+
54+
Args:
55+
client_version: The MySQL client version string to return from get_client_info()
56+
57+
Returns:
58+
Tuple of (mock_connect_module, mock_connection, mock_cursor)
59+
"""
60+
mock_connect_module = mock.MagicMock(
61+
__name__="mysql.connector",
62+
__version__="foobar",
63+
threadsafety="123",
64+
apilevel="123",
65+
paramstyle="test",
66+
)
67+
mock_connection = mock.MagicMock()
68+
mock_connection.database = "test"
69+
mock_connection.server_host = "localhost"
70+
mock_connection.server_port = 3306
71+
72+
mock_cursor = mock_connect_module.connect().cursor()
73+
mock_cursor._cnx = mock_connection
74+
mock_cursor._cnx._cmysql.get_client_info.return_value = client_version
75+
76+
mock_connection.cursor.return_value = mock_cursor
77+
mock_connect_module.connect.return_value = mock_connection
78+
79+
return mock_connect_module, mock_connection, mock_cursor
80+
81+
3882
class TestMysqlIntegration(TestBase):
3983
def tearDown(self):
4084
super().tearDown()
@@ -44,6 +88,7 @@ def tearDown(self):
4488
@mock.patch("mysql.connector.connect")
4589
# pylint: disable=unused-argument
4690
def test_instrumentor(self, mock_connect):
91+
mock_connect.return_value = make_mysql_connection_mock()
4792
MySQLInstrumentor().instrument()
4893

4994
connect_and_execute_query()
@@ -68,6 +113,7 @@ def test_instrumentor(self, mock_connect):
68113
@mock.patch("mysql.connector.connect")
69114
# pylint: disable=unused-argument
70115
def test_custom_tracer_provider(self, mock_connect):
116+
mock_connect.return_value = make_mysql_connection_mock()
71117
resource = resources.Resource.create({})
72118
result = self.create_tracer_provider(resource=resource)
73119
tracer_provider, exporter = result
@@ -84,6 +130,7 @@ def test_custom_tracer_provider(self, mock_connect):
84130
@mock.patch("mysql.connector.connect")
85131
# pylint: disable=unused-argument
86132
def test_instrument_connection(self, mock_connect):
133+
mock_connect.return_value = make_mysql_connection_mock()
87134
cnx, query = connect_and_execute_query()
88135

89136
spans_list = self.memory_exporter.get_finished_spans()
@@ -98,6 +145,7 @@ def test_instrument_connection(self, mock_connect):
98145

99146
@mock.patch("mysql.connector.connect")
100147
def test_instrument_connection_no_op_tracer_provider(self, mock_connect):
148+
mock_connect.return_value = make_mysql_connection_mock()
101149
tracer_provider = trace_api.NoOpTracerProvider()
102150
MySQLInstrumentor().instrument(tracer_provider=tracer_provider)
103151
connect_and_execute_query()
@@ -128,17 +176,9 @@ def test_instrument_connection_enable_commenter_dbapi_kwargs(
128176
self.assertEqual(kwargs["enable_attribute_commenter"], True)
129177

130178
def test_instrument_connection_with_dbapi_sqlcomment_enabled(self):
131-
mock_connect_module = mock.MagicMock(
132-
__name__="mysql.connector",
133-
__version__="foobar",
134-
threadsafety="123",
135-
apilevel="123",
136-
paramstyle="test",
179+
mock_connect_module, mock_connection, mock_cursor = (
180+
make_mysql_commenter_mocks()
137181
)
138-
mock_cursor = mock_connect_module.connect().cursor()
139-
mock_cursor._cnx._cmysql.get_client_info.return_value = "foobaz"
140-
mock_connection = mock.MagicMock()
141-
mock_connection.cursor.return_value = mock_cursor
142182

143183
with mock.patch(
144184
"opentelemetry.instrumentation.mysql.mysql.connector",
@@ -166,17 +206,9 @@ def test_instrument_connection_with_dbapi_sqlcomment_enabled(self):
166206
def test_instrument_connection_with_dbapi_sqlcomment_enabled_stmt_enabled(
167207
self,
168208
):
169-
mock_connect_module = mock.MagicMock(
170-
__name__="mysql.connector",
171-
__version__="foobar",
172-
threadsafety="123",
173-
apilevel="123",
174-
paramstyle="test",
209+
mock_connect_module, mock_connection, mock_cursor = (
210+
make_mysql_commenter_mocks()
175211
)
176-
mock_cursor = mock_connect_module.connect().cursor()
177-
mock_cursor._cnx._cmysql.get_client_info.return_value = "foobaz"
178-
mock_connection = mock.MagicMock()
179-
mock_connection.cursor.return_value = mock_cursor
180212

181213
with mock.patch(
182214
"opentelemetry.instrumentation.mysql.mysql.connector",
@@ -205,17 +237,9 @@ def test_instrument_connection_with_dbapi_sqlcomment_enabled_stmt_enabled(
205237
def test_instrument_connection_with_dbapi_sqlcomment_enabled_with_options(
206238
self,
207239
):
208-
mock_connect_module = mock.MagicMock(
209-
__name__="mysql.connector",
210-
__version__="foobar",
211-
threadsafety="123",
212-
apilevel="123",
213-
paramstyle="test",
240+
mock_connect_module, mock_connection, mock_cursor = (
241+
make_mysql_commenter_mocks()
214242
)
215-
mock_cursor = mock_connect_module.connect().cursor()
216-
mock_cursor._cnx._cmysql.get_client_info.return_value = "foobaz"
217-
mock_connection = mock.MagicMock()
218-
mock_connection.cursor.return_value = mock_cursor
219243

220244
with mock.patch(
221245
"opentelemetry.instrumentation.mysql.mysql.connector",
@@ -248,18 +272,9 @@ def test_instrument_connection_with_dbapi_sqlcomment_enabled_with_options(
248272
def test_instrument_connection_with_dbapi_sqlcomment_not_enabled_default(
249273
self,
250274
):
251-
mock_connect_module = mock.MagicMock(
252-
__name__="mysql.connector",
253-
__version__="foobar",
254-
threadsafety="123",
255-
apilevel="123",
256-
paramstyle="test",
275+
mock_connect_module, mock_connection, mock_cursor = (
276+
make_mysql_commenter_mocks()
257277
)
258-
mock_cursor = mock_connect_module.connect().cursor()
259-
mock_cursor._cnx._cmysql.get_client_info.return_value = "foobaz"
260-
mock_cursor = mock_connect_module.connect().cursor()
261-
mock_connection = mock.MagicMock()
262-
mock_connection.cursor.return_value = mock_cursor
263278

264279
with mock.patch(
265280
"opentelemetry.instrumentation.mysql.mysql.connector",
@@ -301,18 +316,7 @@ def test_instrument_enable_commenter_dbapi_kwargs(
301316
def test_instrument_with_dbapi_sqlcomment_enabled(
302317
self,
303318
):
304-
mock_connect_module = mock.MagicMock(
305-
__name__="mysql.connector",
306-
__version__="foobar",
307-
threadsafety="123",
308-
apilevel="123",
309-
paramstyle="test",
310-
)
311-
mock_cursor = mock_connect_module.connect().cursor()
312-
mock_cursor._cnx._cmysql.get_client_info.return_value = "foobaz"
313-
mock_cursor = mock_connect_module.connect().cursor()
314-
mock_connection = mock.MagicMock()
315-
mock_connection.cursor.return_value = mock_cursor
319+
mock_connect_module, _, mock_cursor = make_mysql_commenter_mocks()
316320

317321
with mock.patch(
318322
"opentelemetry.instrumentation.mysql.mysql.connector",
@@ -341,18 +345,7 @@ def test_instrument_with_dbapi_sqlcomment_enabled(
341345
def test_instrument_with_dbapi_sqlcomment_enabled_stmt_enabled(
342346
self,
343347
):
344-
mock_connect_module = mock.MagicMock(
345-
__name__="mysql.connector",
346-
__version__="foobar",
347-
threadsafety="123",
348-
apilevel="123",
349-
paramstyle="test",
350-
)
351-
mock_cursor = mock_connect_module.connect().cursor()
352-
mock_cursor._cnx._cmysql.get_client_info.return_value = "foobaz"
353-
mock_cursor = mock_connect_module.connect().cursor()
354-
mock_connection = mock.MagicMock()
355-
mock_connection.cursor.return_value = mock_cursor
348+
mock_connect_module, _, mock_cursor = make_mysql_commenter_mocks()
356349

357350
with mock.patch(
358351
"opentelemetry.instrumentation.mysql.mysql.connector",
@@ -382,18 +375,7 @@ def test_instrument_with_dbapi_sqlcomment_enabled_stmt_enabled(
382375
def test_instrument_with_dbapi_sqlcomment_enabled_with_options(
383376
self,
384377
):
385-
mock_connect_module = mock.MagicMock(
386-
__name__="mysql.connector",
387-
__version__="foobar",
388-
threadsafety="123",
389-
apilevel="123",
390-
paramstyle="test",
391-
)
392-
mock_cursor = mock_connect_module.connect().cursor()
393-
mock_cursor._cnx._cmysql.get_client_info.return_value = "foobaz"
394-
mock_cursor = mock_connect_module.connect().cursor()
395-
mock_connection = mock.MagicMock()
396-
mock_connection.cursor.return_value = mock_cursor
378+
mock_connect_module, _, mock_cursor = make_mysql_commenter_mocks()
397379

398380
with mock.patch(
399381
"opentelemetry.instrumentation.mysql.mysql.connector",
@@ -427,18 +409,7 @@ def test_instrument_with_dbapi_sqlcomment_enabled_with_options(
427409
def test_instrument_with_dbapi_sqlcomment_not_enabled_default(
428410
self,
429411
):
430-
mock_connect_module = mock.MagicMock(
431-
__name__="mysql.connector",
432-
__version__="foobar",
433-
threadsafety="123",
434-
apilevel="123",
435-
paramstyle="test",
436-
)
437-
mock_cursor = mock_connect_module.connect().cursor()
438-
mock_cursor._cnx._cmysql.get_client_info.return_value = "foobaz"
439-
mock_cursor = mock_connect_module.connect().cursor()
440-
mock_connection = mock.MagicMock()
441-
mock_connection.cursor.return_value = mock_cursor
412+
mock_connect_module, _, mock_cursor = make_mysql_commenter_mocks()
442413

443414
with mock.patch(
444415
"opentelemetry.instrumentation.mysql.mysql.connector",
@@ -462,6 +433,7 @@ def test_instrument_with_dbapi_sqlcomment_not_enabled_default(
462433
@mock.patch("mysql.connector.connect")
463434
# pylint: disable=unused-argument
464435
def test_uninstrument_connection(self, mock_connect):
436+
mock_connect.return_value = make_mysql_connection_mock()
465437
MySQLInstrumentor().instrument()
466438
cnx, query = connect_and_execute_query()
467439

0 commit comments

Comments
 (0)