mirror of
https://github.com/home-assistant/core.git
synced 2025-04-28 03:07:50 +00:00
Fix some handle leaks in rainforest_raven (#113035)
There were leaks when * The component was shutdown * There was a timeout during the initial device opening Additionally, the device was not closed/reopened when there was a timeout reading regular data.
This commit is contained in:
parent
f01095fb66
commit
eb81599400
@ -133,16 +133,27 @@ class RAVEnDataCoordinator(DataUpdateCoordinator):
|
|||||||
)
|
)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
async def async_shutdown(self) -> None:
|
||||||
|
"""Shutdown the coordinator."""
|
||||||
|
await self._cleanup_device()
|
||||||
|
await super().async_shutdown()
|
||||||
|
|
||||||
async def _async_update_data(self) -> dict[str, Any]:
|
async def _async_update_data(self) -> dict[str, Any]:
|
||||||
try:
|
try:
|
||||||
device = await self._get_device()
|
device = await self._get_device()
|
||||||
async with asyncio.timeout(5):
|
async with asyncio.timeout(5):
|
||||||
return await _get_all_data(device, self.entry.data[CONF_MAC])
|
return await _get_all_data(device, self.entry.data[CONF_MAC])
|
||||||
except RAVEnConnectionError as err:
|
except RAVEnConnectionError as err:
|
||||||
if self._raven_device:
|
await self._cleanup_device()
|
||||||
await self._raven_device.close()
|
|
||||||
self._raven_device = None
|
|
||||||
raise UpdateFailed(f"RAVEnConnectionError: {err}") from err
|
raise UpdateFailed(f"RAVEnConnectionError: {err}") from err
|
||||||
|
except TimeoutError:
|
||||||
|
await self._cleanup_device()
|
||||||
|
raise
|
||||||
|
|
||||||
|
async def _cleanup_device(self) -> None:
|
||||||
|
device, self._raven_device = self._raven_device, None
|
||||||
|
if device is not None:
|
||||||
|
await device.close()
|
||||||
|
|
||||||
async def _get_device(self) -> RAVEnSerialDevice:
|
async def _get_device(self) -> RAVEnSerialDevice:
|
||||||
if self._raven_device is not None:
|
if self._raven_device is not None:
|
||||||
@ -150,15 +161,14 @@ class RAVEnDataCoordinator(DataUpdateCoordinator):
|
|||||||
|
|
||||||
device = RAVEnSerialDevice(self.entry.data[CONF_DEVICE])
|
device = RAVEnSerialDevice(self.entry.data[CONF_DEVICE])
|
||||||
|
|
||||||
async with asyncio.timeout(5):
|
try:
|
||||||
await device.open()
|
async with asyncio.timeout(5):
|
||||||
|
await device.open()
|
||||||
try:
|
|
||||||
await device.synchronize()
|
await device.synchronize()
|
||||||
self._device_info = await device.get_device_info()
|
self._device_info = await device.get_device_info()
|
||||||
except Exception:
|
except:
|
||||||
await device.close()
|
await device.close()
|
||||||
raise
|
raise
|
||||||
|
|
||||||
self._raven_device = device
|
self._raven_device = device
|
||||||
return device
|
return device
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
"""Tests for the Rainforest RAVEn data coordinator."""
|
"""Tests for the Rainforest RAVEn data coordinator."""
|
||||||
|
|
||||||
|
import asyncio
|
||||||
|
import functools
|
||||||
|
|
||||||
from aioraven.device import RAVEnConnectionError
|
from aioraven.device import RAVEnConnectionError
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
@ -84,6 +87,19 @@ async def test_coordinator_device_error_update(hass: HomeAssistant, mock_device)
|
|||||||
assert coordinator.last_update_success is False
|
assert coordinator.last_update_success is False
|
||||||
|
|
||||||
|
|
||||||
|
async def test_coordinator_device_timeout_update(hass: HomeAssistant, mock_device):
|
||||||
|
"""Test handling of a device timeout during an update."""
|
||||||
|
entry = create_mock_entry()
|
||||||
|
coordinator = RAVEnDataCoordinator(hass, entry)
|
||||||
|
|
||||||
|
await coordinator.async_config_entry_first_refresh()
|
||||||
|
assert coordinator.last_update_success is True
|
||||||
|
|
||||||
|
mock_device.get_network_info.side_effect = functools.partial(asyncio.sleep, 10)
|
||||||
|
await coordinator.async_refresh()
|
||||||
|
assert coordinator.last_update_success is False
|
||||||
|
|
||||||
|
|
||||||
async def test_coordinator_comm_error(hass: HomeAssistant, mock_device):
|
async def test_coordinator_comm_error(hass: HomeAssistant, mock_device):
|
||||||
"""Test handling of an error parsing or reading raw device data."""
|
"""Test handling of an error parsing or reading raw device data."""
|
||||||
entry = create_mock_entry()
|
entry = create_mock_entry()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user