Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions homeassistant/components/portainer/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -236,5 +236,10 @@
},
"name": "Prune unused images"
}
},
"system_health": {
"info": {
"can_reach_server": "Reach Portainer server"
}
}
}
28 changes: 28 additions & 0 deletions homeassistant/components/portainer/system_health.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
"""Provide info to system health."""

from typing import Any

from homeassistant.components import system_health
from homeassistant.const import CONF_URL
from homeassistant.core import HomeAssistant, callback

from .const import DOMAIN


@callback
def async_register(
hass: HomeAssistant, register: system_health.SystemHealthRegistration
) -> None:
"""Register system health callbacks."""
register.async_register_info(system_health_info)


async def system_health_info(hass: HomeAssistant) -> dict[str, Any]:
"""Get info for the info page."""
config_entry = hass.config_entries.async_entries(DOMAIN)[0]

return {
"can_reach_server": system_health.async_check_can_reach_url(
hass, f"{config_entry.data[CONF_URL].rstrip('/')}/api/system/status"
Comment thread
erwindouna marked this conversation as resolved.
),
Comment on lines +24 to +27
}
59 changes: 59 additions & 0 deletions tests/components/portainer/test_system_health.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
"""Test Portainer system health."""

import asyncio
from unittest.mock import AsyncMock

from aiohttp import ClientError

from homeassistant.components.portainer.const import DOMAIN
from homeassistant.core import HomeAssistant
from homeassistant.setup import async_setup_component

from . import setup_integration

from tests.common import MockConfigEntry, get_system_health_info
from tests.test_util.aiohttp import AiohttpClientMocker

MOCK_HEALTH_URL = "https://127.0.0.1:9000/api/system/status"


async def test_system_health(
hass: HomeAssistant,
aioclient_mock: AiohttpClientMocker,
mock_config_entry: MockConfigEntry,
mock_portainer_client: AsyncMock,
) -> None:
"""Test system health when server is reachable."""
aioclient_mock.get(MOCK_HEALTH_URL, text="ok")

assert await async_setup_component(hass, "system_health", {})
await setup_integration(hass, mock_config_entry)

info = await get_system_health_info(hass, DOMAIN)

for key, val in info.items():
if asyncio.iscoroutine(val):
info[key] = await val

assert info["can_reach_server"] == "ok"


async def test_system_health_failed_connect(
hass: HomeAssistant,
aioclient_mock: AiohttpClientMocker,
mock_config_entry: MockConfigEntry,
mock_portainer_client: AsyncMock,
) -> None:
"""Test system health when server is unreachable."""
aioclient_mock.get(MOCK_HEALTH_URL, exc=ClientError)

assert await async_setup_component(hass, "system_health", {})
await setup_integration(hass, mock_config_entry)

info = await get_system_health_info(hass, DOMAIN)

for key, val in info.items():
if asyncio.iscoroutine(val):
info[key] = await val

assert info["can_reach_server"] == {"error": "unreachable", "type": "failed"}