1- import pytest
1+ import random
2+ import asyncio
23
3- sanic = pytest . importorskip ( "sanic" )
4+ import pytest
45
5- from sentry_sdk import capture_message
6+ from sentry_sdk import capture_message , configure_scope
67from sentry_sdk .integrations .sanic import SanicIntegration
78
8- from sanic import Sanic , response
9+ from sanic import Sanic , request , response
910
1011
1112@pytest .fixture
@@ -67,7 +68,7 @@ def myerror(request):
6768 assert exception ["type" ] == "ValueError"
6869 assert exception ["value" ] == "oh no"
6970 assert any (
70- frame ["filename" ] == "test_sanic.py"
71+ frame ["filename" ]. endswith ( "test_sanic.py" )
7172 for frame in exception ["stacktrace" ]["frames" ]
7273 )
7374
@@ -92,13 +93,55 @@ def myhandler(request, exception):
9293 exception , = event1 ["exception" ]["values" ]
9394 assert exception ["type" ] == "ValueError"
9495 assert any (
95- frame ["filename" ] == "test_sanic.py"
96+ frame ["filename" ]. endswith ( "test_sanic.py" )
9697 for frame in exception ["stacktrace" ]["frames" ]
9798 )
9899
99100 exception , = event2 ["exception" ]["values" ]
100101 assert exception ["type" ] == "ZeroDivisionError"
101102 assert any (
102- frame ["filename" ] == "test_sanic.py"
103+ frame ["filename" ]. endswith ( "test_sanic.py" )
103104 for frame in exception ["stacktrace" ]["frames" ]
104105 )
106+
107+
108+ def test_concurrency (sentry_init , app ):
109+ sentry_init (integrations = [SanicIntegration ()])
110+
111+ @app .route ("/context-check/<i>" )
112+ async def context_check (request , i ):
113+ with configure_scope () as scope :
114+ scope .set_tag ("i" , i )
115+
116+ await asyncio .sleep (random .random ())
117+
118+ with configure_scope () as scope :
119+ assert scope ._tags ["i" ] == i
120+
121+ return response .text ("ok" )
122+
123+ async def task (i ):
124+ responses = []
125+
126+ await app .handle_request (
127+ request .Request (
128+ url_bytes = f"http://localhost/context-check/{ i } " .encode ("ascii" ),
129+ headers = {},
130+ version = "1.1" ,
131+ method = "GET" ,
132+ transport = None ,
133+ ),
134+ write_callback = responses .append ,
135+ stream_callback = responses .append ,
136+ )
137+
138+ r , = responses
139+ assert r .status == 200
140+
141+ async def runner ():
142+ await asyncio .gather (* (task (i ) for i in range (1000 )))
143+
144+ asyncio .run (runner ())
145+
146+ with configure_scope () as scope :
147+ assert not scope ._tags
0 commit comments