Skip to content

Commit 8454450

Browse files
committed
fix(mdns): Add tests for delegated answers
1 parent f07f344 commit 8454450

File tree

2 files changed

+62
-3
lines changed

2 files changed

+62
-3
lines changed

components/mdns/tests/host_test/dnsfixture.py

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
1+
# SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
22
# SPDX-License-Identifier: Unlicense OR CC0-1.0
33
import logging
44
import re
@@ -92,10 +92,58 @@ def check_record(self, name, query_type, expected=True, expect=None):
9292
if expect is None:
9393
expect = name
9494
if expected:
95-
assert any(expect in answer for answer in answers), f"Expected record '{expect}' not found in answer section"
95+
assert any(expect in answer for answer in answers), f"Expected record '{expect}' not in answer section"
9696
else:
9797
assert not any(expect in answer for answer in answers), f"Unexpected record '{expect}' found in answer section"
9898

99+
def parse_section(self, response, section: str, rdtype_text: str):
100+
"""Parse a specific response section (answer, authority, additional) for given rdtype.
101+
102+
Returns list of textual records for that rdtype.
103+
"""
104+
out = []
105+
if not response:
106+
return out
107+
rrsets = []
108+
if section == 'answer':
109+
rrsets = response.answer
110+
elif section == 'authority':
111+
rrsets = response.authority
112+
elif section == 'additional':
113+
rrsets = response.additional
114+
else:
115+
raise ValueError('invalid section')
116+
for rr in rrsets:
117+
if dns.rdatatype.to_text(rr.rdtype) != rdtype_text:
118+
continue
119+
for item in rr.items:
120+
full = (
121+
f'{rr.name} {rr.ttl} '
122+
f'{dns.rdataclass.to_text(rr.rdclass)} '
123+
f'{dns.rdatatype.to_text(rr.rdtype)} '
124+
f'{item.to_text()}'
125+
)
126+
out.append(full)
127+
return out
128+
129+
def check_additional(self, response, rdtype_text: str, owner_contains: str, expected: bool = True, expect_substr: str | None = None):
130+
"""Check Additional section for an RR of type rdtype_text whose owner includes owner_contains.
131+
132+
If expect_substr is provided, also require it to appear in the textual RR.
133+
"""
134+
records = self.parse_section(response, 'additional', rdtype_text)
135+
logger.info(f'additional({rdtype_text}): {records}')
136+
137+
def _matches(line: str) -> bool:
138+
in_owner = owner_contains in line
139+
has_val = (expect_substr in line) if expect_substr else True
140+
return in_owner and has_val
141+
found = any(_matches(r) for r in records)
142+
if expected:
143+
assert found, f"Expected {rdtype_text} for {owner_contains} in Additional not found"
144+
else:
145+
assert not found, f"Unexpected {rdtype_text} for {owner_contains} found in Additional"
146+
99147

100148
if __name__ == '__main__':
101149
if len(sys.argv) < 3:

components/mdns/tests/host_test/pytest_mdns.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
1+
# SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
22
# SPDX-License-Identifier: Unlicense OR CC0-1.0
33
import logging
44

@@ -65,6 +65,17 @@ def test_add_service(mdns_console, dig_app):
6565
dig_app.check_record('_http._tcp.local', query_type='PTR', expected=True)
6666

6767

68+
def test_ptr_additional_records_for_service(dig_app):
69+
# Query PTR for the service type and ensure SRV/TXT are in Additional (RFC 6763 §12.1)
70+
resp = dig_app.run_query('_http._tcp.local', query_type='PTR')
71+
# Answer section should have at least one PTR to the instance
72+
answers = dig_app.parse_answer_section(resp, 'PTR')
73+
assert any('test_service._http._tcp.local' in a for a in answers)
74+
# Additional section should include SRV and TXT for the same instance
75+
dig_app.check_additional(resp, 'SRV', 'test_service._http._tcp.local', expected=True)
76+
dig_app.check_additional(resp, 'TXT', 'test_service._http._tcp.local', expected=True)
77+
78+
6879
def test_remove_service(mdns_console, dig_app):
6980
mdns_console.send_input('mdns_service_remove _http _tcp')
7081
mdns_console.send_input('mdns_service_lookup _http _tcp')

0 commit comments

Comments
 (0)