diff --git a/django/test/testcases.py b/django/test/testcases.py
index 8203a38..03a59fc 100644
a
|
b
|
class LiveServerThread(threading.Thread):
|
1257 | 1257 | Thread for running a live http server while the tests are running. |
1258 | 1258 | """ |
1259 | 1259 | |
1260 | | def __init__(self, host, static_handler, connections_override=None): |
| 1260 | def __init__(self, host, port, static_handler, connections_override=None): |
1261 | 1261 | self.host = host |
1262 | | self.port = None |
| 1262 | self.port = port |
1263 | 1263 | self.is_ready = threading.Event() |
1264 | 1264 | self.error = None |
1265 | 1265 | self.static_handler = static_handler |
… |
… |
class LiveServerThread(threading.Thread):
|
1279 | 1279 | try: |
1280 | 1280 | # Create the handler for serving static and media files |
1281 | 1281 | handler = self.static_handler(_MediaFilesHandler(WSGIHandler())) |
1282 | | self.httpd = self._create_server(0) |
1283 | | self.port = self.httpd.server_address[1] |
| 1282 | self.httpd = self._create_server() |
| 1283 | if self.port == 0: |
| 1284 | self.port = self.httpd.server_address[1] |
1284 | 1285 | self.httpd.set_app(handler) |
1285 | 1286 | self.is_ready.set() |
1286 | 1287 | self.httpd.serve_forever() |
… |
… |
class LiveServerThread(threading.Thread):
|
1290 | 1291 | finally: |
1291 | 1292 | connections.close_all() |
1292 | 1293 | |
1293 | | def _create_server(self, port): |
1294 | | return WSGIServer((self.host, port), QuietWSGIRequestHandler, allow_reuse_address=False) |
| 1294 | def _create_server(self): |
| 1295 | return WSGIServer((self.host, self.port), QuietWSGIRequestHandler, allow_reuse_address=False) |
1295 | 1296 | |
1296 | 1297 | def terminate(self): |
1297 | 1298 | if hasattr(self, 'httpd'): |
… |
… |
class LiveServerTestCase(TransactionTestCase):
|
1313 | 1314 | other thread can see the changes. |
1314 | 1315 | """ |
1315 | 1316 | host = 'localhost' |
| 1317 | port = 0 |
1316 | 1318 | server_thread_class = LiveServerThread |
1317 | 1319 | static_handler = _StaticFilesHandler |
1318 | 1320 | |
… |
… |
class LiveServerTestCase(TransactionTestCase):
|
1352 | 1354 | def _create_server_thread(cls, connections_override): |
1353 | 1355 | return cls.server_thread_class( |
1354 | 1356 | cls.host, |
| 1357 | cls.port, |
1355 | 1358 | cls.static_handler, |
1356 | 1359 | connections_override=connections_override, |
1357 | 1360 | ) |
diff --git a/tests/servers/tests.py b/tests/servers/tests.py
index 03e05d0..d64d862 100644
a
|
b
|
class LiveServerPort(LiveServerBase):
|
136 | 136 | finally: |
137 | 137 | if hasattr(TestCase, 'server_thread'): |
138 | 138 | TestCase.server_thread.terminate() |
| 139 | |
| 140 | def test_specified_port_bind(self): |
| 141 | """ |
| 142 | When the developer specifies a port with LiveServerTestCase.port = xyz, |
| 143 | ensure that port xyz is actually bound. |
| 144 | """ |
| 145 | TestCase = type(str("TestCase"), (LiveServerBase,), {}) |
| 146 | |
| 147 | # Find an open port. |
| 148 | try: |
| 149 | s = socket.socket() |
| 150 | s.bind(('', 0)) |
| 151 | TestCase.port = s.getsockname()[1] |
| 152 | s.close() |
| 153 | except socket.error as e: |
| 154 | # There are no open ports. What to do?? |
| 155 | raise |
| 156 | |
| 157 | try: |
| 158 | TestCase.setUpClass() |
| 159 | except socket.error as e: |
| 160 | if e.errno == errno.EADDRINUSE: |
| 161 | # The socket we found closed before TestCase could bind to it. What to do?? |
| 162 | raise |
| 163 | try: |
| 164 | # We've acquired a free port and told TestCase to use it. Ensure that TestCase actually used it. |
| 165 | self.assertEqual( |
| 166 | TestCase.port, TestCase.server_thread.port, |
| 167 | "Did not use specified port for LiveServerTestCase thread: %s" % TestCase.port |
| 168 | ) |
| 169 | finally: |
| 170 | if hasattr(TestCase, 'server_thread'): |
| 171 | TestCase.server_thread.terminate() |