File: test_benchmarks_http_websocket.py

package info (click to toggle)
python-aiohttp 3.11.16-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 16,156 kB
  • sloc: python: 51,898; ansic: 20,843; makefile: 395; javascript: 31; sh: 3
file content (133 lines) | stat: -rw-r--r-- 4,689 bytes parent folder | download
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
"""codspeed benchmarks for http websocket."""

import asyncio
from typing import Union

from pytest_codspeed import BenchmarkFixture

from aiohttp._websocket.helpers import MSG_SIZE, PACK_LEN3
from aiohttp._websocket.reader import WebSocketDataQueue
from aiohttp.base_protocol import BaseProtocol
from aiohttp.http_websocket import WebSocketReader, WebSocketWriter, WSMsgType


def test_read_large_binary_websocket_messages(
    loop: asyncio.AbstractEventLoop, benchmark: BenchmarkFixture
) -> None:
    """Read one hundred large binary websocket messages."""
    queue = WebSocketDataQueue(BaseProtocol(loop), 2**16, loop=loop)
    reader = WebSocketReader(queue, max_msg_size=2**18)

    # PACK3 has a minimum message length of 2**16 bytes.
    message = b"x" * ((2**16) + 1)
    msg_length = len(message)
    first_byte = 0x80 | 0 | WSMsgType.BINARY.value
    header = PACK_LEN3(first_byte, 127, msg_length)
    raw_message = header + message
    feed_data = reader.feed_data

    @benchmark
    def _run() -> None:
        for _ in range(100):
            feed_data(raw_message)


def test_read_one_hundred_websocket_text_messages(
    loop: asyncio.AbstractEventLoop, benchmark: BenchmarkFixture
) -> None:
    """Benchmark reading 100 WebSocket text messages."""
    queue = WebSocketDataQueue(BaseProtocol(loop), 2**16, loop=loop)
    reader = WebSocketReader(queue, max_msg_size=2**16)
    raw_message = (
        b'\x81~\x01!{"id":1,"src":"shellyplugus-c049ef8c30e4","dst":"aios-1453812500'
        b'8","result":{"name":null,"id":"shellyplugus-c049ef8c30e4","mac":"C049EF8C30E'
        b'4","slot":1,"model":"SNPL-00116US","gen":2,"fw_id":"20231219-133953/1.1.0-g3'
        b'4b5d4f","ver":"1.1.0","app":"PlugUS","auth_en":false,"auth_domain":null}}'
    )
    feed_data = reader.feed_data

    @benchmark
    def _run() -> None:
        for _ in range(100):
            feed_data(raw_message)


class MockTransport(asyncio.Transport):
    """Mock transport for testing that do no real I/O."""

    def is_closing(self) -> bool:
        """Swallow is_closing."""
        return False

    def write(self, data: Union[bytes, bytearray, memoryview]) -> None:
        """Swallow writes."""


class MockProtocol(BaseProtocol):

    async def _drain_helper(self) -> None:
        """Swallow drain."""


def test_send_one_hundred_websocket_text_messages(
    loop: asyncio.AbstractEventLoop, benchmark: BenchmarkFixture
) -> None:
    """Benchmark sending 100 WebSocket text messages."""
    writer = WebSocketWriter(MockProtocol(loop=loop), MockTransport())
    raw_message = b"Hello, World!" * 100

    async def _send_one_hundred_websocket_text_messages() -> None:
        for _ in range(100):
            await writer.send_frame(raw_message, WSMsgType.TEXT)

    @benchmark
    def _run() -> None:
        loop.run_until_complete(_send_one_hundred_websocket_text_messages())


def test_send_one_hundred_large_websocket_text_messages(
    loop: asyncio.AbstractEventLoop, benchmark: BenchmarkFixture
) -> None:
    """Benchmark sending 100 WebSocket text messages."""
    writer = WebSocketWriter(MockProtocol(loop=loop), MockTransport())
    raw_message = b"x" * MSG_SIZE * 4

    async def _send_one_hundred_websocket_text_messages() -> None:
        for _ in range(100):
            await writer.send_frame(raw_message, WSMsgType.TEXT)

    @benchmark
    def _run() -> None:
        loop.run_until_complete(_send_one_hundred_websocket_text_messages())


def test_send_one_hundred_websocket_text_messages_with_mask(
    loop: asyncio.AbstractEventLoop, benchmark: BenchmarkFixture
) -> None:
    """Benchmark sending 100 masked WebSocket text messages."""
    writer = WebSocketWriter(MockProtocol(loop=loop), MockTransport(), use_mask=True)
    raw_message = b"Hello, World!" * 100

    async def _send_one_hundred_websocket_text_messages() -> None:
        for _ in range(100):
            await writer.send_frame(raw_message, WSMsgType.TEXT)

    @benchmark
    def _run() -> None:
        loop.run_until_complete(_send_one_hundred_websocket_text_messages())


def test_send_one_hundred_websocket_compressed_messages(
    loop: asyncio.AbstractEventLoop, benchmark: BenchmarkFixture
) -> None:
    """Benchmark sending 100 WebSocket compressed messages."""
    writer = WebSocketWriter(MockProtocol(loop=loop), MockTransport(), compress=15)
    raw_message = b"Hello, World!" * 100

    async def _send_one_hundred_websocket_compressed_messages() -> None:
        for _ in range(100):
            await writer.send_frame(raw_message, WSMsgType.BINARY)

    @benchmark
    def _run() -> None:
        loop.run_until_complete(_send_one_hundred_websocket_compressed_messages())