From ab42acf4d73ccf8af76ab9abe4da4b8c2b29780b Mon Sep 17 00:00:00 2001 From: Colin O'Dell Date: Fri, 3 Mar 2017 16:11:40 -0500 Subject: [PATCH 1/2] Don't initialize components which have already been discovered (#6381) * Don't initialize components which have already been discovered (fixes #5588) * Don't log that we've found a service unless we know it's not a duplicate * Encode discovery data hash with JSON This also solves the issue of trying to hash non-hashable objects like dicts * Add test for duplicate device discovery --- homeassistant/components/discovery.py | 12 ++++++++++-- tests/components/test_discovery.py | 27 +++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/discovery.py b/homeassistant/components/discovery.py index 028a6df01fb..2d66f4e4b7c 100644 --- a/homeassistant/components/discovery.py +++ b/homeassistant/components/discovery.py @@ -7,6 +7,7 @@ Knows which components handle certain types, will make sure they are loaded before the EVENT_PLATFORM_DISCOVERED is fired. """ import asyncio +import json from datetime import timedelta import logging @@ -65,6 +66,7 @@ def async_setup(hass, config): logger = logging.getLogger(__name__) netdisco = NetworkDiscovery() + already_discovered = set() # Disable zeroconf logging, it spams logging.getLogger('zeroconf').setLevel(logging.CRITICAL) @@ -79,14 +81,20 @@ def async_setup(hass, config): logger.info("Ignoring service: %s %s", service, info) return - logger.info("Found new service: %s %s", service, info) - comp_plat = SERVICE_HANDLERS.get(service) # We do not know how to handle this service. if not comp_plat: return + discovery_hash = json.dumps([service, info], sort_keys=True) + if discovery_hash in already_discovered: + return + + already_discovered.add(discovery_hash) + + logger.info("Found new service: %s %s", service, info) + component, platform = comp_plat if platform is None: diff --git a/tests/components/test_discovery.py b/tests/components/test_discovery.py index bc2be3ed463..abffc3b17cd 100644 --- a/tests/components/test_discovery.py +++ b/tests/components/test_discovery.py @@ -126,3 +126,30 @@ def test_ignore_service(hass): assert not mock_discover.called assert not mock_platform.called + + +@asyncio.coroutine +def test_discover_duplicates(hass): + """Test load a component.""" + result = yield from async_setup_component(hass, 'discovery', BASE_CONFIG) + assert result + + def discover(netdisco): + """Fake discovery.""" + return [(SERVICE_NO_PLATFORM, SERVICE_INFO), + (SERVICE_NO_PLATFORM, SERVICE_INFO)] + + with patch.object(discovery, '_discover', discover), \ + 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: + hass.bus.async_fire(EVENT_HOMEASSISTANT_START) + yield from hass.async_block_till_done() + + 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) From 3e9e388745a670173d65ccecc442a426f837e6ef Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Fri, 3 Mar 2017 13:14:52 -0800 Subject: [PATCH 2/2] Version bump to 0.39.3 --- homeassistant/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/const.py b/homeassistant/const.py index f52c524f314..c7ad7b4062b 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -2,7 +2,7 @@ """Constants used by Home Assistant components.""" MAJOR_VERSION = 0 MINOR_VERSION = 39 -PATCH_VERSION = '2' +PATCH_VERSION = '3' __short_version__ = '{}.{}'.format(MAJOR_VERSION, MINOR_VERSION) __version__ = '{}.{}'.format(__short_version__, PATCH_VERSION) REQUIRED_PYTHON_VER = (3, 4, 2)