1
0
mirror of https://github.com/esphome/esphome.git synced 2025-09-18 11:12:20 +01:00

Fix dashboard dns lookup delay

This commit is contained in:
J. Nick Koston
2025-09-11 18:21:01 -05:00
parent bbef0e173e
commit 4d3405340d
10 changed files with 448 additions and 57 deletions

View File

@@ -594,3 +594,90 @@ def test_resolve_ip_address_sorting() -> None:
assert result[0][4][0] == "2001:db8::1" # IPv6 (preference 1)
assert result[1][4][0] == "192.168.1.100" # IPv4 (preference 2)
assert result[2][4][0] == "fe80::1" # Link-local no scope (preference 3)
def test_resolve_ip_address_with_cache() -> None:
"""Test that the cache is used when provided."""
from esphome.address_cache import AddressCache
cache = AddressCache(
mdns_cache={"test.local": ["192.168.1.100", "192.168.1.101"]},
dns_cache={
"example.com": ["93.184.216.34", "2606:2800:220:1:248:1893:25c8:1946"]
},
)
# Test mDNS cache hit
result = helpers.resolve_ip_address("test.local", 6053, address_cache=cache)
# Should return cached addresses without calling resolver
assert len(result) == 2
assert result[0][4][0] == "192.168.1.100"
assert result[1][4][0] == "192.168.1.101"
# Test DNS cache hit
result = helpers.resolve_ip_address("example.com", 6053, address_cache=cache)
# Should return cached addresses with IPv6 first due to preference
assert len(result) == 2
assert result[0][4][0] == "2606:2800:220:1:248:1893:25c8:1946" # IPv6 first
assert result[1][4][0] == "93.184.216.34" # IPv4 second
def test_resolve_ip_address_cache_miss() -> None:
"""Test that resolver is called when not in cache."""
from esphome.address_cache import AddressCache
cache = AddressCache(mdns_cache={"other.local": ["192.168.1.200"]})
mock_addr_info = AddrInfo(
family=socket.AF_INET,
type=socket.SOCK_STREAM,
proto=socket.IPPROTO_TCP,
sockaddr=IPv4Sockaddr(address="192.168.1.100", port=6053),
)
with patch("esphome.resolver.AsyncResolver") as MockResolver:
mock_resolver = MockResolver.return_value
mock_resolver.resolve.return_value = [mock_addr_info]
result = helpers.resolve_ip_address("test.local", 6053, address_cache=cache)
# Should call resolver since test.local is not in cache
MockResolver.assert_called_once_with(["test.local"], 6053)
assert len(result) == 1
assert result[0][4][0] == "192.168.1.100"
def test_resolve_ip_address_mixed_cached_uncached() -> None:
"""Test resolution with mix of cached and uncached hosts."""
from esphome.address_cache import AddressCache
cache = AddressCache(mdns_cache={"cached.local": ["192.168.1.50"]})
mock_addr_info = AddrInfo(
family=socket.AF_INET,
type=socket.SOCK_STREAM,
proto=socket.IPPROTO_TCP,
sockaddr=IPv4Sockaddr(address="192.168.1.100", port=6053),
)
with patch("esphome.resolver.AsyncResolver") as MockResolver:
mock_resolver = MockResolver.return_value
mock_resolver.resolve.return_value = [mock_addr_info]
# Pass a list with cached IP, cached hostname, and uncached hostname
result = helpers.resolve_ip_address(
["192.168.1.10", "cached.local", "uncached.local"],
6053,
address_cache=cache,
)
# Should only resolve uncached.local
MockResolver.assert_called_once_with(["uncached.local"], 6053)
# Results should include all addresses
addresses = [r[4][0] for r in result]
assert "192.168.1.10" in addresses # Direct IP
assert "192.168.1.50" in addresses # From cache
assert "192.168.1.100" in addresses # From resolver