From d9e20307dec91973a7fbd96cf201cc5049f378d3 Mon Sep 17 00:00:00 2001 From: Pascal Vizeli Date: Thu, 26 Nov 2020 22:38:33 +0100 Subject: [PATCH] Allow check to cleanup issues (#2302) --- supervisor/resolution/checks/base.py | 28 +++++++++++++++---- supervisor/resolution/checks/free_space.py | 10 +++++-- tests/resolution/check/test_check.py | 15 ++++++++++ .../resolution/check/test_check_free_space.py | 12 ++++++++ 4 files changed, 57 insertions(+), 8 deletions(-) diff --git a/supervisor/resolution/checks/base.py b/supervisor/resolution/checks/base.py index 0f8c6430a..c3e176931 100644 --- a/supervisor/resolution/checks/base.py +++ b/supervisor/resolution/checks/base.py @@ -1,11 +1,12 @@ """Baseclass for system checks.""" from abc import ABC, abstractmethod, abstractproperty import logging -from typing import List +from typing import List, Optional from ...const import CoreState from ...coresys import CoreSys, CoreSysAttributes from ..const import ContextType, IssueType +from ..data import Issue _LOGGER: logging.Logger = logging.getLogger(__name__) @@ -22,18 +23,33 @@ class CheckBase(ABC, CoreSysAttributes): if self.sys_core.state not in self.states: return - # Don't need run if issue exists + # Check if system is affected by the issue + affected: Optional[Issue] = None for issue in self.sys_resolution.issues: if issue.type != self.issue or issue.context != self.context: continue + affected = issue + break + + # System is not affected + if affected is None: + _LOGGER.debug("Run check for %s/%s", self.issue, self.context) + await self.run_check() return - _LOGGER.debug("Run check for %s/%s", self.issue, self.context) - await self.run_check() + # Check if issue still exists + if await self.approve_check(): + return + + self.sys_resolution.dismiss_issue(affected) @abstractmethod - async def run_check(self): - """Run check.""" + async def run_check(self) -> None: + """Run check if not affected by issue.""" + + @abstractmethod + async def approve_check(self) -> bool: + """Approve check if it is affected by issue.""" @property @abstractproperty diff --git a/supervisor/resolution/checks/free_space.py b/supervisor/resolution/checks/free_space.py index f4c108f83..7f692de58 100644 --- a/supervisor/resolution/checks/free_space.py +++ b/supervisor/resolution/checks/free_space.py @@ -19,8 +19,8 @@ _LOGGER: logging.Logger = logging.getLogger(__name__) class CheckFreeSpace(CheckBase): """Storage class for check.""" - async def run_check(self): - """Run check.""" + async def run_check(self) -> None: + """Run check if not affected by issue.""" if self.sys_host.info.free_space > MINIMUM_FREE_SPACE_THRESHOLD: if len(self.sys_snapshots.list_snapshots) == 0: # No snapshots, let's suggest the user to create one! @@ -46,6 +46,12 @@ class CheckFreeSpace(CheckBase): IssueType.FREE_SPACE, ContextType.SYSTEM, suggestions=suggestions ) + async def approve_check(self) -> bool: + """Approve check if it is affected by issue.""" + if self.sys_host.info.free_space > MINIMUM_FREE_SPACE_THRESHOLD: + return False + return True + @property def issue(self) -> IssueType: """Return a IssueType enum.""" diff --git a/tests/resolution/check/test_check.py b/tests/resolution/check/test_check.py index 5141e7ccf..0b821faf2 100644 --- a/tests/resolution/check/test_check.py +++ b/tests/resolution/check/test_check.py @@ -37,3 +37,18 @@ async def test_if_check_make_issue(coresys: CoreSys): await coresys.resolution.check.check_system() assert coresys.resolution.issues[-1].type == IssueType.FREE_SPACE + + +async def test_if_check_cleanup_issue(coresys: CoreSys): + """Test check for setup.""" + coresys.core.state = CoreState.RUNNING + + with patch("shutil.disk_usage", return_value=(1, 1, 1)): + await coresys.resolution.check.check_system() + + assert coresys.resolution.issues[-1].type == IssueType.FREE_SPACE + + with patch("shutil.disk_usage", return_value=(42, 42, 2 * (1024.0 ** 3))): + await coresys.resolution.check.check_system() + + assert len(coresys.resolution.issues) == 0 diff --git a/tests/resolution/check/test_check_free_space.py b/tests/resolution/check/test_check_free_space.py index 690e8b279..825800dee 100644 --- a/tests/resolution/check/test_check_free_space.py +++ b/tests/resolution/check/test_check_free_space.py @@ -26,6 +26,18 @@ async def test_check(coresys: CoreSys): assert coresys.resolution.issues[-1].type == IssueType.FREE_SPACE +async def test_approve(coresys: CoreSys): + """Test check.""" + free_space = CheckFreeSpace(coresys) + coresys.core.state = CoreState.RUNNING + + with patch("shutil.disk_usage", return_value=(1, 1, 1)): + assert await free_space.approve_check() + + with patch("shutil.disk_usage", return_value=(42, 42, 2 * (1024.0 ** 3))): + assert not await free_space.approve_check() + + async def test_did_run(coresys: CoreSys): """Test that the check ran as expected.""" free_space = CheckFreeSpace(coresys)