mirror of
https://github.com/home-assistant/core.git
synced 2025-04-26 10:17:51 +00:00
Migrate to using aiohttp-asyncmdnsresolver for aiohttp resolver (#134830)
This commit is contained in:
parent
d13c14eedb
commit
89c73f56b1
@ -144,17 +144,27 @@ class ZeroconfServiceInfo(BaseServiceInfo):
|
|||||||
|
|
||||||
@bind_hass
|
@bind_hass
|
||||||
async def async_get_instance(hass: HomeAssistant) -> HaZeroconf:
|
async def async_get_instance(hass: HomeAssistant) -> HaZeroconf:
|
||||||
"""Zeroconf instance to be shared with other integrations that use it."""
|
"""Get or create the shared HaZeroconf instance."""
|
||||||
return cast(HaZeroconf, (await _async_get_instance(hass)).zeroconf)
|
return cast(HaZeroconf, (_async_get_instance(hass)).zeroconf)
|
||||||
|
|
||||||
|
|
||||||
@bind_hass
|
@bind_hass
|
||||||
async def async_get_async_instance(hass: HomeAssistant) -> HaAsyncZeroconf:
|
async def async_get_async_instance(hass: HomeAssistant) -> HaAsyncZeroconf:
|
||||||
"""Zeroconf instance to be shared with other integrations that use it."""
|
"""Get or create the shared HaAsyncZeroconf instance."""
|
||||||
return await _async_get_instance(hass)
|
return _async_get_instance(hass)
|
||||||
|
|
||||||
|
|
||||||
async def _async_get_instance(hass: HomeAssistant, **zcargs: Any) -> HaAsyncZeroconf:
|
@callback
|
||||||
|
def async_get_async_zeroconf(hass: HomeAssistant) -> HaAsyncZeroconf:
|
||||||
|
"""Get or create the shared HaAsyncZeroconf instance.
|
||||||
|
|
||||||
|
This method must be run in the event loop, and is an alternative
|
||||||
|
to the async_get_async_instance method when a coroutine cannot be used.
|
||||||
|
"""
|
||||||
|
return _async_get_instance(hass)
|
||||||
|
|
||||||
|
|
||||||
|
def _async_get_instance(hass: HomeAssistant, **zcargs: Any) -> HaAsyncZeroconf:
|
||||||
if DOMAIN in hass.data:
|
if DOMAIN in hass.data:
|
||||||
return cast(HaAsyncZeroconf, hass.data[DOMAIN])
|
return cast(HaAsyncZeroconf, hass.data[DOMAIN])
|
||||||
|
|
||||||
@ -221,7 +231,7 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
|||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
aio_zc = await _async_get_instance(hass, **zc_args)
|
aio_zc = _async_get_instance(hass, **zc_args)
|
||||||
zeroconf = cast(HaZeroconf, aio_zc.zeroconf)
|
zeroconf = cast(HaZeroconf, aio_zc.zeroconf)
|
||||||
zeroconf_types = await async_get_zeroconf(hass)
|
zeroconf_types = await async_get_zeroconf(hass)
|
||||||
homekit_models = await async_get_homekit(hass)
|
homekit_models = await async_get_homekit(hass)
|
||||||
|
@ -14,10 +14,11 @@ from typing import TYPE_CHECKING, Any, Self
|
|||||||
import aiohttp
|
import aiohttp
|
||||||
from aiohttp import web
|
from aiohttp import web
|
||||||
from aiohttp.hdrs import CONTENT_TYPE, USER_AGENT
|
from aiohttp.hdrs import CONTENT_TYPE, USER_AGENT
|
||||||
from aiohttp.resolver import AsyncResolver
|
|
||||||
from aiohttp.web_exceptions import HTTPBadGateway, HTTPGatewayTimeout
|
from aiohttp.web_exceptions import HTTPBadGateway, HTTPGatewayTimeout
|
||||||
|
from aiohttp_asyncmdnsresolver.api import AsyncMDNSResolver
|
||||||
|
|
||||||
from homeassistant import config_entries
|
from homeassistant import config_entries
|
||||||
|
from homeassistant.components import zeroconf
|
||||||
from homeassistant.const import APPLICATION_NAME, EVENT_HOMEASSISTANT_CLOSE, __version__
|
from homeassistant.const import APPLICATION_NAME, EVENT_HOMEASSISTANT_CLOSE, __version__
|
||||||
from homeassistant.core import Event, HomeAssistant, callback
|
from homeassistant.core import Event, HomeAssistant, callback
|
||||||
from homeassistant.loader import bind_hass
|
from homeassistant.loader import bind_hass
|
||||||
@ -362,7 +363,7 @@ def _async_get_connector(
|
|||||||
ssl=ssl_context,
|
ssl=ssl_context,
|
||||||
limit=MAXIMUM_CONNECTIONS,
|
limit=MAXIMUM_CONNECTIONS,
|
||||||
limit_per_host=MAXIMUM_CONNECTIONS_PER_HOST,
|
limit_per_host=MAXIMUM_CONNECTIONS_PER_HOST,
|
||||||
resolver=AsyncResolver(),
|
resolver=_async_make_resolver(hass),
|
||||||
)
|
)
|
||||||
connectors[connector_key] = connector
|
connectors[connector_key] = connector
|
||||||
|
|
||||||
@ -373,3 +374,8 @@ def _async_get_connector(
|
|||||||
hass.bus.async_listen_once(EVENT_HOMEASSISTANT_CLOSE, _async_close_connector)
|
hass.bus.async_listen_once(EVENT_HOMEASSISTANT_CLOSE, _async_close_connector)
|
||||||
|
|
||||||
return connector
|
return connector
|
||||||
|
|
||||||
|
|
||||||
|
@callback
|
||||||
|
def _async_make_resolver(hass: HomeAssistant) -> AsyncMDNSResolver:
|
||||||
|
return AsyncMDNSResolver(async_zeroconf=zeroconf.async_get_async_zeroconf(hass))
|
||||||
|
@ -4,6 +4,7 @@ aiodhcpwatcher==1.0.2
|
|||||||
aiodiscover==2.1.0
|
aiodiscover==2.1.0
|
||||||
aiodns==3.2.0
|
aiodns==3.2.0
|
||||||
aiohasupervisor==0.2.2b5
|
aiohasupervisor==0.2.2b5
|
||||||
|
aiohttp-asyncmdnsresolver==0.0.1
|
||||||
aiohttp-fast-zlib==0.2.0
|
aiohttp-fast-zlib==0.2.0
|
||||||
aiohttp==3.11.11
|
aiohttp==3.11.11
|
||||||
aiohttp_cors==0.7.0
|
aiohttp_cors==0.7.0
|
||||||
|
@ -32,6 +32,7 @@ dependencies = [
|
|||||||
"aiohttp==3.11.11",
|
"aiohttp==3.11.11",
|
||||||
"aiohttp_cors==0.7.0",
|
"aiohttp_cors==0.7.0",
|
||||||
"aiohttp-fast-zlib==0.2.0",
|
"aiohttp-fast-zlib==0.2.0",
|
||||||
|
"aiohttp-asyncmdnsresolver==0.0.1",
|
||||||
"aiozoneinfo==0.2.1",
|
"aiozoneinfo==0.2.1",
|
||||||
"astral==2.2",
|
"astral==2.2",
|
||||||
"async-interrupt==1.2.0",
|
"async-interrupt==1.2.0",
|
||||||
@ -82,6 +83,7 @@ dependencies = [
|
|||||||
"voluptuous-openapi==0.0.5",
|
"voluptuous-openapi==0.0.5",
|
||||||
"yarl==1.18.3",
|
"yarl==1.18.3",
|
||||||
"webrtc-models==0.3.0",
|
"webrtc-models==0.3.0",
|
||||||
|
"zeroconf==0.136.2"
|
||||||
]
|
]
|
||||||
|
|
||||||
[project.urls]
|
[project.urls]
|
||||||
|
@ -8,6 +8,7 @@ aiohasupervisor==0.2.2b5
|
|||||||
aiohttp==3.11.11
|
aiohttp==3.11.11
|
||||||
aiohttp_cors==0.7.0
|
aiohttp_cors==0.7.0
|
||||||
aiohttp-fast-zlib==0.2.0
|
aiohttp-fast-zlib==0.2.0
|
||||||
|
aiohttp-asyncmdnsresolver==0.0.1
|
||||||
aiozoneinfo==0.2.1
|
aiozoneinfo==0.2.1
|
||||||
astral==2.2
|
astral==2.2
|
||||||
async-interrupt==1.2.0
|
async-interrupt==1.2.0
|
||||||
@ -50,3 +51,4 @@ voluptuous-serialize==2.6.0
|
|||||||
voluptuous-openapi==0.0.5
|
voluptuous-openapi==0.0.5
|
||||||
yarl==1.18.3
|
yarl==1.18.3
|
||||||
webrtc-models==0.3.0
|
webrtc-models==0.3.0
|
||||||
|
zeroconf==0.136.2
|
||||||
|
@ -20,6 +20,7 @@ from typing import TYPE_CHECKING, Any, cast
|
|||||||
from unittest.mock import AsyncMock, MagicMock, Mock, _patch, patch
|
from unittest.mock import AsyncMock, MagicMock, Mock, _patch, patch
|
||||||
|
|
||||||
from aiohttp import client
|
from aiohttp import client
|
||||||
|
from aiohttp.resolver import AsyncResolver
|
||||||
from aiohttp.test_utils import (
|
from aiohttp.test_utils import (
|
||||||
BaseTestServer,
|
BaseTestServer,
|
||||||
TestClient,
|
TestClient,
|
||||||
@ -1220,6 +1221,30 @@ def disable_translations_once(
|
|||||||
translations_once.start()
|
translations_once.start()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(autouse=True, scope="session")
|
||||||
|
def mock_zeroconf_resolver() -> Generator[_patch]:
|
||||||
|
"""Mock out the zeroconf resolver."""
|
||||||
|
patcher = patch(
|
||||||
|
"homeassistant.helpers.aiohttp_client._async_make_resolver",
|
||||||
|
return_value=AsyncResolver(),
|
||||||
|
)
|
||||||
|
patcher.start()
|
||||||
|
try:
|
||||||
|
yield patcher
|
||||||
|
finally:
|
||||||
|
patcher.stop()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def disable_mock_zeroconf_resolver(
|
||||||
|
mock_zeroconf_resolver: _patch,
|
||||||
|
) -> Generator[None]:
|
||||||
|
"""Disable the zeroconf resolver."""
|
||||||
|
mock_zeroconf_resolver.stop()
|
||||||
|
yield
|
||||||
|
mock_zeroconf_resolver.start()
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def mock_zeroconf() -> Generator[MagicMock]:
|
def mock_zeroconf() -> Generator[MagicMock]:
|
||||||
"""Mock zeroconf."""
|
"""Mock zeroconf."""
|
||||||
|
@ -390,3 +390,16 @@ async def test_client_session_immutable_headers(hass: HomeAssistant) -> None:
|
|||||||
|
|
||||||
with pytest.raises(AttributeError):
|
with pytest.raises(AttributeError):
|
||||||
session.headers.update({"user-agent": "bla"})
|
session.headers.update({"user-agent": "bla"})
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.usefixtures("disable_mock_zeroconf_resolver")
|
||||||
|
@pytest.mark.usefixtures("mock_async_zeroconf")
|
||||||
|
async def test_async_mdnsresolver(
|
||||||
|
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
|
||||||
|
) -> None:
|
||||||
|
"""Test async_mdnsresolver."""
|
||||||
|
resp = aioclient_mock.post("http://localhost/xyz", json={"x": 1})
|
||||||
|
session = client.async_create_clientsession(hass)
|
||||||
|
resp = await session.post("http://localhost/xyz", json={"x": 1})
|
||||||
|
assert resp.status == 200
|
||||||
|
assert await resp.json() == {"x": 1}
|
||||||
|
@ -1392,9 +1392,13 @@ async def test_bootstrap_does_not_preload_stage_1_integrations() -> None:
|
|||||||
assert process.returncode == 0
|
assert process.returncode == 0
|
||||||
decoded_stdout = stdout.decode()
|
decoded_stdout = stdout.decode()
|
||||||
|
|
||||||
|
disallowed_integrations = bootstrap.STAGE_1_INTEGRATIONS.copy()
|
||||||
|
# zeroconf is a top level dep now
|
||||||
|
disallowed_integrations.remove("zeroconf")
|
||||||
|
|
||||||
# Ensure no stage1 integrations have been imported
|
# Ensure no stage1 integrations have been imported
|
||||||
# as a side effect of importing the pre-imports
|
# as a side effect of importing the pre-imports
|
||||||
for integration in bootstrap.STAGE_1_INTEGRATIONS:
|
for integration in disallowed_integrations:
|
||||||
assert f"homeassistant.components.{integration}" not in decoded_stdout
|
assert f"homeassistant.components.{integration}" not in decoded_stdout
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user