From 547a07fa7ec4364ea9ecd2aabfdd16ee4c63003c Mon Sep 17 00:00:00 2001 From: Michael Galler Date: Thu, 20 Aug 2020 18:41:22 +0200 Subject: Fixed #31905 -- Made MiddlewareMixin call process_request()/process_response() with thread sensitive. Co-authored-by: Carlton Gibson --- tests/deprecation/test_middleware_mixin.py | 43 +++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/deprecation/test_middleware_mixin.py b/tests/deprecation/test_middleware_mixin.py index f03d9168ec..c90aeb8360 100644 --- a/tests/deprecation/test_middleware_mixin.py +++ b/tests/deprecation/test_middleware_mixin.py @@ -1,11 +1,18 @@ +import threading + +from asgiref.sync import async_to_sync + from django.contrib.sessions.middleware import SessionMiddleware +from django.db import connection +from django.http.request import HttpRequest +from django.http.response import HttpResponse from django.middleware.cache import ( CacheMiddleware, FetchFromCacheMiddleware, UpdateCacheMiddleware, ) from django.middleware.common import CommonMiddleware from django.middleware.security import SecurityMiddleware from django.test import SimpleTestCase -from django.utils.deprecation import RemovedInDjango40Warning +from django.utils.deprecation import MiddlewareMixin, RemovedInDjango40Warning class MiddlewareMixinTests(SimpleTestCase): @@ -37,3 +44,37 @@ class MiddlewareMixinTests(SimpleTestCase): with self.subTest(middleware=middleware): with self.assertRaisesMessage(RemovedInDjango40Warning, self.msg): middleware() + + def test_sync_to_async_uses_base_thread_and_connection(self): + """ + The process_request() and process_response() hooks must be called with + the sync_to_async thread_sensitive flag enabled, so that database + operations use the correct thread and connection. + """ + def request_lifecycle(): + """Fake request_started/request_finished.""" + return (threading.get_ident(), id(connection)) + + async def get_response(self): + return HttpResponse() + + class SimpleMiddleWare(MiddlewareMixin): + def process_request(self, request): + request.thread_and_connection = request_lifecycle() + + def process_response(self, request, response): + response.thread_and_connection = request_lifecycle() + return response + + threads_and_connections = [] + threads_and_connections.append(request_lifecycle()) + + request = HttpRequest() + response = async_to_sync(SimpleMiddleWare(get_response))(request) + threads_and_connections.append(request.thread_and_connection) + threads_and_connections.append(response.thread_and_connection) + + threads_and_connections.append(request_lifecycle()) + + self.assertEqual(len(threads_and_connections), 4) + self.assertEqual(len(set(threads_and_connections)), 1) -- cgit v1.3