Implement resilient startup for bond integration with ConfigEntryNotReady support (#38253)

This commit is contained in:
Eugene Prystupa 2020-07-26 19:27:18 -04:00 committed by GitHub
parent 455ac1cadf
commit 4d73f107c4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 32 additions and 4 deletions

View File

@ -1,18 +1,22 @@
"""The Bond integration."""
import asyncio
from asyncio import TimeoutError as AsyncIOTimeoutError
import logging
from aiohttp import ClientTimeout
from aiohttp import ClientError, ClientTimeout
from bond_api import Bond
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_ACCESS_TOKEN, CONF_HOST
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers import device_registry as dr
from homeassistant.helpers.entity import SLOW_UPDATE_WARNING
from .const import DOMAIN
from .utils import BondHub
_LOGGER = logging.getLogger(__name__)
PLATFORMS = ["cover", "fan", "light", "switch"]
_API_TIMEOUT = SLOW_UPDATE_WARNING - 1
@ -30,7 +34,11 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
bond = Bond(host=host, token=token, timeout=ClientTimeout(total=_API_TIMEOUT))
hub = BondHub(bond)
await hub.setup()
try:
await hub.setup()
except (ClientError, AsyncIOTimeoutError, OSError) as error:
raise ConfigEntryNotReady from error
hass.data[DOMAIN][entry.entry_id] = hub
device_registry = await dr.async_get_registry(hass)

View File

@ -73,7 +73,9 @@ async def setup_platform(
return mock_entry
def patch_bond_version(enabled: bool = True, return_value: Optional[dict] = None):
def patch_bond_version(
enabled: bool = True, return_value: Optional[dict] = None, side_effect=None
):
"""Patch Bond API version endpoint."""
if not enabled:
return nullcontext()
@ -82,7 +84,9 @@ def patch_bond_version(enabled: bool = True, return_value: Optional[dict] = None
return_value = {"bondid": "test-bond-id"}
return patch(
"homeassistant.components.bond.Bond.version", return_value=return_value
"homeassistant.components.bond.Bond.version",
return_value=return_value,
side_effect=side_effect,
)

View File

@ -1,8 +1,13 @@
"""Tests for the Bond module."""
from aiohttp import ClientConnectionError
import pytest
from homeassistant.components.bond import async_setup_entry
from homeassistant.components.bond.const import DOMAIN
from homeassistant.config_entries import ENTRY_STATE_LOADED, ENTRY_STATE_NOT_LOADED
from homeassistant.const import CONF_ACCESS_TOKEN, CONF_HOST
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers import device_registry as dr
from homeassistant.setup import async_setup_component
@ -18,6 +23,17 @@ async def test_async_setup_no_domain_config(hass: HomeAssistant):
assert result is True
async def test_async_setup_raises_entry_not_ready(hass: HomeAssistant):
"""Test that it throws ConfigEntryNotReady when exception occurs during setup."""
config_entry = MockConfigEntry(
domain=DOMAIN, data={CONF_HOST: "some host", CONF_ACCESS_TOKEN: "test-token"},
)
with patch_bond_version(side_effect=ClientConnectionError()):
with pytest.raises(ConfigEntryNotReady):
await async_setup_entry(hass, config_entry)
async def test_async_setup_entry_sets_up_hub_and_supported_domains(hass: HomeAssistant):
"""Test that configuring entry sets up cover domain."""
config_entry = MockConfigEntry(