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, ".")
|
||||
application = import_by_path(args.application)
|
||||
# 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
|
||||
args.host = DEFAULT_HOST
|
||||
args.port = DEFAULT_PORT
|
||||
elif args.host and not args.port:
|
||||
elif args.host and args.port is None:
|
||||
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
|
||||
# Build endpoint description strings from (optional) cli arguments
|
||||
endpoints = build_endpoint_description_strings(
|
||||
|
|
|
@ -108,7 +108,7 @@ class Server(object):
|
|||
reactor.callLater(2, self.timeout_checker)
|
||||
|
||||
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))
|
||||
listener = ep.listen(self.http_factory)
|
||||
listener.addCallback(self.listen_success)
|
||||
|
@ -139,6 +139,7 @@ class Server(object):
|
|||
host = port.getHost()
|
||||
if hasattr(host, "host") and hasattr(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):
|
||||
logger.critical("Listen failure: %s", failure.getErrorMessage())
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import errno
|
||||
import random
|
||||
|
||||
import socket
|
||||
import struct
|
||||
import subprocess
|
||||
|
@ -19,60 +18,38 @@ class DaphneTestingInstance:
|
|||
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.http_timeout = http_timeout
|
||||
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):
|
||||
# Clear result storage
|
||||
TestApplication.delete_setup()
|
||||
TestApplication.delete_result()
|
||||
# Find a port to listen on
|
||||
self.port = self.find_free_port()
|
||||
daphne_args = ["daphne", "-p", str(self.port), "-v", "0"]
|
||||
# Tell Daphne to use port 0 so the OS gives it a free port
|
||||
daphne_args = ["daphne", "-p", "0", "-v", "1"]
|
||||
# Optionally enable X-Forwarded-For support.
|
||||
if self.xff:
|
||||
daphne_args += ["--proxy-headers"]
|
||||
if self.http_timeout:
|
||||
daphne_args += ["--http-timeout=%i" % self.http_timeout]
|
||||
# Start up process and make sure it begins listening. Try this 3 times.
|
||||
for _ in range(3):
|
||||
self.process = subprocess.Popen(daphne_args + ["daphne.test_application:TestApplication"])
|
||||
for _ in range(30):
|
||||
time.sleep(0.1)
|
||||
if self.port_in_use(self.port):
|
||||
# Start up process
|
||||
self.process = subprocess.Popen(
|
||||
daphne_args + ["daphne.test_application:TestApplication"],
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT,
|
||||
)
|
||||
# Read the port from its stdout
|
||||
stdout = b""
|
||||
for line in self.process.stdout:
|
||||
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
|
||||
# Daphne didn't start up. Sadface.
|
||||
self.process.terminate()
|
||||
raise RuntimeError("Daphne never came up.")
|
||||
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):
|
||||
# Shut down the process
|
||||
|
|
Loading…
Reference in New Issue
Block a user