Skip to content

Commit

Permalink
Merge 51a383c into 1acd752
Browse files Browse the repository at this point in the history
  • Loading branch information
JeffLIrion committed May 8, 2020
2 parents 1acd752 + 51a383c commit 6ee8c8a
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 11 deletions.
5 changes: 2 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
language: python
python:
- "2.7"
- "3.6"
- "3.7"
- "3.8"
install:
- pip install .
- pip install flake8 pylint coveralls
- python --version 2>&1 | grep -q "Python 2" && pip install mock || true
script:
- flake8 androidtv/ && pylint androidtv/ && coverage run --source androidtv setup.py test
after_success:
Expand Down
27 changes: 26 additions & 1 deletion androidtv/adb_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
"""


from contextlib import contextmanager
import asyncio
from contextlib import asynccontextmanager, contextmanager
import logging
import sys
import threading
Expand All @@ -26,6 +27,9 @@
if sys.version_info[0] == 2: # pragma: no cover
FileNotFoundError = IOError # pylint: disable=redefined-builtin

#: Default timeout for acquiring the async lock that protects ADB commands
DEFAULT_TIMEOUT = 3.0


@contextmanager
def _acquire(lock):
Expand Down Expand Up @@ -58,6 +62,27 @@ def _acquire(lock):
lock.release()


@asynccontextmanager
async def _aacquire(lock, timeout=DEFAULT_TIMEOUT):
"""TODO
"""
try:
acquired = False
try:
acquired = await asyncio.wait_for(lock.acquire(), timeout)
if not acquired:
raise LockNotAcquiredException
yield acquired

except asyncio.TimeoutError:
raise LockNotAcquiredException

finally:
if acquired:
lock.release()


class ADBPython(object):
"""A manager for ADB connections that uses a Python implementation of the ADB protocol.
Expand Down
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@
author='Jeff Irion',
author_email='jefflirion@users.noreply.github.com',
packages=['androidtv'],
install_requires=['adb-shell>=0.1.3', 'pure-python-adb>=0.2.2.dev0'],
install_requires=['adb-shell>=0.1.3', 'pure-python-adb>=0.2.2.dev0', 'aio-adb-shell'],
python_requires='>=3.6',
classifiers=[
'License :: OSI Approved :: MIT License',
'Operating System :: OS Independent',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 2',
],
test_suite='tests'
)
12 changes: 12 additions & 0 deletions tests/async_wrapper.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import asyncio


def _await(coro):
return asyncio.get_event_loop().run_until_complete(coro)


def awaiter(func):
def sync_func(*args, **kwargs):
return _await(func(*args, **kwargs))

return sync_func
57 changes: 52 additions & 5 deletions tests/test_adb_manager.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import asyncio
from contextlib import contextmanager
import sys
import unittest
Expand All @@ -9,13 +10,10 @@

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

from androidtv.adb_manager import _acquire, ADBPython, ADBServer
from androidtv.adb_manager import _acquire, _aacquire, ADBPython, ADBServer
from androidtv.exceptions import LockNotAcquiredException
from . import patchers


if sys.version_info[0] == 2:
FileNotFoundError = IOError
from .async_wrapper import awaiter


class Read(object):
Expand Down Expand Up @@ -73,6 +71,55 @@ def __init__(self, *args, **kwargs):
self._acquired = False


class AsyncFakeLock:
def __init__(self):
self._acquired = True

async def acquire(self):
if self._acquired:
self._acquired = False
return True
return self._acquired

async def release(self):
self._acquired = True


class AsyncLockedLock(AsyncFakeLock):
def __init__(self):
self._acquired = False


class AsyncTimedLock(AsyncFakeLock):
async def acquire(self):
await asyncio.sleep(1.0)
return await super().acquire()


class TestLockAcquire(unittest.TestCase):
@awaiter
async def test_succeed(self):
lock = AsyncFakeLock()
async with _aacquire(lock):
self.assertTrue(True)
return
self.assertTrue(False)

@awaiter
async def test_fail(self):
lock = AsyncLockedLock()
with self.assertRaises(LockNotAcquiredException):
async with _aacquire(lock):
pass #self.assertTrue(False)

@awaiter
async def test_fail_timeout(self):
lock = AsyncTimedLock()
with self.assertRaises(LockNotAcquiredException):
async with _aacquire(lock, 0.1):
pass #self.assertTrue(False)


class TestADBPython(unittest.TestCase):
"""Test the `ADBPython` class."""

Expand Down

0 comments on commit 6ee8c8a

Please sign in to comment.