open-telemetry / open-telemetry/opentelemetry-python-contrib
Flaky sqlalchemy tests on Pypy
Open
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 1.1k
- Forks
- 1.1k
- Avg merge
- 4d 15h
- Merged PRs (30d)
- 16
Description
=================================== FAILURES ===================================
________ TestSqlalchemyInstrumentation.test_create_async_engine_wrapper ________
self = <tests.test_sqlalchemy.TestSqlalchemyInstrumentation testMethod=test_create_async_engine_wrapper>
def tearDown(self):
super().tearDown()
> SQLAlchemyInstrumentor().uninstrument()
instrumentation/opentelemetry-instrumentation-sqlalchemy/tests/test_sqlalchemy.py:60:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
opentelemetry-instrumentation/src/opentelemetry/instrumentation/instrumentor.py:128: in uninstrument
result = self._uninstrument(**kwargs)
instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/__init__.py:304: in _uninstrument
EngineTracer.remove_all_event_listeners()
instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/engine.py:319: in remove_all_event_listeners
remove(weak_ref_target(), identifier, func)
.tox/pypy3-test-instrumentation-sqlalchemy-1/lib/pypy3.10/site-packages/sqlalchemy/event/api.py:213: in remove
_event_key(target, identifier, fn).remove()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
target = None, identifier = 'checkout'
fn = <bound method EngineTracer._pool_checkout of <opentelemetry.instrumentation.sqlalchemy.engine.EngineTracer object at 0x000000000a8c4598>>
def _event_key(target, identifier, fn):
for evt_cls in _registrars[identifier]:
tgt = evt_cls._accept_with(target)
if tgt is not None:
return _EventKey(target, identifier, fn, tgt)
else:
> raise exc.InvalidRequestError(
"No such event '%s' for target '%s'" % (identifier, target)
)
E sqlalchemy.exc.InvalidRequestError: No such event 'checkout' for target 'None'
.tox/pypy3-test-instrumentation-sqlalchemy-1/lib/pypy3.10/site-packages/sqlalchemy/event/api.py:29: InvalidRequestError
_ TestSqlalchemyInstrumentation.test_create_async_engine_wrapper_enable_commenter _
self = <tests.test_sqlalchemy.TestSqlalchemyInstrumentation testMethod=test_create_async_engine_wrapper_enable_commenter>
@pytest.mark.skipif(
not sqlalchemy.__version__.startswith("1.4"),
reason="only run async tests for 1.4",
)
def test_create_async_engine_wrapper_enable_commenter(self):
async def run():
logging.getLogger("sqlalchemy.engine").setLevel(logging.INFO)
SQLAlchemyInstrumentor().instrument(
enable_commenter=True,
commenter_options={
"db_framework": False,
},
)
from sqlalchemy.ext.asyncio import ( # pylint: disable-all # noqa: PLC0415
create_async_engine,
)
engine = create_async_engine("sqlite+aiosqlite:///:memory:")
async with engine.connect() as cnx:
await cnx.execute(text("SELECT 1;"))
# sqlcommenter
self.assertRegex(
self.caplog.records[1].getMessage(),
r"SELECT 1 /\*db_driver='(.*)',traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;",
)
spans = self.memory_exporter.get_finished_spans()
self.assertEqual(len(spans), 2)
# first span is connection to db
self.assertEqual(spans[0].name, "connect")
# second span is query itself
query_span = spans[1]
self.assertEqual(
query_span.attributes[DB_STATEMENT],
"SELECT 1;",
)
> asyncio.get_event_loop().run_until_complete(run())
instrumentation/opentelemetry-instrumentation-sqlalchemy/tests/test_sqlalchemy.py:442:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/opt/hostedtoolcache/PyPy/3.10.16/x64/lib/pypy3.10/asyncio/base_events.py:649: in run_until_complete
return future.result()
/opt/hostedtoolcache/PyPy/3.10.16/x64/lib/pypy3.10/asyncio/futures.py:201: in result
raise self._exception.with_traceback(self._exception_tb)
/opt/hostedtoolcache/PyPy/3.10.16/x64/lib/pypy3.10/asyncio/tasks.py:232: in __step
result = coro.send(None)
instrumentation/opentelemetry-instrumentation-sqlalchemy/tests/test_sqlalchemy.py:427: in run
self.assertRegex(
E AssertionError: Regex didn't match: "SELECT 1 /\\*db_driver='(.*)',traceparent='\\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\\d{1,2}'\\*/;" not found in 'BEGIN (implicit)'
------------------------------ Captured log call -------------------------------
WARNING opentelemetry.instrumentation.instrumentor:instrumentor.py:92 Attempting to instrument while already instrumented
INFO sqlalchemy.engine.Engine:base.py:1032 BEGIN (implicit)
INFO sqlalchemy.engine.Engine:base.py:1863 SELECT 1;
INFO sqlalchemy.engine.Engine:base.py:1868 [generated in 0.00030s] ()
INFO sqlalchemy.engine.Engine:base.py:1060 ROLLBACK
=========================== short test summary info ============================
FAILED instrumentation/opentelemetry-instrumentation-sqlalchemy/tests/test_sqlalchemy.py::TestSqlalchemyInstrumentation::test_create_async_engine_wrapper
FAILED instrumentation/opentelemetry-instrumentation-sqlalchemy/tests/test_sqlalchemy.py::TestSqlalchemyInstrumentation::test_create_async_engine_wrapper_enable_commenter
========================= 2 failed, 64 passed in 2.67s =========================
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with instrumentation/opentelemetry-instrumentation-sqlalchemy/tests/test_sqlalchemy.py, especially test_create_async_engine_wrapper and its teardown, then inspect EngineTracer.remove_all_event_listeners in engine.py. Reproduce the failures in the PyPy SQLAlchemy tox environment and check the async test's log and listener cleanup behavior. Done means the affected tests pass reliably on PyPy without breaking the existing SQLAlchemy instrumentation tests.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python, sqlalchemy
- Domain
- backend, testing-qa
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100