Skip to content

Commit 7e875d8

Browse files
antonpirkerarjenzorgdoc
authored andcommitted
Cleaning up ASGI tests for Django (getsentry#3180)
Cleaning up the ASGI tests for Django. Making sure it is always `wait()`ed for the application to finish and also made the tests a bit more readable and removed some useless asserts. Fixes getsentry#3142
1 parent 25b75af commit 7e875d8

File tree

3 files changed

+85
-46
lines changed

3 files changed

+85
-46
lines changed

tests/integrations/django/asgi/test_asgi.py

Lines changed: 76 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,17 @@
3131
@pytest.mark.asyncio
3232
@pytest.mark.forked
3333
async def test_basic(sentry_init, capture_events, application):
34-
sentry_init(integrations=[DjangoIntegration()], send_default_pii=True)
34+
sentry_init(
35+
integrations=[DjangoIntegration()],
36+
send_default_pii=True,
37+
)
3538

3639
events = capture_events()
3740

3841
comm = HttpCommunicator(application, "GET", "/view-exc?test=query")
3942
response = await comm.get_response()
43+
await comm.wait()
44+
4045
assert response["status"] == 500
4146

4247
(event,) = events
@@ -67,12 +72,17 @@ async def test_basic(sentry_init, capture_events, application):
6772
django.VERSION < (3, 1), reason="async views have been introduced in Django 3.1"
6873
)
6974
async def test_async_views(sentry_init, capture_events, application):
70-
sentry_init(integrations=[DjangoIntegration()], send_default_pii=True)
75+
sentry_init(
76+
integrations=[DjangoIntegration()],
77+
send_default_pii=True,
78+
)
7179

7280
events = capture_events()
7381

7482
comm = HttpCommunicator(application, "GET", "/async_message")
7583
response = await comm.get_response()
84+
await comm.wait()
85+
7686
assert response["status"] == 200
7787

7888
(event,) = events
@@ -108,17 +118,16 @@ async def test_active_thread_id(sentry_init, capture_envelopes, endpoint, applic
108118

109119
comm = HttpCommunicator(application, "GET", endpoint)
110120
response = await comm.get_response()
111-
assert response["status"] == 200, response["body"]
112-
113121
await comm.wait()
114122

115-
data = json.loads(response["body"])
116-
envelopes = [envelope for envelope in envelopes]
123+
assert response["status"] == 200, response["body"]
117124
assert len(envelopes) == 1
118125

119126
profiles = [item for item in envelopes[0].items if item.type == "profile"]
120127
assert len(profiles) == 1
121128

129+
data = json.loads(response["body"])
130+
122131
for profile in profiles:
123132
transactions = profile.payload.json["transactions"]
124133
assert len(transactions) == 1
@@ -137,7 +146,10 @@ async def test_async_views_concurrent_execution(sentry_init, settings):
137146
settings.MIDDLEWARE = []
138147
asgi_application.load_middleware(is_async=True)
139148

140-
sentry_init(integrations=[DjangoIntegration()], send_default_pii=True)
149+
sentry_init(
150+
integrations=[DjangoIntegration()],
151+
send_default_pii=True,
152+
)
141153

142154
comm = HttpCommunicator(
143155
asgi_application, "GET", "/my_async_view"
@@ -181,7 +193,10 @@ async def test_async_middleware_that_is_function_concurrent_execution(
181193
]
182194
asgi_application.load_middleware(is_async=True)
183195

184-
sentry_init(integrations=[DjangoIntegration()], send_default_pii=True)
196+
sentry_init(
197+
integrations=[DjangoIntegration()],
198+
send_default_pii=True,
199+
)
185200

186201
comm = HttpCommunicator(
187202
asgi_application, "GET", "/my_async_view"
@@ -233,13 +248,13 @@ async def test_async_middleware_spans(
233248

234249
events = capture_events()
235250

236-
comm = HttpCommunicator(asgi_application, "GET", "/async_message")
251+
comm = HttpCommunicator(asgi_application, "GET", "/simple_async_view")
237252
response = await comm.get_response()
238-
assert response["status"] == 200
239-
240253
await comm.wait()
241254

242-
message, transaction = events
255+
assert response["status"] == 200
256+
257+
(transaction,) = events
243258

244259
assert (
245260
render_span_tree(transaction)
@@ -252,7 +267,7 @@ async def test_async_middleware_spans(
252267
- op="middleware.django": description="django.middleware.csrf.CsrfViewMiddleware.__acall__"
253268
- op="middleware.django": description="tests.integrations.django.myapp.settings.TestMiddleware.__acall__"
254269
- op="middleware.django": description="django.middleware.csrf.CsrfViewMiddleware.process_view"
255-
- op="view.render": description="async_message"
270+
- op="view.render": description="simple_async_view"
256271
- op="event.django": description="django.db.close_old_connections"
257272
- op="event.django": description="django.core.cache.close_caches"
258273
- op="event.django": description="django.core.handlers.base.reset_urlconf\""""
@@ -265,27 +280,25 @@ async def test_async_middleware_spans(
265280
django.VERSION < (3, 1), reason="async views have been introduced in Django 3.1"
266281
)
267282
async def test_has_trace_if_performance_enabled(sentry_init, capture_events):
268-
sentry_init(integrations=[DjangoIntegration()], traces_sample_rate=1.0)
283+
sentry_init(
284+
integrations=[DjangoIntegration()],
285+
traces_sample_rate=1.0,
286+
)
269287

270288
events = capture_events()
271289

272290
comm = HttpCommunicator(asgi_application, "GET", "/view-exc-with-msg")
273291
response = await comm.get_response()
274-
assert response["status"] == 500
275-
276-
# ASGI Django does not create transactions per default,
277-
# so we do not have a transaction_event here.
278-
(msg_event, error_event) = events
292+
await comm.wait()
279293

280-
assert msg_event["contexts"]["trace"]
281-
assert "trace_id" in msg_event["contexts"]["trace"]
294+
assert response["status"] == 500
282295

283-
assert error_event["contexts"]["trace"]
284-
assert "trace_id" in error_event["contexts"]["trace"]
296+
(msg_event, error_event, transaction_event) = events
285297

286298
assert (
287299
msg_event["contexts"]["trace"]["trace_id"]
288300
== error_event["contexts"]["trace"]["trace_id"]
301+
== transaction_event["contexts"]["trace"]["trace_id"]
289302
)
290303

291304

@@ -295,12 +308,16 @@ async def test_has_trace_if_performance_enabled(sentry_init, capture_events):
295308
django.VERSION < (3, 1), reason="async views have been introduced in Django 3.1"
296309
)
297310
async def test_has_trace_if_performance_disabled(sentry_init, capture_events):
298-
sentry_init(integrations=[DjangoIntegration()])
311+
sentry_init(
312+
integrations=[DjangoIntegration()],
313+
)
299314

300315
events = capture_events()
301316

302317
comm = HttpCommunicator(asgi_application, "GET", "/view-exc-with-msg")
303318
response = await comm.get_response()
319+
await comm.wait()
320+
304321
assert response["status"] == 500
305322

306323
(msg_event, error_event) = events
@@ -322,7 +339,10 @@ async def test_has_trace_if_performance_disabled(sentry_init, capture_events):
322339
django.VERSION < (3, 1), reason="async views have been introduced in Django 3.1"
323340
)
324341
async def test_trace_from_headers_if_performance_enabled(sentry_init, capture_events):
325-
sentry_init(integrations=[DjangoIntegration()], traces_sample_rate=1.0)
342+
sentry_init(
343+
integrations=[DjangoIntegration()],
344+
traces_sample_rate=1.0,
345+
)
326346

327347
events = capture_events()
328348

@@ -336,20 +356,15 @@ async def test_trace_from_headers_if_performance_enabled(sentry_init, capture_ev
336356
headers=[(b"sentry-trace", sentry_trace_header.encode())],
337357
)
338358
response = await comm.get_response()
339-
assert response["status"] == 500
359+
await comm.wait()
340360

341-
# ASGI Django does not create transactions per default,
342-
# so we do not have a transaction_event here.
343-
(msg_event, error_event) = events
361+
assert response["status"] == 500
344362

345-
assert msg_event["contexts"]["trace"]
346-
assert "trace_id" in msg_event["contexts"]["trace"]
347-
348-
assert error_event["contexts"]["trace"]
349-
assert "trace_id" in error_event["contexts"]["trace"]
363+
(msg_event, error_event, transaction_event) = events
350364

351365
assert msg_event["contexts"]["trace"]["trace_id"] == trace_id
352366
assert error_event["contexts"]["trace"]["trace_id"] == trace_id
367+
assert transaction_event["contexts"]["trace"]["trace_id"] == trace_id
353368

354369

355370
@pytest.mark.asyncio
@@ -358,7 +373,9 @@ async def test_trace_from_headers_if_performance_enabled(sentry_init, capture_ev
358373
django.VERSION < (3, 1), reason="async views have been introduced in Django 3.1"
359374
)
360375
async def test_trace_from_headers_if_performance_disabled(sentry_init, capture_events):
361-
sentry_init(integrations=[DjangoIntegration()])
376+
sentry_init(
377+
integrations=[DjangoIntegration()],
378+
)
362379

363380
events = capture_events()
364381

@@ -372,16 +389,12 @@ async def test_trace_from_headers_if_performance_disabled(sentry_init, capture_e
372389
headers=[(b"sentry-trace", sentry_trace_header.encode())],
373390
)
374391
response = await comm.get_response()
392+
await comm.wait()
393+
375394
assert response["status"] == 500
376395

377396
(msg_event, error_event) = events
378397

379-
assert msg_event["contexts"]["trace"]
380-
assert "trace_id" in msg_event["contexts"]["trace"]
381-
382-
assert error_event["contexts"]["trace"]
383-
assert "trace_id" in error_event["contexts"]["trace"]
384-
385398
assert msg_event["contexts"]["trace"]["trace_id"] == trace_id
386399
assert error_event["contexts"]["trace"]["trace_id"] == trace_id
387400

@@ -504,10 +517,8 @@ async def test_asgi_request_body(
504517
expected_data,
505518
):
506519
sentry_init(
520+
integrations=[DjangoIntegration()],
507521
send_default_pii=send_default_pii,
508-
integrations=[
509-
DjangoIntegration(),
510-
],
511522
)
512523

513524
envelopes = capture_envelopes()
@@ -520,9 +531,9 @@ async def test_asgi_request_body(
520531
body=body,
521532
)
522533
response = await comm.get_response()
523-
assert response["status"] == 200
524-
525534
await comm.wait()
535+
536+
assert response["status"] == 200
526537
assert response["body"] == body
527538

528539
(envelope,) = envelopes
@@ -594,3 +605,22 @@ def get_response(): ...
594605

595606
instance = sentry_asgi_mixin(get_response)
596607
assert not inspect.iscoroutinefunction(instance)
608+
609+
610+
@pytest.mark.parametrize("application", APPS)
611+
@pytest.mark.asyncio
612+
async def test_async_view(sentry_init, capture_events, application):
613+
sentry_init(
614+
integrations=[DjangoIntegration()],
615+
traces_sample_rate=1.0,
616+
)
617+
618+
events = capture_events()
619+
620+
comm = HttpCommunicator(application, "GET", "/simple_async_view")
621+
await comm.get_response()
622+
await comm.wait()
623+
624+
(event,) = events
625+
assert event["type"] == "transaction"
626+
assert event["transaction"] == "/simple_async_view"

tests/integrations/django/myapp/urls.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,11 @@ def path(path, *args, **kwargs):
8888
if views.my_async_view is not None:
8989
urlpatterns.append(path("my_async_view", views.my_async_view, name="my_async_view"))
9090

91+
if views.my_async_view is not None:
92+
urlpatterns.append(
93+
path("simple_async_view", views.simple_async_view, name="simple_async_view")
94+
)
95+
9196
if views.thread_ids_async is not None:
9297
urlpatterns.append(
9398
path("async/thread_ids", views.thread_ids_async, name="thread_ids_async")

tests/integrations/django/myapp/views.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,10 @@ async def my_async_view(request):
240240
return HttpResponse("Hello World")
241241

242242

243+
async def simple_async_view(request):
244+
return HttpResponse("Simple Hello World")
245+
246+
243247
async def thread_ids_async(request):
244248
response = json.dumps(
245249
{

0 commit comments

Comments
 (0)