8
8
import sentry_sdk
9
9
from sentry_sdk .consts import OP
10
10
from sentry_sdk .integrations .asyncio import AsyncioIntegration , patch_asyncio
11
+ from sentry_sdk .utils import mark_sentry_task_internal
12
+
11
13
12
14
try :
13
15
from contextvars import Context , ContextVar
@@ -379,6 +381,55 @@ async def test_span_origin(
379
381
assert event ["spans" ][0 ]["origin" ] == "auto.function.asyncio"
380
382
381
383
384
+ @minimum_python_38
385
+ @pytest .mark .asyncio (loop_scope = "module" )
386
+ async def test_internal_tasks_not_wrapped (sentry_init , capture_events ):
387
+
388
+ sentry_init (integrations = [AsyncioIntegration ()], traces_sample_rate = 1.0 )
389
+ events = capture_events ()
390
+
391
+ # Create a user task that should be wrapped
392
+ async def user_task ():
393
+ await asyncio .sleep (0.01 )
394
+ return "user_result"
395
+
396
+ # Create an internal task that should NOT be wrapped
397
+ async def internal_task ():
398
+ await asyncio .sleep (0.01 )
399
+ return "internal_result"
400
+
401
+ with sentry_sdk .start_transaction (name = "test_transaction" ):
402
+ user_task_obj = asyncio .create_task (user_task ())
403
+
404
+ with mark_sentry_task_internal ():
405
+ internal_task_obj = asyncio .create_task (internal_task ())
406
+
407
+ user_result = await user_task_obj
408
+ internal_result = await internal_task_obj
409
+
410
+ assert user_result == "user_result"
411
+ assert internal_result == "internal_result"
412
+
413
+ assert len (events ) == 1
414
+ transaction = events [0 ]
415
+
416
+ user_spans = []
417
+ internal_spans = []
418
+
419
+ for span in transaction .get ("spans" , []):
420
+ if "user_task" in span .get ("description" , "" ):
421
+ user_spans .append (span )
422
+ elif "internal_task" in span .get ("description" , "" ):
423
+ internal_spans .append (span )
424
+
425
+ assert (
426
+ len (user_spans ) > 0
427
+ ), f"User task should have been traced. All spans: { [s .get ('description' ) for s in transaction .get ('spans' , [])]} "
428
+ assert (
429
+ len (internal_spans ) == 0
430
+ ), f"Internal task should NOT have been traced. All spans: { [s .get ('description' ) for s in transaction .get ('spans' , [])]} "
431
+
432
+
382
433
@minimum_python_38
383
434
def test_loop_close_patching (sentry_init ):
384
435
sentry_init (integrations = [AsyncioIntegration ()])
@@ -405,6 +456,12 @@ def test_loop_close_flushes_async_transport(sentry_init):
405
456
406
457
sentry_init (integrations = [AsyncioIntegration ()])
407
458
459
+ # Save the current event loop to restore it later
460
+ try :
461
+ original_loop = asyncio .get_event_loop ()
462
+ except RuntimeError :
463
+ original_loop = None
464
+
408
465
loop = asyncio .new_event_loop ()
409
466
asyncio .set_event_loop (loop )
410
467
@@ -415,14 +472,16 @@ def test_loop_close_flushes_async_transport(sentry_init):
415
472
mock_client = Mock ()
416
473
mock_transport = Mock (spec = AsyncHttpTransport )
417
474
mock_client .transport = mock_transport
418
- mock_client .close = AsyncMock (return_value = None )
475
+ mock_client .close_async = AsyncMock (return_value = None )
419
476
420
477
with patch ("sentry_sdk.get_client" , return_value = mock_client ):
421
478
loop .close ()
422
479
423
- mock_client .close .assert_called_once ()
424
- mock_client .close .assert_awaited_once ()
480
+ mock_client .close_async .assert_called_once ()
481
+ mock_client .close_async .assert_awaited_once ()
425
482
426
- except Exception :
483
+ finally :
427
484
if not loop .is_closed ():
428
485
loop .close ()
486
+ if original_loop :
487
+ asyncio .set_event_loop (original_loop )
0 commit comments