Skip to content

Commit 9f6af54

Browse files
authored
chore: enable codspeed benchmarks (#1456)
1 parent 7b4a29b commit 9f6af54

7 files changed

Lines changed: 635 additions & 1 deletion

File tree

.github/workflows/ci.yml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,25 @@ jobs:
9191
with:
9292
token: ${{ secrets.CODECOV_TOKEN }}
9393

94+
benchmark:
95+
runs-on: ubuntu-latest
96+
steps:
97+
- uses: actions/checkout@v4
98+
- name: Setup Python 3.12
99+
uses: actions/setup-python@v4
100+
with:
101+
python-version: 3.12
102+
- uses: snok/install-poetry@v1.3.4
103+
- name: Install Dependencies
104+
run: |
105+
REQUIRE_CYTHON=1 poetry install --only=main,dev
106+
shell: bash
107+
- name: Run benchmarks
108+
uses: CodSpeedHQ/action@v3
109+
with:
110+
token: ${{ secrets.CODSPEED_TOKEN }}
111+
run: poetry run pytest --no-cov -vvvvv --codspeed tests/benchmarks
112+
94113
release:
95114
needs:
96115
- test

poetry.lock

Lines changed: 243 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ pytest-asyncio = ">=0.20.3,<0.25.0"
8080
cython = "^3.0.5"
8181
setuptools = ">=65.6.3,<76.0.0"
8282
pytest-timeout = "^2.1.0"
83+
pytest-codspeed = "^3.1.0"
8384

8485
[tool.ruff]
8586
target-version = "py38"

tests/benchmarks/__init__.py

Whitespace-only changes.

tests/benchmarks/test_incoming.py

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
"""Benchmark for DNSIncoming."""
2+
3+
import socket
4+
from typing import List
5+
6+
from pytest_codspeed import BenchmarkFixture
7+
8+
from zeroconf import (
9+
DNSAddress,
10+
DNSIncoming,
11+
DNSNsec,
12+
DNSOutgoing,
13+
DNSService,
14+
DNSText,
15+
const,
16+
)
17+
18+
19+
def generate_packets() -> List[bytes]:
20+
out = DNSOutgoing(const._FLAGS_QR_RESPONSE | const._FLAGS_AA)
21+
address = socket.inet_pton(socket.AF_INET, "192.168.208.5")
22+
23+
additionals = [
24+
{
25+
"name": "HASS Bridge ZJWH FF5137._hap._tcp.local.",
26+
"address": address,
27+
"port": 51832,
28+
"text": b"\x13md=HASS Bridge"
29+
b" ZJWH\x06pv=1.0\x14id=01:6B:30:FF:51:37\x05c#=12\x04s#=1\x04ff=0\x04"
30+
b"ci=2\x04sf=0\x0bsh=L0m/aQ==",
31+
},
32+
{
33+
"name": "HASS Bridge 3K9A C2582A._hap._tcp.local.",
34+
"address": address,
35+
"port": 51834,
36+
"text": b"\x13md=HASS Bridge"
37+
b" 3K9A\x06pv=1.0\x14id=E2:AA:5B:C2:58:2A\x05c#=12\x04s#=1\x04ff=0\x04"
38+
b"ci=2\x04sf=0\x0bsh=b2CnzQ==",
39+
},
40+
{
41+
"name": "Master Bed TV CEDB27._hap._tcp.local.",
42+
"address": address,
43+
"port": 51830,
44+
"text": b"\x10md=Master Bed"
45+
b" TV\x06pv=1.0\x14id=9E:B7:44:CE:DB:27\x05c#=18\x04s#=1\x04ff=0\x05"
46+
b"ci=31\x04sf=0\x0bsh=CVj1kw==",
47+
},
48+
{
49+
"name": "Living Room TV 921B77._hap._tcp.local.",
50+
"address": address,
51+
"port": 51833,
52+
"text": b"\x11md=Living Room"
53+
b" TV\x06pv=1.0\x14id=11:61:E7:92:1B:77\x05c#=17\x04s#=1\x04ff=0\x05"
54+
b"ci=31\x04sf=0\x0bsh=qU77SQ==",
55+
},
56+
{
57+
"name": "HASS Bridge ZC8X FF413D._hap._tcp.local.",
58+
"address": address,
59+
"port": 51829,
60+
"text": b"\x13md=HASS Bridge"
61+
b" ZC8X\x06pv=1.0\x14id=96:14:45:FF:41:3D\x05c#=12\x04s#=1\x04ff=0\x04"
62+
b"ci=2\x04sf=0\x0bsh=b0QZlg==",
63+
},
64+
{
65+
"name": "HASS Bridge WLTF 4BE61F._hap._tcp.local.",
66+
"address": address,
67+
"port": 51837,
68+
"text": b"\x13md=HASS Bridge"
69+
b" WLTF\x06pv=1.0\x14id=E0:E7:98:4B:E6:1F\x04c#=2\x04s#=1\x04ff=0\x04"
70+
b"ci=2\x04sf=0\x0bsh=ahAISA==",
71+
},
72+
{
73+
"name": "FrontdoorCamera 8941D1._hap._tcp.local.",
74+
"address": address,
75+
"port": 54898,
76+
"text": b"\x12md=FrontdoorCamera\x06pv=1.0\x14id=9F:B7:DC:89:41:D1\x04c#=2\x04"
77+
b"s#=1\x04ff=0\x04ci=2\x04sf=0\x0bsh=0+MXmA==",
78+
},
79+
{
80+
"name": "HASS Bridge W9DN 5B5CC5._hap._tcp.local.",
81+
"address": address,
82+
"port": 51836,
83+
"text": b"\x13md=HASS Bridge"
84+
b" W9DN\x06pv=1.0\x14id=11:8E:DB:5B:5C:C5\x05c#=12\x04s#=1\x04ff=0\x04"
85+
b"ci=2\x04sf=0\x0bsh=6fLM5A==",
86+
},
87+
{
88+
"name": "HASS Bridge Y9OO EFF0A7._hap._tcp.local.",
89+
"address": address,
90+
"port": 51838,
91+
"text": b"\x13md=HASS Bridge"
92+
b" Y9OO\x06pv=1.0\x14id=D3:FE:98:EF:F0:A7\x04c#=2\x04s#=1\x04ff=0\x04"
93+
b"ci=2\x04sf=0\x0bsh=u3bdfw==",
94+
},
95+
{
96+
"name": "Snooze Room TV 6B89B0._hap._tcp.local.",
97+
"address": address,
98+
"port": 51835,
99+
"text": b"\x11md=Snooze Room"
100+
b" TV\x06pv=1.0\x14id=5F:D5:70:6B:89:B0\x05c#=17\x04s#=1\x04ff=0\x05"
101+
b"ci=31\x04sf=0\x0bsh=xNTqsg==",
102+
},
103+
{
104+
"name": "AlexanderHomeAssistant 74651D._hap._tcp.local.",
105+
"address": address,
106+
"port": 54811,
107+
"text": b"\x19md=AlexanderHomeAssistant\x06pv=1.0\x14id=59:8A:0B:74:65:1D\x05"
108+
b"c#=14\x04s#=1\x04ff=0\x04ci=2\x04sf=0\x0bsh=ccZLPA==",
109+
},
110+
{
111+
"name": "HASS Bridge OS95 39C053._hap._tcp.local.",
112+
"address": address,
113+
"port": 51831,
114+
"text": b"\x13md=HASS Bridge"
115+
b" OS95\x06pv=1.0\x14id=7E:8C:E6:39:C0:53\x05c#=12\x04s#=1\x04ff=0\x04ci=2"
116+
b"\x04sf=0\x0bsh=Xfe5LQ==",
117+
},
118+
]
119+
120+
out.add_answer_at_time(
121+
DNSText(
122+
"HASS Bridge W9DN 5B5CC5._hap._tcp.local.",
123+
const._TYPE_TXT,
124+
const._CLASS_IN | const._CLASS_UNIQUE,
125+
const._DNS_OTHER_TTL,
126+
b"\x13md=HASS Bridge W9DN\x06pv=1.0\x14id=11:8E:DB:5B:5C:C5\x05c#=12\x04s#=1"
127+
b"\x04ff=0\x04ci=2\x04sf=0\x0bsh=6fLM5A==",
128+
),
129+
0,
130+
)
131+
132+
for record in additionals:
133+
out.add_additional_answer(
134+
DNSService(
135+
record["name"], # type: ignore
136+
const._TYPE_SRV,
137+
const._CLASS_IN | const._CLASS_UNIQUE,
138+
const._DNS_HOST_TTL,
139+
0,
140+
0,
141+
record["port"], # type: ignore
142+
record["name"], # type: ignore
143+
)
144+
)
145+
out.add_additional_answer(
146+
DNSText(
147+
record["name"], # type: ignore
148+
const._TYPE_TXT,
149+
const._CLASS_IN | const._CLASS_UNIQUE,
150+
const._DNS_OTHER_TTL,
151+
record["text"], # type: ignore
152+
)
153+
)
154+
out.add_additional_answer(
155+
DNSAddress(
156+
record["name"], # type: ignore
157+
const._TYPE_A,
158+
const._CLASS_IN | const._CLASS_UNIQUE,
159+
const._DNS_HOST_TTL,
160+
record["address"], # type: ignore
161+
)
162+
)
163+
out.add_additional_answer(
164+
DNSNsec(
165+
record["name"], # type: ignore
166+
const._TYPE_NSEC,
167+
const._CLASS_IN | const._CLASS_UNIQUE,
168+
const._DNS_OTHER_TTL,
169+
record["name"], # type: ignore
170+
[const._TYPE_TXT, const._TYPE_SRV],
171+
)
172+
)
173+
174+
return out.packets()
175+
176+
177+
packets = generate_packets()
178+
179+
180+
def test_parse_incoming_message(benchmark: BenchmarkFixture) -> None:
181+
@benchmark
182+
def parse_incoming_message() -> None:
183+
for packet in packets:
184+
DNSIncoming(packet).answers # noqa: B018
185+
break

tests/benchmarks/test_outgoing.py

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
"""Benchmark for DNSOutgoing."""
2+
3+
import socket
4+
5+
from pytest_codspeed import BenchmarkFixture
6+
7+
from zeroconf import DNSAddress, DNSOutgoing, DNSService, DNSText, const
8+
from zeroconf._protocol.outgoing import State
9+
10+
11+
def generate_packets() -> DNSOutgoing:
12+
out = DNSOutgoing(const._FLAGS_QR_RESPONSE | const._FLAGS_AA)
13+
address = socket.inet_pton(socket.AF_INET, "192.168.208.5")
14+
15+
additionals = [
16+
{
17+
"name": "HASS Bridge ZJWH FF5137._hap._tcp.local.",
18+
"address": address,
19+
"port": 51832,
20+
"text": b"\x13md=HASS Bridge"
21+
b" ZJWH\x06pv=1.0\x14id=01:6B:30:FF:51:37\x05c#=12\x04s#=1\x04ff=0\x04"
22+
b"ci=2\x04sf=0\x0bsh=L0m/aQ==",
23+
},
24+
{
25+
"name": "HASS Bridge 3K9A C2582A._hap._tcp.local.",
26+
"address": address,
27+
"port": 51834,
28+
"text": b"\x13md=HASS Bridge"
29+
b" 3K9A\x06pv=1.0\x14id=E2:AA:5B:C2:58:2A\x05c#=12\x04s#=1\x04ff=0\x04"
30+
b"ci=2\x04sf=0\x0bsh=b2CnzQ==",
31+
},
32+
{
33+
"name": "Master Bed TV CEDB27._hap._tcp.local.",
34+
"address": address,
35+
"port": 51830,
36+
"text": b"\x10md=Master Bed"
37+
b" TV\x06pv=1.0\x14id=9E:B7:44:CE:DB:27\x05c#=18\x04s#=1\x04ff=0\x05"
38+
b"ci=31\x04sf=0\x0bsh=CVj1kw==",
39+
},
40+
{
41+
"name": "Living Room TV 921B77._hap._tcp.local.",
42+
"address": address,
43+
"port": 51833,
44+
"text": b"\x11md=Living Room"
45+
b" TV\x06pv=1.0\x14id=11:61:E7:92:1B:77\x05c#=17\x04s#=1\x04ff=0\x05"
46+
b"ci=31\x04sf=0\x0bsh=qU77SQ==",
47+
},
48+
{
49+
"name": "HASS Bridge ZC8X FF413D._hap._tcp.local.",
50+
"address": address,
51+
"port": 51829,
52+
"text": b"\x13md=HASS Bridge"
53+
b" ZC8X\x06pv=1.0\x14id=96:14:45:FF:41:3D\x05c#=12\x04s#=1\x04ff=0\x04"
54+
b"ci=2\x04sf=0\x0bsh=b0QZlg==",
55+
},
56+
{
57+
"name": "HASS Bridge WLTF 4BE61F._hap._tcp.local.",
58+
"address": address,
59+
"port": 51837,
60+
"text": b"\x13md=HASS Bridge"
61+
b" WLTF\x06pv=1.0\x14id=E0:E7:98:4B:E6:1F\x04c#=2\x04s#=1\x04ff=0\x04"
62+
b"ci=2\x04sf=0\x0bsh=ahAISA==",
63+
},
64+
{
65+
"name": "FrontdoorCamera 8941D1._hap._tcp.local.",
66+
"address": address,
67+
"port": 54898,
68+
"text": b"\x12md=FrontdoorCamera\x06pv=1.0\x14id=9F:B7:DC:89:41:D1\x04c#=2\x04"
69+
b"s#=1\x04ff=0\x04ci=2\x04sf=0\x0bsh=0+MXmA==",
70+
},
71+
{
72+
"name": "HASS Bridge W9DN 5B5CC5._hap._tcp.local.",
73+
"address": address,
74+
"port": 51836,
75+
"text": b"\x13md=HASS Bridge"
76+
b" W9DN\x06pv=1.0\x14id=11:8E:DB:5B:5C:C5\x05c#=12\x04s#=1\x04ff=0\x04"
77+
b"ci=2\x04sf=0\x0bsh=6fLM5A==",
78+
},
79+
{
80+
"name": "HASS Bridge Y9OO EFF0A7._hap._tcp.local.",
81+
"address": address,
82+
"port": 51838,
83+
"text": b"\x13md=HASS Bridge"
84+
b" Y9OO\x06pv=1.0\x14id=D3:FE:98:EF:F0:A7\x04c#=2\x04s#=1\x04ff=0\x04"
85+
b"ci=2\x04sf=0\x0bsh=u3bdfw==",
86+
},
87+
{
88+
"name": "Snooze Room TV 6B89B0._hap._tcp.local.",
89+
"address": address,
90+
"port": 51835,
91+
"text": b"\x11md=Snooze Room"
92+
b" TV\x06pv=1.0\x14id=5F:D5:70:6B:89:B0\x05c#=17\x04s#=1\x04ff=0\x05"
93+
b"ci=31\x04sf=0\x0bsh=xNTqsg==",
94+
},
95+
{
96+
"name": "AlexanderHomeAssistant 74651D._hap._tcp.local.",
97+
"address": address,
98+
"port": 54811,
99+
"text": b"\x19md=AlexanderHomeAssistant\x06pv=1.0\x14id=59:8A:0B:74:65:1D\x05"
100+
b"c#=14\x04s#=1\x04ff=0\x04ci=2\x04sf=0\x0bsh=ccZLPA==",
101+
},
102+
{
103+
"name": "HASS Bridge OS95 39C053._hap._tcp.local.",
104+
"address": address,
105+
"port": 51831,
106+
"text": b"\x13md=HASS Bridge"
107+
b" OS95\x06pv=1.0\x14id=7E:8C:E6:39:C0:53\x05c#=12\x04s#=1\x04ff=0\x04ci=2"
108+
b"\x04sf=0\x0bsh=Xfe5LQ==",
109+
},
110+
]
111+
112+
out.add_answer_at_time(
113+
DNSText(
114+
"HASS Bridge W9DN 5B5CC5._hap._tcp.local.",
115+
const._TYPE_TXT,
116+
const._CLASS_IN | const._CLASS_UNIQUE,
117+
const._DNS_OTHER_TTL,
118+
b"\x13md=HASS Bridge W9DN\x06pv=1.0\x14id=11:8E:DB:5B:5C:C5\x05c#=12\x04s#=1"
119+
b"\x04ff=0\x04ci=2\x04sf=0\x0bsh=6fLM5A==",
120+
),
121+
0,
122+
)
123+
124+
for record in additionals:
125+
out.add_additional_answer(
126+
DNSService(
127+
record["name"], # type: ignore
128+
const._TYPE_SRV,
129+
const._CLASS_IN | const._CLASS_UNIQUE,
130+
const._DNS_HOST_TTL,
131+
0,
132+
0,
133+
record["port"], # type: ignore
134+
record["name"], # type: ignore
135+
)
136+
)
137+
out.add_additional_answer(
138+
DNSText(
139+
record["name"], # type: ignore
140+
const._TYPE_TXT,
141+
const._CLASS_IN | const._CLASS_UNIQUE,
142+
const._DNS_OTHER_TTL,
143+
record["text"], # type: ignore
144+
)
145+
)
146+
out.add_additional_answer(
147+
DNSAddress(
148+
record["name"], # type: ignore
149+
const._TYPE_A,
150+
const._CLASS_IN | const._CLASS_UNIQUE,
151+
const._DNS_HOST_TTL,
152+
record["address"], # type: ignore
153+
)
154+
)
155+
156+
return out
157+
158+
159+
out = generate_packets()
160+
161+
162+
def test_parse_outgoing_message(benchmark: BenchmarkFixture) -> None:
163+
@benchmark
164+
def make_outgoing_message() -> None:
165+
out.packets()
166+
out.state = State.init.value
167+
out.finished = False
168+
out._reset_for_next_packet()

0 commit comments

Comments
 (0)