Skip to content

Commit 0158026

Browse files
archy-rock3t-cloudtammy-baylis-swixrmx
authored
test(sqlite3): add uninstrument, error status, suppress, and no-op tests (#4335)
* test(sqlite3): add uninstrument, error, suppress, and no-op tests Signed-off-by: Artem Muterko <artem@sopho.tech> Signed-off-by: Artem Muterko <artieua@gmail.com> * test(sqlite3): address review feedback and add CHANGELOG - Add _connect helper with addCleanup for proper resource teardown - Rename test_uninstrument_connection to test_uninstrument_connection_with_instrument for consistency with psycopg2 - Use same query before and after uninstrumenting - Clear memory exporter and assert zero spans after uninstrument - Use sqlite3.OperationalError instead of generic Exception - Add span.status.description assertion for error test - Add CHANGELOG entry Signed-off-by: Artem Muterko <artem@sopho.tech> Signed-off-by: Artem Muterko <artieua@gmail.com> * test(sqlite3): add additional tests Signed-off-by: Artem Muterko <artem@sopho.tech> Signed-off-by: Artem Muterko <artieua@gmail.com> * Update CHANGELOG.md --------- Signed-off-by: Artem Muterko <artem@sopho.tech> Signed-off-by: Artem Muterko <artieua@gmail.com> Co-authored-by: Tammy Baylis <96076570+tammy-baylis-swi@users.noreply.github.com> Co-authored-by: Riccardo Magliocchetti <riccardo.magliocchetti@gmail.com>
1 parent 3ece058 commit 0158026

2 files changed

Lines changed: 110 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1515

1616
- Bump `pylint` to `4.0.5`
1717
([#4244](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4244))
18+
- `opentelemetry-instrumentation-sqlite3`: Add uninstrument, error status, suppress, and no-op tests
19+
([#4335](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4335))
1820

1921
### Fixed
2022

instrumentation/opentelemetry-instrumentation-sqlite3/tests/test_sqlite3.py

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@
1717

1818
from opentelemetry import trace as trace_api
1919
from opentelemetry.instrumentation.sqlite3 import SQLite3Instrumentor
20+
from opentelemetry.instrumentation.utils import suppress_instrumentation
21+
from opentelemetry.semconv._incubating.attributes.db_attributes import (
22+
DB_STATEMENT,
23+
)
2024
from opentelemetry.test.test_base import TestBase
2125

2226

@@ -120,3 +124,107 @@ def test_callproc(self):
120124
):
121125
self._cursor.callproc("test", ())
122126
self.validate_spans("test")
127+
128+
129+
class TestSQLite3Integration(TestBase):
130+
def tearDown(self):
131+
super().tearDown()
132+
SQLite3Instrumentor().uninstrument()
133+
134+
def _connect(self):
135+
"""Create an in-memory connection with cleanup registered."""
136+
cnx = sqlite3.connect(":memory:")
137+
self.addCleanup(cnx.close)
138+
return cnx
139+
140+
def test_uninstrument(self):
141+
"""Should stop generating spans after uninstrument."""
142+
SQLite3Instrumentor().instrument(tracer_provider=self.tracer_provider)
143+
cnx = self._connect()
144+
cursor = cnx.cursor()
145+
self.addCleanup(cursor.close)
146+
cursor.execute("CREATE TABLE IF NOT EXISTS test (id integer)")
147+
148+
spans_list = self.memory_exporter.get_finished_spans()
149+
self.assertEqual(len(spans_list), 1)
150+
151+
SQLite3Instrumentor().uninstrument()
152+
self.memory_exporter.clear()
153+
154+
cnx2 = self._connect()
155+
cursor2 = cnx2.cursor()
156+
self.addCleanup(cursor2.close)
157+
cursor2.execute("CREATE TABLE IF NOT EXISTS test (id integer)")
158+
159+
spans_list = self.memory_exporter.get_finished_spans()
160+
self.assertEqual(len(spans_list), 0)
161+
162+
def test_uninstrument_connection_with_instrument(self):
163+
"""Should stop generating spans for uninstrumented connection."""
164+
SQLite3Instrumentor().instrument(tracer_provider=self.tracer_provider)
165+
cnx = self._connect()
166+
query = "CREATE TABLE IF NOT EXISTS test (id integer)"
167+
cursor = cnx.cursor()
168+
self.addCleanup(cursor.close)
169+
cursor.execute(query)
170+
171+
spans_list = self.memory_exporter.get_finished_spans()
172+
self.assertEqual(len(spans_list), 1)
173+
174+
self.memory_exporter.clear()
175+
cnx = SQLite3Instrumentor.uninstrument_connection(cnx)
176+
cursor = cnx.cursor()
177+
self.addCleanup(cursor.close)
178+
cursor.execute(query)
179+
180+
spans_list = self.memory_exporter.get_finished_spans()
181+
self.assertEqual(len(spans_list), 0)
182+
183+
def test_no_op_tracer_provider(self):
184+
"""Should produce no spans with NoOpTracerProvider."""
185+
SQLite3Instrumentor().instrument(
186+
tracer_provider=trace_api.NoOpTracerProvider()
187+
)
188+
cnx = self._connect()
189+
cursor = cnx.cursor()
190+
self.addCleanup(cursor.close)
191+
cursor.execute("CREATE TABLE IF NOT EXISTS test (id integer)")
192+
193+
spans_list = self.memory_exporter.get_finished_spans()
194+
self.assertEqual(len(spans_list), 0)
195+
196+
def test_suppress_instrumentation(self):
197+
"""Should produce no spans when suppressed."""
198+
SQLite3Instrumentor().instrument(tracer_provider=self.tracer_provider)
199+
cnx = self._connect()
200+
201+
with suppress_instrumentation():
202+
cursor = cnx.cursor()
203+
self.addCleanup(cursor.close)
204+
cursor.execute("CREATE TABLE IF NOT EXISTS test (id integer)")
205+
206+
spans_list = self.memory_exporter.get_finished_spans()
207+
self.assertEqual(len(spans_list), 0)
208+
209+
def test_span_failed(self):
210+
"""Should set error status on span when query fails."""
211+
SQLite3Instrumentor().instrument(tracer_provider=self.tracer_provider)
212+
cnx = self._connect()
213+
cursor = cnx.cursor()
214+
self.addCleanup(cursor.close)
215+
216+
with self.assertRaises(sqlite3.OperationalError):
217+
cursor.execute("SELECT * FROM nonexistent_table")
218+
219+
spans_list = self.memory_exporter.get_finished_spans()
220+
self.assertEqual(len(spans_list), 1)
221+
span = spans_list[0]
222+
self.assertEqual(
223+
span.attributes[DB_STATEMENT],
224+
"SELECT * FROM nonexistent_table",
225+
)
226+
self.assertIs(span.status.status_code, trace_api.StatusCode.ERROR)
227+
self.assertEqual(
228+
span.status.description,
229+
"OperationalError: no such table: nonexistent_table",
230+
)

0 commit comments

Comments
 (0)