Skip to content

Commit 9244881

Browse files
salomvarytim-schilling
authored andcommitted
Add tests for async usage (#1819)
1 parent 2bd42d6 commit 9244881

File tree

4 files changed

+102
-0
lines changed

4 files changed

+102
-0
lines changed

tests/panels/test_sql.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,20 @@ def sql_call(*, use_iterator=False):
3232
return list(qs)
3333

3434

35+
async def async_sql_call(*, use_iterator=False):
36+
qs = User.objects.all()
37+
if use_iterator:
38+
qs = qs.iterator()
39+
return await sync_to_async(list)(qs)
40+
41+
42+
async def concurrent_async_sql_call(*, use_iterator=False):
43+
qs = User.objects.all()
44+
if use_iterator:
45+
qs = qs.iterator()
46+
return await asyncio.gather(sync_to_async(list)(qs), User.objects.acount())
47+
48+
3549
class SQLPanelTestCase(BaseTestCase):
3650
panel_id = "SQLPanel"
3751

@@ -57,6 +71,39 @@ def test_recording(self):
5771
# ensure the stacktrace is populated
5872
self.assertTrue(len(query["stacktrace"]) > 0)
5973

74+
async def test_recording_async(self):
75+
self.assertEqual(len(self.panel._queries), 0)
76+
77+
await async_sql_call()
78+
79+
# ensure query was logged
80+
self.assertEqual(len(self.panel._queries), 1)
81+
query = self.panel._queries[0]
82+
self.assertEqual(query["alias"], "default")
83+
self.assertTrue("sql" in query)
84+
self.assertTrue("duration" in query)
85+
self.assertTrue("stacktrace" in query)
86+
87+
# ensure the stacktrace is populated
88+
self.assertTrue(len(query["stacktrace"]) > 0)
89+
90+
async def test_recording_concurrent_async(self):
91+
self.assertEqual(len(self.panel._queries), 0)
92+
93+
await concurrent_async_sql_call()
94+
95+
# ensure query was logged
96+
self.assertEqual(len(self.panel._queries), 2)
97+
query = self.panel._queries[0]
98+
self.assertEqual(query["alias"], "default")
99+
self.assertTrue("sql" in query)
100+
self.assertTrue("duration" in query)
101+
self.assertTrue("stacktrace" in query)
102+
103+
# ensure the stacktrace is populated
104+
self.assertTrue(len(query["stacktrace"]) > 0)
105+
106+
60107
@unittest.skipUnless(
61108
connection.vendor == "postgresql", "Test valid only on PostgreSQL"
62109
)

tests/test_integration.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,18 @@ def test_data_gone(self):
250250
)
251251
self.assertIn("Please reload the page and retry.", response.json()["content"])
252252

253+
def test_sql_page(self):
254+
response = self.client.get("/execute_sql/")
255+
self.assertEqual(len(response.toolbar.get_panel_by_id("SQLPanel").get_stats()["queries"]), 1)
256+
257+
def test_async_sql_page(self):
258+
response = self.client.get("/async_execute_sql/")
259+
self.assertEqual(len(response.toolbar.get_panel_by_id("SQLPanel").get_stats()["queries"]), 1)
260+
261+
def test_concurrent_async_sql_page(self):
262+
response = self.client.get("/async_execute_sql_concurrently/")
263+
self.assertEqual(len(response.toolbar.get_panel_by_id("SQLPanel").get_stats()["queries"]), 2)
264+
253265

254266
@override_settings(DEBUG=True)
255267
class DebugToolbarIntegrationTestCase(IntegrationTestCase):
@@ -843,3 +855,30 @@ def test_theme_toggle(self):
843855
self.get("/regular/basic/")
844856
toolbar = self.selenium.find_element(By.ID, "djDebug")
845857
self.assertEqual(toolbar.get_attribute("data-theme"), "light")
858+
859+
def test_async_sql_action(self):
860+
self.get("/async_execute_sql/")
861+
sql_panel = self.selenium.find_element(By.ID, "SQLPanel")
862+
debug_window = self.selenium.find_element(By.ID, "djDebugWindow")
863+
864+
# Click to show the SQL panel
865+
self.selenium.find_element(By.CLASS_NAME, "SQLPanel").click()
866+
867+
# SQL panel loads
868+
button = self.wait.until(
869+
EC.visibility_of_element_located((By.CSS_SELECTOR, ".remoteCall"))
870+
)
871+
872+
873+
def test_concurrent_async_sql_action(self):
874+
self.get("/async_execute_sql_concurrently/")
875+
sql_panel = self.selenium.find_element(By.ID, "SQLPanel")
876+
debug_window = self.selenium.find_element(By.ID, "djDebugWindow")
877+
878+
# Click to show the SQL panel
879+
self.selenium.find_element(By.CLASS_NAME, "SQLPanel").click()
880+
881+
# SQL panel loads
882+
button = self.wait.until(
883+
EC.visibility_of_element_located((By.CSS_SELECTOR, ".remoteCall"))
884+
)

tests/urls.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
path("non_ascii_request/", views.regular_view, {"title": NonAsciiRepr()}),
1818
path("new_user/", views.new_user),
1919
path("execute_sql/", views.execute_sql),
20+
path("async_execute_sql/", views.async_execute_sql),
21+
path("async_execute_sql_concurrently/", views.async_execute_sql_concurrently),
2022
path("cached_view/", views.cached_view),
2123
path("cached_low_level_view/", views.cached_low_level_view),
2224
path("json_view/", views.json_view),

tests/views.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import asyncio
2+
3+
from asgiref.sync import sync_to_async
14
from django.contrib.auth.models import User
25
from django.core.cache import cache
36
from django.http import HttpResponseRedirect, JsonResponse
@@ -11,6 +14,17 @@ def execute_sql(request):
1114
return render(request, "base.html")
1215

1316

17+
async def async_execute_sql(request):
18+
await sync_to_async(list)(User.objects.all())
19+
return render(request, "base.html")
20+
21+
22+
async def async_execute_sql_concurrently(request):
23+
await asyncio.gather(sync_to_async(list)(User.objects.all()), User.objects.acount())
24+
return render(request, "base.html")
25+
26+
27+
1428
def regular_view(request, title):
1529
return render(request, "basic.html", {"title": title})
1630

0 commit comments

Comments
 (0)