|
1 | 1 | # HTTP websocket server functional tests
|
2 | 2 |
|
3 | 3 | import asyncio
|
| 4 | +import contextlib |
| 5 | +import sys |
4 | 6 | from typing import Any, Optional
|
5 | 7 |
|
6 | 8 | import pytest
|
@@ -797,3 +799,94 @@ async def ws_handler(request):
|
797 | 799 | resp = await client.get("/api/null", timeout=1)
|
798 | 800 | assert (await resp.json()) == {"err": None}
|
799 | 801 | resp.close()
|
| 802 | + |
| 803 | + |
| 804 | +async def test_receive_being_cancelled_keeps_connection_open( |
| 805 | + loop: Any, aiohttp_client: Any |
| 806 | +) -> None: |
| 807 | + closed = loop.create_future() |
| 808 | + |
| 809 | + async def handler(request): |
| 810 | + ws = web.WebSocketResponse(autoping=False) |
| 811 | + await ws.prepare(request) |
| 812 | + |
| 813 | + task = asyncio.create_task(ws.receive()) |
| 814 | + await asyncio.sleep(0) |
| 815 | + task.cancel() |
| 816 | + with contextlib.suppress(asyncio.CancelledError): |
| 817 | + await task |
| 818 | + |
| 819 | + msg = await ws.receive() |
| 820 | + assert msg.type == WSMsgType.PING |
| 821 | + await asyncio.sleep(0) |
| 822 | + await ws.pong("data") |
| 823 | + |
| 824 | + msg = await ws.receive() |
| 825 | + assert msg.type == WSMsgType.CLOSE |
| 826 | + assert msg.data == WSCloseCode.OK |
| 827 | + assert msg.extra == "exit message" |
| 828 | + closed.set_result(None) |
| 829 | + return ws |
| 830 | + |
| 831 | + app = web.Application() |
| 832 | + app.router.add_get("/", handler) |
| 833 | + client = await aiohttp_client(app) |
| 834 | + |
| 835 | + ws = await client.ws_connect("/", autoping=False) |
| 836 | + |
| 837 | + await asyncio.sleep(0) |
| 838 | + await ws.ping("data") |
| 839 | + |
| 840 | + msg = await ws.receive() |
| 841 | + assert msg.type == WSMsgType.PONG |
| 842 | + assert msg.data == b"data" |
| 843 | + |
| 844 | + await ws.close(code=WSCloseCode.OK, message="exit message") |
| 845 | + |
| 846 | + await closed |
| 847 | + |
| 848 | + |
| 849 | +async def test_receive_timeout_keeps_connection_open( |
| 850 | + loop: Any, aiohttp_client: Any |
| 851 | +) -> None: |
| 852 | + closed = loop.create_future() |
| 853 | + timed_out = loop.create_future() |
| 854 | + |
| 855 | + async def handler(request): |
| 856 | + ws = web.WebSocketResponse(autoping=False) |
| 857 | + await ws.prepare(request) |
| 858 | + |
| 859 | + task = asyncio.create_task(ws.receive(sys.float_info.min)) |
| 860 | + with contextlib.suppress(asyncio.TimeoutError): |
| 861 | + await task |
| 862 | + |
| 863 | + timed_out.set_result(None) |
| 864 | + |
| 865 | + msg = await ws.receive() |
| 866 | + assert msg.type == WSMsgType.PING |
| 867 | + await asyncio.sleep(0) |
| 868 | + await ws.pong("data") |
| 869 | + |
| 870 | + msg = await ws.receive() |
| 871 | + assert msg.type == WSMsgType.CLOSE |
| 872 | + assert msg.data == WSCloseCode.OK |
| 873 | + assert msg.extra == "exit message" |
| 874 | + closed.set_result(None) |
| 875 | + return ws |
| 876 | + |
| 877 | + app = web.Application() |
| 878 | + app.router.add_get("/", handler) |
| 879 | + client = await aiohttp_client(app) |
| 880 | + |
| 881 | + ws = await client.ws_connect("/", autoping=False) |
| 882 | + |
| 883 | + await timed_out |
| 884 | + await ws.ping("data") |
| 885 | + |
| 886 | + msg = await ws.receive() |
| 887 | + assert msg.type == WSMsgType.PONG |
| 888 | + assert msg.data == b"data" |
| 889 | + |
| 890 | + await ws.close(code=WSCloseCode.OK, message="exit message") |
| 891 | + |
| 892 | + await closed |
0 commit comments