1
0
mirror of https://github.com/home-assistant/supervisor.git synced 2025-12-24 20:35:55 +00:00

Identify and handle dhcp issues (#3806)

* Identify and handle dhcp issues

* Change test from DHCP to Connection Problem
This commit is contained in:
Mike Degatano
2022-08-23 07:57:16 -04:00
committed by GitHub
parent c7f7fbd41a
commit b4e1e3e853
9 changed files with 251 additions and 11 deletions

View File

@@ -6,7 +6,7 @@
"Type": "802-3-ethernet",
"Devices": ["/org/freedesktop/NetworkManager/Devices/1"],
"State": 2,
"StateFlags": 12,
"StateFlags": 92,
"Default": true,
"Ip4Config": "/org/freedesktop/NetworkManager/IP4Config/1",
"Dhcp4Config": "/org/freedesktop/NetworkManager/DHCP4Config/1",

View File

@@ -1,8 +1,9 @@
"""Test network manager."""
from unittest.mock import Mock, patch
from ipaddress import IPv4Address, IPv6Address
from unittest.mock import Mock, PropertyMock, patch
from supervisor.coresys import CoreSys
from supervisor.dbus.const import InterfaceMethod
from supervisor.dbus.const import ConnectionStateFlags, InterfaceMethod
from supervisor.host.const import InterfaceType
from supervisor.host.network import Interface, IpConfig
@@ -24,6 +25,14 @@ async def test_load(coresys: CoreSys):
assert len(coresys.host.network.interfaces) == 2
assert coresys.host.network.interfaces[0].name == "eth0"
assert coresys.host.network.interfaces[0].enabled is True
assert coresys.host.network.interfaces[0].ipv4.method == InterfaceMethod.AUTO
assert coresys.host.network.interfaces[0].ipv4.gateway == IPv4Address(
"192.168.2.1"
)
assert coresys.host.network.interfaces[0].ipv6.method == InterfaceMethod.AUTO
assert coresys.host.network.interfaces[0].ipv6.gateway == IPv6Address(
"fe80::da58:d7ff:fe00:9c69"
)
assert coresys.host.network.interfaces[1].name == "wlan0"
assert coresys.host.network.interfaces[1].enabled is False
@@ -56,3 +65,31 @@ async def test_load_with_disabled_methods(coresys: CoreSys):
await coresys.host.network.load()
activate_connection.assert_not_called()
async def test_load_with_network_connection_issues(coresys: CoreSys):
"""Test load does not update interfaces with network connection issues."""
with patch(
"supervisor.dbus.network.connection.NetworkConnection.state_flags",
new=PropertyMock(return_value={ConnectionStateFlags.IP6_READY}),
), patch(
"supervisor.dbus.network.connection.NetworkConnection.ipv4",
new=PropertyMock(return_value=None),
), patch.object(
coresys.host.sys_dbus.network,
"activate_connection",
new=Mock(wraps=coresys.host.sys_dbus.network.activate_connection),
) as activate_connection:
await coresys.host.network.load()
activate_connection.assert_not_called()
assert len(coresys.host.network.interfaces) == 2
assert coresys.host.network.interfaces[0].name == "eth0"
assert coresys.host.network.interfaces[0].enabled is True
assert coresys.host.network.interfaces[0].ipv4.method == InterfaceMethod.AUTO
assert coresys.host.network.interfaces[0].ipv4.gateway is None
assert coresys.host.network.interfaces[0].ipv6.method == InterfaceMethod.AUTO
assert coresys.host.network.interfaces[0].ipv6.gateway == IPv6Address(
"fe80::da58:d7ff:fe00:9c69"
)

View File

@@ -0,0 +1,94 @@
"""Test Check Network Interface."""
from unittest.mock import PropertyMock, patch
import pytest
from supervisor.const import CoreState
from supervisor.coresys import CoreSys
from supervisor.dbus.const import ConnectionStateFlags
from supervisor.resolution.checks.network_interface import CheckNetworkInterface
from supervisor.resolution.const import ContextType, IssueType
from supervisor.resolution.data import Issue
async def test_base(coresys: CoreSys):
"""Test check basics."""
network_interface = CheckNetworkInterface(coresys)
assert network_interface.slug == "network_interface"
assert network_interface.enabled
@pytest.mark.parametrize(
"state_flags",
[
{ConnectionStateFlags.IP4_READY},
{ConnectionStateFlags.IP6_READY},
{ConnectionStateFlags.NONE},
],
)
async def test_check(coresys: CoreSys, state_flags: set[ConnectionStateFlags]):
"""Test check."""
network_interface = CheckNetworkInterface(coresys)
coresys.core.state = CoreState.RUNNING
assert len(coresys.resolution.issues) == 0
await network_interface.run_check()
assert len(coresys.resolution.issues) == 0
with patch(
"supervisor.dbus.network.connection.NetworkConnection.state_flags",
new=PropertyMock(return_value=state_flags),
):
await network_interface.run_check()
assert coresys.resolution.issues == [
Issue(IssueType.NETWORK_CONNECTION_PROBLEM, ContextType.SYSTEM, "eth0")
]
@pytest.mark.parametrize(
"state_flags",
[
{ConnectionStateFlags.IP4_READY},
{ConnectionStateFlags.IP6_READY},
{ConnectionStateFlags.NONE},
],
)
async def test_approve(coresys: CoreSys, state_flags: set[ConnectionStateFlags]):
"""Test check."""
network_interface = CheckNetworkInterface(coresys)
coresys.core.state = CoreState.RUNNING
assert not await network_interface.approve_check("eth0")
with patch(
"supervisor.dbus.network.connection.NetworkConnection.state_flags",
new=PropertyMock(return_value=state_flags),
):
assert await network_interface.approve_check("eth0")
async def test_did_run(coresys: CoreSys):
"""Test that the check ran as expected."""
network_interface = CheckNetworkInterface(coresys)
should_run = network_interface.states
should_not_run = [state for state in CoreState if state not in should_run]
assert len(should_run) != 0
assert len(should_not_run) != 0
with patch(
"supervisor.resolution.checks.network_interface.CheckNetworkInterface.run_check",
return_value=None,
) as check:
for state in should_run:
coresys.core.state = state
await network_interface()
check.assert_called_once()
check.reset_mock()
for state in should_not_run:
coresys.core.state = state
await network_interface()
check.assert_not_called()
check.reset_mock()