summaryrefslogtreecommitdiff
path: root/tests/servers
diff options
context:
space:
mode:
authoratsuo ishimoto <atsuoishimoto@gmail.com>2019-07-07 00:43:59 +0900
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2019-07-10 13:22:17 +0200
commita9c6ab03560424ed7dff24849c8ddaa3e1eae62e (patch)
treec1f53269e1b7edcfb568efc20275e9cdc82a40fb /tests/servers
parent00d4e6f8b587dcea147c51ece253dc54c461a11d (diff)
downloaddjango-a9c6ab03560424ed7dff24849c8ddaa3e1eae62e.tar.gz
Fixed #30619 -- Made runserver --nothreading use single threaded WSGIServer.
Browsers often use multiple connections with Connection: keep-alive. If --nothreading is specified, the WSGI server cannot accept new connections until the old connection is closed, causing hangs. Force Connection: close when --nothreading option is used.
Diffstat (limited to 'tests/servers')
-rw-r--r--tests/servers/tests.py37
1 files changed, 37 insertions, 0 deletions
diff --git a/tests/servers/tests.py b/tests/servers/tests.py
index 1f111fb5ae..243b5a4200 100644
--- a/tests/servers/tests.py
+++ b/tests/servers/tests.py
@@ -9,7 +9,9 @@ from urllib.error import HTTPError
from urllib.parse import urlencode
from urllib.request import urlopen
+from django.core.servers.basehttp import WSGIServer
from django.test import LiveServerTestCase, override_settings
+from django.test.testcases import LiveServerThread, QuietWSGIRequestHandler
from .models import Person
@@ -50,6 +52,15 @@ class LiveServerAddress(LiveServerBase):
self.assertEqual(self.live_server_url_test[0], self.live_server_url)
+class LiveServerSingleThread(LiveServerThread):
+ def _create_server(self):
+ return WSGIServer((self.host, self.port), QuietWSGIRequestHandler, allow_reuse_address=False)
+
+
+class SingleThreadLiveServerTestCase(LiveServerTestCase):
+ server_thread_class = LiveServerSingleThread
+
+
class LiveServerViews(LiveServerBase):
def test_protocol(self):
"""Launched server serves with HTTP 1.1."""
@@ -162,6 +173,32 @@ class LiveServerViews(LiveServerBase):
self.assertIn(b"QUERY_STRING: 'q=%D1%82%D0%B5%D1%81%D1%82'", f.read())
+@override_settings(ROOT_URLCONF='servers.urls')
+class SingleTreadLiveServerViews(SingleThreadLiveServerTestCase):
+ available_apps = ['servers']
+
+ def test_closes_connection_with_content_length(self):
+ """
+ Contrast to
+ LiveServerViews.test_keep_alive_on_connection_with_content_length().
+ Persistent connections require threading server.
+ """
+ conn = HTTPConnection(
+ SingleTreadLiveServerViews.server_thread.host,
+ SingleTreadLiveServerViews.server_thread.port,
+ timeout=1,
+ )
+ try:
+ conn.request('GET', '/example_view/', headers={'Connection': 'keep-alive'})
+ response = conn.getresponse()
+ self.assertTrue(response.will_close)
+ self.assertEqual(response.read(), b'example view')
+ self.assertEqual(response.status, 200)
+ self.assertEqual(response.getheader('Connection'), 'close')
+ finally:
+ conn.close()
+
+
class LiveServerDatabase(LiveServerBase):
def test_fixtures_loaded(self):