Stop ssdp scans when stop event happens (#49140)
This commit is contained in:
parent
aaa600e00a
commit
403c6b9e26
2 changed files with 141 additions and 45 deletions
|
@ -1,31 +1,37 @@
|
|||
"""Test the SSDP integration."""
|
||||
import asyncio
|
||||
from unittest.mock import Mock, patch
|
||||
from datetime import timedelta
|
||||
from unittest.mock import patch
|
||||
|
||||
import aiohttp
|
||||
import pytest
|
||||
|
||||
from homeassistant.components import ssdp
|
||||
from homeassistant.const import EVENT_HOMEASSISTANT_STARTED, EVENT_HOMEASSISTANT_STOP
|
||||
from homeassistant.setup import async_setup_component
|
||||
import homeassistant.util.dt as dt_util
|
||||
|
||||
from tests.common import mock_coro
|
||||
from tests.common import async_fire_time_changed, mock_coro
|
||||
|
||||
|
||||
async def test_scan_match_st(hass, caplog):
|
||||
"""Test matching based on ST."""
|
||||
scanner = ssdp.Scanner(hass, {"mock-domain": [{"st": "mock-st"}]})
|
||||
|
||||
async def _inject_entry(*args, **kwargs):
|
||||
scanner.async_store_entry(
|
||||
Mock(
|
||||
st="mock-st",
|
||||
location=None,
|
||||
values={"usn": "mock-usn", "server": "mock-server", "ext": ""},
|
||||
)
|
||||
async def _mock_async_scan(*args, async_callback=None, **kwargs):
|
||||
await async_callback(
|
||||
{
|
||||
"st": "mock-st",
|
||||
"location": None,
|
||||
"usn": "mock-usn",
|
||||
"server": "mock-server",
|
||||
"ext": "",
|
||||
}
|
||||
)
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.ssdp.async_search",
|
||||
side_effect=_inject_entry,
|
||||
side_effect=_mock_async_scan,
|
||||
), patch.object(
|
||||
hass.config_entries.flow, "async_init", return_value=mock_coro()
|
||||
) as mock_init:
|
||||
|
@ -61,19 +67,25 @@ async def test_scan_match_upnp_devicedesc(hass, aioclient_mock, key):
|
|||
)
|
||||
scanner = ssdp.Scanner(hass, {"mock-domain": [{key: "Paulus"}]})
|
||||
|
||||
async def _inject_entry(*args, **kwargs):
|
||||
scanner.async_store_entry(
|
||||
Mock(st="mock-st", location="http://1.1.1.1", values={})
|
||||
)
|
||||
async def _mock_async_scan(*args, async_callback=None, **kwargs):
|
||||
for _ in range(5):
|
||||
await async_callback(
|
||||
{
|
||||
"st": "mock-st",
|
||||
"location": "http://1.1.1.1",
|
||||
}
|
||||
)
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.ssdp.async_search",
|
||||
side_effect=_inject_entry,
|
||||
side_effect=_mock_async_scan,
|
||||
), patch.object(
|
||||
hass.config_entries.flow, "async_init", return_value=mock_coro()
|
||||
) as mock_init:
|
||||
await scanner.async_scan(None)
|
||||
|
||||
# If we get duplicate respones, ensure we only look it up once
|
||||
assert len(aioclient_mock.mock_calls) == 1
|
||||
assert len(mock_init.mock_calls) == 1
|
||||
assert mock_init.mock_calls[0][1][0] == "mock-domain"
|
||||
assert mock_init.mock_calls[0][2]["context"] == {"source": "ssdp"}
|
||||
|
@ -103,14 +115,17 @@ async def test_scan_not_all_present(hass, aioclient_mock):
|
|||
},
|
||||
)
|
||||
|
||||
async def _inject_entry(*args, **kwargs):
|
||||
scanner.async_store_entry(
|
||||
Mock(st="mock-st", location="http://1.1.1.1", values={})
|
||||
async def _mock_async_scan(*args, async_callback=None, **kwargs):
|
||||
await async_callback(
|
||||
{
|
||||
"st": "mock-st",
|
||||
"location": "http://1.1.1.1",
|
||||
}
|
||||
)
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.ssdp.async_search",
|
||||
side_effect=_inject_entry,
|
||||
side_effect=_mock_async_scan,
|
||||
), patch.object(
|
||||
hass.config_entries.flow, "async_init", return_value=mock_coro()
|
||||
) as mock_init:
|
||||
|
@ -144,14 +159,17 @@ async def test_scan_not_all_match(hass, aioclient_mock):
|
|||
},
|
||||
)
|
||||
|
||||
async def _inject_entry(*args, **kwargs):
|
||||
scanner.async_store_entry(
|
||||
Mock(st="mock-st", location="http://1.1.1.1", values={})
|
||||
async def _mock_async_scan(*args, async_callback=None, **kwargs):
|
||||
await async_callback(
|
||||
{
|
||||
"st": "mock-st",
|
||||
"location": "http://1.1.1.1",
|
||||
}
|
||||
)
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.ssdp.async_search",
|
||||
side_effect=_inject_entry,
|
||||
side_effect=_mock_async_scan,
|
||||
), patch.object(
|
||||
hass.config_entries.flow, "async_init", return_value=mock_coro()
|
||||
) as mock_init:
|
||||
|
@ -166,14 +184,17 @@ async def test_scan_description_fetch_fail(hass, aioclient_mock, exc):
|
|||
aioclient_mock.get("http://1.1.1.1", exc=exc)
|
||||
scanner = ssdp.Scanner(hass, {})
|
||||
|
||||
async def _inject_entry(*args, **kwargs):
|
||||
scanner.async_store_entry(
|
||||
Mock(st="mock-st", location="http://1.1.1.1", values={})
|
||||
async def _mock_async_scan(*args, async_callback=None, **kwargs):
|
||||
await async_callback(
|
||||
{
|
||||
"st": "mock-st",
|
||||
"location": "http://1.1.1.1",
|
||||
}
|
||||
)
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.ssdp.async_search",
|
||||
side_effect=_inject_entry,
|
||||
side_effect=_mock_async_scan,
|
||||
):
|
||||
await scanner.async_scan(None)
|
||||
|
||||
|
@ -188,14 +209,17 @@ async def test_scan_description_parse_fail(hass, aioclient_mock):
|
|||
)
|
||||
scanner = ssdp.Scanner(hass, {})
|
||||
|
||||
async def _inject_entry(*args, **kwargs):
|
||||
scanner.async_store_entry(
|
||||
Mock(st="mock-st", location="http://1.1.1.1", values={})
|
||||
async def _mock_async_scan(*args, async_callback=None, **kwargs):
|
||||
await async_callback(
|
||||
{
|
||||
"st": "mock-st",
|
||||
"location": "http://1.1.1.1",
|
||||
}
|
||||
)
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.ssdp.async_search",
|
||||
side_effect=_inject_entry,
|
||||
side_effect=_mock_async_scan,
|
||||
):
|
||||
await scanner.async_scan(None)
|
||||
|
||||
|
@ -224,14 +248,17 @@ async def test_invalid_characters(hass, aioclient_mock):
|
|||
},
|
||||
)
|
||||
|
||||
async def _inject_entry(*args, **kwargs):
|
||||
scanner.async_store_entry(
|
||||
Mock(st="mock-st", location="http://1.1.1.1", values={})
|
||||
async def _mock_async_scan(*args, async_callback=None, **kwargs):
|
||||
await async_callback(
|
||||
{
|
||||
"st": "mock-st",
|
||||
"location": "http://1.1.1.1",
|
||||
}
|
||||
)
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.ssdp.async_search",
|
||||
side_effect=_inject_entry,
|
||||
side_effect=_mock_async_scan,
|
||||
), patch.object(
|
||||
hass.config_entries.flow, "async_init", return_value=mock_coro()
|
||||
) as mock_init:
|
||||
|
@ -246,3 +273,67 @@ async def test_invalid_characters(hass, aioclient_mock):
|
|||
"deviceType": "ABC",
|
||||
"serialNumber": "ÿÿÿÿ",
|
||||
}
|
||||
|
||||
|
||||
@patch("homeassistant.components.ssdp.async_search")
|
||||
async def test_start_stop_scanner(async_search_mock, hass):
|
||||
"""Test we start and stop the scanner."""
|
||||
assert await async_setup_component(hass, ssdp.DOMAIN, {ssdp.DOMAIN: {}})
|
||||
|
||||
hass.bus.async_fire(EVENT_HOMEASSISTANT_STARTED)
|
||||
await hass.async_block_till_done()
|
||||
async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=200))
|
||||
await hass.async_block_till_done()
|
||||
assert async_search_mock.call_count == 2
|
||||
|
||||
hass.bus.async_fire(EVENT_HOMEASSISTANT_STOP)
|
||||
await hass.async_block_till_done()
|
||||
async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=200))
|
||||
await hass.async_block_till_done()
|
||||
assert async_search_mock.call_count == 2
|
||||
|
||||
|
||||
async def test_unexpected_exception_while_fetching(hass, aioclient_mock, caplog):
|
||||
"""Test unexpected exception while fetching."""
|
||||
aioclient_mock.get(
|
||||
"http://1.1.1.1",
|
||||
text="""
|
||||
<root>
|
||||
<device>
|
||||
<deviceType>ABC</deviceType>
|
||||
<serialNumber>\xff\xff\xff\xff</serialNumber>
|
||||
</device>
|
||||
</root>
|
||||
""",
|
||||
)
|
||||
scanner = ssdp.Scanner(
|
||||
hass,
|
||||
{
|
||||
"mock-domain": [
|
||||
{
|
||||
ssdp.ATTR_UPNP_DEVICE_TYPE: "ABC",
|
||||
}
|
||||
]
|
||||
},
|
||||
)
|
||||
|
||||
async def _mock_async_scan(*args, async_callback=None, **kwargs):
|
||||
await async_callback(
|
||||
{
|
||||
"st": "mock-st",
|
||||
"location": "http://1.1.1.1",
|
||||
}
|
||||
)
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.ssdp.ElementTree.fromstring", side_effect=ValueError
|
||||
), patch(
|
||||
"homeassistant.components.ssdp.async_search",
|
||||
side_effect=_mock_async_scan,
|
||||
), patch.object(
|
||||
hass.config_entries.flow, "async_init", return_value=mock_coro()
|
||||
) as mock_init:
|
||||
await scanner.async_scan(None)
|
||||
|
||||
assert len(mock_init.mock_calls) == 0
|
||||
assert "Failed to fetch ssdp data from: http://1.1.1.1" in caplog.text
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue