diff --git a/tests/tracing/test_misc.py b/tests/tracing/test_misc.py index 0a62a5e0a0..4fb881c9da 100644 --- a/tests/tracing/test_misc.py +++ b/tests/tracing/test_misc.py @@ -1,6 +1,3 @@ -import gc -import os -import uuid from unittest import mock from unittest.mock import MagicMock @@ -263,122 +260,6 @@ def test_finds_non_orphan_span_on_scope_span_streaming(sentry_init): assert scope._span.name == "sniffing" -def test_circular_references(monkeypatch, sentry_init, request): - # TODO: We discovered while writing this test about transaction/span - # reference cycles that there's actually also a circular reference in - # `serializer.py`, between the functions `_serialize_node` and - # `_serialize_node_impl`, both of which are defined inside of the main - # `serialize` function, and each of which calls the other one. For now, in - # order to avoid having those ref cycles give us a false positive here, we - # can mock out `serialize`. In the long run, though, we should probably fix - # that. (Whenever we do work on fixing it, it may be useful to add - # - # gc.set_debug(gc.DEBUG_LEAK) - # request.addfinalizer(lambda: gc.set_debug(~gc.DEBUG_LEAK)) - # - # immediately after the initial collection below, so we can see what new - # objects the garbage collector has to clean up once `transaction.finish` is - # called and the serializer runs.) - monkeypatch.setattr( - sentry_sdk.client, - "serialize", - mock.Mock( - return_value=None, - ), - ) - - # In certain versions of python, in some environments (specifically, python - # 3.4 when run in GH Actions), we run into a `ctypes` bug which creates - # circular references when `uuid4()` is called, as happens when we're - # generating event ids. Mocking it with an implementation which doesn't use - # the `ctypes` function lets us avoid having false positives when garbage - # collecting. See https://bugs.python.org/issue20519. - monkeypatch.setattr( - uuid, - "uuid4", - mock.Mock( - return_value=uuid.UUID(bytes=os.urandom(16)), - ), - ) - - gc.disable() - request.addfinalizer(gc.enable) - - sentry_init(traces_sample_rate=1.0) - - # Make sure that we're starting with a clean slate before we start creating - # transaction/span reference cycles - gc.collect() - - dogpark_transaction = start_transaction(name="dogpark") - sniffing_span = dogpark_transaction.start_child(op="sniffing") - wagging_span = dogpark_transaction.start_child(op="wagging") - - # At some point, you have to stop sniffing - there are balls to chase! - so finish - # this span while the dogpark transaction is still open - sniffing_span.finish() - - # The wagging, however, continues long past the dogpark, so that span will - # NOT finish before the transaction ends. (Doing it in this order proves - # that both finished and unfinished spans get their cycles broken.) - dogpark_transaction.finish() - - # Eventually you gotta sleep... - wagging_span.finish() - - # assuming there are no cycles by this point, these should all be able to go - # out of scope and get their memory deallocated without the garbage - # collector having anything to do - del sniffing_span - del wagging_span - del dogpark_transaction - - assert gc.collect() == 0 - - -def test_circular_references_span_streaming(monkeypatch, sentry_init, request): - gc.disable() - request.addfinalizer(gc.enable) - - sentry_init( - traces_sample_rate=1.0, - trace_lifecycle="stream", - ) - - # Make sure that we're starting with a clean slate before we start creating - # transaction/span reference cycles - gc.collect() - - dogpark_segment = sentry_sdk.traces.start_span(name="dogpark") - sniffing_span = sentry_sdk.traces.start_span( - name="sniffing", parent_span=dogpark_segment - ) - wagging_span = sentry_sdk.traces.start_span( - name="wagging", parent_span=dogpark_segment - ) - - # At some point, you have to stop sniffing - there are balls to chase! - so finish - # this span while the dogpark transaction is still open - sniffing_span.end() - - # The wagging, however, continues long past the dogpark, so that span will - # NOT finish before the transaction ends. (Doing it in this order proves - # that both finished and unfinished spans get their cycles broken.) - dogpark_segment.end() - - # Eventually you gotta sleep... - wagging_span.end() - - # assuming there are no cycles by this point, these should all be able to go - # out of scope and get their memory deallocated without the garbage - # collector having anything to do - del sniffing_span - del wagging_span - del dogpark_segment - - assert gc.collect() == 0 - - def test_set_measurement(sentry_init, capture_events): sentry_init(traces_sample_rate=1.0)