Fix network adapter change detection and address review feedback

This commit is contained in:
J. Nick Koston
2026-06-22 16:50:18 -05:00
parent b96aa49b8a
commit cffbb385cb
4 changed files with 26 additions and 15 deletions
+3 -1
View File
@@ -21,7 +21,7 @@ from .const import (
SIGNAL_NETWORK_ADAPTERS_CHANGED,
)
from .models import Adapter
from .network import Network, async_get_loaded_network, async_get_network
from .network import DATA_NETWORK, Network, async_get_loaded_network, async_get_network
_LOGGER = logging.getLogger(__name__)
@@ -55,6 +55,8 @@ def async_get_loaded_adapters(hass: HomeAssistant) -> list[Adapter]:
async def async_reload_adapters(hass: HomeAssistant) -> None:
"""Reload the network adapters and notify listeners if they changed."""
if DATA_NETWORK not in hass.data:
return
if await async_get_loaded_network(hass).async_reload():
async_dispatcher_send(hass, SIGNAL_NETWORK_ADAPTERS_CHANGED)
+9 -6
View File
@@ -64,13 +64,16 @@ class Network:
await storage_load_task
async def async_reload(self) -> bool:
"""Reload adapters from the system, returning True if they changed."""
adapters = await async_load_adapters()
if adapters == self.adapters:
return False
self.adapters = adapters
"""Reload adapters from the system, returning True if they changed.
Freshly loaded adapters are unconfigured (all disabled), so the new
set must be configured before it can be compared against the current,
already configured adapters.
"""
previous = self.adapters
self.adapters = await async_load_adapters()
self.async_configure()
return True
return self.adapters != previous
@callback
def async_configure(self) -> None:
+1 -1
View File
@@ -254,6 +254,7 @@ async def test_setup_onboarding_supervisor_update_error(
supervisor_client.supervisor.update.assert_called_once()
@pytest.mark.usefixtures("supervisor_client")
@pytest.mark.parametrize(
("update_key", "expected_calls"),
[("network", 1), ("supervisor", 0)],
@@ -261,7 +262,6 @@ async def test_setup_onboarding_supervisor_update_error(
)
async def test_supervisor_network_event_reloads_adapters(
hass: HomeAssistant,
supervisor_client: AsyncMock,
update_key: str,
expected_calls: int,
) -> None:
+13 -7
View File
@@ -707,8 +707,8 @@ _ADAPTERS_WITH_MANUAL_CONFIG = [
async def test_async_reload_adapters(hass: HomeAssistant) -> None:
"""Test reloading adapters dispatches a signal only when they change."""
with patch(
"homeassistant.components.network.util.ifaddr.get_adapters",
return_value=[],
"homeassistant.components.network.network.async_load_adapters",
return_value=deepcopy(_ADAPTERS_WITH_MANUAL_CONFIG),
):
assert await async_setup_component(hass, DOMAIN, {DOMAIN: {}})
await hass.async_block_till_done()
@@ -721,22 +721,28 @@ async def test_async_reload_adapters(hass: HomeAssistant) -> None:
async_dispatcher_connect(hass, SIGNAL_NETWORK_ADAPTERS_CHANGED, _track)
# Unchanged adapters do not dispatch a signal.
# The same hardware loads unconfigured (all disabled); once configured it
# matches the current adapters, so no signal is dispatched.
unconfigured = deepcopy(_ADAPTERS_WITH_MANUAL_CONFIG)
for adapter in unconfigured:
adapter["enabled"] = False
with patch(
"homeassistant.components.network.network.async_load_adapters",
return_value=network.async_get_loaded_adapters(hass),
return_value=unconfigured,
):
await network.async_reload_adapters(hass)
assert signals == []
# Changed adapters dispatch a signal and update the loaded adapters.
# A physically different adapter set dispatches a signal.
changed = deepcopy(_ADAPTERS_WITH_MANUAL_CONFIG)
changed[1]["ipv4"][0]["address"] = "192.168.1.99"
with patch(
"homeassistant.components.network.network.async_load_adapters",
return_value=deepcopy(_ADAPTERS_WITH_MANUAL_CONFIG),
return_value=changed,
):
await network.async_reload_adapters(hass)
assert len(signals) == 1
assert network.async_get_loaded_adapters(hass) == _ADAPTERS_WITH_MANUAL_CONFIG
assert network.async_get_loaded_adapters(hass) == changed
async def test_async_get_announce_addresses(hass: HomeAssistant) -> None: