Skip to content

Commit

Permalink
Supervisor issues update retries on failure (#113373)
Browse files Browse the repository at this point in the history
  • Loading branch information
mdegat01 authored and frenck committed Mar 14, 2024
1 parent 45ef5a3 commit 6ca837b
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 3 deletions.
12 changes: 10 additions & 2 deletions homeassistant/components/hassio/issues.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@

import asyncio
from dataclasses import dataclass, field
from datetime import datetime
import logging
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.event import async_call_later
from homeassistant.helpers.issue_registry import (
IssueSeverity,
async_create_issue,
Expand Down Expand Up @@ -35,6 +37,7 @@
EVENT_SUPPORTED_CHANGED,
ISSUE_KEY_SYSTEM_DOCKER_CONFIG,
PLACEHOLDER_KEY_REFERENCE,
REQUEST_REFRESH_DELAY,
UPDATE_KEY_SUPERVISOR,
SupervisorIssueContext,
)
Expand Down Expand Up @@ -302,12 +305,17 @@ async def setup(self) -> None:
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."""
try:
data = await self._client.get_resolution_info()
except HassioAPIError as 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
self.unhealthy_reasons = set(data[ATTR_UNHEALTHY])
self.unsupported_reasons = set(data[ATTR_UNSUPPORTED])
Expand Down
78 changes: 77 additions & 1 deletion tests/components/hassio/test_issues.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
"""Test issues from supervisor issues."""
from __future__ import annotations

import asyncio
from http import HTTPStatus
import os
from typing import Any
from unittest.mock import ANY, patch
Expand All @@ -13,7 +15,7 @@

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


Expand Down Expand Up @@ -529,6 +531,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(
hass: HomeAssistant,
aioclient_mock: AiohttpClientMocker,
Expand Down

0 comments on commit 6ca837b

Please sign in to comment.