Clean ondilo ico logging (#126310)

* Clean too verbose logging

* Add tests
This commit is contained in:
Martin Hjelmare 2024-09-20 12:03:16 +02:00 committed by GitHub
parent 1768daf98c
commit 7ff0d54291
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 110 additions and 8 deletions

View File

@ -42,9 +42,7 @@ class OndiloIcoCoordinator(DataUpdateCoordinator[dict[str, OndiloIcoData]]):
"""Fetch data from API endpoint.""" """Fetch data from API endpoint."""
try: try:
return await self.hass.async_add_executor_job(self._update_data) return await self.hass.async_add_executor_job(self._update_data)
except OndiloError as err: except OndiloError as err:
_LOGGER.exception("Error getting pools")
raise UpdateFailed(f"Error communicating with API: {err}") from err raise UpdateFailed(f"Error communicating with API: {err}") from err
def _update_data(self) -> dict[str, OndiloIcoData]: def _update_data(self) -> dict[str, OndiloIcoData]:
@ -52,23 +50,28 @@ class OndiloIcoCoordinator(DataUpdateCoordinator[dict[str, OndiloIcoData]]):
res = {} res = {}
pools = self.api.get_pools() pools = self.api.get_pools()
_LOGGER.debug("Pools: %s", pools) _LOGGER.debug("Pools: %s", pools)
error: OndiloError | None = None
for pool in pools: for pool in pools:
pool_id = pool["id"]
try: try:
ico = self.api.get_ICO_details(pool["id"]) ico = self.api.get_ICO_details(pool_id)
if not ico: if not ico:
_LOGGER.debug( _LOGGER.debug(
"The pool id %s does not have any ICO attached", pool["id"] "The pool id %s does not have any ICO attached", pool_id
) )
continue continue
sensors = self.api.get_last_pool_measures(pool["id"]) sensors = self.api.get_last_pool_measures(pool_id)
except OndiloError: except OndiloError as err:
_LOGGER.exception("Error communicating with API for %s", pool["id"]) error = err
_LOGGER.debug("Error communicating with API for %s: %s", pool_id, err)
continue continue
res[pool["id"]] = OndiloIcoData( res[pool_id] = OndiloIcoData(
ico=ico, ico=ico,
pool=pool, pool=pool,
sensors={sensor["data_type"]: sensor["value"] for sensor in sensors}, sensors={sensor["data_type"]: sensor["value"] for sensor in sensors},
) )
if not res: if not res:
if error:
raise UpdateFailed(f"Error communicating with API: {error}") from error
raise UpdateFailed("No data available") raise UpdateFailed("No data available")
return res return res

View File

@ -3,6 +3,8 @@
from typing import Any from typing import Any
from unittest.mock import MagicMock from unittest.mock import MagicMock
from ondilo import OndiloError
import pytest
from syrupy import SnapshotAssertion from syrupy import SnapshotAssertion
from homeassistant.config_entries import ConfigEntryState from homeassistant.config_entries import ConfigEntryState
@ -35,6 +37,29 @@ async def test_devices(
assert device_entry == snapshot(name=f"{identifier[0]}-{identifier[1]}") assert device_entry == snapshot(name=f"{identifier[0]}-{identifier[1]}")
async def test_get_pools_error(
hass: HomeAssistant,
mock_ondilo_client: MagicMock,
config_entry: MockConfigEntry,
) -> None:
"""Test get pools errors."""
mock_ondilo_client.get_pools.side_effect = OndiloError(
502,
(
"<html> <head><title>502 Bad Gateway</title></head> "
"<body> <center><h1>502 Bad Gateway</h1></center> </body> </html>"
),
)
await setup_integration(hass, config_entry, mock_ondilo_client)
# No sensor should be created
assert not hass.states.async_all()
# We should not have tried to retrieve pool measures
assert mock_ondilo_client.get_ICO_details.call_count == 0
assert mock_ondilo_client.get_last_pool_measures.call_count == 0
assert config_entry.state is ConfigEntryState.SETUP_RETRY
async def test_init_with_no_ico_attached( async def test_init_with_no_ico_attached(
hass: HomeAssistant, hass: HomeAssistant,
mock_ondilo_client: MagicMock, mock_ondilo_client: MagicMock,
@ -53,3 +78,77 @@ async def test_init_with_no_ico_attached(
# We should not have tried to retrieve pool measures # We should not have tried to retrieve pool measures
mock_ondilo_client.get_last_pool_measures.assert_not_called() mock_ondilo_client.get_last_pool_measures.assert_not_called()
assert config_entry.state is ConfigEntryState.SETUP_RETRY assert config_entry.state is ConfigEntryState.SETUP_RETRY
@pytest.mark.parametrize("api", ["get_ICO_details", "get_last_pool_measures"])
async def test_details_error_all_pools(
hass: HomeAssistant,
mock_ondilo_client: MagicMock,
device_registry: dr.DeviceRegistry,
config_entry: MockConfigEntry,
pool1: dict[str, Any],
api: str,
) -> None:
"""Test details and measures error for all pools."""
mock_ondilo_client.get_pools.return_value = pool1
client_api = getattr(mock_ondilo_client, api)
client_api.side_effect = OndiloError(400, "error")
await setup_integration(hass, config_entry, mock_ondilo_client)
device_entries = dr.async_entries_for_config_entry(
device_registry, config_entry.entry_id
)
assert not device_entries
assert config_entry.state is ConfigEntryState.SETUP_RETRY
async def test_details_error_one_pool(
hass: HomeAssistant,
mock_ondilo_client: MagicMock,
device_registry: dr.DeviceRegistry,
config_entry: MockConfigEntry,
ico_details2: dict[str, Any],
) -> None:
"""Test details error for one pool and success for the other."""
mock_ondilo_client.get_ICO_details.side_effect = [
OndiloError(
404,
"Not Found",
),
ico_details2,
]
await setup_integration(hass, config_entry, mock_ondilo_client)
device_entries = dr.async_entries_for_config_entry(
device_registry, config_entry.entry_id
)
assert len(device_entries) == 1
async def test_measures_error_one_pool(
hass: HomeAssistant,
mock_ondilo_client: MagicMock,
device_registry: dr.DeviceRegistry,
config_entry: MockConfigEntry,
last_measures: list[dict[str, Any]],
) -> None:
"""Test measures error for one pool and success for the other."""
mock_ondilo_client.get_last_pool_measures.side_effect = [
OndiloError(
404,
"Not Found",
),
last_measures,
]
await setup_integration(hass, config_entry, mock_ondilo_client)
device_entries = dr.async_entries_for_config_entry(
device_registry, config_entry.entry_id
)
assert len(device_entries) == 1