mirror of
https://github.com/esphome/aioesphomeapi.git
synced 2024-11-29 13:15:10 +01:00
153 lines
4.9 KiB
Python
153 lines
4.9 KiB
Python
import asyncio
|
|
import socket
|
|
|
|
import pytest
|
|
from mock import AsyncMock, MagicMock, patch
|
|
|
|
import aioesphomeapi.host_resolver as hr
|
|
from aioesphomeapi.core import APIConnectionError
|
|
|
|
|
|
@pytest.fixture
|
|
def async_zeroconf():
|
|
with patch("zeroconf.asyncio.AsyncZeroconf") as klass:
|
|
yield klass.return_value
|
|
|
|
|
|
@pytest.fixture
|
|
def addr_infos():
|
|
return [
|
|
hr.AddrInfo(
|
|
family=socket.AF_INET,
|
|
type=socket.SOCK_STREAM,
|
|
proto=socket.IPPROTO_TCP,
|
|
sockaddr=hr.IPv4Sockaddr(address="10.0.0.42", port=6052),
|
|
),
|
|
hr.AddrInfo(
|
|
family=socket.AF_INET6,
|
|
type=socket.SOCK_STREAM,
|
|
proto=socket.IPPROTO_TCP,
|
|
sockaddr=hr.IPv6Sockaddr(
|
|
address="2001:db8:85a3::8a2e:370:7334",
|
|
port=6052,
|
|
flowinfo=0,
|
|
scope_id=0,
|
|
),
|
|
),
|
|
]
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_resolve_host_zeroconf(async_zeroconf, addr_infos):
|
|
info = MagicMock()
|
|
info.addresses_by_version.return_value = [
|
|
b"\n\x00\x00*",
|
|
b" \x01\r\xb8\x85\xa3\x00\x00\x00\x00\x8a.\x03ps4",
|
|
]
|
|
async_zeroconf.async_get_service_info = AsyncMock(return_value=info)
|
|
async_zeroconf.async_close = AsyncMock()
|
|
loop = asyncio.get_event_loop()
|
|
|
|
ret = await hr._async_resolve_host_zeroconf(loop, "asdf", 6052)
|
|
|
|
async_zeroconf.async_get_service_info.assert_called_once_with(
|
|
"_esphomelib._tcp.local.", "asdf._esphomelib._tcp.local.", 3000
|
|
)
|
|
async_zeroconf.async_close.assert_called_once_with()
|
|
|
|
assert ret == addr_infos
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_resolve_host_zeroconf_empty(async_zeroconf):
|
|
async_zeroconf.async_get_service_info = AsyncMock(return_value=None)
|
|
async_zeroconf.async_close = AsyncMock()
|
|
loop = asyncio.get_event_loop()
|
|
|
|
ret = await hr._async_resolve_host_zeroconf(loop, "asdf.local", 6052)
|
|
assert ret == []
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_resolve_host_getaddrinfo(addr_infos):
|
|
eventloop = AsyncMock()
|
|
eventloop.getaddrinfo.return_value = [
|
|
(
|
|
socket.AF_INET,
|
|
socket.SOCK_STREAM,
|
|
socket.IPPROTO_TCP,
|
|
"canon1",
|
|
("10.0.0.42", 6052),
|
|
),
|
|
(
|
|
socket.AF_INET6,
|
|
socket.SOCK_STREAM,
|
|
socket.IPPROTO_TCP,
|
|
"canon2",
|
|
("2001:db8:85a3::8a2e:370:7334", 6052, 0, 0),
|
|
),
|
|
(-1, socket.SOCK_STREAM, socket.IPPROTO_TCP, "canon3", ("10.0.0.42", 6052)),
|
|
]
|
|
ret = await hr._async_resolve_host_getaddrinfo(eventloop, "example.com", 6052)
|
|
|
|
assert ret == addr_infos
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_resolve_host_getaddrinfo_oserror():
|
|
eventloop = AsyncMock()
|
|
eventloop.getaddrinfo.side_effect = OSError()
|
|
with pytest.raises(APIConnectionError):
|
|
await hr._async_resolve_host_getaddrinfo(eventloop, "example.com", 6052)
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
@patch("aioesphomeapi.host_resolver._async_resolve_host_zeroconf")
|
|
@patch("aioesphomeapi.host_resolver._async_resolve_host_getaddrinfo")
|
|
async def test_resolve_host_mdns(resolve_addr, resolve_zc, addr_infos):
|
|
resolve_zc.return_value = addr_infos
|
|
loop = asyncio.get_event_loop()
|
|
ret = await hr.async_resolve_host(loop, "example.local", 6052)
|
|
|
|
resolve_zc.assert_called_once_with(loop, "example", 6052, zeroconf_instance=None)
|
|
resolve_addr.assert_not_called()
|
|
assert ret == addr_infos[0]
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
@patch("aioesphomeapi.host_resolver._async_resolve_host_zeroconf")
|
|
@patch("aioesphomeapi.host_resolver._async_resolve_host_getaddrinfo")
|
|
async def test_resolve_host_mdns_empty(resolve_addr, resolve_zc, addr_infos):
|
|
resolve_zc.return_value = []
|
|
resolve_addr.return_value = addr_infos
|
|
loop = asyncio.get_event_loop()
|
|
ret = await hr.async_resolve_host(loop, "example.local", 6052)
|
|
|
|
resolve_zc.assert_called_once_with(loop, "example", 6052, zeroconf_instance=None)
|
|
resolve_addr.assert_called_once_with(loop, "example.local", 6052)
|
|
assert ret == addr_infos[0]
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
@patch("aioesphomeapi.host_resolver._async_resolve_host_zeroconf")
|
|
@patch("aioesphomeapi.host_resolver._async_resolve_host_getaddrinfo")
|
|
async def test_resolve_host_addrinfo(resolve_addr, resolve_zc, addr_infos):
|
|
resolve_addr.return_value = addr_infos
|
|
ret = await hr.async_resolve_host(None, "example.com", 6052)
|
|
|
|
resolve_zc.assert_not_called()
|
|
resolve_addr.assert_called_once_with(None, "example.com", 6052)
|
|
assert ret == addr_infos[0]
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
@patch("aioesphomeapi.host_resolver._async_resolve_host_zeroconf")
|
|
@patch("aioesphomeapi.host_resolver._async_resolve_host_getaddrinfo")
|
|
async def test_resolve_host_addrinfo_empty(resolve_addr, resolve_zc, addr_infos):
|
|
resolve_addr.return_value = []
|
|
with pytest.raises(APIConnectionError):
|
|
await hr.async_resolve_host(None, "example.com", 6052)
|
|
|
|
resolve_zc.assert_not_called()
|
|
resolve_addr.assert_called_once_with(None, "example.com", 6052)
|