From 4ea27f631135337696bc5152adc37635945bc7dd Mon Sep 17 00:00:00 2001 From: Mike Degatano Date: Tue, 30 Aug 2022 02:39:08 -0400 Subject: [PATCH] Network connection check only about ipv4 (#3830) * Network connection test only about ipv4 * Better test of change being made --- supervisor/host/network.py | 4 +- ...interface.py => network_interface_ipv4.py} | 15 +++--- supervisor/resolution/const.py | 2 +- ...y => test_check_network_interface_ipv4.py} | 48 +++++++++++-------- 4 files changed, 37 insertions(+), 32 deletions(-) rename supervisor/resolution/checks/{network_interface.py => network_interface_ipv4.py} (79%) rename tests/resolution/check/{test_check_network_interface.py => test_check_network_interface_ipv4.py} (60%) diff --git a/supervisor/host/network.py b/supervisor/host/network.py index 487d5283b..b0d91e336 100644 --- a/supervisor/host/network.py +++ b/supervisor/host/network.py @@ -32,7 +32,7 @@ from ..exceptions import ( ) from ..jobs.const import JobCondition from ..jobs.decorator import Job -from ..resolution.checks.network_interface import CheckNetworkInterface +from ..resolution.checks.network_interface_ipv4 import CheckNetworkInterfaceIPV4 from .const import AuthMethod, InterfaceMethod, InterfaceType, WifiMode _LOGGER: logging.Logger = logging.getLogger(__name__) @@ -113,7 +113,7 @@ class NetworkManager(CoreSysAttributes): interfaces = [ Interface.from_dbus_interface(interface) for interface in self.sys_dbus.network.interfaces.values() - if not CheckNetworkInterface.check_interface(interface) + if not CheckNetworkInterfaceIPV4.check_interface(interface) ] with suppress(HostNetworkNotFound): await asyncio.gather( diff --git a/supervisor/resolution/checks/network_interface.py b/supervisor/resolution/checks/network_interface_ipv4.py similarity index 79% rename from supervisor/resolution/checks/network_interface.py rename to supervisor/resolution/checks/network_interface_ipv4.py index 4e9e21191..59b8660a0 100644 --- a/supervisor/resolution/checks/network_interface.py +++ b/supervisor/resolution/checks/network_interface_ipv4.py @@ -9,18 +9,18 @@ from .base import CheckBase def setup(coresys: CoreSys) -> CheckBase: """Check setup function.""" - return CheckNetworkInterface(coresys) + return CheckNetworkInterfaceIPV4(coresys) -class CheckNetworkInterface(CheckBase): - """CheckNetworkInterface class for check.""" +class CheckNetworkInterfaceIPV4(CheckBase): + """CheckNetworkInterfaceIPV4 class for check.""" async def run_check(self) -> None: """Run check if not affected by issue.""" for interface in self.sys_dbus.network.interfaces.values(): - if CheckNetworkInterface.check_interface(interface): + if CheckNetworkInterfaceIPV4.check_interface(interface): self.sys_resolution.create_issue( - IssueType.NETWORK_CONNECTION_PROBLEM, + IssueType.IPV4_CONNECTION_PROBLEM, ContextType.SYSTEM, interface.name, ) @@ -32,7 +32,7 @@ class CheckNetworkInterface(CheckBase): interface = self.sys_dbus.network.interfaces.get(reference) - return interface and CheckNetworkInterface.check_interface(interface) + return interface and CheckNetworkInterfaceIPV4.check_interface(interface) @staticmethod def check_interface(interface: NetworkInterface) -> bool: @@ -44,13 +44,12 @@ class CheckNetworkInterface(CheckBase): interface.connection.state in [ConnectionStateType.ACTIVATED, ConnectionStateType.ACTIVATING] and ConnectionStateFlags.IP4_READY in interface.connection.state_flags - and ConnectionStateFlags.IP6_READY in interface.connection.state_flags ) @property def issue(self) -> IssueType: """Return a IssueType enum.""" - return IssueType.NETWORK_CONNECTION_PROBLEM + return IssueType.IPV4_CONNECTION_PROBLEM @property def context(self) -> ContextType: diff --git a/supervisor/resolution/const.py b/supervisor/resolution/const.py index 702b29d24..d0716876d 100644 --- a/supervisor/resolution/const.py +++ b/supervisor/resolution/const.py @@ -72,8 +72,8 @@ class IssueType(str, Enum): DOCKER_RATELIMIT = "docker_ratelimit" FATAL_ERROR = "fatal_error" FREE_SPACE = "free_space" + IPV4_CONNECTION_PROBLEM = "ipv4_connection_problem" MISSING_IMAGE = "missing_image" - NETWORK_CONNECTION_PROBLEM = "network_connection_problem" PWNED = "pwned" SECURITY = "security" TRUST = "trust" diff --git a/tests/resolution/check/test_check_network_interface.py b/tests/resolution/check/test_check_network_interface_ipv4.py similarity index 60% rename from tests/resolution/check/test_check_network_interface.py rename to tests/resolution/check/test_check_network_interface_ipv4.py index 5776ee7fd..ff8ba71b1 100644 --- a/tests/resolution/check/test_check_network_interface.py +++ b/tests/resolution/check/test_check_network_interface_ipv4.py @@ -6,29 +6,35 @@ 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.checks.network_interface_ipv4 import ( + CheckNetworkInterfaceIPV4, +) from supervisor.resolution.const import ContextType, IssueType from supervisor.resolution.data import Issue +TEST_ISSUE = Issue(IssueType.IPV4_CONNECTION_PROBLEM, ContextType.SYSTEM, "eth0") + async def test_base(coresys: CoreSys): """Test check basics.""" - network_interface = CheckNetworkInterface(coresys) - assert network_interface.slug == "network_interface" + network_interface = CheckNetworkInterfaceIPV4(coresys) + assert network_interface.slug == "network_interface_ipv4" assert network_interface.enabled @pytest.mark.parametrize( - "state_flags", + "state_flags,issues", [ - {ConnectionStateFlags.IP4_READY}, - {ConnectionStateFlags.IP6_READY}, - {ConnectionStateFlags.NONE}, + ({ConnectionStateFlags.IP4_READY}, []), + ({ConnectionStateFlags.IP6_READY}, [TEST_ISSUE]), + ({ConnectionStateFlags.NONE}, [TEST_ISSUE]), ], ) -async def test_check(coresys: CoreSys, state_flags: set[ConnectionStateFlags]): +async def test_check( + coresys: CoreSys, state_flags: set[ConnectionStateFlags], issues: list[Issue] +): """Test check.""" - network_interface = CheckNetworkInterface(coresys) + network_interface = CheckNetworkInterfaceIPV4(coresys) coresys.core.state = CoreState.RUNNING assert len(coresys.resolution.issues) == 0 @@ -42,22 +48,22 @@ async def test_check(coresys: CoreSys, state_flags: set[ConnectionStateFlags]): ): await network_interface.run_check() - assert coresys.resolution.issues == [ - Issue(IssueType.NETWORK_CONNECTION_PROBLEM, ContextType.SYSTEM, "eth0") - ] + assert coresys.resolution.issues == issues @pytest.mark.parametrize( - "state_flags", + "state_flags,approved", [ - {ConnectionStateFlags.IP4_READY}, - {ConnectionStateFlags.IP6_READY}, - {ConnectionStateFlags.NONE}, + ({ConnectionStateFlags.IP4_READY}, False), + ({ConnectionStateFlags.IP6_READY}, True), + ({ConnectionStateFlags.NONE}, True), ], ) -async def test_approve(coresys: CoreSys, state_flags: set[ConnectionStateFlags]): +async def test_approve( + coresys: CoreSys, state_flags: set[ConnectionStateFlags], approved: bool +): """Test check.""" - network_interface = CheckNetworkInterface(coresys) + network_interface = CheckNetworkInterfaceIPV4(coresys) coresys.core.state = CoreState.RUNNING assert not await network_interface.approve_check("eth0") @@ -66,19 +72,19 @@ async def test_approve(coresys: CoreSys, state_flags: set[ConnectionStateFlags]) "supervisor.dbus.network.connection.NetworkConnection.state_flags", new=PropertyMock(return_value=state_flags), ): - assert await network_interface.approve_check("eth0") + assert await network_interface.approve_check("eth0") is approved async def test_did_run(coresys: CoreSys): """Test that the check ran as expected.""" - network_interface = CheckNetworkInterface(coresys) + network_interface = CheckNetworkInterfaceIPV4(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", + "supervisor.resolution.checks.network_interface_ipv4.CheckNetworkInterfaceIPV4.run_check", return_value=None, ) as check: for state in should_run: