Skip to content

Commit 7290f9c

Browse files
salty-ivykorverdevpre-commit-ci[bot]
authored
Async integration tests (#2001)
Co-authored-by: Casey Korver <[email protected]> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent ee04104 commit 7290f9c

File tree

5 files changed

+552
-4
lines changed

5 files changed

+552
-4
lines changed

tests/base.py

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,23 @@
1+
import contextvars
12
from typing import Optional
23

34
import html5lib
45
from asgiref.local import Local
56
from django.http import HttpResponse
6-
from django.test import Client, RequestFactory, TestCase, TransactionTestCase
7+
from django.test import (
8+
AsyncClient,
9+
AsyncRequestFactory,
10+
Client,
11+
RequestFactory,
12+
TestCase,
13+
TransactionTestCase,
14+
)
715

816
from debug_toolbar.panels import Panel
917
from debug_toolbar.toolbar import DebugToolbar
1018

19+
data_contextvar = contextvars.ContextVar("djdt_toolbar_test_client")
20+
1121

1222
class ToolbarTestClient(Client):
1323
def request(self, **request):
@@ -29,11 +39,35 @@ def handle_toolbar_created(sender, toolbar=None, **kwargs):
2939
return response
3040

3141

42+
class AsyncToolbarTestClient(AsyncClient):
43+
async def request(self, **request):
44+
# Use a thread/async task context-local variable to guard against a
45+
# concurrent _created signal from a different thread/task.
46+
# In cases testsuite will have both regular and async tests or
47+
# multiple async tests running in an eventloop making async_client calls.
48+
data_contextvar.set(None)
49+
50+
def handle_toolbar_created(sender, toolbar=None, **kwargs):
51+
data_contextvar.set(toolbar)
52+
53+
DebugToolbar._created.connect(handle_toolbar_created)
54+
try:
55+
response = await super().request(**request)
56+
finally:
57+
DebugToolbar._created.disconnect(handle_toolbar_created)
58+
response.toolbar = data_contextvar.get()
59+
60+
return response
61+
62+
3263
rf = RequestFactory()
64+
arf = AsyncRequestFactory()
3365

3466

3567
class BaseMixin:
68+
_is_async = False
3669
client_class = ToolbarTestClient
70+
async_client_class = AsyncToolbarTestClient
3771

3872
panel: Optional[Panel] = None
3973
panel_id = None
@@ -42,7 +76,11 @@ def setUp(self):
4276
super().setUp()
4377
self._get_response = lambda request: HttpResponse()
4478
self.request = rf.get("/")
45-
self.toolbar = DebugToolbar(self.request, self.get_response)
79+
if self._is_async:
80+
self.request = arf.get("/")
81+
self.toolbar = DebugToolbar(self.request, self.get_response_async)
82+
else:
83+
self.toolbar = DebugToolbar(self.request, self.get_response)
4684
self.toolbar.stats = {}
4785

4886
if self.panel_id:
@@ -59,6 +97,9 @@ def tearDown(self):
5997
def get_response(self, request):
6098
return self._get_response(request)
6199

100+
async def get_response_async(self, request):
101+
return self._get_response(request)
102+
62103
def assertValidHTML(self, content):
63104
parser = html5lib.HTMLParser()
64105
parser.parseFragment(content)

tests/settings.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
"tests",
3131
]
3232

33+
3334
USE_GIS = os.getenv("DB_BACKEND") == "postgis"
3435

3536
if USE_GIS:

tests/test_integration.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ def test_sql_page(self):
288288
def test_async_sql_page(self):
289289
response = self.client.get("/async_execute_sql/")
290290
self.assertEqual(
291-
len(response.toolbar.get_panel_by_id("SQLPanel").get_stats()["queries"]), 1
291+
len(response.toolbar.get_panel_by_id("SQLPanel").get_stats()["queries"]), 2
292292
)
293293

294294
def test_concurrent_async_sql_page(self):

0 commit comments

Comments
 (0)