From 048f9e7daa134b0a540af5ba2c5e0ab9146cee8f Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Tue, 10 Mar 2020 19:10:00 -0500 Subject: [PATCH] =?UTF-8?q?Throw=20ConfigEntryNotReady=20when=20august=20s?= =?UTF-8?q?ervers=20are=20offline=20or=20u=E2=80=A6=20(#32635)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Throw ConfigEntryNotReady when august servers are offline * august has tests now and its nearing 100% * Adjust per review * define in init --- .coveragerc | 1 - homeassistant/components/august/__init__.py | 9 ++++--- homeassistant/components/august/gateway.py | 14 ++++++----- tests/components/august/test_init.py | 27 +++++++++++++++++++-- 4 files changed, 39 insertions(+), 12 deletions(-) diff --git a/.coveragerc b/.coveragerc index 89da763f3ca..0e372cb9e1d 100644 --- a/.coveragerc +++ b/.coveragerc @@ -61,7 +61,6 @@ omit = homeassistant/components/asterisk_mbox/* homeassistant/components/aten_pe/* homeassistant/components/atome/* - homeassistant/components/august/* homeassistant/components/aurora_abb_powerone/sensor.py homeassistant/components/automatic/device_tracker.py homeassistant/components/avea/light.py diff --git a/homeassistant/components/august/__init__.py b/homeassistant/components/august/__init__.py index e51d087d519..373fcae8d0c 100644 --- a/homeassistant/components/august/__init__.py +++ b/homeassistant/components/august/__init__.py @@ -11,7 +11,7 @@ import voluptuous as vol from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry from homeassistant.const import CONF_PASSWORD, CONF_TIMEOUT, CONF_USERNAME from homeassistant.core import HomeAssistant -from homeassistant.exceptions import HomeAssistantError +from homeassistant.exceptions import ConfigEntryNotReady, HomeAssistantError import homeassistant.helpers.config_validation as cv from .activity import ActivityStream @@ -164,9 +164,12 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry): """Set up August from a config entry.""" august_gateway = AugustGateway(hass) - await august_gateway.async_setup(entry.data) - return await async_setup_august(hass, entry, august_gateway) + try: + await august_gateway.async_setup(entry.data) + return await async_setup_august(hass, entry, august_gateway) + except asyncio.TimeoutError: + raise ConfigEntryNotReady async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry): diff --git a/homeassistant/components/august/gateway.py b/homeassistant/components/august/gateway.py index 356414173ac..bb39523a984 100644 --- a/homeassistant/components/august/gateway.py +++ b/homeassistant/components/august/gateway.py @@ -29,6 +29,7 @@ class AugustGateway: """Init the connection.""" self._aiohttp_session = aiohttp_client.async_get_clientsession(hass) self._token_refresh_lock = asyncio.Lock() + self._access_token_cache_file = None self._hass = hass self._config = None self._api = None @@ -63,17 +64,18 @@ class AugustGateway: CONF_PASSWORD: self._config[CONF_PASSWORD], CONF_INSTALL_ID: self._config.get(CONF_INSTALL_ID), CONF_TIMEOUT: self._config.get(CONF_TIMEOUT), - CONF_ACCESS_TOKEN_CACHE_FILE: self._config[CONF_ACCESS_TOKEN_CACHE_FILE], + CONF_ACCESS_TOKEN_CACHE_FILE: self._access_token_cache_file, } async def async_setup(self, conf): """Create the api and authenticator objects.""" if conf.get(VERIFICATION_CODE_KEY): return - if conf.get(CONF_ACCESS_TOKEN_CACHE_FILE) is None: - conf[ - CONF_ACCESS_TOKEN_CACHE_FILE - ] = f".{conf[CONF_USERNAME]}{DEFAULT_AUGUST_CONFIG_FILE}" + + self._access_token_cache_file = conf.get( + CONF_ACCESS_TOKEN_CACHE_FILE, + f".{conf[CONF_USERNAME]}{DEFAULT_AUGUST_CONFIG_FILE}", + ) self._config = conf self._api = ApiAsync( @@ -87,7 +89,7 @@ class AugustGateway: self._config[CONF_PASSWORD], install_id=self._config.get(CONF_INSTALL_ID), access_token_cache_file=self._hass.config.path( - self._config[CONF_ACCESS_TOKEN_CACHE_FILE] + self._access_token_cache_file ), ) diff --git a/tests/components/august/test_init.py b/tests/components/august/test_init.py index 906eeff6213..c287a26b34f 100644 --- a/tests/components/august/test_init.py +++ b/tests/components/august/test_init.py @@ -1,4 +1,6 @@ """The tests for the august platform.""" +import asyncio + from asynctest import patch from august.exceptions import AugustApiAIOHTTPError @@ -8,8 +10,10 @@ from homeassistant.components.august.const import ( CONF_INSTALL_ID, CONF_LOGIN_METHOD, DEFAULT_AUGUST_CONFIG_FILE, + DOMAIN, ) from homeassistant.components.lock import DOMAIN as LOCK_DOMAIN +from homeassistant.config_entries import ENTRY_STATE_SETUP_RETRY from homeassistant.const import ( ATTR_ENTITY_ID, CONF_PASSWORD, @@ -23,6 +27,7 @@ from homeassistant.const import ( from homeassistant.exceptions import HomeAssistantError from homeassistant.setup import async_setup_component +from tests.common import MockConfigEntry from tests.components.august.mocks import ( _create_august_with_devices, _mock_doorsense_enabled_august_lock_detail, @@ -33,6 +38,25 @@ from tests.components.august.mocks import ( ) +async def test_august_is_offline(hass): + """Config entry state is ENTRY_STATE_SETUP_RETRY when august is offline.""" + + config_entry = MockConfigEntry( + domain=DOMAIN, data=_mock_get_config()[DOMAIN], title="August august", + ) + config_entry.add_to_hass(hass) + + await setup.async_setup_component(hass, "persistent_notification", {}) + with patch( + "august.authenticator_async.AuthenticatorAsync.async_authenticate", + side_effect=asyncio.TimeoutError, + ): + await hass.config_entries.async_setup(config_entry.entry_id) + + await hass.async_block_till_done() + assert config_entry.state == ENTRY_STATE_SETUP_RETRY + + async def test_unlock_throws_august_api_http_error(hass): """Test unlock throws correct error on http error.""" mocked_lock_detail = await _mock_operative_august_lock_detail(hass) @@ -127,8 +151,7 @@ async def test_set_up_from_yaml(hass): "homeassistant.components.august.config_flow.AugustGateway.async_authenticate", return_value=True, ): - mocked_config = _mock_get_config() - assert await async_setup_component(hass, "august", mocked_config) + assert await async_setup_component(hass, DOMAIN, _mock_get_config()) await hass.async_block_till_done() assert len(mock_setup_august.mock_calls) == 1 call = mock_setup_august.call_args