diff --git a/.gitignore b/.gitignore index 73e923d397..4a834a7a49 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,4 @@ settings.py docs/_build/ docs/_api/ build/* +.DS_Store diff --git a/docs/sanic/testing.md b/docs/sanic/testing.md index b8427a00c9..0aca9184bf 100644 --- a/docs/sanic/testing.md +++ b/docs/sanic/testing.md @@ -59,7 +59,7 @@ the available arguments to aiohttp can be found [in the documentation for ClientSession](https://aiohttp.readthedocs.io/en/stable/client_reference.html#client-session). -# pytest-sanic +## pytest-sanic [pytest-sanic](https://github.com/yunstanford/pytest-sanic) is a pytest plugin, it helps you to test your code asynchronously. Just write tests like, diff --git a/sanic/app.py b/sanic/app.py index f0ccad865c..c0c850e8c8 100644 --- a/sanic/app.py +++ b/sanic/app.py @@ -633,14 +633,31 @@ async def create_server(self, host=None, port=None, debug=False, warnings.simplefilter('default') warnings.warn("stop_event will be removed from future versions.", DeprecationWarning) + server_settings = self._helper( host=host, port=port, debug=debug, ssl=ssl, sock=sock, loop=get_event_loop(), protocol=protocol, backlog=backlog, run_async=True, has_log=log_config is not None) + # Trigger before_start events + await self.trigger_events( + server_settings.get('before_start', []), + server_settings.get('loop') + ) + return await serve(**server_settings) + async def trigger_events(self, events, loop): + """Trigger events (functions or async) + :param events: one or more sync or async functions to execute + :param loop: event loop + """ + for event in events: + result = event(loop) + if isawaitable(result): + await result + async def _run_request_middleware(self, request): # The if improves speed. I don't know why if self.request_middleware: diff --git a/tests/test_server_events.py b/tests/test_server_events.py index 0dcaba1cc5..d78f0aed5e 100644 --- a/tests/test_server_events.py +++ b/tests/test_server_events.py @@ -59,3 +59,20 @@ def test_all_listeners(): start_stop_app(random_name_app) for listener_name in AVAILABLE_LISTENERS: assert random_name_app.name + listener_name == output.pop() + + +async def test_trigger_before_events_create_server(): + + class MySanicDb: + pass + + app = Sanic("test_sanic_app") + + @app.listener('before_server_start') + async def init_db(app, loop): + app.db = MySanicDb() + + await app.create_server() + + assert hasattr(app, "db") + assert isinstance(app.db, MySanicDb) diff --git a/tox.ini b/tox.ini index de1dc2d598..dcebb05035 100644 --- a/tox.ini +++ b/tox.ini @@ -10,6 +10,7 @@ deps = coverage pytest pytest-cov + pytest-sanic pytest-sugar aiohttp==1.3.5 chardet<=2.3.0