mirror of
https://github.com/home-assistant/core.git
synced 2026-11-02 03:31:34 -04:00
Add repair when IPv6 is disabled for Matter (#174653)
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
Copilot Autofix powered by AI
parent
f0ed257f47
commit
0808e30e37
@@ -5,7 +5,7 @@ from collections.abc import Generator
|
||||
from unittest.mock import AsyncMock, MagicMock, call, patch
|
||||
|
||||
from aiohasupervisor import SupervisorError
|
||||
from aiohasupervisor.models import PartialBackupOptions
|
||||
from aiohasupervisor.models import InterfaceMethod, PartialBackupOptions
|
||||
from matter_server.client.exceptions import (
|
||||
CannotConnect,
|
||||
NotConnected,
|
||||
@@ -550,6 +550,197 @@ async def test_issue_registry_invalid_version(
|
||||
assert not issue_registry.async_get_issue(DOMAIN, issue_raised)
|
||||
|
||||
|
||||
def _mock_network_interface(
|
||||
*, enabled: bool, connected: bool, ipv6_method: InterfaceMethod | None
|
||||
) -> MagicMock:
|
||||
"""Build a mock Supervisor network interface."""
|
||||
interface = MagicMock()
|
||||
interface.enabled = enabled
|
||||
interface.connected = connected
|
||||
interface.ipv6 = None if ipv6_method is None else MagicMock(method=ipv6_method)
|
||||
return interface
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("interfaces", "issue_expected"),
|
||||
[
|
||||
pytest.param(
|
||||
[
|
||||
_mock_network_interface(
|
||||
enabled=True, connected=True, ipv6_method=InterfaceMethod.DISABLED
|
||||
)
|
||||
],
|
||||
True,
|
||||
id="ipv6_disabled",
|
||||
),
|
||||
pytest.param(
|
||||
[_mock_network_interface(enabled=True, connected=True, ipv6_method=None)],
|
||||
True,
|
||||
id="no_ipv6_config",
|
||||
),
|
||||
pytest.param(
|
||||
[
|
||||
_mock_network_interface(
|
||||
enabled=True, connected=True, ipv6_method=InterfaceMethod.AUTO
|
||||
)
|
||||
],
|
||||
False,
|
||||
id="ipv6_auto",
|
||||
),
|
||||
pytest.param(
|
||||
[
|
||||
_mock_network_interface(
|
||||
enabled=True, connected=True, ipv6_method=InterfaceMethod.STATIC
|
||||
)
|
||||
],
|
||||
False,
|
||||
id="ipv6_static",
|
||||
),
|
||||
pytest.param(
|
||||
[
|
||||
_mock_network_interface(
|
||||
enabled=True, connected=True, ipv6_method=InterfaceMethod.DISABLED
|
||||
),
|
||||
_mock_network_interface(
|
||||
enabled=True, connected=True, ipv6_method=InterfaceMethod.AUTO
|
||||
),
|
||||
],
|
||||
False,
|
||||
id="ipv6_enabled_on_secondary_interface",
|
||||
),
|
||||
pytest.param(
|
||||
[
|
||||
_mock_network_interface(
|
||||
enabled=True, connected=False, ipv6_method=InterfaceMethod.DISABLED
|
||||
)
|
||||
],
|
||||
False,
|
||||
id="no_connected_interface",
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_ipv6_disabled_repair(
|
||||
hass: HomeAssistant,
|
||||
matter_client: MagicMock,
|
||||
issue_registry: ir.IssueRegistry,
|
||||
interfaces: list[MagicMock],
|
||||
issue_expected: bool,
|
||||
) -> None:
|
||||
"""Test repair issue when IPv6 is disabled in Supervisor network settings."""
|
||||
supervisor_client = MagicMock()
|
||||
supervisor_client.network.info = AsyncMock(
|
||||
return_value=MagicMock(interfaces=interfaces)
|
||||
)
|
||||
|
||||
entry = MockConfigEntry(domain=DOMAIN, data={"url": "ws://localhost:5580/ws"})
|
||||
entry.add_to_hass(hass)
|
||||
|
||||
with (
|
||||
patch("homeassistant.components.matter.is_hassio", return_value=True),
|
||||
patch(
|
||||
"homeassistant.components.matter.get_supervisor_client",
|
||||
return_value=supervisor_client,
|
||||
),
|
||||
):
|
||||
await hass.config_entries.async_setup(entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert entry.state is ConfigEntryState.LOADED
|
||||
issue = issue_registry.async_get_issue(DOMAIN, "ipv6_disabled")
|
||||
assert (issue is not None) is issue_expected
|
||||
|
||||
|
||||
async def test_ipv6_repair_not_raised_without_supervisor(
|
||||
hass: HomeAssistant,
|
||||
matter_client: MagicMock,
|
||||
issue_registry: ir.IssueRegistry,
|
||||
) -> None:
|
||||
"""Test the IPv6 repair is skipped when not running on Supervisor."""
|
||||
with patch(
|
||||
"homeassistant.components.matter.get_supervisor_client"
|
||||
) as get_supervisor_client:
|
||||
entry = MockConfigEntry(domain=DOMAIN, data={"url": "ws://localhost:5580/ws"})
|
||||
entry.add_to_hass(hass)
|
||||
await hass.config_entries.async_setup(entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert entry.state is ConfigEntryState.LOADED
|
||||
get_supervisor_client.assert_not_called()
|
||||
assert not issue_registry.async_get_issue(DOMAIN, "ipv6_disabled")
|
||||
|
||||
|
||||
async def test_ipv6_repair_supervisor_error(
|
||||
hass: HomeAssistant,
|
||||
matter_client: MagicMock,
|
||||
issue_registry: ir.IssueRegistry,
|
||||
) -> None:
|
||||
"""Test the IPv6 repair handles Supervisor errors gracefully."""
|
||||
supervisor_client = MagicMock()
|
||||
supervisor_client.network.info = AsyncMock(side_effect=SupervisorError("boom"))
|
||||
|
||||
entry = MockConfigEntry(domain=DOMAIN, data={"url": "ws://localhost:5580/ws"})
|
||||
entry.add_to_hass(hass)
|
||||
|
||||
with (
|
||||
patch("homeassistant.components.matter.is_hassio", return_value=True),
|
||||
patch(
|
||||
"homeassistant.components.matter.get_supervisor_client",
|
||||
return_value=supervisor_client,
|
||||
),
|
||||
):
|
||||
await hass.config_entries.async_setup(entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert entry.state is ConfigEntryState.LOADED
|
||||
assert not issue_registry.async_get_issue(DOMAIN, "ipv6_disabled")
|
||||
|
||||
|
||||
async def test_ipv6_repair_resolves_on_reload(
|
||||
hass: HomeAssistant,
|
||||
matter_client: MagicMock,
|
||||
issue_registry: ir.IssueRegistry,
|
||||
) -> None:
|
||||
"""Test the IPv6 repair is removed once IPv6 is enabled again."""
|
||||
supervisor_client = MagicMock()
|
||||
supervisor_client.network.info = AsyncMock(
|
||||
return_value=MagicMock(
|
||||
interfaces=[
|
||||
_mock_network_interface(
|
||||
enabled=True, connected=True, ipv6_method=InterfaceMethod.DISABLED
|
||||
)
|
||||
]
|
||||
)
|
||||
)
|
||||
|
||||
entry = MockConfigEntry(domain=DOMAIN, data={"url": "ws://localhost:5580/ws"})
|
||||
entry.add_to_hass(hass)
|
||||
|
||||
with (
|
||||
patch("homeassistant.components.matter.is_hassio", return_value=True),
|
||||
patch(
|
||||
"homeassistant.components.matter.get_supervisor_client",
|
||||
return_value=supervisor_client,
|
||||
),
|
||||
):
|
||||
await hass.config_entries.async_setup(entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert issue_registry.async_get_issue(DOMAIN, "ipv6_disabled")
|
||||
|
||||
supervisor_client.network.info.return_value = MagicMock(
|
||||
interfaces=[
|
||||
_mock_network_interface(
|
||||
enabled=True, connected=True, ipv6_method=InterfaceMethod.AUTO
|
||||
)
|
||||
]
|
||||
)
|
||||
await hass.config_entries.async_reload(entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert entry.state is ConfigEntryState.LOADED
|
||||
assert not issue_registry.async_get_issue(DOMAIN, "ipv6_disabled")
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("stop_addon_side_effect", "entry_state"),
|
||||
[
|
||||
|
||||
Reference in New Issue
Block a user