From c87540cee5a3d5b676b9359c01bdea35f733aabb Mon Sep 17 00:00:00 2001 From: Marten Kenbeek Date: Wed, 30 Dec 2015 13:23:50 +0100 Subject: [PATCH] Fixed #26011 -- Prevented random LiveServerTestCase test failures on Windows. Prevented LiveServerTestCase from stealing ports used by concurrent processes on Windows. --- django/core/servers/basehttp.py | 1 + django/test/testcases.py | 2 +- tests/servers/tests.py | 29 +++++++++++++++++++++++++++++ 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/django/core/servers/basehttp.py b/django/core/servers/basehttp.py index 4e2f8dd863..b9184ca20d 100644 --- a/django/core/servers/basehttp.py +++ b/django/core/servers/basehttp.py @@ -70,6 +70,7 @@ class WSGIServer(simple_server.WSGIServer, object): def __init__(self, *args, **kwargs): if kwargs.pop('ipv6', False): self.address_family = socket.AF_INET6 + self.allow_reuse_address = kwargs.pop('allow_reuse_address', True) super(WSGIServer, self).__init__(*args, **kwargs) def server_bind(self): diff --git a/django/test/testcases.py b/django/test/testcases.py index 2acacd5a91..4e4ada9c64 100644 --- a/django/test/testcases.py +++ b/django/test/testcases.py @@ -1252,7 +1252,7 @@ class LiveServerThread(threading.Thread): self.is_ready.set() def _create_server(self, port): - return WSGIServer((self.host, port), QuietWSGIRequestHandler) + return WSGIServer((self.host, port), QuietWSGIRequestHandler, allow_reuse_address=False) def terminate(self): if hasattr(self, 'httpd'): diff --git a/tests/servers/tests.py b/tests/servers/tests.py index dbb298e003..18102ff509 100644 --- a/tests/servers/tests.py +++ b/tests/servers/tests.py @@ -5,6 +5,7 @@ Tests for django.core.servers. from __future__ import unicode_literals import contextlib +import errno import os import socket @@ -174,3 +175,31 @@ class LiveServerDatabase(LiveServerBase): ['jane', 'robert', 'emily'], lambda b: b.name ) + + +class LiveServerPort(LiveServerBase): + + def test_port_bind(self): + """ + Each LiveServerTestCase binds to a unique port or fails to start a + server thread when run concurrently (#26011). + """ + TestCase = type(str("TestCase"), (LiveServerBase,), {}) + try: + TestCase.setUpClass() + except socket.error as e: + if e.ernrno == errno.EADDRINUSE: + # We're out of ports, LiveServerTestCase correctly fails with + # a socket error. + return + # Unexpected error. + raise + try: + # We've acquired a port, ensure our server threads acquired + # different addresses. + self.assertNotEqual( + self.live_server_url, TestCase.live_server_url, + "Acquired duplicate server addresses for server threads: %s" % self.live_server_url + ) + finally: + TestCase.tearDownClass()