1
- import pytest
1
+ import random
2
+ import asyncio
2
3
3
- sanic = pytest . importorskip ( "sanic" )
4
+ import pytest
4
5
5
- from sentry_sdk import capture_message
6
+ from sentry_sdk import capture_message , configure_scope
6
7
from sentry_sdk .integrations .sanic import SanicIntegration
7
8
8
- from sanic import Sanic , response
9
+ from sanic import Sanic , request , response
9
10
10
11
11
12
@pytest .fixture
@@ -67,7 +68,7 @@ def myerror(request):
67
68
assert exception ["type" ] == "ValueError"
68
69
assert exception ["value" ] == "oh no"
69
70
assert any (
70
- frame ["filename" ] == "test_sanic.py"
71
+ frame ["filename" ]. endswith ( "test_sanic.py" )
71
72
for frame in exception ["stacktrace" ]["frames" ]
72
73
)
73
74
@@ -92,13 +93,55 @@ def myhandler(request, exception):
92
93
exception , = event1 ["exception" ]["values" ]
93
94
assert exception ["type" ] == "ValueError"
94
95
assert any (
95
- frame ["filename" ] == "test_sanic.py"
96
+ frame ["filename" ]. endswith ( "test_sanic.py" )
96
97
for frame in exception ["stacktrace" ]["frames" ]
97
98
)
98
99
99
100
exception , = event2 ["exception" ]["values" ]
100
101
assert exception ["type" ] == "ZeroDivisionError"
101
102
assert any (
102
- frame ["filename" ] == "test_sanic.py"
103
+ frame ["filename" ]. endswith ( "test_sanic.py" )
103
104
for frame in exception ["stacktrace" ]["frames" ]
104
105
)
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