1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
|
import asyncio
from unittest import mock
import pytest
from aiohttp import client, helpers, web
async def test_simple_server(aiohttp_raw_server, aiohttp_client) -> None:
async def handler(request):
return web.Response(text=str(request.rel_url))
server = await aiohttp_raw_server(handler)
cli = await aiohttp_client(server)
resp = await cli.get("/path/to")
assert resp.status == 200
txt = await resp.text()
assert txt == "/path/to"
@pytest.mark.xfail(
not helpers.NO_EXTENSIONS,
raises=client.ServerDisconnectedError,
reason="The behavior of C-extensions differs from pure-Python: "
"https://github.com/aio-libs/aiohttp/issues/6446",
)
async def test_unsupported_upgrade(aiohttp_raw_server, aiohttp_client) -> None:
# don't fail if a client probes for an unsupported protocol upgrade
# https://github.com/aio-libs/aiohttp/issues/6446#issuecomment-999032039
async def handler(request: web.Request):
return web.Response(body=await request.read())
upgrade_headers = {"Connection": "Upgrade", "Upgrade": "unsupported_proto"}
server = await aiohttp_raw_server(handler)
cli = await aiohttp_client(server)
test_data = b"Test"
resp = await cli.post("/path/to", data=test_data, headers=upgrade_headers)
assert resp.status == 200
data = await resp.read()
assert data == test_data
async def test_raw_server_not_http_exception(aiohttp_raw_server, aiohttp_client):
exc = RuntimeError("custom runtime error")
async def handler(request):
raise exc
logger = mock.Mock()
server = await aiohttp_raw_server(handler, logger=logger, debug=False)
cli = await aiohttp_client(server)
resp = await cli.get("/path/to")
assert resp.status == 500
assert resp.headers["Content-Type"].startswith("text/plain")
txt = await resp.text()
assert txt.startswith("500 Internal Server Error")
assert "Traceback" not in txt
logger.exception.assert_called_with("Error handling request", exc_info=exc)
async def test_raw_server_handler_timeout(aiohttp_raw_server, aiohttp_client) -> None:
exc = asyncio.TimeoutError("error")
async def handler(request):
raise exc
logger = mock.Mock()
server = await aiohttp_raw_server(handler, logger=logger)
cli = await aiohttp_client(server)
resp = await cli.get("/path/to")
assert resp.status == 504
await resp.text()
logger.debug.assert_called_with("Request handler timed out.", exc_info=exc)
async def test_raw_server_do_not_swallow_exceptions(aiohttp_raw_server, aiohttp_client):
async def handler(request):
raise asyncio.CancelledError()
logger = mock.Mock()
server = await aiohttp_raw_server(handler, logger=logger)
cli = await aiohttp_client(server)
with pytest.raises(client.ServerDisconnectedError):
await cli.get("/path/to")
logger.debug.assert_called_with("Ignored premature client disconnection")
async def test_raw_server_cancelled_in_write_eof(aiohttp_raw_server, aiohttp_client):
async def handler(request):
resp = web.Response(text=str(request.rel_url))
resp.write_eof = mock.Mock(side_effect=asyncio.CancelledError("error"))
return resp
logger = mock.Mock()
server = await aiohttp_raw_server(handler, logger=logger)
cli = await aiohttp_client(server)
resp = await cli.get("/path/to")
with pytest.raises(client.ClientPayloadError):
await resp.read()
logger.debug.assert_called_with("Ignored premature client disconnection")
async def test_raw_server_not_http_exception_debug(aiohttp_raw_server, aiohttp_client):
exc = RuntimeError("custom runtime error")
async def handler(request):
raise exc
logger = mock.Mock()
server = await aiohttp_raw_server(handler, logger=logger, debug=True)
cli = await aiohttp_client(server)
resp = await cli.get("/path/to")
assert resp.status == 500
assert resp.headers["Content-Type"].startswith("text/plain")
txt = await resp.text()
assert "Traceback (most recent call last):\n" in txt
logger.exception.assert_called_with("Error handling request", exc_info=exc)
async def test_raw_server_html_exception(aiohttp_raw_server, aiohttp_client):
exc = RuntimeError("custom runtime error")
async def handler(request):
raise exc
logger = mock.Mock()
server = await aiohttp_raw_server(handler, logger=logger, debug=False)
cli = await aiohttp_client(server)
resp = await cli.get("/path/to", headers={"Accept": "text/html"})
assert resp.status == 500
assert resp.headers["Content-Type"].startswith("text/html")
txt = await resp.text()
assert txt == (
"<html><head><title>500 Internal Server Error</title></head><body>\n"
"<h1>500 Internal Server Error</h1>\n"
"Server got itself in trouble\n"
"</body></html>\n"
)
logger.exception.assert_called_with("Error handling request", exc_info=exc)
async def test_raw_server_html_exception_debug(aiohttp_raw_server, aiohttp_client):
exc = RuntimeError("custom runtime error")
async def handler(request):
raise exc
logger = mock.Mock()
server = await aiohttp_raw_server(handler, logger=logger, debug=True)
cli = await aiohttp_client(server)
resp = await cli.get("/path/to", headers={"Accept": "text/html"})
assert resp.status == 500
assert resp.headers["Content-Type"].startswith("text/html")
txt = await resp.text()
assert txt.startswith(
"<html><head><title>500 Internal Server Error</title></head><body>\n"
"<h1>500 Internal Server Error</h1>\n"
"<h2>Traceback:</h2>\n"
"<pre>Traceback (most recent call last):\n"
)
logger.exception.assert_called_with("Error handling request", exc_info=exc)
|