diff --git a/CHANGELOG.txt b/CHANGELOG.txt index eb2c58a..c462568 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -41,6 +41,9 @@ This is a beta release to allow testing compatibility with the upcoming Channels * Removed deprecated ``--ws_protocols`` CLI option. +* Made the ``DaphneProcess`` tests helper class compatible with the ``spawn`` + process start method, which is used on macOS and Windows. + 3.0.2 (2021-04-07) ------------------ diff --git a/daphne/testing.py b/daphne/testing.py index e2c7200..785edf9 100644 --- a/daphne/testing.py +++ b/daphne/testing.py @@ -26,6 +26,9 @@ class BaseDaphneTestingInstance: self.request_buffer_size = request_buffer_size self.application = application + def get_application(self): + return self.application + def __enter__(self): # Option Daphne features kwargs = {} @@ -41,7 +44,7 @@ class BaseDaphneTestingInstance: # Start up process self.process = DaphneProcess( host=self.host, - application=self.application, + get_application=self.get_application, kwargs=kwargs, setup=self.process_setup, teardown=self.process_teardown, @@ -123,13 +126,13 @@ class DaphneProcess(multiprocessing.Process): port it ends up listening on back to the parent process. """ - def __init__(self, host, application, kwargs=None, setup=None, teardown=None): + def __init__(self, host, get_application, kwargs=None, setup=None, teardown=None): super().__init__() self.host = host - self.application = application + self.get_application = get_application self.kwargs = kwargs or {} - self.setup = setup or (lambda: None) - self.teardown = teardown or (lambda: None) + self.setup = setup + self.teardown = teardown self.port = multiprocessing.Value("i") self.ready = multiprocessing.Event() self.errors = multiprocessing.Queue() @@ -146,11 +149,13 @@ class DaphneProcess(multiprocessing.Process): from .endpoints import build_endpoint_description_strings from .server import Server + application = self.get_application() + try: # Create the server class endpoints = build_endpoint_description_strings(host=self.host, port=0) self.server = Server( - application=self.application, + application=application, endpoints=endpoints, signal_handlers=False, **self.kwargs @@ -158,11 +163,13 @@ class DaphneProcess(multiprocessing.Process): # Set up a poller to look for the port reactor.callLater(0.1, self.resolve_port) # Run with setup/teardown - self.setup() + if self.setup is not None: + self.setup() try: self.server.run() finally: - self.teardown() + if self.teardown is not None: + self.teardown() except BaseException as e: # Put the error on our queue so the parent gets it self.errors.put((e, traceback.format_exc())) diff --git a/tests/test_websocket.py b/tests/test_websocket.py index 9b67aa1..e954486 100644 --- a/tests/test_websocket.py +++ b/tests/test_websocket.py @@ -288,7 +288,7 @@ async def cancelling_application(scope, receive, send): from twisted.internet import reactor # Stop the server after a short delay so that the teardown is run. - reactor.callLater(2, lambda: reactor.stop()) + reactor.callLater(2, reactor.stop) await send({"type": "websocket.accept"}) raise asyncio.CancelledError()