sanic/tests/test_app.py

211 lines
5.9 KiB
Python
Raw Normal View History

2018-12-13 17:50:50 +00:00
import asyncio
import logging
import sys
2019-01-15 13:11:38 +00:00
2019-01-15 12:52:53 +00:00
from inspect import isawaitable
2018-12-13 17:50:50 +00:00
import pytest
from sanic.exceptions import SanicException
from sanic.response import text
def uvloop_installed():
try:
import uvloop # noqa
return True
except ImportError:
return False
2018-12-13 17:50:50 +00:00
def test_app_loop_running(app):
2018-12-30 11:18:06 +00:00
@app.get("/test")
2018-12-13 17:50:50 +00:00
async def handler(request):
assert isinstance(app.loop, asyncio.AbstractEventLoop)
2018-12-30 11:18:06 +00:00
return text("pass")
2018-12-13 17:50:50 +00:00
2018-12-30 11:18:06 +00:00
request, response = app.test_client.get("/test")
assert response.text == "pass"
2018-12-13 17:50:50 +00:00
@pytest.mark.skipif(
sys.version_info < (3, 7), reason="requires python3.7 or higher"
)
def test_create_asyncio_server(app):
2019-01-15 15:45:47 +00:00
if not uvloop_installed():
loop = asyncio.get_event_loop()
asyncio_srv_coro = app.create_server(return_asyncio_server=True)
2019-01-15 15:45:47 +00:00
assert isawaitable(asyncio_srv_coro)
srv = loop.run_until_complete(asyncio_srv_coro)
assert srv.is_serving() is True
2019-01-15 12:52:53 +00:00
@pytest.mark.skipif(
sys.version_info < (3, 7), reason="requires python3.7 or higher"
)
def test_asyncio_server_no_start_serving(app):
2019-01-15 15:45:47 +00:00
if not uvloop_installed():
loop = asyncio.get_event_loop()
asyncio_srv_coro = app.create_server(
port=43123,
2019-01-15 15:45:47 +00:00
return_asyncio_server=True,
asyncio_server_kwargs=dict(start_serving=False),
)
2019-01-15 15:45:47 +00:00
srv = loop.run_until_complete(asyncio_srv_coro)
assert srv.is_serving() is False
@pytest.mark.skipif(
sys.version_info < (3, 7), reason="requires python3.7 or higher"
)
def test_asyncio_server_start_serving(app):
if not uvloop_installed():
loop = asyncio.get_event_loop()
asyncio_srv_coro = app.create_server(
port=43124,
return_asyncio_server=True,
asyncio_server_kwargs=dict(start_serving=False),
)
srv = loop.run_until_complete(asyncio_srv_coro)
assert srv.is_serving() is False
loop.run_until_complete(srv.start_serving())
assert srv.is_serving() is True
srv.close()
# Looks like we can't easily test `serve_forever()`
2018-12-13 17:50:50 +00:00
def test_app_loop_not_running(app):
with pytest.raises(SanicException) as excinfo:
2019-06-04 08:58:00 +01:00
app.loop
2018-12-13 17:50:50 +00:00
assert str(excinfo.value) == (
2018-12-30 11:18:06 +00:00
"Loop can only be retrieved after the app has started "
"running. Not supported with `create_server` function"
2018-12-13 17:50:50 +00:00
)
def test_app_run_raise_type_error(app):
with pytest.raises(TypeError) as excinfo:
2018-12-30 11:18:06 +00:00
app.run(loop="loop")
2018-12-13 17:50:50 +00:00
assert str(excinfo.value) == (
2018-12-30 11:18:06 +00:00
"loop is not a valid argument. To use an existing loop, "
"change to create_server().\nSee more: "
"https://sanic.readthedocs.io/en/latest/sanic/deploying.html"
"#asynchronous-support"
2018-12-13 17:50:50 +00:00
)
def test_app_route_raise_value_error(app):
with pytest.raises(ValueError) as excinfo:
2018-12-30 11:18:06 +00:00
@app.route("/test")
2018-12-13 17:50:50 +00:00
async def handler():
2018-12-30 11:18:06 +00:00
return text("test")
2018-12-13 17:50:50 +00:00
2018-12-30 11:18:06 +00:00
assert (
str(excinfo.value)
== "Required parameter `request` missing in the handler() route?"
)
2018-12-13 17:50:50 +00:00
def test_app_handle_request_handler_is_none(app, monkeypatch):
def mockreturn(*args, **kwargs):
return None, [], {}, "", ""
2018-12-13 17:50:50 +00:00
# Not sure how to make app.router.get() return None, so use mock here.
2018-12-30 11:18:06 +00:00
monkeypatch.setattr(app.router, "get", mockreturn)
2018-12-13 17:50:50 +00:00
2018-12-30 11:18:06 +00:00
@app.get("/test")
2018-12-13 17:50:50 +00:00
def handler(request):
2018-12-30 11:18:06 +00:00
return text("test")
2018-12-13 17:50:50 +00:00
2018-12-30 11:18:06 +00:00
request, response = app.test_client.get("/test")
2018-12-13 17:50:50 +00:00
assert "'None' was returned while requesting a handler from the router" in response.text
2018-12-13 17:50:50 +00:00
2018-12-30 11:18:06 +00:00
@pytest.mark.parametrize("websocket_enabled", [True, False])
@pytest.mark.parametrize("enable", [True, False])
def test_app_enable_websocket(app, websocket_enabled, enable):
2018-12-13 17:50:50 +00:00
app.websocket_enabled = websocket_enabled
app.enable_websocket(enable=enable)
assert app.websocket_enabled == enable
2018-12-30 11:18:06 +00:00
@app.websocket("/ws")
2018-12-13 17:50:50 +00:00
async def handler(request, ws):
2018-12-30 11:18:06 +00:00
await ws.send("test")
2018-12-13 17:50:50 +00:00
assert app.websocket_enabled == True
def test_handle_request_with_nested_exception(app, monkeypatch):
2018-12-30 11:18:06 +00:00
err_msg = "Mock Exception"
# Not sure how to raise an exception in app.error_handler.response(), use mock here
def mock_error_handler_response(*args, **kwargs):
raise Exception(err_msg)
2018-12-30 11:18:06 +00:00
monkeypatch.setattr(
app.error_handler, "response", mock_error_handler_response
)
2018-12-30 11:18:06 +00:00
@app.get("/")
def handler(request):
raise Exception
2018-12-30 11:18:06 +00:00
request, response = app.test_client.get("/")
assert response.status == 500
2018-12-30 11:18:06 +00:00
assert response.text == "An error occurred while handling an error"
def test_handle_request_with_nested_exception_debug(app, monkeypatch):
2018-12-30 11:18:06 +00:00
err_msg = "Mock Exception"
# Not sure how to raise an exception in app.error_handler.response(), use mock here
def mock_error_handler_response(*args, **kwargs):
raise Exception(err_msg)
2018-12-30 11:18:06 +00:00
monkeypatch.setattr(
app.error_handler, "response", mock_error_handler_response
)
2018-12-30 11:18:06 +00:00
@app.get("/")
def handler(request):
raise Exception
2018-12-30 11:18:06 +00:00
request, response = app.test_client.get("/", debug=True)
assert response.status == 500
assert response.text.startswith(
f"Error while handling error: {err_msg}\nStack: Traceback (most recent call last):\n"
)
def test_handle_request_with_nested_sanic_exception(app, monkeypatch, caplog):
# Not sure how to raise an exception in app.error_handler.response(), use mock here
def mock_error_handler_response(*args, **kwargs):
2018-12-30 11:18:06 +00:00
raise SanicException("Mock SanicException")
2018-12-30 11:18:06 +00:00
monkeypatch.setattr(
app.error_handler, "response", mock_error_handler_response
)
2018-12-30 11:18:06 +00:00
@app.get("/")
def handler(request):
raise Exception
with caplog.at_level(logging.ERROR):
2018-12-30 11:18:06 +00:00
request, response = app.test_client.get("/")
assert response.status == 500
assert "Mock SanicException" in response.text
assert (
2018-12-30 11:18:06 +00:00
"sanic.root",
logging.ERROR,
2018-12-30 11:18:06 +00:00
"Exception occurred while handling uri: 'http://127.0.0.1:42101/'",
) in caplog.record_tuples