Skip to content

Commit

Permalink
Merge f2eacf0 into 7c13f1e
Browse files Browse the repository at this point in the history
  • Loading branch information
JeffLIrion committed Jul 2, 2020
2 parents 7c13f1e + f2eacf0 commit cdf49c7
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 16 deletions.
14 changes: 7 additions & 7 deletions androidtv/adb_manager/adb_manager_async.py
Expand Up @@ -21,37 +21,37 @@
_LOGGER = logging.getLogger(__name__)


class DeviceAsync: # pragma: no cover
class DeviceAsync:
"""A fake ``DeviceAsync`` class."""
def __init__(self, device):
self._device = device

async def pull(self, device_path, local_path):
"""Download a file."""
return self._device.pull(device_path, local_path)
return await asyncio.get_running_loop().run_in_executor(None, self._device.pull, device_path, local_path)

async def push(self, local_path, device_path):
"""Upload a file."""
return self._device.push(local_path, device_path)
return await asyncio.get_running_loop().run_in_executor(None, self._device.push, local_path, device_path)

async def screencap(self):
"""Take a screencap."""
return self._device.screencap()
return await asyncio.get_running_loop().run_in_executor(None, self._device.screencap)

async def shell(self, cmd):
"""Send a shell command."""
return self._device.shell(cmd)
return await asyncio.get_running_loop().run_in_executor(None, self._device.shell, cmd)


# pylint: disable=too-few-public-methods
class ClientAsync: # pragma: no cover
class ClientAsync:
"""A fake ``ClientAsync`` class."""
def __init__(self, host, port):
self._client = Client(host, port)

async def device(self, serial):
"""Get a fake ``DeviceAsync`` instance."""
return DeviceAsync(self._client.device(serial))
return DeviceAsync(await asyncio.get_running_loop().run_in_executor(None, self._client.device, serial))


@asynccontextmanager
Expand Down
2 changes: 2 additions & 0 deletions tests/async_patchers.py
Expand Up @@ -144,6 +144,8 @@ async def shell_fail_server(self, cmd):

PATCH_ADB_DEVICE_TCP = patch("androidtv.adb_manager.adb_manager_async.AdbDeviceTcpAsync", AdbDeviceTcpAsyncFake)

PATCH_ADB_SERVER_RUNTIME_ERROR = async_patch("{}.{}.device".format(__name__, CLIENT_ASYNC_FAKE_SUCCESS), side_effect=RuntimeError)


class CustomException(Exception):
"""A custom exception type."""
Expand Down
24 changes: 17 additions & 7 deletions tests/patchers.py
Expand Up @@ -8,6 +8,14 @@
from mock import patch


KEY_PYTHON = "python"
KEY_SERVER = "server"

ADB_DEVICE_TCP_FAKE = "AdbDeviceTcpFake"
CLIENT_FAKE_SUCCESS = "ClientFakeSuccess"
CLIENT_FAKE_FAIL = "ClientFakeFail"
DEVICE_FAKE = "DeviceFake"

class AdbDeviceTcpFake(object):
"""A fake of the `adb_shell.adb_device.AdbDeviceTcp` class."""

Expand Down Expand Up @@ -94,8 +102,8 @@ def connect_fail_python(self, *args, **kwargs):
raise OSError

if success:
return {"python": patch("{}.AdbDeviceTcpFake.connect".format(__name__), connect_success_python), "server": patch("androidtv.adb_manager.adb_manager_sync.Client", ClientFakeSuccess)}
return {"python": patch("{}.AdbDeviceTcpFake.connect".format(__name__), connect_fail_python), "server": patch("androidtv.adb_manager.adb_manager_sync.Client", ClientFakeFail)}
return {KEY_PYTHON: patch("{}.{}.connect".format(__name__, ADB_DEVICE_TCP_FAKE), connect_success_python), KEY_SERVER: patch("androidtv.adb_manager.adb_manager_sync.Client", ClientFakeSuccess)}
return {KEY_PYTHON: patch("{}.{}.connect".format(__name__, ADB_DEVICE_TCP_FAKE), connect_fail_python), KEY_SERVER: patch("androidtv.adb_manager.adb_manager_sync.Client", ClientFakeFail)}


def patch_shell(response=None, error=False):
Expand All @@ -117,19 +125,21 @@ def shell_fail_server(self, cmd):
raise ConnectionResetError

if not error:
return {"python": patch("{}.AdbDeviceTcpFake.shell".format(__name__), shell_success), "server": patch("{}.DeviceFake.shell".format(__name__), shell_success)}
return {"python": patch("{}.AdbDeviceTcpFake.shell".format(__name__), shell_fail_python), "server": patch("{}.DeviceFake.shell".format(__name__), shell_fail_server)}
return {KEY_PYTHON: patch("{}.{}.shell".format(__name__, ADB_DEVICE_TCP_FAKE), shell_success), KEY_SERVER: patch("{}.{}.shell".format(__name__, DEVICE_FAKE), shell_success)}
return {KEY_PYTHON: patch("{}.{}.shell".format(__name__, ADB_DEVICE_TCP_FAKE), shell_fail_python), KEY_SERVER: patch("{}.{}.shell".format(__name__, DEVICE_FAKE), shell_fail_server)}


PATCH_PUSH = {"python": patch("{}.AdbDeviceTcpFake.push".format(__name__)), "server": patch("{}.DeviceFake.push".format(__name__))}
PATCH_PUSH = {KEY_PYTHON: patch("{}.{}.push".format(__name__, ADB_DEVICE_TCP_FAKE)), KEY_SERVER: patch("{}.{}.push".format(__name__, DEVICE_FAKE))}

PATCH_PULL = {"python": patch("{}.AdbDeviceTcpFake.pull".format(__name__)), "server": patch("{}.DeviceFake.pull".format(__name__))}
PATCH_PULL = {KEY_PYTHON: patch("{}.{}.pull".format(__name__, ADB_DEVICE_TCP_FAKE)), KEY_SERVER: patch("{}.{}.pull".format(__name__, DEVICE_FAKE))}

PATCH_ADB_DEVICE_TCP = patch("androidtv.adb_manager.adb_manager_sync.AdbDeviceTcp", AdbDeviceTcpFake)

PATCH_ADB_SERVER_RUNTIME_ERROR = patch("{}.{}.device".format(__name__, CLIENT_FAKE_SUCCESS), side_effect=RuntimeError)


class CustomException(Exception):
"""A custom exception type."""


PATCH_CONNECT_FAIL_CUSTOM_EXCEPTION = {"python": patch("{}.AdbDeviceTcpFake.connect".format(__name__), side_effect=CustomException), "server": patch("{}.ClientFakeSuccess.device".format(__name__), side_effect=CustomException)}
PATCH_CONNECT_FAIL_CUSTOM_EXCEPTION = {KEY_PYTHON: patch("{}.{}.connect".format(__name__, ADB_DEVICE_TCP_FAKE), side_effect=CustomException), KEY_SERVER: patch("{}.{}.device".format(__name__, CLIENT_FAKE_SUCCESS), side_effect=CustomException)}
2 changes: 1 addition & 1 deletion tests/test_adb_manager_async.py
Expand Up @@ -334,7 +334,7 @@ async def test_connect_fail_server(self):
with async_patchers.patch_connect(True)[self.PATCH_KEY]:
self.assertTrue(await self.adb.connect())

with async_patchers.async_patch('{}.async_patchers.ClientAsyncFakeSuccess.device'.format(__name__), side_effect=RuntimeError):
with async_patchers.PATCH_ADB_SERVER_RUNTIME_ERROR:
self.assertFalse(await self.adb.connect())
self.assertFalse(self.adb.available)
self.assertFalse(self.adb._available)
Expand Down
37 changes: 37 additions & 0 deletions tests/test_adb_manager_async_temp.py
@@ -0,0 +1,37 @@
import sys
import unittest
from unittest.mock import patch

sys.path.insert(0, '..')

from androidtv.adb_manager.adb_manager_async import ClientAsync

from .async_wrapper import awaiter
from . import patchers


class TestAsyncClientDevice(unittest.TestCase):
"""Test the ``ClientAsync`` and ``DeviceAsync`` classes defined in ``adb_manager_async.py``.
This file can be removed once true async support for using an ADB server is available.
"""

@awaiter
async def test_async_client_device(self):
with patch("androidtv.adb_manager.adb_manager_async.Client", patchers.ClientFakeSuccess):
client = ClientAsync("host", "port")

device = await client.device("serial")

with patch("{}.DeviceFake.shell".format(patchers.__name__)):
await device.shell("test")

with patch("{}.DeviceFake.push".format(patchers.__name__)):
await device.push("local_path", "device_path")

with patch("{}.DeviceFake.pull".format(patchers.__name__)):
await device.pull("device_path", "local_path")

with patch("{}.DeviceFake.screencap".format(patchers.__name__)):
await device.screencap()
2 changes: 1 addition & 1 deletion tests/test_adb_manager_sync.py
Expand Up @@ -305,7 +305,7 @@ def test_connect_fail_server(self):
with patchers.patch_connect(True)[self.PATCH_KEY]:
self.assertTrue(self.adb.connect())

with patch('{}.patchers.ClientFakeSuccess.device'.format(__name__), side_effect=RuntimeError):
with patchers.PATCH_ADB_SERVER_RUNTIME_ERROR:
self.assertFalse(self.adb.connect())
self.assertFalse(self.adb.available)
self.assertFalse(self.adb._available)
Expand Down

0 comments on commit cdf49c7

Please sign in to comment.