Supervisor issues update retries on failure (#113373)

This commit is contained in:
Mike Degatano 2024-03-14 05:55:04 -04:00 committed by GitHub
parent 6d903300be
commit 5a25349cf7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 87 additions and 3 deletions

View File

@ -4,11 +4,13 @@ from __future__ import annotations
import asyncio import asyncio
from dataclasses import dataclass, field from dataclasses import dataclass, field
from datetime import datetime
import logging import logging
from typing import Any, NotRequired, TypedDict from typing import Any, NotRequired, TypedDict
from homeassistant.core import HomeAssistant, callback from homeassistant.core import HassJob, HomeAssistant, callback
from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.event import async_call_later
from homeassistant.helpers.issue_registry import ( from homeassistant.helpers.issue_registry import (
IssueSeverity, IssueSeverity,
async_create_issue, async_create_issue,
@ -36,6 +38,7 @@ from .const import (
EVENT_SUPPORTED_CHANGED, EVENT_SUPPORTED_CHANGED,
ISSUE_KEY_SYSTEM_DOCKER_CONFIG, ISSUE_KEY_SYSTEM_DOCKER_CONFIG,
PLACEHOLDER_KEY_REFERENCE, PLACEHOLDER_KEY_REFERENCE,
REQUEST_REFRESH_DELAY,
UPDATE_KEY_SUPERVISOR, UPDATE_KEY_SUPERVISOR,
SupervisorIssueContext, SupervisorIssueContext,
) )
@ -303,12 +306,17 @@ class SupervisorIssues:
self._hass, EVENT_SUPERVISOR_EVENT, self._supervisor_events_to_issues self._hass, EVENT_SUPERVISOR_EVENT, self._supervisor_events_to_issues
) )
async def update(self) -> None: async def update(self, _: datetime | None = None) -> None:
"""Update issues from Supervisor resolution center.""" """Update issues from Supervisor resolution center."""
try: try:
data = await self._client.get_resolution_info() data = await self._client.get_resolution_info()
except HassioAPIError as err: except HassioAPIError as err:
_LOGGER.error("Failed to update supervisor issues: %r", err) _LOGGER.error("Failed to update supervisor issues: %r", err)
async_call_later(
self._hass,
REQUEST_REFRESH_DELAY,
HassJob(self.update, cancel_on_shutdown=True),
)
return return
self.unhealthy_reasons = set(data[ATTR_UNHEALTHY]) self.unhealthy_reasons = set(data[ATTR_UNHEALTHY])
self.unsupported_reasons = set(data[ATTR_UNSUPPORTED]) self.unsupported_reasons = set(data[ATTR_UNSUPPORTED])

View File

@ -2,6 +2,8 @@
from __future__ import annotations from __future__ import annotations
import asyncio
from http import HTTPStatus
import os import os
from typing import Any from typing import Any
from unittest.mock import ANY, patch from unittest.mock import ANY, patch
@ -14,7 +16,7 @@ from homeassistant.setup import async_setup_component
from .test_init import MOCK_ENVIRON from .test_init import MOCK_ENVIRON
from tests.test_util.aiohttp import AiohttpClientMocker from tests.test_util.aiohttp import AiohttpClientMocker, AiohttpClientMockResponse
from tests.typing import WebSocketGenerator from tests.typing import WebSocketGenerator
@ -530,6 +532,80 @@ async def test_supervisor_issues(
) )
async def test_supervisor_issues_initial_failure(
hass: HomeAssistant,
aioclient_mock: AiohttpClientMocker,
hass_ws_client: WebSocketGenerator,
) -> None:
"""Test issues manager retries after initial update failure."""
responses = [
AiohttpClientMockResponse(
method="get",
url="http://127.0.0.1/resolution/info",
status=HTTPStatus.BAD_REQUEST,
json={
"result": "error",
"message": "System is not ready with state: setup",
},
),
AiohttpClientMockResponse(
method="get",
url="http://127.0.0.1/resolution/info",
status=HTTPStatus.OK,
json={
"result": "ok",
"data": {
"unsupported": [],
"unhealthy": [],
"suggestions": [],
"issues": [
{
"uuid": "1234",
"type": "reboot_required",
"context": "system",
"reference": None,
},
],
"checks": [
{"enabled": True, "slug": "supervisor_trust"},
{"enabled": True, "slug": "free_space"},
],
},
},
),
]
async def mock_responses(*args):
nonlocal responses
return responses.pop(0)
aioclient_mock.get(
"http://127.0.0.1/resolution/info",
side_effect=mock_responses,
)
aioclient_mock.get(
"http://127.0.0.1/resolution/issue/1234/suggestions",
json={"result": "ok", "data": {"suggestions": []}},
)
with patch("homeassistant.components.hassio.issues.REQUEST_REFRESH_DELAY", new=0.1):
result = await async_setup_component(hass, "hassio", {})
assert result
client = await hass_ws_client(hass)
await client.send_json({"id": 1, "type": "repairs/list_issues"})
msg = await client.receive_json()
assert msg["success"]
assert len(msg["result"]["issues"]) == 0
await asyncio.sleep(0.1)
await client.send_json({"id": 2, "type": "repairs/list_issues"})
msg = await client.receive_json()
assert msg["success"]
assert len(msg["result"]["issues"]) == 1
async def test_supervisor_issues_add_remove( async def test_supervisor_issues_add_remove(
hass: HomeAssistant, hass: HomeAssistant,
aioclient_mock: AiohttpClientMocker, aioclient_mock: AiohttpClientMocker,