mirror of
https://github.com/home-assistant/core.git
synced 2025-07-24 21:57:51 +00:00
Bump adb-shell to 0.1.0 and androidtv to 0.0.36 (#29938)
* Bump adb-shell to 0.1.0 and androidtv to 0.0.36 * Add test for setting up two devices * Add test_setup_same_device_twice * Fix test_setup_two_devices * Fix coverage * Coverage * Fix flaky 'test_setup_two_devices' * Another stab at coverage * Rename 'address' back to 'host'
This commit is contained in:
parent
a28545b69b
commit
8a5bce81c8
@ -3,8 +3,8 @@
|
|||||||
"name": "Androidtv",
|
"name": "Androidtv",
|
||||||
"documentation": "https://www.home-assistant.io/integrations/androidtv",
|
"documentation": "https://www.home-assistant.io/integrations/androidtv",
|
||||||
"requirements": [
|
"requirements": [
|
||||||
"adb-shell==0.0.9",
|
"adb-shell==0.1.0",
|
||||||
"androidtv==0.0.35",
|
"androidtv==0.0.36",
|
||||||
"pure-python-adb==0.2.2.dev0"
|
"pure-python-adb==0.2.2.dev0"
|
||||||
],
|
],
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
|
@ -146,7 +146,8 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
|
|||||||
adb_log = f"using Python ADB implementation with adbkey='{adbkey}'"
|
adb_log = f"using Python ADB implementation with adbkey='{adbkey}'"
|
||||||
|
|
||||||
aftv = setup(
|
aftv = setup(
|
||||||
host,
|
config[CONF_HOST],
|
||||||
|
config[CONF_PORT],
|
||||||
adbkey,
|
adbkey,
|
||||||
device_class=config[CONF_DEVICE_CLASS],
|
device_class=config[CONF_DEVICE_CLASS],
|
||||||
state_detection_rules=config[CONF_STATE_DETECTION_RULES],
|
state_detection_rules=config[CONF_STATE_DETECTION_RULES],
|
||||||
@ -159,7 +160,8 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
|
|||||||
)
|
)
|
||||||
|
|
||||||
aftv = setup(
|
aftv = setup(
|
||||||
host,
|
config[CONF_HOST],
|
||||||
|
config[CONF_PORT],
|
||||||
config[CONF_ADBKEY],
|
config[CONF_ADBKEY],
|
||||||
device_class=config[CONF_DEVICE_CLASS],
|
device_class=config[CONF_DEVICE_CLASS],
|
||||||
state_detection_rules=config[CONF_STATE_DETECTION_RULES],
|
state_detection_rules=config[CONF_STATE_DETECTION_RULES],
|
||||||
@ -171,7 +173,8 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
|
|||||||
adb_log = f"using ADB server at {config[CONF_ADB_SERVER_IP]}:{config[CONF_ADB_SERVER_PORT]}"
|
adb_log = f"using ADB server at {config[CONF_ADB_SERVER_IP]}:{config[CONF_ADB_SERVER_PORT]}"
|
||||||
|
|
||||||
aftv = setup(
|
aftv = setup(
|
||||||
host,
|
config[CONF_HOST],
|
||||||
|
config[CONF_PORT],
|
||||||
adb_server_ip=config[CONF_ADB_SERVER_IP],
|
adb_server_ip=config[CONF_ADB_SERVER_IP],
|
||||||
adb_server_port=config[CONF_ADB_SERVER_PORT],
|
adb_server_port=config[CONF_ADB_SERVER_PORT],
|
||||||
device_class=config[CONF_DEVICE_CLASS],
|
device_class=config[CONF_DEVICE_CLASS],
|
||||||
|
@ -115,7 +115,7 @@ adafruit-blinka==1.2.1
|
|||||||
adafruit-circuitpython-mcp230xx==1.1.2
|
adafruit-circuitpython-mcp230xx==1.1.2
|
||||||
|
|
||||||
# homeassistant.components.androidtv
|
# homeassistant.components.androidtv
|
||||||
adb-shell==0.0.9
|
adb-shell==0.1.0
|
||||||
|
|
||||||
# homeassistant.components.adguard
|
# homeassistant.components.adguard
|
||||||
adguardhome==0.3.0
|
adguardhome==0.3.0
|
||||||
@ -215,7 +215,7 @@ ambiclimate==0.2.1
|
|||||||
amcrest==1.5.3
|
amcrest==1.5.3
|
||||||
|
|
||||||
# homeassistant.components.androidtv
|
# homeassistant.components.androidtv
|
||||||
androidtv==0.0.35
|
androidtv==0.0.36
|
||||||
|
|
||||||
# homeassistant.components.anel_pwrctrl
|
# homeassistant.components.anel_pwrctrl
|
||||||
anel_pwrctrl-homeassistant==0.0.1.dev2
|
anel_pwrctrl-homeassistant==0.0.1.dev2
|
||||||
|
@ -29,7 +29,7 @@ YesssSMS==0.4.1
|
|||||||
abodepy==0.16.7
|
abodepy==0.16.7
|
||||||
|
|
||||||
# homeassistant.components.androidtv
|
# homeassistant.components.androidtv
|
||||||
adb-shell==0.0.9
|
adb-shell==0.1.0
|
||||||
|
|
||||||
# homeassistant.components.adguard
|
# homeassistant.components.adguard
|
||||||
adguardhome==0.3.0
|
adguardhome==0.3.0
|
||||||
@ -84,7 +84,7 @@ airly==0.0.2
|
|||||||
ambiclimate==0.2.1
|
ambiclimate==0.2.1
|
||||||
|
|
||||||
# homeassistant.components.androidtv
|
# homeassistant.components.androidtv
|
||||||
androidtv==0.0.35
|
androidtv==0.0.36
|
||||||
|
|
||||||
# homeassistant.components.apns
|
# homeassistant.components.apns
|
||||||
apns2==0.3.0
|
apns2==0.3.0
|
||||||
|
@ -3,11 +3,11 @@
|
|||||||
from unittest.mock import mock_open, patch
|
from unittest.mock import mock_open, patch
|
||||||
|
|
||||||
|
|
||||||
class AdbDeviceFake:
|
class AdbDeviceTcpFake:
|
||||||
"""A fake of the `adb_shell.adb_device.AdbDevice` class."""
|
"""A fake of the `adb_shell.adb_device.AdbDeviceTcp` class."""
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
"""Initialize a fake `adb_shell.adb_device.AdbDevice` instance."""
|
"""Initialize a fake `adb_shell.adb_device.AdbDeviceTcp` instance."""
|
||||||
self.available = False
|
self.available = False
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
@ -74,39 +74,39 @@ class DeviceFake:
|
|||||||
|
|
||||||
|
|
||||||
def patch_connect(success):
|
def patch_connect(success):
|
||||||
"""Mock the `adb_shell.adb_device.AdbDevice` and `ppadb.client.Client` classes."""
|
"""Mock the `adb_shell.adb_device.AdbDeviceTcp` and `ppadb.client.Client` classes."""
|
||||||
|
|
||||||
def connect_success_python(self, *args, **kwargs):
|
def connect_success_python(self, *args, **kwargs):
|
||||||
"""Mock the `AdbDeviceFake.connect` method when it succeeds."""
|
"""Mock the `AdbDeviceTcpFake.connect` method when it succeeds."""
|
||||||
self.available = True
|
self.available = True
|
||||||
|
|
||||||
def connect_fail_python(self, *args, **kwargs):
|
def connect_fail_python(self, *args, **kwargs):
|
||||||
"""Mock the `AdbDeviceFake.connect` method when it fails."""
|
"""Mock the `AdbDeviceTcpFake.connect` method when it fails."""
|
||||||
raise OSError
|
raise OSError
|
||||||
|
|
||||||
if success:
|
if success:
|
||||||
return {
|
return {
|
||||||
"python": patch(
|
"python": patch(
|
||||||
f"{__name__}.AdbDeviceFake.connect", connect_success_python
|
f"{__name__}.AdbDeviceTcpFake.connect", connect_success_python
|
||||||
),
|
),
|
||||||
"server": patch("androidtv.adb_manager.Client", ClientFakeSuccess),
|
"server": patch("androidtv.adb_manager.Client", ClientFakeSuccess),
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
"python": patch(f"{__name__}.AdbDeviceFake.connect", connect_fail_python),
|
"python": patch(f"{__name__}.AdbDeviceTcpFake.connect", connect_fail_python),
|
||||||
"server": patch("androidtv.adb_manager.Client", ClientFakeFail),
|
"server": patch("androidtv.adb_manager.Client", ClientFakeFail),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def patch_shell(response=None, error=False):
|
def patch_shell(response=None, error=False):
|
||||||
"""Mock the `AdbDeviceFake.shell` and `DeviceFake.shell` methods."""
|
"""Mock the `AdbDeviceTcpFake.shell` and `DeviceFake.shell` methods."""
|
||||||
|
|
||||||
def shell_success(self, cmd):
|
def shell_success(self, cmd):
|
||||||
"""Mock the `AdbDeviceFake.shell` and `DeviceFake.shell` methods when they are successful."""
|
"""Mock the `AdbDeviceTcpFake.shell` and `DeviceFake.shell` methods when they are successful."""
|
||||||
self.shell_cmd = cmd
|
self.shell_cmd = cmd
|
||||||
return response
|
return response
|
||||||
|
|
||||||
def shell_fail_python(self, cmd):
|
def shell_fail_python(self, cmd):
|
||||||
"""Mock the `AdbDeviceFake.shell` method when it fails."""
|
"""Mock the `AdbDeviceTcpFake.shell` method when it fails."""
|
||||||
self.shell_cmd = cmd
|
self.shell_cmd = cmd
|
||||||
raise AttributeError
|
raise AttributeError
|
||||||
|
|
||||||
@ -117,16 +117,16 @@ def patch_shell(response=None, error=False):
|
|||||||
|
|
||||||
if not error:
|
if not error:
|
||||||
return {
|
return {
|
||||||
"python": patch(f"{__name__}.AdbDeviceFake.shell", shell_success),
|
"python": patch(f"{__name__}.AdbDeviceTcpFake.shell", shell_success),
|
||||||
"server": patch(f"{__name__}.DeviceFake.shell", shell_success),
|
"server": patch(f"{__name__}.DeviceFake.shell", shell_success),
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
"python": patch(f"{__name__}.AdbDeviceFake.shell", shell_fail_python),
|
"python": patch(f"{__name__}.AdbDeviceTcpFake.shell", shell_fail_python),
|
||||||
"server": patch(f"{__name__}.DeviceFake.shell", shell_fail_server),
|
"server": patch(f"{__name__}.DeviceFake.shell", shell_fail_server),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PATCH_ADB_DEVICE = patch("androidtv.adb_manager.AdbDevice", AdbDeviceFake)
|
PATCH_ADB_DEVICE_TCP = patch("androidtv.adb_manager.AdbDeviceTcp", AdbDeviceTcpFake)
|
||||||
PATCH_ANDROIDTV_OPEN = patch("androidtv.adb_manager.open", mock_open())
|
PATCH_ANDROIDTV_OPEN = patch("androidtv.adb_manager.open", mock_open())
|
||||||
PATCH_KEYGEN = patch("homeassistant.components.androidtv.media_player.keygen")
|
PATCH_KEYGEN = patch("homeassistant.components.androidtv.media_player.keygen")
|
||||||
PATCH_SIGNER = patch("androidtv.adb_manager.PythonRSASigner")
|
PATCH_SIGNER = patch("androidtv.adb_manager.PythonRSASigner")
|
||||||
|
@ -95,7 +95,7 @@ async def _test_reconnect(hass, caplog, config):
|
|||||||
"""
|
"""
|
||||||
patch_key, entity_id = _setup(hass, config)
|
patch_key, entity_id = _setup(hass, config)
|
||||||
|
|
||||||
with patchers.PATCH_ADB_DEVICE, patchers.patch_connect(True)[
|
with patchers.PATCH_ADB_DEVICE_TCP, patchers.patch_connect(True)[
|
||||||
patch_key
|
patch_key
|
||||||
], patchers.patch_shell("")[
|
], patchers.patch_shell("")[
|
||||||
patch_key
|
patch_key
|
||||||
@ -166,7 +166,7 @@ async def _test_adb_shell_returns_none(hass, config):
|
|||||||
"""
|
"""
|
||||||
patch_key, entity_id = _setup(hass, config)
|
patch_key, entity_id = _setup(hass, config)
|
||||||
|
|
||||||
with patchers.PATCH_ADB_DEVICE, patchers.patch_connect(True)[
|
with patchers.PATCH_ADB_DEVICE_TCP, patchers.patch_connect(True)[
|
||||||
patch_key
|
patch_key
|
||||||
], patchers.patch_shell("")[
|
], patchers.patch_shell("")[
|
||||||
patch_key
|
patch_key
|
||||||
@ -274,7 +274,7 @@ async def test_setup_with_adbkey(hass):
|
|||||||
config[DOMAIN][CONF_ADBKEY] = hass.config.path("user_provided_adbkey")
|
config[DOMAIN][CONF_ADBKEY] = hass.config.path("user_provided_adbkey")
|
||||||
patch_key, entity_id = _setup(hass, config)
|
patch_key, entity_id = _setup(hass, config)
|
||||||
|
|
||||||
with patchers.PATCH_ADB_DEVICE, patchers.patch_connect(True)[
|
with patchers.PATCH_ADB_DEVICE_TCP, patchers.patch_connect(True)[
|
||||||
patch_key
|
patch_key
|
||||||
], patchers.patch_shell("")[
|
], patchers.patch_shell("")[
|
||||||
patch_key
|
patch_key
|
||||||
@ -292,7 +292,7 @@ async def _test_sources(hass, config0):
|
|||||||
config[DOMAIN][CONF_APPS] = {"com.app.test1": "TEST 1"}
|
config[DOMAIN][CONF_APPS] = {"com.app.test1": "TEST 1"}
|
||||||
patch_key, entity_id = _setup(hass, config)
|
patch_key, entity_id = _setup(hass, config)
|
||||||
|
|
||||||
with patchers.PATCH_ADB_DEVICE, patchers.patch_connect(True)[
|
with patchers.PATCH_ADB_DEVICE_TCP, patchers.patch_connect(True)[
|
||||||
patch_key
|
patch_key
|
||||||
], patchers.patch_shell("")[patch_key]:
|
], patchers.patch_shell("")[patch_key]:
|
||||||
assert await async_setup_component(hass, DOMAIN, config)
|
assert await async_setup_component(hass, DOMAIN, config)
|
||||||
@ -364,7 +364,7 @@ async def _test_select_source(hass, config0, source, expected_arg, method_patch)
|
|||||||
config[DOMAIN][CONF_APPS] = {"com.app.test1": "TEST 1"}
|
config[DOMAIN][CONF_APPS] = {"com.app.test1": "TEST 1"}
|
||||||
patch_key, entity_id = _setup(hass, config)
|
patch_key, entity_id = _setup(hass, config)
|
||||||
|
|
||||||
with patchers.PATCH_ADB_DEVICE, patchers.patch_connect(True)[
|
with patchers.PATCH_ADB_DEVICE_TCP, patchers.patch_connect(True)[
|
||||||
patch_key
|
patch_key
|
||||||
], patchers.patch_shell("")[patch_key]:
|
], patchers.patch_shell("")[patch_key]:
|
||||||
assert await async_setup_component(hass, DOMAIN, config)
|
assert await async_setup_component(hass, DOMAIN, config)
|
||||||
@ -515,3 +515,68 @@ async def test_firetv_select_source_stop_app_id_no_name(hass):
|
|||||||
"com.app.test2",
|
"com.app.test2",
|
||||||
patchers.PATCH_STOP_APP,
|
patchers.PATCH_STOP_APP,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def _test_setup_fail(hass, config):
|
||||||
|
"""Test that the entity is not created when the ADB connection is not established."""
|
||||||
|
patch_key, entity_id = _setup(hass, config)
|
||||||
|
|
||||||
|
with patchers.PATCH_ADB_DEVICE_TCP, patchers.patch_connect(False)[
|
||||||
|
patch_key
|
||||||
|
], patchers.patch_shell("")[
|
||||||
|
patch_key
|
||||||
|
], patchers.PATCH_KEYGEN, patchers.PATCH_ANDROIDTV_OPEN, patchers.PATCH_SIGNER:
|
||||||
|
assert await async_setup_component(hass, DOMAIN, config)
|
||||||
|
await hass.helpers.entity_component.async_update_entity(entity_id)
|
||||||
|
state = hass.states.get(entity_id)
|
||||||
|
assert state is None
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
async def test_setup_fail_androidtv(hass):
|
||||||
|
"""Test that the Android TV entity is not created when the ADB connection is not established."""
|
||||||
|
assert await _test_setup_fail(hass, CONFIG_ANDROIDTV_PYTHON_ADB)
|
||||||
|
|
||||||
|
|
||||||
|
async def test_setup_fail_firetv(hass):
|
||||||
|
"""Test that the Fire TV entity is not created when the ADB connection is not established."""
|
||||||
|
assert await _test_setup_fail(hass, CONFIG_FIRETV_PYTHON_ADB)
|
||||||
|
|
||||||
|
|
||||||
|
async def test_setup_two_devices(hass):
|
||||||
|
"""Test that two devices can be set up."""
|
||||||
|
config = {
|
||||||
|
DOMAIN: [
|
||||||
|
CONFIG_ANDROIDTV_ADB_SERVER[DOMAIN],
|
||||||
|
CONFIG_FIRETV_ADB_SERVER[DOMAIN].copy(),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
config[DOMAIN][1][CONF_HOST] = "127.0.0.2"
|
||||||
|
|
||||||
|
patch_key = "server"
|
||||||
|
with patchers.PATCH_ADB_DEVICE_TCP, patchers.patch_connect(True)[
|
||||||
|
patch_key
|
||||||
|
], patchers.patch_shell("")[patch_key]:
|
||||||
|
assert await async_setup_component(hass, DOMAIN, config)
|
||||||
|
|
||||||
|
for entity_id in ["media_player.android_tv", "media_player.fire_tv"]:
|
||||||
|
await hass.helpers.entity_component.async_update_entity(entity_id)
|
||||||
|
state = hass.states.get(entity_id)
|
||||||
|
assert state is not None
|
||||||
|
assert state.state == STATE_OFF
|
||||||
|
|
||||||
|
|
||||||
|
async def test_setup_same_device_twice(hass):
|
||||||
|
"""Test that setup succeeds with a duplicated config entry."""
|
||||||
|
patch_key = "server"
|
||||||
|
|
||||||
|
with patchers.PATCH_ADB_DEVICE_TCP, patchers.patch_connect(True)[
|
||||||
|
patch_key
|
||||||
|
], patchers.patch_shell("")[patch_key]:
|
||||||
|
assert await async_setup_component(hass, DOMAIN, CONFIG_ANDROIDTV_ADB_SERVER)
|
||||||
|
|
||||||
|
with patchers.PATCH_ADB_DEVICE_TCP, patchers.patch_connect(True)[
|
||||||
|
patch_key
|
||||||
|
], patchers.patch_shell("")[patch_key]:
|
||||||
|
assert await async_setup_component(hass, DOMAIN, CONFIG_ANDROIDTV_ADB_SERVER)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user