diff --git a/tests/integrations/boto3/test_trace_propagation.py b/tests/integrations/boto3/test_trace_propagation.py index b04af56855..3f49e32dbd 100644 --- a/tests/integrations/boto3/test_trace_propagation.py +++ b/tests/integrations/boto3/test_trace_propagation.py @@ -176,6 +176,7 @@ def test_presigned_urls_do_not_require_sentry_headers(sentry_init): traces_sample_rate=1.0, default_integrations=False, integrations=[Boto3Integration(), StdlibIntegration()], + trace_lifecycle="stream", ) client = boto3.client( # type: ignore[attr-defined] "s3", diff --git a/tests/integrations/django/test_basic.py b/tests/integrations/django/test_basic.py index 224fd1f4a5..09a8dda1f7 100644 --- a/tests/integrations/django/test_basic.py +++ b/tests/integrations/django/test_basic.py @@ -1514,6 +1514,7 @@ def test_render_spans_queryset_in_data(sentry_init, client, capture_events): ) ], traces_sample_rate=1.0, + trace_lifecycle="stream", ) events = capture_events() diff --git a/tests/integrations/django/test_tasks.py b/tests/integrations/django/test_tasks.py index 1bd9dcd8b0..ffbaf1a250 100644 --- a/tests/integrations/django/test_tasks.py +++ b/tests/integrations/django/test_tasks.py @@ -95,6 +95,7 @@ def test_task_enqueue_returns_result(sentry_init, immediate_backend): sentry_init( integrations=[DjangoIntegration()], traces_sample_rate=1.0, + trace_lifecycle="stream", ) result = add_numbers.enqueue(3, 5) diff --git a/tests/integrations/grpc/test_grpc.py b/tests/integrations/grpc/test_grpc.py index 15575b7344..edd7b96646 100644 --- a/tests/integrations/grpc/test_grpc.py +++ b/tests/integrations/grpc/test_grpc.py @@ -426,7 +426,11 @@ def test_grpc_client_and_servers_interceptors_integration( @pytest.mark.forked def test_stream_stream(sentry_init): - sentry_init(traces_sample_rate=1.0, integrations=[GRPCIntegration()]) + sentry_init( + traces_sample_rate=1.0, + integrations=[GRPCIntegration()], + trace_lifecycle="stream", + ) server, channel = _set_up() # Use the provided channel @@ -444,7 +448,11 @@ def test_stream_unary(sentry_init): Test to verify stream-stream works. Tracing not supported for it yet. """ - sentry_init(traces_sample_rate=1.0, integrations=[GRPCIntegration()]) + sentry_init( + traces_sample_rate=1.0, + integrations=[GRPCIntegration()], + trace_lifecycle="stream", + ) server, channel = _set_up() # Use the provided channel diff --git a/tests/integrations/threading/test_threading.py b/tests/integrations/threading/test_threading.py index 03aec5d815..f64ede4c00 100644 --- a/tests/integrations/threading/test_threading.py +++ b/tests/integrations/threading/test_threading.py @@ -129,65 +129,72 @@ def do_some_work(): ids=["propagate_scope=True", "propagate_scope=False"], ) def test_spans_from_multiple_threads( - sentry_init, capture_events, render_span_tree, propagate_scope + sentry_init, capture_items, render_span_tree, propagate_scope ): sentry_init( traces_sample_rate=1.0, integrations=[ThreadingIntegration(propagate_scope=propagate_scope)], + trace_lifecycle="stream", ) - events = capture_events() + items = capture_items("span") def do_some_work(number): - with sentry_sdk.start_span( - op=f"inner-run-{number}", name=f"Thread: child-{number}" + with sentry_sdk.traces.start_span( + name=f"Thread: child-{number}", + attributes={"sentry.op": f"inner-run-{number}"}, ): pass - threads = [] - - with sentry_sdk.start_transaction(op="outer-trx"): + with sentry_sdk.traces.start_span( + name="root span", attributes={"sentry.op": "outer-trx"}, parent_span=None + ): for number in range(5): - with sentry_sdk.start_span( - op=f"outer-submit-{number}", name="Thread: main" + with sentry_sdk.traces.start_span( + name="Thread: main", + attributes={"sentry.op": f"outer-submit-{number}"}, ): t = Thread(target=do_some_work, args=(number,)) t.start() - threads.append(t) + t.join() - for t in threads: - t.join() + sentry_sdk.flush() - (event,) = events + spans = [item.payload for item in items] - # Free-threaded builds set thread_inherit_context to True, otherwise thread_inherit_context is False - if propagate_scope or getattr(sys.flags, "thread_inherit_context", None): - assert event["type"] == "transaction" - assert render_span_tree(event["spans"], event["contexts"]["trace"]) == dedent( + # Filter to the main trace only (child threads with propagate_scope=False + # create spans on a separate trace that confuse render_span_tree). + root = next(s for s in spans if s.get("is_segment") and s["name"] == "root span") + spans = [s for s in spans if s["trace_id"] == root["trace_id"]] + + expects_child_spans = propagate_scope or getattr( + sys.flags, "thread_inherit_context", None + ) + if expects_child_spans: + assert render_span_tree(spans) == dedent( """\ - - op="outer-trx": description=null - - op="outer-submit-0": description="Thread: main" - - op="inner-run-0": description="Thread: child-0" - - op="outer-submit-1": description="Thread: main" - - op="inner-run-1": description="Thread: child-1" - - op="outer-submit-2": description="Thread: main" - - op="inner-run-2": description="Thread: child-2" - - op="outer-submit-3": description="Thread: main" - - op="inner-run-3": description="Thread: child-3" - - op="outer-submit-4": description="Thread: main" - - op="inner-run-4": description="Thread: child-4"\ + - sentry.op="outer-trx": name="root span" + - sentry.op="outer-submit-0": name="Thread: main" + - sentry.op="inner-run-0": name="Thread: child-0" + - sentry.op="outer-submit-1": name="Thread: main" + - sentry.op="inner-run-1": name="Thread: child-1" + - sentry.op="outer-submit-2": name="Thread: main" + - sentry.op="inner-run-2": name="Thread: child-2" + - sentry.op="outer-submit-3": name="Thread: main" + - sentry.op="inner-run-3": name="Thread: child-3" + - sentry.op="outer-submit-4": name="Thread: main" + - sentry.op="inner-run-4": name="Thread: child-4"\ """ ) elif not propagate_scope: - assert event["type"] == "transaction" - assert render_span_tree(event["spans"], event["contexts"]["trace"]) == dedent( + assert render_span_tree(spans) == dedent( """\ - - op="outer-trx": description=null - - op="outer-submit-0": description="Thread: main" - - op="outer-submit-1": description="Thread: main" - - op="outer-submit-2": description="Thread: main" - - op="outer-submit-3": description="Thread: main" - - op="outer-submit-4": description="Thread: main"\ + - sentry.op="outer-trx": name="root span" + - sentry.op="outer-submit-0": name="Thread: main" + - sentry.op="outer-submit-1": name="Thread: main" + - sentry.op="outer-submit-2": name="Thread: main" + - sentry.op="outer-submit-3": name="Thread: main" + - sentry.op="outer-submit-4": name="Thread: main"\ """ ) @@ -198,59 +205,68 @@ def do_some_work(number): ids=["propagate_scope=True", "propagate_scope=False"], ) def test_spans_from_threadpool( - sentry_init, capture_events, render_span_tree, propagate_scope + sentry_init, capture_items, render_span_tree, propagate_scope ): sentry_init( traces_sample_rate=1.0, integrations=[ThreadingIntegration(propagate_scope=propagate_scope)], + trace_lifecycle="stream", ) - events = capture_events() + items = capture_items("span") def do_some_work(number): - with sentry_sdk.start_span( - op=f"inner-run-{number}", name=f"Thread: child-{number}" + with sentry_sdk.traces.start_span( + name=f"Thread: child-{number}", + attributes={"sentry.op": f"inner-run-{number}"}, ): pass - with sentry_sdk.start_transaction(op="outer-trx"): + with sentry_sdk.traces.start_span( + name="root span", attributes={"sentry.op": "outer-trx"}, parent_span=None + ): with futures.ThreadPoolExecutor(max_workers=1) as executor: for number in range(5): - with sentry_sdk.start_span( - op=f"outer-submit-{number}", name="Thread: main" + with sentry_sdk.traces.start_span( + name="Thread: main", + attributes={"sentry.op": f"outer-submit-{number}"}, ): future = executor.submit(do_some_work, number) future.result() - (event,) = events + sentry_sdk.flush() + + spans = [item.payload for item in items] + root = next(s for s in spans if s.get("is_segment") and s["name"] == "root span") + spans = [s for s in spans if s["trace_id"] == root["trace_id"]] - # Free-threaded builds set thread_inherit_context to True, otherwise thread_inherit_context is False - if propagate_scope or getattr(sys.flags, "thread_inherit_context", None): - assert event["type"] == "transaction" - assert render_span_tree(event["spans"], event["contexts"]["trace"]) == dedent( + expects_child_spans = propagate_scope or getattr( + sys.flags, "thread_inherit_context", None + ) + if expects_child_spans: + assert render_span_tree(spans) == dedent( """\ - - op="outer-trx": description=null - - op="outer-submit-0": description="Thread: main" - - op="inner-run-0": description="Thread: child-0" - - op="outer-submit-1": description="Thread: main" - - op="inner-run-1": description="Thread: child-1" - - op="outer-submit-2": description="Thread: main" - - op="inner-run-2": description="Thread: child-2" - - op="outer-submit-3": description="Thread: main" - - op="inner-run-3": description="Thread: child-3" - - op="outer-submit-4": description="Thread: main" - - op="inner-run-4": description="Thread: child-4"\ + - sentry.op="outer-trx": name="root span" + - sentry.op="outer-submit-0": name="Thread: main" + - sentry.op="inner-run-0": name="Thread: child-0" + - sentry.op="outer-submit-1": name="Thread: main" + - sentry.op="inner-run-1": name="Thread: child-1" + - sentry.op="outer-submit-2": name="Thread: main" + - sentry.op="inner-run-2": name="Thread: child-2" + - sentry.op="outer-submit-3": name="Thread: main" + - sentry.op="inner-run-3": name="Thread: child-3" + - sentry.op="outer-submit-4": name="Thread: main" + - sentry.op="inner-run-4": name="Thread: child-4"\ """ ) elif not propagate_scope: - assert event["type"] == "transaction" - assert render_span_tree(event["spans"], event["contexts"]["trace"]) == dedent( + assert render_span_tree(spans) == dedent( """\ - - op="outer-trx": description=null - - op="outer-submit-0": description="Thread: main" - - op="outer-submit-1": description="Thread: main" - - op="outer-submit-2": description="Thread: main" - - op="outer-submit-3": description="Thread: main" - - op="outer-submit-4": description="Thread: main"\ + - sentry.op="outer-trx": name="root span" + - sentry.op="outer-submit-0": name="Thread: main" + - sentry.op="outer-submit-1": name="Thread: main" + - sentry.op="outer-submit-2": name="Thread: main" + - sentry.op="outer-submit-3": name="Thread: main" + - sentry.op="outer-submit-4": name="Thread: main"\ """ )