|
1 | 1 | import gc |
2 | 2 | from concurrent import futures |
| 3 | +from textwrap import dedent |
3 | 4 | from threading import Thread |
4 | 5 |
|
5 | 6 | import pytest |
6 | 7 |
|
7 | 8 | import sentry_sdk |
8 | 9 | from sentry_sdk import capture_message |
9 | 10 | from sentry_sdk.integrations.threading import ThreadingIntegration |
| 11 | +from sentry_sdk.utils import get_current_thread_meta |
10 | 12 |
|
11 | 13 | original_start = Thread.start |
12 | 14 | original_run = Thread.run |
@@ -207,3 +209,70 @@ def do_some_work(): |
207 | 209 | assert initial_iso_scope._tags == { |
208 | 210 | "initial_tag": "initial_value" |
209 | 211 | }, "The isolation scope in the main thread should not be modified by the started thread." |
| 212 | + |
| 213 | + |
| 214 | +@pytest.mark.parametrize( |
| 215 | + "propagate_scope", |
| 216 | + (True, False), |
| 217 | + ids=["propagate_scope=True", "propagate_scope=False"], |
| 218 | +) |
| 219 | +def test_spans_from_multiple_threads( |
| 220 | + sentry_init, capture_events, render_span_tree, propagate_scope |
| 221 | +): |
| 222 | + sentry_init( |
| 223 | + traces_sample_rate=1.0, |
| 224 | + integrations=[ThreadingIntegration(propagate_scope=propagate_scope)], |
| 225 | + ) |
| 226 | + events = capture_events() |
| 227 | + |
| 228 | + def do_some_work(number): |
| 229 | + with sentry_sdk.start_span( |
| 230 | + op=f"inner-run-{number}", |
| 231 | + name=f"Thread: {get_current_thread_meta()[1]}", |
| 232 | + ): |
| 233 | + pass |
| 234 | + |
| 235 | + threads = [] |
| 236 | + |
| 237 | + with sentry_sdk.start_transaction(op="outer-trx"): |
| 238 | + for number in range(5): |
| 239 | + with sentry_sdk.start_span( |
| 240 | + op=f"outer-submit-{number}", |
| 241 | + name=f"Thread: {get_current_thread_meta()[1]}", |
| 242 | + ): |
| 243 | + t = Thread(target=do_some_work, args=(number,)) |
| 244 | + t.start() |
| 245 | + threads.append(t) |
| 246 | + |
| 247 | + for t in threads: |
| 248 | + t.join() |
| 249 | + |
| 250 | + (event,) = events |
| 251 | + if propagate_scope: |
| 252 | + assert render_span_tree(event) == dedent( |
| 253 | + """\ |
| 254 | + - op="outer-trx": description=null |
| 255 | + - op="outer-submit-0": description="Thread: MainThread" |
| 256 | + - op="inner-run-0": description="Thread: Thread-1 (do_some_work)" |
| 257 | + - op="outer-submit-1": description="Thread: MainThread" |
| 258 | + - op="inner-run-1": description="Thread: Thread-2 (do_some_work)" |
| 259 | + - op="outer-submit-2": description="Thread: MainThread" |
| 260 | + - op="inner-run-2": description="Thread: Thread-3 (do_some_work)" |
| 261 | + - op="outer-submit-3": description="Thread: MainThread" |
| 262 | + - op="inner-run-3": description="Thread: Thread-4 (do_some_work)" |
| 263 | + - op="outer-submit-4": description="Thread: MainThread" |
| 264 | + - op="inner-run-4": description="Thread: Thread-5 (do_some_work)"\ |
| 265 | +""" |
| 266 | + ) |
| 267 | + |
| 268 | + elif not propagate_scope: |
| 269 | + assert render_span_tree(event) == dedent( |
| 270 | + """\ |
| 271 | + - op="outer-trx": description=null |
| 272 | + - op="outer-submit-0": description="Thread: MainThread" |
| 273 | + - op="outer-submit-1": description="Thread: MainThread" |
| 274 | + - op="outer-submit-2": description="Thread: MainThread" |
| 275 | + - op="outer-submit-3": description="Thread: MainThread" |
| 276 | + - op="outer-submit-4": description="Thread: MainThread"\ |
| 277 | +""" |
| 278 | + ) |
0 commit comments