mirror of
https://github.com/django/daphne.git
synced 2024-11-21 23:46:33 +03:00
Fixed #162: Test suite now uses port 0 binding
This commit is contained in:
parent
678a97ec7f
commit
13511d2ca6
|
@ -176,13 +176,13 @@ class CommandLineInterface(object):
|
||||||
sys.path.insert(0, ".")
|
sys.path.insert(0, ".")
|
||||||
application = import_by_path(args.application)
|
application = import_by_path(args.application)
|
||||||
# Set up port/host bindings
|
# Set up port/host bindings
|
||||||
if not any([args.host, args.port, args.unix_socket, args.file_descriptor, args.socket_strings]):
|
if not any([args.host, args.port is not None, args.unix_socket, args.file_descriptor, args.socket_strings]):
|
||||||
# no advanced binding options passed, patch in defaults
|
# no advanced binding options passed, patch in defaults
|
||||||
args.host = DEFAULT_HOST
|
args.host = DEFAULT_HOST
|
||||||
args.port = DEFAULT_PORT
|
args.port = DEFAULT_PORT
|
||||||
elif args.host and not args.port:
|
elif args.host and args.port is None:
|
||||||
args.port = DEFAULT_PORT
|
args.port = DEFAULT_PORT
|
||||||
elif args.port and not args.host:
|
elif args.port is not None and not args.host:
|
||||||
args.host = DEFAULT_HOST
|
args.host = DEFAULT_HOST
|
||||||
# Build endpoint description strings from (optional) cli arguments
|
# Build endpoint description strings from (optional) cli arguments
|
||||||
endpoints = build_endpoint_description_strings(
|
endpoints = build_endpoint_description_strings(
|
||||||
|
|
|
@ -108,7 +108,7 @@ class Server(object):
|
||||||
reactor.callLater(2, self.timeout_checker)
|
reactor.callLater(2, self.timeout_checker)
|
||||||
|
|
||||||
for socket_description in self.endpoints:
|
for socket_description in self.endpoints:
|
||||||
logger.info("Listening on endpoint %s", socket_description)
|
logger.info("Configuring endpoint %s", socket_description)
|
||||||
ep = serverFromString(reactor, str(socket_description))
|
ep = serverFromString(reactor, str(socket_description))
|
||||||
listener = ep.listen(self.http_factory)
|
listener = ep.listen(self.http_factory)
|
||||||
listener.addCallback(self.listen_success)
|
listener.addCallback(self.listen_success)
|
||||||
|
@ -139,6 +139,7 @@ class Server(object):
|
||||||
host = port.getHost()
|
host = port.getHost()
|
||||||
if hasattr(host, "host") and hasattr(host, "port"):
|
if hasattr(host, "host") and hasattr(host, "port"):
|
||||||
self.listening_addresses.append((host.host, host.port))
|
self.listening_addresses.append((host.host, host.port))
|
||||||
|
logger.info("Listening on TCP address %s:%s", port.getHost().host, port.getHost().port)
|
||||||
|
|
||||||
def listen_error(self, failure):
|
def listen_error(self, failure):
|
||||||
logger.critical("Listen failure: %s", failure.getErrorMessage())
|
logger.critical("Listen failure: %s", failure.getErrorMessage())
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import errno
|
|
||||||
import random
|
|
||||||
import socket
|
import socket
|
||||||
import struct
|
import struct
|
||||||
import subprocess
|
import subprocess
|
||||||
|
@ -19,60 +18,38 @@ class DaphneTestingInstance:
|
||||||
Works as a context manager.
|
Works as a context manager.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, xff=False, http_timeout=60):
|
def __init__(self, xff=False, http_timeout=None):
|
||||||
self.xff = xff
|
self.xff = xff
|
||||||
self.http_timeout = http_timeout
|
self.http_timeout = http_timeout
|
||||||
self.host = "127.0.0.1"
|
self.host = "127.0.0.1"
|
||||||
|
|
||||||
def port_in_use(self, port):
|
|
||||||
"""
|
|
||||||
Tests if a port is in use on the local machine.
|
|
||||||
"""
|
|
||||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
||||||
try:
|
|
||||||
s.bind(("127.0.0.1", port))
|
|
||||||
except socket.error as e:
|
|
||||||
if e.errno in [errno.EACCES, errno.EADDRINUSE]:
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
raise
|
|
||||||
else:
|
|
||||||
return False
|
|
||||||
finally:
|
|
||||||
s.close()
|
|
||||||
|
|
||||||
def find_free_port(self):
|
|
||||||
"""
|
|
||||||
Finds an unused port to test stuff on
|
|
||||||
"""
|
|
||||||
for _ in range(100):
|
|
||||||
port = random.randint(11200, 11300)
|
|
||||||
if not self.port_in_use(port):
|
|
||||||
return port
|
|
||||||
raise RuntimeError("Cannot find a free port to test on")
|
|
||||||
|
|
||||||
def __enter__(self):
|
def __enter__(self):
|
||||||
# Clear result storage
|
# Clear result storage
|
||||||
TestApplication.delete_setup()
|
TestApplication.delete_setup()
|
||||||
TestApplication.delete_result()
|
TestApplication.delete_result()
|
||||||
# Find a port to listen on
|
# Tell Daphne to use port 0 so the OS gives it a free port
|
||||||
self.port = self.find_free_port()
|
daphne_args = ["daphne", "-p", "0", "-v", "1"]
|
||||||
daphne_args = ["daphne", "-p", str(self.port), "-v", "0"]
|
|
||||||
# Optionally enable X-Forwarded-For support.
|
# Optionally enable X-Forwarded-For support.
|
||||||
if self.xff:
|
if self.xff:
|
||||||
daphne_args += ["--proxy-headers"]
|
daphne_args += ["--proxy-headers"]
|
||||||
if self.http_timeout:
|
if self.http_timeout:
|
||||||
daphne_args += ["--http-timeout=%i" % self.http_timeout]
|
daphne_args += ["--http-timeout=%i" % self.http_timeout]
|
||||||
# Start up process and make sure it begins listening. Try this 3 times.
|
# Start up process
|
||||||
for _ in range(3):
|
self.process = subprocess.Popen(
|
||||||
self.process = subprocess.Popen(daphne_args + ["daphne.test_application:TestApplication"])
|
daphne_args + ["daphne.test_application:TestApplication"],
|
||||||
for _ in range(30):
|
stdout=subprocess.PIPE,
|
||||||
time.sleep(0.1)
|
stderr=subprocess.STDOUT,
|
||||||
if self.port_in_use(self.port):
|
)
|
||||||
return self
|
# Read the port from its stdout
|
||||||
# Daphne didn't start up. Sadface.
|
stdout = b""
|
||||||
self.process.terminate()
|
for line in self.process.stdout:
|
||||||
raise RuntimeError("Daphne never came up.")
|
stdout += line
|
||||||
|
if b"Listening on TCP address " in line:
|
||||||
|
self.port = int(line.split(b"TCP address ")[1].split(b":")[1].strip())
|
||||||
|
return self
|
||||||
|
else:
|
||||||
|
# Daphne didn't start up right :(
|
||||||
|
raise RuntimeError("Daphne never listened on a port. Output: \n%s" % stdout)
|
||||||
|
|
||||||
def __exit__(self, exc_type, exc_value, traceback):
|
def __exit__(self, exc_type, exc_value, traceback):
|
||||||
# Shut down the process
|
# Shut down the process
|
||||||
|
|
Loading…
Reference in New Issue
Block a user