Review AndroidTV decorator exception management (#114133)
This commit is contained in:
parent
8e66e5bb11
commit
5db8082f91
2 changed files with 39 additions and 18 deletions
|
@ -77,22 +77,33 @@ def adb_decorator(
|
||||||
)
|
)
|
||||||
return None
|
return None
|
||||||
except self.exceptions as err:
|
except self.exceptions as err:
|
||||||
_LOGGER.error(
|
if self.available:
|
||||||
(
|
_LOGGER.error(
|
||||||
"Failed to execute an ADB command. ADB connection re-"
|
(
|
||||||
"establishing attempt in the next update. Error: %s"
|
"Failed to execute an ADB command. ADB connection re-"
|
||||||
),
|
"establishing attempt in the next update. Error: %s"
|
||||||
err,
|
),
|
||||||
)
|
err,
|
||||||
|
)
|
||||||
|
|
||||||
await self.aftv.adb_close()
|
await self.aftv.adb_close()
|
||||||
self._attr_available = False
|
self._attr_available = False
|
||||||
return None
|
return None
|
||||||
except Exception:
|
except Exception as err: # pylint: disable=broad-except
|
||||||
# An unforeseen exception occurred. Close the ADB connection so that
|
# An unforeseen exception occurred. Close the ADB connection so that
|
||||||
# it doesn't happen over and over again, then raise the exception.
|
# it doesn't happen over and over again.
|
||||||
|
if self.available:
|
||||||
|
_LOGGER.error(
|
||||||
|
(
|
||||||
|
"Unexpected exception executing an ADB command. ADB connection"
|
||||||
|
" re-establishing attempt in the next update. Error: %s"
|
||||||
|
),
|
||||||
|
err,
|
||||||
|
)
|
||||||
|
|
||||||
await self.aftv.adb_close()
|
await self.aftv.adb_close()
|
||||||
self._attr_available = False
|
self._attr_available = False
|
||||||
raise
|
return None
|
||||||
|
|
||||||
return _adb_exception_catcher
|
return _adb_exception_catcher
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
"""The tests for the androidtv platform."""
|
"""The tests for the androidtv platform."""
|
||||||
|
|
||||||
|
from collections.abc import Generator
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
import logging
|
import logging
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
@ -170,7 +171,7 @@ CONFIG_FIRETV_DEFAULT = CONFIG_FIRETV_PYTHON_ADB
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture(autouse=True)
|
||||||
def adb_device_tcp_fixture() -> None:
|
def adb_device_tcp_fixture() -> Generator[None, patchers.AdbDeviceTcpAsyncFake, None]:
|
||||||
"""Patch ADB Device TCP."""
|
"""Patch ADB Device TCP."""
|
||||||
with patch(
|
with patch(
|
||||||
"androidtv.adb_manager.adb_manager_async.AdbDeviceTcpAsync",
|
"androidtv.adb_manager.adb_manager_async.AdbDeviceTcpAsync",
|
||||||
|
@ -180,7 +181,7 @@ def adb_device_tcp_fixture() -> None:
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture(autouse=True)
|
||||||
def load_adbkey_fixture() -> None:
|
def load_adbkey_fixture() -> Generator[None, str, None]:
|
||||||
"""Patch load_adbkey."""
|
"""Patch load_adbkey."""
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.androidtv.ADBPythonSync.load_adbkey",
|
"homeassistant.components.androidtv.ADBPythonSync.load_adbkey",
|
||||||
|
@ -190,7 +191,7 @@ def load_adbkey_fixture() -> None:
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture(autouse=True)
|
||||||
def keygen_fixture() -> None:
|
def keygen_fixture() -> Generator[None, Mock, None]:
|
||||||
"""Patch keygen."""
|
"""Patch keygen."""
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.androidtv.keygen",
|
"homeassistant.components.androidtv.keygen",
|
||||||
|
@ -1181,7 +1182,7 @@ async def test_connection_closed_on_ha_stop(hass: HomeAssistant) -> None:
|
||||||
assert adb_close.called
|
assert adb_close.called
|
||||||
|
|
||||||
|
|
||||||
async def test_exception(hass: HomeAssistant) -> None:
|
async def test_exception(hass: HomeAssistant, caplog: pytest.LogCaptureFixture) -> None:
|
||||||
"""Test that the ADB connection gets closed when there is an unforeseen exception.
|
"""Test that the ADB connection gets closed when there is an unforeseen exception.
|
||||||
|
|
||||||
HA will attempt to reconnect on the next update.
|
HA will attempt to reconnect on the next update.
|
||||||
|
@ -1201,12 +1202,21 @@ async def test_exception(hass: HomeAssistant) -> None:
|
||||||
assert state is not None
|
assert state is not None
|
||||||
assert state.state == STATE_OFF
|
assert state.state == STATE_OFF
|
||||||
|
|
||||||
|
caplog.clear()
|
||||||
|
caplog.set_level(logging.ERROR)
|
||||||
|
|
||||||
# When an unforeseen exception occurs, we close the ADB connection and raise the exception
|
# When an unforeseen exception occurs, we close the ADB connection and raise the exception
|
||||||
with patchers.PATCH_ANDROIDTV_UPDATE_EXCEPTION, pytest.raises(Exception):
|
with patchers.PATCH_ANDROIDTV_UPDATE_EXCEPTION:
|
||||||
await async_update_entity(hass, entity_id)
|
await async_update_entity(hass, entity_id)
|
||||||
state = hass.states.get(entity_id)
|
|
||||||
assert state is not None
|
state = hass.states.get(entity_id)
|
||||||
assert state.state == STATE_UNAVAILABLE
|
assert state is not None
|
||||||
|
assert state.state == STATE_UNAVAILABLE
|
||||||
|
assert len(caplog.record_tuples) == 1
|
||||||
|
assert caplog.record_tuples[0][1] == logging.ERROR
|
||||||
|
assert caplog.record_tuples[0][2].startswith(
|
||||||
|
"Unexpected exception executing an ADB command"
|
||||||
|
)
|
||||||
|
|
||||||
# On the next update, HA will reconnect to the device
|
# On the next update, HA will reconnect to the device
|
||||||
await async_update_entity(hass, entity_id)
|
await async_update_entity(hass, entity_id)
|
||||||
|
|
Loading…
Add table
Reference in a new issue