hass-core/tests/components/discovery/test_init.py
J. Nick Koston 7b016063ca
Refactor zeroconf setup to be async (#39955)
* Refactor zeroconf setup to be async

Most of the setup was calling back to async because
we were setting up listeners.  Since we only need
to jump into the executor to create the zeroconf
instance, its much faster to setup in async.

In testing this cut the setup time in half
or better.

* partial revert to after_deps
2020-09-13 18:06:19 -05:00

166 lines
5.1 KiB
Python

"""The tests for the discovery component."""
from unittest.mock import MagicMock
import pytest
from homeassistant import config_entries
from homeassistant.bootstrap import async_setup_component
from homeassistant.components import discovery
from homeassistant.const import EVENT_HOMEASSISTANT_STARTED
from homeassistant.util.dt import utcnow
from tests.async_mock import patch
from tests.common import async_fire_time_changed, mock_coro
# One might consider to "mock" services, but it's easy enough to just use
# what is already available.
SERVICE = "yamaha"
SERVICE_COMPONENT = "media_player"
SERVICE_NO_PLATFORM = "hass_ios"
SERVICE_NO_PLATFORM_COMPONENT = "ios"
SERVICE_INFO = {"key": "value"} # Can be anything
UNKNOWN_SERVICE = "this_service_will_never_be_supported"
BASE_CONFIG = {discovery.DOMAIN: {"ignore": [], "enable": []}}
IGNORE_CONFIG = {discovery.DOMAIN: {"ignore": [SERVICE_NO_PLATFORM]}}
@pytest.fixture(autouse=True)
def netdisco_mock():
"""Mock netdisco."""
with patch.dict("sys.modules", {"netdisco.discovery": MagicMock()}):
yield
async def mock_discovery(hass, discoveries, config=BASE_CONFIG):
"""Mock discoveries."""
with patch("homeassistant.components.zeroconf.async_get_instance"), patch(
"homeassistant.components.zeroconf.async_setup", return_value=True
):
assert await async_setup_component(hass, "discovery", config)
await hass.async_block_till_done()
await hass.async_start()
hass.bus.async_fire(EVENT_HOMEASSISTANT_STARTED)
await hass.async_block_till_done()
with patch.object(discovery, "_discover", discoveries), patch(
"homeassistant.components.discovery.async_discover", return_value=mock_coro()
) as mock_discover, patch(
"homeassistant.components.discovery.async_load_platform",
return_value=mock_coro(),
) as mock_platform:
async_fire_time_changed(hass, utcnow())
# Work around an issue where our loop.call_soon not get caught
await hass.async_block_till_done()
await hass.async_block_till_done()
return mock_discover, mock_platform
async def test_unknown_service(hass):
"""Test that unknown service is ignored."""
def discover(netdisco, zeroconf_instance):
"""Fake discovery."""
return [("this_service_will_never_be_supported", {"info": "some"})]
mock_discover, mock_platform = await mock_discovery(hass, discover)
assert not mock_discover.called
assert not mock_platform.called
async def test_load_platform(hass):
"""Test load a platform."""
def discover(netdisco, zeroconf_instance):
"""Fake discovery."""
return [(SERVICE, SERVICE_INFO)]
mock_discover, mock_platform = await mock_discovery(hass, discover)
assert not mock_discover.called
assert mock_platform.called
mock_platform.assert_called_with(
hass, SERVICE_COMPONENT, SERVICE, SERVICE_INFO, BASE_CONFIG
)
async def test_load_component(hass):
"""Test load a component."""
def discover(netdisco, zeroconf_instance):
"""Fake discovery."""
return [(SERVICE_NO_PLATFORM, SERVICE_INFO)]
mock_discover, mock_platform = await mock_discovery(hass, discover)
assert mock_discover.called
assert not mock_platform.called
mock_discover.assert_called_with(
hass,
SERVICE_NO_PLATFORM,
SERVICE_INFO,
SERVICE_NO_PLATFORM_COMPONENT,
BASE_CONFIG,
)
async def test_ignore_service(hass):
"""Test ignore service."""
def discover(netdisco, zeroconf_instance):
"""Fake discovery."""
return [(SERVICE_NO_PLATFORM, SERVICE_INFO)]
mock_discover, mock_platform = await mock_discovery(hass, discover, IGNORE_CONFIG)
assert not mock_discover.called
assert not mock_platform.called
async def test_discover_duplicates(hass):
"""Test load a component."""
def discover(netdisco, zeroconf_instance):
"""Fake discovery."""
return [
(SERVICE_NO_PLATFORM, SERVICE_INFO),
(SERVICE_NO_PLATFORM, SERVICE_INFO),
]
mock_discover, mock_platform = await mock_discovery(hass, discover)
assert mock_discover.called
assert mock_discover.call_count == 1
assert not mock_platform.called
mock_discover.assert_called_with(
hass,
SERVICE_NO_PLATFORM,
SERVICE_INFO,
SERVICE_NO_PLATFORM_COMPONENT,
BASE_CONFIG,
)
async def test_discover_config_flow(hass):
"""Test discovery triggering a config flow."""
discovery_info = {"hello": "world"}
def discover(netdisco, zeroconf_instance):
"""Fake discovery."""
return [("mock-service", discovery_info)]
with patch.dict(
discovery.CONFIG_ENTRY_HANDLERS, {"mock-service": "mock-component"}
), patch("homeassistant.data_entry_flow.FlowManager.async_init") as m_init:
await mock_discovery(hass, discover)
assert len(m_init.mock_calls) == 1
args, kwargs = m_init.mock_calls[0][1:]
assert args == ("mock-component",)
assert kwargs["context"]["source"] == config_entries.SOURCE_DISCOVERY
assert kwargs["data"] == discovery_info