mirror of
https://github.com/home-assistant/core.git
synced 2025-07-25 22:27:07 +00:00
Handle the correct exception type when subscribing to the router service returns an error in the upnp component (#127006)
* Catch the right exception when handling subscription errors * Assert device is forced to poll
This commit is contained in:
parent
4c6ab3921a
commit
f8b192bd94
@ -11,7 +11,7 @@ from urllib.parse import urlparse
|
|||||||
from async_upnp_client.aiohttp import AiohttpNotifyServer, AiohttpSessionRequester
|
from async_upnp_client.aiohttp import AiohttpNotifyServer, AiohttpSessionRequester
|
||||||
from async_upnp_client.client_factory import UpnpFactory
|
from async_upnp_client.client_factory import UpnpFactory
|
||||||
from async_upnp_client.const import AddressTupleVXType
|
from async_upnp_client.const import AddressTupleVXType
|
||||||
from async_upnp_client.exceptions import UpnpConnectionError
|
from async_upnp_client.exceptions import UpnpCommunicationError
|
||||||
from async_upnp_client.profiles.igd import IgdDevice, IgdStateItem
|
from async_upnp_client.profiles.igd import IgdDevice, IgdStateItem
|
||||||
from async_upnp_client.utils import async_get_local_ip
|
from async_upnp_client.utils import async_get_local_ip
|
||||||
from getmac import get_mac_address
|
from getmac import get_mac_address
|
||||||
@ -206,7 +206,7 @@ class Device:
|
|||||||
"""Subscribe to services."""
|
"""Subscribe to services."""
|
||||||
try:
|
try:
|
||||||
await self._igd_device.async_subscribe_services(auto_resubscribe=True)
|
await self._igd_device.async_subscribe_services(auto_resubscribe=True)
|
||||||
except UpnpConnectionError as ex:
|
except UpnpCommunicationError as ex:
|
||||||
_LOGGER.debug(
|
_LOGGER.debug(
|
||||||
"Error subscribing to services, falling back to forced polling: %s", ex
|
"Error subscribing to services, falling back to forced polling: %s", ex
|
||||||
)
|
)
|
||||||
@ -214,7 +214,10 @@ class Device:
|
|||||||
|
|
||||||
async def async_unsubscribe_services(self) -> None:
|
async def async_unsubscribe_services(self) -> None:
|
||||||
"""Unsubscribe from services."""
|
"""Unsubscribe from services."""
|
||||||
|
try:
|
||||||
await self._igd_device.async_unsubscribe_services()
|
await self._igd_device.async_unsubscribe_services()
|
||||||
|
except UpnpCommunicationError as ex:
|
||||||
|
_LOGGER.debug("Error unsubscribing to services: %s", ex)
|
||||||
|
|
||||||
async def async_get_data(
|
async def async_get_data(
|
||||||
self, entity_description_keys: list[str] | None
|
self, entity_description_keys: list[str] | None
|
||||||
|
@ -7,6 +7,7 @@ import copy
|
|||||||
from typing import Any
|
from typing import Any
|
||||||
from unittest.mock import AsyncMock, MagicMock, patch
|
from unittest.mock import AsyncMock, MagicMock, patch
|
||||||
|
|
||||||
|
from async_upnp_client.exceptions import UpnpCommunicationError
|
||||||
from async_upnp_client.profiles.igd import IgdDevice
|
from async_upnp_client.profiles.igd import IgdDevice
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
@ -179,7 +180,7 @@ async def test_async_setup_udn_mismatch(
|
|||||||
async def test_async_setup_entry_force_poll(
|
async def test_async_setup_entry_force_poll(
|
||||||
hass: HomeAssistant, mock_igd_device: IgdDevice
|
hass: HomeAssistant, mock_igd_device: IgdDevice
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test async_setup_entry."""
|
"""Test async_setup_entry with forced polling."""
|
||||||
entry = MockConfigEntry(
|
entry = MockConfigEntry(
|
||||||
domain=DOMAIN,
|
domain=DOMAIN,
|
||||||
unique_id=TEST_USN,
|
unique_id=TEST_USN,
|
||||||
@ -200,3 +201,47 @@ async def test_async_setup_entry_force_poll(
|
|||||||
assert await hass.config_entries.async_setup(entry.entry_id) is True
|
assert await hass.config_entries.async_setup(entry.entry_id) is True
|
||||||
|
|
||||||
mock_igd_device.async_subscribe_services.assert_not_called()
|
mock_igd_device.async_subscribe_services.assert_not_called()
|
||||||
|
|
||||||
|
# Ensure that the device is forced to poll.
|
||||||
|
mock_igd_device.async_get_traffic_and_status_data.assert_called_with(
|
||||||
|
None, force_poll=True
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.usefixtures(
|
||||||
|
"ssdp_instant_discovery",
|
||||||
|
"mock_get_source_ip",
|
||||||
|
"mock_mac_address_from_host",
|
||||||
|
)
|
||||||
|
async def test_async_setup_entry_force_poll_subscribe_error(
|
||||||
|
hass: HomeAssistant, mock_igd_device: IgdDevice
|
||||||
|
) -> None:
|
||||||
|
"""Test async_setup_entry where subscribing fails."""
|
||||||
|
entry = MockConfigEntry(
|
||||||
|
domain=DOMAIN,
|
||||||
|
unique_id=TEST_USN,
|
||||||
|
data={
|
||||||
|
CONFIG_ENTRY_ST: TEST_ST,
|
||||||
|
CONFIG_ENTRY_UDN: TEST_UDN,
|
||||||
|
CONFIG_ENTRY_ORIGINAL_UDN: TEST_UDN,
|
||||||
|
CONFIG_ENTRY_LOCATION: TEST_LOCATION,
|
||||||
|
CONFIG_ENTRY_MAC_ADDRESS: TEST_MAC_ADDRESS,
|
||||||
|
},
|
||||||
|
options={
|
||||||
|
CONFIG_ENTRY_FORCE_POLL: False,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
# Subscribing partially succeeds, but not completely.
|
||||||
|
# Unsubscribing will fail for the subscribed services afterwards.
|
||||||
|
mock_igd_device.async_subscribe_services.side_effect = UpnpCommunicationError
|
||||||
|
mock_igd_device.async_unsubscribe_services.side_effect = UpnpCommunicationError
|
||||||
|
|
||||||
|
# Load config_entry, should still be able to load, falling back to polling/the old functionality.
|
||||||
|
entry.add_to_hass(hass)
|
||||||
|
assert await hass.config_entries.async_setup(entry.entry_id) is True
|
||||||
|
|
||||||
|
# Ensure that the device is forced to poll.
|
||||||
|
mock_igd_device.async_get_traffic_and_status_data.assert_called_with(
|
||||||
|
None, force_poll=True
|
||||||
|
)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user