From 45ef5a3edf2411b73a5ea5164cae1fc577999b2a Mon Sep 17 00:00:00 2001 From: Mike Degatano Date: Thu, 14 Mar 2024 05:53:55 -0400 Subject: [PATCH] Apply suggestion failures fail supervisor repair (#113372) --- homeassistant/components/hassio/handler.py | 5 +- homeassistant/components/hassio/repairs.py | 11 ++-- tests/components/hassio/test_issues.py | 3 +- tests/components/hassio/test_repairs.py | 72 ++++++++++++++++++++++ 4 files changed, 79 insertions(+), 12 deletions(-) diff --git a/homeassistant/components/hassio/handler.py b/homeassistant/components/hassio/handler.py index 65c0824dbd2bef..82a2db3c2341b2 100644 --- a/homeassistant/components/hassio/handler.py +++ b/homeassistant/components/hassio/handler.py @@ -262,10 +262,7 @@ async def async_update_core( @bind_hass @_api_bool async def async_apply_suggestion(hass: HomeAssistant, suggestion_uuid: str) -> dict: - """Apply a suggestion from supervisor's resolution center. - - The caller of the function should handle HassioAPIError. - """ + """Apply a suggestion from supervisor's resolution center.""" hassio: HassIO = hass.data[DOMAIN] command = f"/resolution/suggestion/{suggestion_uuid}" return await hassio.send_command(command, timeout=None) diff --git a/homeassistant/components/hassio/repairs.py b/homeassistant/components/hassio/repairs.py index fcfe23dda6e6c6..4538d9e1b332de 100644 --- a/homeassistant/components/hassio/repairs.py +++ b/homeassistant/components/hassio/repairs.py @@ -18,7 +18,7 @@ PLACEHOLDER_KEY_REFERENCE, SupervisorIssueContext, ) -from .handler import HassioAPIError, async_apply_suggestion +from .handler import async_apply_suggestion from .issues import Issue, Suggestion SUGGESTION_CONFIRMATION_REQUIRED = {"system_execute_reboot"} @@ -109,12 +109,9 @@ async def _async_step_apply_suggestion( if not confirmed and suggestion.key in SUGGESTION_CONFIRMATION_REQUIRED: return self._async_form_for_suggestion(suggestion) - try: - await async_apply_suggestion(self.hass, suggestion.uuid) - except HassioAPIError: - return self.async_abort(reason="apply_suggestion_fail") - - return self.async_create_entry(data={}) + if await async_apply_suggestion(self.hass, suggestion.uuid): + return self.async_create_entry(data={}) + return self.async_abort(reason="apply_suggestion_fail") @staticmethod def _async_step( diff --git a/tests/components/hassio/test_issues.py b/tests/components/hassio/test_issues.py index 21cd249bd53b75..83cb65b8ccae04 100644 --- a/tests/components/hassio/test_issues.py +++ b/tests/components/hassio/test_issues.py @@ -40,6 +40,7 @@ def mock_resolution_info( unsupported: list[str] | None = None, unhealthy: list[str] | None = None, issues: list[dict[str, str]] | None = None, + suggestion_result: str = "ok", ): """Mock resolution/info endpoint with unsupported/unhealthy reasons and/or issues.""" aioclient_mock.get( @@ -76,7 +77,7 @@ def mock_resolution_info( for suggestion in suggestions: aioclient_mock.post( f"http://127.0.0.1/resolution/suggestion/{suggestion['uuid']}", - json={"result": "ok"}, + json={"result": suggestion_result}, ) diff --git a/tests/components/hassio/test_repairs.py b/tests/components/hassio/test_repairs.py index 5dd73a2161538e..97a13fe1e5dcf4 100644 --- a/tests/components/hassio/test_repairs.py +++ b/tests/components/hassio/test_repairs.py @@ -404,6 +404,78 @@ async def test_supervisor_issue_repair_flow_skip_confirmation( ) +async def test_mount_failed_repair_flow_error( + hass: HomeAssistant, + aioclient_mock: AiohttpClientMocker, + hass_client: ClientSessionGenerator, + issue_registry: ir.IssueRegistry, + all_setup_requests, +) -> None: + """Test repair flow fails when repair fails to apply.""" + mock_resolution_info( + aioclient_mock, + issues=[ + { + "uuid": "1234", + "type": "mount_failed", + "context": "mount", + "reference": "backup_share", + "suggestions": [ + { + "uuid": "1235", + "type": "execute_reload", + "context": "mount", + "reference": "backup_share", + }, + { + "uuid": "1236", + "type": "execute_remove", + "context": "mount", + "reference": "backup_share", + }, + ], + }, + ], + suggestion_result=False, + ) + + assert await async_setup_component(hass, "hassio", {}) + + repair_issue = issue_registry.async_get_issue(domain="hassio", issue_id="1234") + assert repair_issue + + client = await hass_client() + + resp = await client.post( + "/api/repairs/issues/fix", + json={"handler": "hassio", "issue_id": repair_issue.issue_id}, + ) + + assert resp.status == HTTPStatus.OK + data = await resp.json() + flow_id = data["flow_id"] + + resp = await client.post( + f"/api/repairs/issues/fix/{flow_id}", + json={"next_step_id": "mount_execute_reload"}, + ) + + assert resp.status == HTTPStatus.OK + data = await resp.json() + + flow_id = data["flow_id"] + assert data == { + "type": "abort", + "flow_id": flow_id, + "handler": "hassio", + "reason": "apply_suggestion_fail", + "result": None, + "description_placeholders": None, + } + + assert issue_registry.async_get_issue(domain="hassio", issue_id="1234") + + async def test_mount_failed_repair_flow( hass: HomeAssistant, aioclient_mock: AiohttpClientMocker,