diff --git a/homeassistant/components/ambiclimate/config_flow.py b/homeassistant/components/ambiclimate/config_flow.py index b022b54c4fd7..00fa339b0d89 100644 --- a/homeassistant/components/ambiclimate/config_flow.py +++ b/homeassistant/components/ambiclimate/config_flow.py @@ -124,7 +124,7 @@ class AmbiclimateFlowHandler(config_entries.ConfigFlow, domain=DOMAIN): ) def _cb_url(self): - return f"{get_url(self.hass)}{AUTH_CALLBACK_PATH}" + return f"{get_url(self.hass, prefer_external=True)}{AUTH_CALLBACK_PATH}" async def _get_authorize_url(self): oauth = self._generate_oauth() diff --git a/homeassistant/components/emulated_hue/__init__.py b/homeassistant/components/emulated_hue/__init__.py index 3cfa710703c1..4dec35a80e86 100644 --- a/homeassistant/components/emulated_hue/__init__.py +++ b/homeassistant/components/emulated_hue/__init__.py @@ -5,7 +5,6 @@ from aiohttp import web import voluptuous as vol from homeassistant.components.network import async_get_source_ip -from homeassistant.components.network.const import PUBLIC_TARGET_IP from homeassistant.const import ( CONF_ENTITIES, CONF_TYPE, @@ -106,7 +105,7 @@ ATTR_EMULATED_HUE_NAME = "emulated_hue_name" async def async_setup(hass, yaml_config): """Activate the emulated_hue component.""" - local_ip = await async_get_source_ip(hass, PUBLIC_TARGET_IP) + local_ip = await async_get_source_ip(hass) config = Config(hass, yaml_config.get(DOMAIN, {}), local_ip) await config.async_setup() diff --git a/homeassistant/components/emulated_roku/__init__.py b/homeassistant/components/emulated_roku/__init__.py index 32e083421919..3d84bf20f444 100644 --- a/homeassistant/components/emulated_roku/__init__.py +++ b/homeassistant/components/emulated_roku/__init__.py @@ -3,7 +3,6 @@ import voluptuous as vol from homeassistant import config_entries from homeassistant.components.network import async_get_source_ip -from homeassistant.components.network.const import PUBLIC_TARGET_IP from homeassistant.const import CONF_NAME import homeassistant.helpers.config_validation as cv @@ -71,9 +70,7 @@ async def async_setup_entry(hass, config_entry): name = config[CONF_NAME] listen_port = config[CONF_LISTEN_PORT] - host_ip = config.get(CONF_HOST_IP) or await async_get_source_ip( - hass, PUBLIC_TARGET_IP - ) + host_ip = config.get(CONF_HOST_IP) or await async_get_source_ip(hass) advertise_ip = config.get(CONF_ADVERTISE_IP) advertise_port = config.get(CONF_ADVERTISE_PORT) upnp_bind_multicast = config.get(CONF_UPNP_BIND_MULTICAST) diff --git a/homeassistant/components/homekit/__init__.py b/homeassistant/components/homekit/__init__.py index 3e2a2a65d182..3c45ba8de39e 100644 --- a/homeassistant/components/homekit/__init__.py +++ b/homeassistant/components/homekit/__init__.py @@ -18,6 +18,7 @@ from homeassistant.components.binary_sensor import ( from homeassistant.components.camera import DOMAIN as CAMERA_DOMAIN from homeassistant.components.http import HomeAssistantView from homeassistant.components.humidifier import DOMAIN as HUMIDIFIER_DOMAIN +from homeassistant.components.network.const import MDNS_TARGET_IP from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry from homeassistant.const import ( @@ -119,8 +120,6 @@ STATUS_WAIT = 3 PORT_CLEANUP_CHECK_INTERVAL_SECS = 1 -MDNS_TARGET_IP = "224.0.0.251" - _HOMEKIT_CONFIG_UPDATE_TIME = ( 5 # number of seconds to wait for homekit to see the c# change ) diff --git a/homeassistant/components/http/__init__.py b/homeassistant/components/http/__init__.py index 15766acdd4c5..7c30acfc1189 100644 --- a/homeassistant/components/http/__init__.py +++ b/homeassistant/components/http/__init__.py @@ -13,6 +13,7 @@ from aiohttp.typedefs import StrOrURL from aiohttp.web_exceptions import HTTPMovedPermanently, HTTPRedirection import voluptuous as vol +from homeassistant.components.network import async_get_source_ip from homeassistant.const import EVENT_HOMEASSISTANT_STOP, SERVER_PORT from homeassistant.core import Event, HomeAssistant from homeassistant.helpers import storage @@ -20,7 +21,6 @@ import homeassistant.helpers.config_validation as cv from homeassistant.helpers.typing import ConfigType from homeassistant.loader import bind_hass from homeassistant.setup import async_start_setup, async_when_setup_or_start -import homeassistant.util as hass_util from homeassistant.util import ssl as ssl_util from .auth import setup_auth @@ -190,7 +190,7 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: hass.http = server - local_ip = await hass.async_add_executor_job(hass_util.get_local_ip) + local_ip = await async_get_source_ip(hass) host = local_ip if server_host is not None: diff --git a/homeassistant/components/local_ip/sensor.py b/homeassistant/components/local_ip/sensor.py index bd1b3d54face..56c1fac7c8f1 100644 --- a/homeassistant/components/local_ip/sensor.py +++ b/homeassistant/components/local_ip/sensor.py @@ -1,7 +1,6 @@ """Sensor platform for local_ip.""" from homeassistant.components.network import async_get_source_ip -from homeassistant.components.network.const import PUBLIC_TARGET_IP from homeassistant.components.sensor import SensorEntity from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_NAME @@ -33,6 +32,4 @@ class IPSensor(SensorEntity): async def async_update(self) -> None: """Fetch new state data for the sensor.""" - self._attr_native_value = await async_get_source_ip( - self.hass, target_ip=PUBLIC_TARGET_IP - ) + self._attr_native_value = await async_get_source_ip(self.hass) diff --git a/homeassistant/components/network/__init__.py b/homeassistant/components/network/__init__.py index e8a2c4c80fd2..7cc864727d73 100644 --- a/homeassistant/components/network/__init__.py +++ b/homeassistant/components/network/__init__.py @@ -2,30 +2,28 @@ from __future__ import annotations from ipaddress import IPv4Address, IPv6Address, ip_interface -import logging from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.typing import ConfigType from homeassistant.loader import bind_hass from . import util -from .const import DOMAIN, IPV4_BROADCAST_ADDR +from .const import IPV4_BROADCAST_ADDR, PUBLIC_TARGET_IP from .models import Adapter -from .network import Network - -ZEROCONF_DOMAIN = "zeroconf" # cannot import from zeroconf due to circular dep -_LOGGER = logging.getLogger(__name__) +from .network import Network, async_get_network @bind_hass async def async_get_adapters(hass: HomeAssistant) -> list[Adapter]: """Get the network adapter configuration.""" - network: Network = hass.data[DOMAIN] + network: Network = await async_get_network(hass) return network.adapters @bind_hass -async def async_get_source_ip(hass: HomeAssistant, target_ip: str) -> str: +async def async_get_source_ip( + hass: HomeAssistant, target_ip: str = PUBLIC_TARGET_IP +) -> str: """Get the source ip for a target ip.""" adapters = await async_get_adapters(hass) all_ipv4s = [] @@ -88,20 +86,10 @@ async def async_get_ipv4_broadcast_addresses(hass: HomeAssistant) -> set[IPv4Add async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: """Set up network for Home Assistant.""" - - hass.data[DOMAIN] = network = Network(hass) - await network.async_setup() - if ZEROCONF_DOMAIN in config: - await network.async_migrate_from_zeroconf(config[ZEROCONF_DOMAIN]) - network.async_configure() - - _LOGGER.debug("Adapters: %s", network.adapters) - # Avoid circular issue: http->network->websocket_api->http from .websocket import ( # pylint: disable=import-outside-toplevel async_register_websocket_commands, ) async_register_websocket_commands(hass) - return True diff --git a/homeassistant/components/network/const.py b/homeassistant/components/network/const.py index 7e7401251fc4..07c12e63a10c 100644 --- a/homeassistant/components/network/const.py +++ b/homeassistant/components/network/const.py @@ -11,6 +11,8 @@ DOMAIN: Final = "network" STORAGE_KEY: Final = "core.network" STORAGE_VERSION: Final = 1 +DATA_NETWORK: Final = "network" + ATTR_ADAPTERS: Final = "adapters" ATTR_CONFIGURED_ADAPTERS: Final = "configured_adapters" DEFAULT_CONFIGURED_ADAPTERS: list[str] = [] diff --git a/homeassistant/components/network/network.py b/homeassistant/components/network/network.py index 5e2e7b8ad6ba..6ec9941da3c3 100644 --- a/homeassistant/components/network/network.py +++ b/homeassistant/components/network/network.py @@ -1,23 +1,35 @@ """Network helper class for the network integration.""" from __future__ import annotations +import logging from typing import Any, cast from homeassistant.core import HomeAssistant, callback +from homeassistant.helpers.singleton import singleton from .const import ( ATTR_CONFIGURED_ADAPTERS, + DATA_NETWORK, DEFAULT_CONFIGURED_ADAPTERS, STORAGE_KEY, STORAGE_VERSION, ) from .models import Adapter -from .util import ( - adapters_with_exernal_addresses, - async_load_adapters, - enable_adapters, - enable_auto_detected_adapters, -) +from .util import async_load_adapters, enable_adapters, enable_auto_detected_adapters + +_LOGGER = logging.getLogger(__name__) + + +@singleton(DATA_NETWORK) +@callback +async def async_get_network(hass: HomeAssistant) -> Network: + """Get network singleton.""" + network = Network(hass) + await network.async_setup() + network.async_configure() + + _LOGGER.debug("Adapters: %s", network.adapters) + return network class Network: @@ -41,21 +53,6 @@ class Network: await self.async_load() self.adapters = await async_load_adapters() - async def async_migrate_from_zeroconf(self, zc_config: dict[str, Any]) -> None: - """Migrate configuration from zeroconf.""" - if self._data or not zc_config: - return - - from homeassistant.components.zeroconf import ( # pylint: disable=import-outside-toplevel - CONF_DEFAULT_INTERFACE, - ) - - if zc_config.get(CONF_DEFAULT_INTERFACE) is False: - self._data[ATTR_CONFIGURED_ADAPTERS] = adapters_with_exernal_addresses( - self.adapters - ) - await self._async_save() - @callback def async_configure(self) -> None: """Configure from storage.""" diff --git a/homeassistant/components/network/util.py b/homeassistant/components/network/util.py index f8b33b3df907..4b920e5d927d 100644 --- a/homeassistant/components/network/util.py +++ b/homeassistant/components/network/util.py @@ -57,15 +57,6 @@ def enable_auto_detected_adapters(adapters: list[Adapter]) -> None: ) -def adapters_with_exernal_addresses(adapters: list[Adapter]) -> list[str]: - """Enable all interfaces with an external address.""" - return [ - adapter["name"] - for adapter in adapters - if _adapter_has_external_address(adapter) - ] - - def _adapter_has_external_address(adapter: Adapter) -> bool: """Adapter has a non-loopback and non-link-local address.""" return any( diff --git a/homeassistant/components/network/websocket.py b/homeassistant/components/network/websocket.py index 77e01375b754..c19ed5e8fd79 100644 --- a/homeassistant/components/network/websocket.py +++ b/homeassistant/components/network/websocket.py @@ -7,13 +7,8 @@ from homeassistant.components import websocket_api from homeassistant.components.websocket_api.connection import ActiveConnection from homeassistant.core import HomeAssistant, callback -from .const import ( - ATTR_ADAPTERS, - ATTR_CONFIGURED_ADAPTERS, - DOMAIN, - NETWORK_CONFIG_SCHEMA, -) -from .network import Network +from .const import ATTR_ADAPTERS, ATTR_CONFIGURED_ADAPTERS, NETWORK_CONFIG_SCHEMA +from .network import async_get_network @callback @@ -32,7 +27,7 @@ async def websocket_network_adapters( msg: dict, ) -> None: """Return network preferences.""" - network: Network = hass.data[DOMAIN] + network = await async_get_network(hass) connection.send_result( msg["id"], { @@ -56,7 +51,7 @@ async def websocket_network_adapters_configure( msg: dict, ) -> None: """Update network config.""" - network: Network = hass.data[DOMAIN] + network = await async_get_network(hass) await network.async_reconfig(msg["config"]) diff --git a/homeassistant/components/zeroconf/__init__.py b/homeassistant/components/zeroconf/__init__.py index 816017026567..01b289f6d18f 100644 --- a/homeassistant/components/zeroconf/__init__.py +++ b/homeassistant/components/zeroconf/__init__.py @@ -17,6 +17,7 @@ from zeroconf.asyncio import AsyncServiceInfo from homeassistant import config_entries from homeassistant.components import network from homeassistant.components.network import async_get_source_ip +from homeassistant.components.network.const import MDNS_TARGET_IP from homeassistant.components.network.models import Adapter from homeassistant.const import ( EVENT_HOMEASSISTANT_START, @@ -52,8 +53,6 @@ DEFAULT_IPV6 = True HOMEKIT_PAIRED_STATUS_FLAG = "sf" HOMEKIT_MODEL = "md" -MDNS_TARGET_IP = "224.0.0.251" - # Property key=value has a max length of 255 # so we use 230 to leave space for key= MAX_PROPERTY_VALUE_LEN = 230 diff --git a/homeassistant/util/__init__.py b/homeassistant/util/__init__.py index 4f7f1af2e7df..3840958d5808 100644 --- a/homeassistant/util/__init__.py +++ b/homeassistant/util/__init__.py @@ -5,10 +5,9 @@ import asyncio from collections.abc import Callable, Coroutine, Iterable, KeysView from datetime import datetime, timedelta import enum -from functools import lru_cache, wraps +from functools import wraps import random import re -import socket import string import threading from types import MappingProxyType @@ -129,26 +128,6 @@ def ensure_unique_string( return test_string -# Taken from: http://stackoverflow.com/a/11735897 -@lru_cache(maxsize=None) -def get_local_ip() -> str: - """Try to determine the local IP address of the machine.""" - try: - sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - - # Use Google Public DNS server to determine own IP - sock.connect(("8.8.8.8", 80)) - - return sock.getsockname()[0] # type: ignore - except OSError: - try: - return socket.gethostbyname(socket.gethostname()) - except socket.gaierror: - return "127.0.0.1" - finally: - sock.close() - - # Taken from http://stackoverflow.com/a/23728630 def get_random_string(length: int = 10) -> str: """Return a random string with letters and digits.""" diff --git a/requirements.txt b/requirements.txt index fe35d852aef1..0049df1cf7ad 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,6 +12,7 @@ bcrypt==3.1.7 certifi>=2021.5.30 ciso8601==2.2.0 httpx==0.19.0 +ifaddr==0.1.7 jinja2==3.0.3 PyJWT==2.1.0 cryptography==35.0.0 diff --git a/script/hassfest/dependencies.py b/script/hassfest/dependencies.py index b650d3232acd..41510a46cb45 100644 --- a/script/hassfest/dependencies.py +++ b/script/hassfest/dependencies.py @@ -134,8 +134,8 @@ IGNORE_VIOLATIONS = { # Demo ("demo", "manual"), ("demo", "openalpr_local"), - # Migration of settings from zeroconf to network - ("network", "zeroconf"), + # This would be a circular dep + ("http", "network"), # This should become a helper method that integrations can submit data to ("websocket_api", "lovelace"), ("websocket_api", "shopping_list"), diff --git a/setup.py b/setup.py index 38a48fb5f0f6..e08fbdf43e5a 100755 --- a/setup.py +++ b/setup.py @@ -43,6 +43,7 @@ REQUIRES = [ "certifi>=2021.5.30", "ciso8601==2.2.0", "httpx==0.19.0", + "ifaddr==0.1.7", "jinja2==3.0.3", "PyJWT==2.1.0", # PyJWT has loose dependency. We want the latest one. diff --git a/tests/components/motioneye/__init__.py b/tests/components/motioneye/__init__.py index c695313c0844..7558e6fbcc49 100644 --- a/tests/components/motioneye/__init__.py +++ b/tests/components/motioneye/__init__.py @@ -179,7 +179,10 @@ async def setup_mock_motioneye_config_entry( await async_process_ha_core_config( hass, - {"external_url": "https://example.com"}, + { + "internal_url": "https://internal.url", + "external_url": "https://external.url", + }, ) config_entry = config_entry or create_mock_motioneye_config_entry(hass) diff --git a/tests/components/motioneye/test_web_hooks.py b/tests/components/motioneye/test_web_hooks.py index 6a51ea871c76..c7aaa4a8638c 100644 --- a/tests/components/motioneye/test_web_hooks.py +++ b/tests/components/motioneye/test_web_hooks.py @@ -77,7 +77,7 @@ async def test_setup_camera_without_webhook(hass: HomeAssistant) -> None: expected_camera[KEY_WEB_HOOK_NOTIFICATIONS_ENABLED] = True expected_camera[KEY_WEB_HOOK_NOTIFICATIONS_HTTP_METHOD] = KEY_HTTP_METHOD_POST_JSON expected_camera[KEY_WEB_HOOK_NOTIFICATIONS_URL] = ( - "https://example.com" + "https://internal.url" + URL_WEBHOOK_PATH.format(webhook_id=config_entry.data[CONF_WEBHOOK_ID]) + f"?{WEB_HOOK_MOTION_DETECTED_QUERY_STRING}&device_id={device.id}" ) @@ -85,7 +85,7 @@ async def test_setup_camera_without_webhook(hass: HomeAssistant) -> None: expected_camera[KEY_WEB_HOOK_STORAGE_ENABLED] = True expected_camera[KEY_WEB_HOOK_STORAGE_HTTP_METHOD] = KEY_HTTP_METHOD_POST_JSON expected_camera[KEY_WEB_HOOK_STORAGE_URL] = ( - "https://example.com" + "https://internal.url" + URL_WEBHOOK_PATH.format(webhook_id=config_entry.data[CONF_WEBHOOK_ID]) + f"?{WEB_HOOK_FILE_STORED_QUERY_STRING}&device_id={device.id}" ) @@ -132,7 +132,7 @@ async def test_setup_camera_with_wrong_webhook( expected_camera[KEY_WEB_HOOK_NOTIFICATIONS_ENABLED] = True expected_camera[KEY_WEB_HOOK_NOTIFICATIONS_HTTP_METHOD] = KEY_HTTP_METHOD_POST_JSON expected_camera[KEY_WEB_HOOK_NOTIFICATIONS_URL] = ( - "https://example.com" + "https://internal.url" + URL_WEBHOOK_PATH.format(webhook_id=config_entry.data[CONF_WEBHOOK_ID]) + f"?{WEB_HOOK_MOTION_DETECTED_QUERY_STRING}&device_id={device.id}" ) @@ -140,7 +140,7 @@ async def test_setup_camera_with_wrong_webhook( expected_camera[KEY_WEB_HOOK_STORAGE_ENABLED] = True expected_camera[KEY_WEB_HOOK_STORAGE_HTTP_METHOD] = KEY_HTTP_METHOD_POST_JSON expected_camera[KEY_WEB_HOOK_STORAGE_URL] = ( - "https://example.com" + "https://internal.url" + URL_WEBHOOK_PATH.format(webhook_id=config_entry.data[CONF_WEBHOOK_ID]) + f"?{WEB_HOOK_FILE_STORED_QUERY_STRING}&device_id={device.id}" ) @@ -185,7 +185,7 @@ async def test_setup_camera_with_old_webhook( expected_camera[KEY_WEB_HOOK_NOTIFICATIONS_ENABLED] = True expected_camera[KEY_WEB_HOOK_NOTIFICATIONS_HTTP_METHOD] = KEY_HTTP_METHOD_POST_JSON expected_camera[KEY_WEB_HOOK_NOTIFICATIONS_URL] = ( - "https://example.com" + "https://internal.url" + URL_WEBHOOK_PATH.format(webhook_id=config_entry.data[CONF_WEBHOOK_ID]) + f"?{WEB_HOOK_MOTION_DETECTED_QUERY_STRING}&device_id={device.id}" ) @@ -193,7 +193,7 @@ async def test_setup_camera_with_old_webhook( expected_camera[KEY_WEB_HOOK_STORAGE_ENABLED] = True expected_camera[KEY_WEB_HOOK_STORAGE_HTTP_METHOD] = KEY_HTTP_METHOD_POST_JSON expected_camera[KEY_WEB_HOOK_STORAGE_URL] = ( - "https://example.com" + "https://internal.url" + URL_WEBHOOK_PATH.format(webhook_id=config_entry.data[CONF_WEBHOOK_ID]) + f"?{WEB_HOOK_FILE_STORED_QUERY_STRING}&device_id={device.id}" ) @@ -223,7 +223,7 @@ async def test_setup_camera_with_correct_webhook( KEY_WEB_HOOK_NOTIFICATIONS_HTTP_METHOD ] = KEY_HTTP_METHOD_POST_JSON cameras[KEY_CAMERAS][0][KEY_WEB_HOOK_NOTIFICATIONS_URL] = ( - "https://example.com" + "https://internal.url" + URL_WEBHOOK_PATH.format(webhook_id=config_entry.data[CONF_WEBHOOK_ID]) + f"?{WEB_HOOK_MOTION_DETECTED_QUERY_STRING}&device_id={device.id}" ) @@ -232,7 +232,7 @@ async def test_setup_camera_with_correct_webhook( KEY_WEB_HOOK_STORAGE_HTTP_METHOD ] = KEY_HTTP_METHOD_POST_JSON cameras[KEY_CAMERAS][0][KEY_WEB_HOOK_STORAGE_URL] = ( - "https://example.com" + "https://internal.url" + URL_WEBHOOK_PATH.format(webhook_id=config_entry.data[CONF_WEBHOOK_ID]) + f"?{WEB_HOOK_FILE_STORED_QUERY_STRING}&device_id={device.id}" ) diff --git a/tests/components/network/conftest.py b/tests/components/network/conftest.py new file mode 100644 index 000000000000..9c1bf232d7bd --- /dev/null +++ b/tests/components/network/conftest.py @@ -0,0 +1,9 @@ +"""Tests for the Network Configuration integration.""" + +import pytest + + +@pytest.fixture(autouse=True) +def mock_get_source_ip(): + """Override mock of network util's async_get_source_ip.""" + return diff --git a/tests/components/network/test_init.py b/tests/components/network/test_init.py index 12d317e826ac..5a6802a14fbc 100644 --- a/tests/components/network/test_init.py +++ b/tests/components/network/test_init.py @@ -8,6 +8,7 @@ from homeassistant.components import network from homeassistant.components.network.const import ( ATTR_ADAPTERS, ATTR_CONFIGURED_ADAPTERS, + DOMAIN, MDNS_TARGET_IP, STORAGE_KEY, STORAGE_VERSION, @@ -59,10 +60,10 @@ async def test_async_detect_interfaces_setting_non_loopback_route(hass, hass_sto "homeassistant.components.network.util.ifaddr.get_adapters", return_value=_generate_mock_adapters(), ): - assert await async_setup_component(hass, network.DOMAIN, {network.DOMAIN: {}}) + assert await async_setup_component(hass, DOMAIN, {DOMAIN: {}}) await hass.async_block_till_done() - network_obj = hass.data[network.DOMAIN] + network_obj = hass.data[DOMAIN] assert network_obj.configured_adapters == [] assert network_obj.adapters == [ @@ -121,10 +122,10 @@ async def test_async_detect_interfaces_setting_loopback_route(hass, hass_storage "homeassistant.components.network.util.ifaddr.get_adapters", return_value=_generate_mock_adapters(), ): - assert await async_setup_component(hass, network.DOMAIN, {network.DOMAIN: {}}) + assert await async_setup_component(hass, DOMAIN, {DOMAIN: {}}) await hass.async_block_till_done() - network_obj = hass.data[network.DOMAIN] + network_obj = hass.data[DOMAIN] assert network_obj.configured_adapters == [] assert network_obj.adapters == [ { @@ -182,10 +183,10 @@ async def test_async_detect_interfaces_setting_empty_route(hass, hass_storage): "homeassistant.components.network.util.ifaddr.get_adapters", return_value=_generate_mock_adapters(), ): - assert await async_setup_component(hass, network.DOMAIN, {network.DOMAIN: {}}) + assert await async_setup_component(hass, DOMAIN, {DOMAIN: {}}) await hass.async_block_till_done() - network_obj = hass.data[network.DOMAIN] + network_obj = hass.data[DOMAIN] assert network_obj.configured_adapters == [] assert network_obj.adapters == [ { @@ -243,10 +244,10 @@ async def test_async_detect_interfaces_setting_exception(hass, hass_storage): "homeassistant.components.network.util.ifaddr.get_adapters", return_value=_generate_mock_adapters(), ): - assert await async_setup_component(hass, network.DOMAIN, {network.DOMAIN: {}}) + assert await async_setup_component(hass, DOMAIN, {DOMAIN: {}}) await hass.async_block_till_done() - network_obj = hass.data[network.DOMAIN] + network_obj = hass.data[DOMAIN] assert network_obj.configured_adapters == [] assert network_obj.adapters == [ { @@ -309,10 +310,10 @@ async def test_interfaces_configured_from_storage(hass, hass_storage): "homeassistant.components.network.util.ifaddr.get_adapters", return_value=_generate_mock_adapters(), ): - assert await async_setup_component(hass, network.DOMAIN, {network.DOMAIN: {}}) + assert await async_setup_component(hass, DOMAIN, {DOMAIN: {}}) await hass.async_block_till_done() - network_obj = hass.data[network.DOMAIN] + network_obj = hass.data[DOMAIN] assert network_obj.configured_adapters == ["eth0", "eth1", "vtun0"] assert network_obj.adapters == [ @@ -378,10 +379,10 @@ async def test_interfaces_configured_from_storage_websocket_update( "homeassistant.components.network.util.ifaddr.get_adapters", return_value=_generate_mock_adapters(), ): - assert await async_setup_component(hass, network.DOMAIN, {network.DOMAIN: {}}) + assert await async_setup_component(hass, DOMAIN, {DOMAIN: {}}) await hass.async_block_till_done() - network_obj = hass.data[network.DOMAIN] + network_obj = hass.data[DOMAIN] assert network_obj.configured_adapters == ["eth0", "eth1", "vtun0"] ws_client = await hass_ws_client(hass) await ws_client.send_json({"id": 1, "type": "network"}) @@ -507,7 +508,7 @@ async def test_async_get_source_ip_matching_interface(hass, hass_storage): "homeassistant.components.network.util.socket.socket", return_value=_mock_socket(["192.168.1.5"]), ): - assert await async_setup_component(hass, network.DOMAIN, {network.DOMAIN: {}}) + assert await async_setup_component(hass, DOMAIN, {DOMAIN: {}}) await hass.async_block_till_done() assert await network.async_get_source_ip(hass, MDNS_TARGET_IP) == "192.168.1.5" @@ -528,7 +529,7 @@ async def test_async_get_source_ip_interface_not_match(hass, hass_storage): "homeassistant.components.network.util.socket.socket", return_value=_mock_socket(["192.168.1.5"]), ): - assert await async_setup_component(hass, network.DOMAIN, {network.DOMAIN: {}}) + assert await async_setup_component(hass, DOMAIN, {DOMAIN: {}}) await hass.async_block_till_done() assert await network.async_get_source_ip(hass, MDNS_TARGET_IP) == "169.254.3.2" @@ -549,7 +550,7 @@ async def test_async_get_source_ip_cannot_determine_target(hass, hass_storage): "homeassistant.components.network.util.socket.socket", return_value=_mock_socket([None]), ): - assert await async_setup_component(hass, network.DOMAIN, {network.DOMAIN: {}}) + assert await async_setup_component(hass, DOMAIN, {DOMAIN: {}}) await hass.async_block_till_done() assert await network.async_get_source_ip(hass, MDNS_TARGET_IP) == "192.168.1.5" @@ -570,7 +571,7 @@ async def test_async_get_ipv4_broadcast_addresses_default(hass, hass_storage): "homeassistant.components.network.util.ifaddr.get_adapters", return_value=_generate_mock_adapters(), ): - assert await async_setup_component(hass, network.DOMAIN, {network.DOMAIN: {}}) + assert await async_setup_component(hass, DOMAIN, {DOMAIN: {}}) await hass.async_block_till_done() assert await network.async_get_ipv4_broadcast_addresses(hass) == { @@ -593,7 +594,7 @@ async def test_async_get_ipv4_broadcast_addresses_multiple(hass, hass_storage): "homeassistant.components.network.util.ifaddr.get_adapters", return_value=_generate_mock_adapters(), ): - assert await async_setup_component(hass, network.DOMAIN, {network.DOMAIN: {}}) + assert await async_setup_component(hass, DOMAIN, {DOMAIN: {}}) await hass.async_block_till_done() assert await network.async_get_ipv4_broadcast_addresses(hass) == { diff --git a/tests/conftest.py b/tests/conftest.py index 61dcd40e53fa..f6713596e561 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -598,7 +598,7 @@ async def mqtt_mock(hass, mqtt_client_mock, mqtt_config): return component -@pytest.fixture +@pytest.fixture(autouse=True) def mock_get_source_ip(): """Mock network util's async_get_source_ip.""" with patch(