|
2 | 2 | # HTTP websocket server functional tests
|
3 | 3 |
|
4 | 4 | import asyncio
|
| 5 | +import contextlib |
| 6 | +import sys |
5 | 7 | from typing import Any, Optional
|
6 | 8 |
|
7 | 9 | import pytest
|
@@ -828,3 +830,94 @@ async def ws_handler(request):
|
828 | 830 | resp = await client.get("/api/null", timeout=aiohttp.ClientTimeout(total=1))
|
829 | 831 | assert (await resp.json()) == {"err": None}
|
830 | 832 | resp.close()
|
| 833 | + |
| 834 | + |
| 835 | +async def test_receive_being_cancelled_keeps_connection_open( |
| 836 | + loop: Any, aiohttp_client: Any |
| 837 | +) -> None: |
| 838 | + closed = loop.create_future() |
| 839 | + |
| 840 | + async def handler(request): |
| 841 | + ws = web.WebSocketResponse(autoping=False) |
| 842 | + await ws.prepare(request) |
| 843 | + |
| 844 | + task = asyncio.create_task(ws.receive()) |
| 845 | + await asyncio.sleep(0) |
| 846 | + task.cancel() |
| 847 | + with contextlib.suppress(asyncio.CancelledError): |
| 848 | + await task |
| 849 | + |
| 850 | + msg = await ws.receive() |
| 851 | + assert msg.type == WSMsgType.PING |
| 852 | + await asyncio.sleep(0) |
| 853 | + await ws.pong("data") |
| 854 | + |
| 855 | + msg = await ws.receive() |
| 856 | + assert msg.type == WSMsgType.CLOSE |
| 857 | + assert msg.data == WSCloseCode.OK |
| 858 | + assert msg.extra == "exit message" |
| 859 | + closed.set_result(None) |
| 860 | + return ws |
| 861 | + |
| 862 | + app = web.Application() |
| 863 | + app.router.add_get("/", handler) |
| 864 | + client = await aiohttp_client(app) |
| 865 | + |
| 866 | + ws = await client.ws_connect("/", autoping=False) |
| 867 | + |
| 868 | + await asyncio.sleep(0) |
| 869 | + await ws.ping("data") |
| 870 | + |
| 871 | + msg = await ws.receive() |
| 872 | + assert msg.type == WSMsgType.PONG |
| 873 | + assert msg.data == b"data" |
| 874 | + |
| 875 | + await ws.close(code=WSCloseCode.OK, message="exit message") |
| 876 | + |
| 877 | + await closed |
| 878 | + |
| 879 | + |
| 880 | +async def test_receive_timeout_keeps_connection_open( |
| 881 | + loop: Any, aiohttp_client: Any |
| 882 | +) -> None: |
| 883 | + closed = loop.create_future() |
| 884 | + timed_out = loop.create_future() |
| 885 | + |
| 886 | + async def handler(request): |
| 887 | + ws = web.WebSocketResponse(autoping=False) |
| 888 | + await ws.prepare(request) |
| 889 | + |
| 890 | + task = asyncio.create_task(ws.receive(sys.float_info.min)) |
| 891 | + with contextlib.suppress(asyncio.TimeoutError): |
| 892 | + await task |
| 893 | + |
| 894 | + timed_out.set_result(None) |
| 895 | + |
| 896 | + msg = await ws.receive() |
| 897 | + assert msg.type == WSMsgType.PING |
| 898 | + await asyncio.sleep(0) |
| 899 | + await ws.pong("data") |
| 900 | + |
| 901 | + msg = await ws.receive() |
| 902 | + assert msg.type == WSMsgType.CLOSE |
| 903 | + assert msg.data == WSCloseCode.OK |
| 904 | + assert msg.extra == "exit message" |
| 905 | + closed.set_result(None) |
| 906 | + return ws |
| 907 | + |
| 908 | + app = web.Application() |
| 909 | + app.router.add_get("/", handler) |
| 910 | + client = await aiohttp_client(app) |
| 911 | + |
| 912 | + ws = await client.ws_connect("/", autoping=False) |
| 913 | + |
| 914 | + await timed_out |
| 915 | + await ws.ping("data") |
| 916 | + |
| 917 | + msg = await ws.receive() |
| 918 | + assert msg.type == WSMsgType.PONG |
| 919 | + assert msg.data == b"data" |
| 920 | + |
| 921 | + await ws.close(code=WSCloseCode.OK, message="exit message") |
| 922 | + |
| 923 | + await closed |
0 commit comments