diff options
-rw-r--r-- | README.md | 1 | ||||
-rw-r--r-- | pyagl/pytest.ini | 9 | ||||
-rw-r--r-- | pyagl/services/audiomixer.py | 2 | ||||
-rw-r--r-- | pyagl/services/base.py | 11 | ||||
-rw-r--r-- | pyagl/services/mediascanner.py | 4 | ||||
-rw-r--r-- | pyagl/tests/test_bluetooth_map.py | 2 | ||||
-rw-r--r-- | pyagl/tests/test_bluetooth_pbap.py | 2 | ||||
-rw-r--r-- | pyagl/tests/test_can.py | 2 | ||||
-rw-r--r-- | pyagl/tests/test_geoclue.py | 7 | ||||
-rw-r--r-- | pyagl/tests/test_homescreen.py | 2 | ||||
-rw-r--r-- | pyagl/tests/test_mediascanner.py | 2 | ||||
-rw-r--r-- | pyagl/tests/test_signal_composer.py | 2 | ||||
-rw-r--r-- | pyagl/tests/test_weather.py | 5 |
13 files changed, 29 insertions, 22 deletions
@@ -92,6 +92,7 @@ Note that the tests have been labelled with `pytest` markers to allow selecting When running tests on target, AGL_TGT_IP is not required, as the tests will assume the local host is the target. Some specific tests are dependent on additional configuration via the following environment variables: +* AGL_TEST_TIMEOUT - optional, over-ride the default 5 second timeout value for binding responses. * AGL_AVAILABLE_INTERFACES - optional, specify which of ethernet, wifi, and bluetooth interfaces are available. The value is a comma separated list, with a default value of "ethernet,wifi,bluetooth". * AGL_BTMAP_RECIPIENT - optional, when running Bluetooth MAP tests, this would be used as phone number to write text messages to. * AGL_BTMAP_TEXT - optional, when running Bluetooth MAP tests, messages will be composed with this text. diff --git a/pyagl/pytest.ini b/pyagl/pytest.ini index db7257a..6587041 100644 --- a/pyagl/pytest.ini +++ b/pyagl/pytest.ini @@ -6,13 +6,14 @@ markers = hwrequired: verb tests requiring available physical hardware audiomixer: agl-service-audiomixer tests bluetooth: agl-service-bluetooth tests - btmap: agl-service-bluetooth-map tests - btpbap: agl-service-bluetooth-pbap tests + bluetooth_map: agl-service-bluetooth-map tests + bluetooth_pbap: agl-service-bluetooth-pbap tests geoclue: agl-service-geoclue tests + homescreen: agl-service-homescreen tests network: agl-service-network tests nfc: agl-service-nfc tests gps: agl-service-gps tests weather: agl-service-weather tests mediascanner: agl-service-mediascanner tests - sigcomp: agl-service-signal-composer tests - can: agl-service-can-low-level tests + signal_composer: agl-service-signal-composer tests + can_low_level: agl-service-can-low-level tests diff --git a/pyagl/services/audiomixer.py b/pyagl/services/audiomixer.py index ec8edd7..8a7743f 100644 --- a/pyagl/services/audiomixer.py +++ b/pyagl/services/audiomixer.py @@ -31,7 +31,7 @@ class AudioMixerService(AGLBaseService): parser.add_argument('--getvolume', help='Get volume level', action='store_true') def __init__(self, ip, port=None, service='agl-service-audiomixer'): - super().__init__(api='audiomixer', ip=ip, port=port, service=service, runservice=True) + super().__init__(api='audiomixer', ip=ip, port=port, service=service) async def subscribe(self, event='volume_changed'): # audio mixer uses 'event' instead 'value', return await self.request('subscribe', {'event': event}) diff --git a/pyagl/services/base.py b/pyagl/services/base.py index 2ee095f..a7dd7aa 100644 --- a/pyagl/services/base.py +++ b/pyagl/services/base.py @@ -134,7 +134,8 @@ class AGLBaseService: return parser def __init__(self, api: str, ip: str, port: str = None, url: str = None, - token: str = 'HELLO', uuid: str = 'magic', service: str = None, runservice: bool = False): + token: str = 'HELLO', uuid: str = 'magic', service: str = None, + runservice: bool = False, timeout: float = 5.0): self.api = api self.url = url self.ip = ip @@ -144,6 +145,10 @@ class AGLBaseService: self.service = service self.runsvc = runservice self.logger = logging.getLogger(service) + try: + self.timeout = float(os.environ.get('AGL_TEST_TIMEOUT', timeout)) + except ValueError: + self.timeout = 5.0 def __await__(self): return self._async_init().__await__() @@ -324,7 +329,7 @@ class AGLBaseService: async def response(self): try: - msg = await self.websocket.recv() + msg = await asyncio.wait_for(self.websocket.recv(), self.timeout) try: data = json.loads(msg) self.logger.debug('[AGL] -> ' + msg) @@ -342,6 +347,8 @@ class AGLBaseService: self.logger.debug("Received keyboard interrupt, exiting") except asyncio.CancelledError: self.logger.warning("Websocket listener coroutine stopped") + except asyncio.TimeoutError: + self.logger.warning("Response wait timed out") except Exception as e: self.logger.error("Unhandled seal: " + str(e)) diff --git a/pyagl/services/mediascanner.py b/pyagl/services/mediascanner.py index c29a10d..6281834 100644 --- a/pyagl/services/mediascanner.py +++ b/pyagl/services/mediascanner.py @@ -26,8 +26,8 @@ class MediaScannerService(AGLBaseService): parser = AGLBaseService.getparser() parser.add_argument('--media_result', help='Query media_results verb', action='store_true') - def __init__(self, ip, port=None, service='agl-service-mediascanner', runservice=True): - super().__init__(api='mediascanner', ip=ip, port=port, service=service, runservice=runservice) + def __init__(self, ip, port=None, service='agl-service-mediascanner'): + super().__init__(api='mediascanner', ip=ip, port=port, service=service) # more init stuff specific to the new service async def media_result(self): diff --git a/pyagl/tests/test_bluetooth_map.py b/pyagl/tests/test_bluetooth_map.py index 8b7b79e..09a9860 100644 --- a/pyagl/tests/test_bluetooth_map.py +++ b/pyagl/tests/test_bluetooth_map.py @@ -22,7 +22,7 @@ from pyagl.services.base import AFBResponse, AFBT from pyagl.services.bluetooth_map import BTMAPService as BMP import logging -pytestmark = [pytest.mark.asyncio, pytest.mark.btmap] +pytestmark = [pytest.mark.asyncio, pytest.mark.bluetooth_map] @pytest.fixture(scope='module') diff --git a/pyagl/tests/test_bluetooth_pbap.py b/pyagl/tests/test_bluetooth_pbap.py index 750c7cc..af1d0e4 100644 --- a/pyagl/tests/test_bluetooth_pbap.py +++ b/pyagl/tests/test_bluetooth_pbap.py @@ -22,7 +22,7 @@ import logging from pyagl.services.base import AFBResponse, AFBT from pyagl.services.bluetooth_pbap import BTPBAPService as PBAP -pytestmark = [pytest.mark.asyncio, pytest.mark.btpbap] +pytestmark = [pytest.mark.asyncio, pytest.mark.bluetooth_pbap] @pytest.fixture(scope='module') diff --git a/pyagl/tests/test_can.py b/pyagl/tests/test_can.py index 469eeaa..a8ef8b3 100644 --- a/pyagl/tests/test_can.py +++ b/pyagl/tests/test_can.py @@ -20,7 +20,7 @@ import logging from pyagl.services.base import AFBResponse, AFBT from pyagl.services.can import CANService as cs -pytestmark = [pytest.mark.asyncio, pytest.mark.can] +pytestmark = [pytest.mark.asyncio, pytest.mark.can_low_level] @pytest.fixture(scope='module') diff --git a/pyagl/tests/test_geoclue.py b/pyagl/tests/test_geoclue.py index 9c02e0a..6d9d025 100644 --- a/pyagl/tests/test_geoclue.py +++ b/pyagl/tests/test_geoclue.py @@ -38,7 +38,6 @@ async def service(): yield svc await svc.websocket.close() -@pytest.mark.xfail(reason='expected to fail if no internet connection is available or geoclue has no data') @pytest.mark.regular async def test_location(event_loop, service: gcs): msgid = await service.location() @@ -56,9 +55,9 @@ async def test_subscribe(event_loop, service: gcs): msgid = await service.subscribe() resp = await service.afbresponse() assert resp.status == 'success' - # event = await service.afbresponse() - # assert event.type == AFBT.EVENT # subscription immediately emits geoclue event - # assert event.api == f'{service.api}/location' + event = await service.afbresponse() + assert event.type == AFBT.EVENT # subscription immediately emits geoclue event + assert event.api == f'{service.api}/location' @pytest.mark.regular diff --git a/pyagl/tests/test_homescreen.py b/pyagl/tests/test_homescreen.py index 7b54cc1..57e562f 100644 --- a/pyagl/tests/test_homescreen.py +++ b/pyagl/tests/test_homescreen.py @@ -22,7 +22,7 @@ from pyagl.services.base import AFBResponse, AFBT from concurrent.futures import TimeoutError from pyagl.services.homescreen import HomeScreenService as hcs -pytestmark = pytest.mark.asyncio +pytestmark = [pytest.mark.asyncio, pytest.mark.homescreen] @pytest.fixture(scope='module') diff --git a/pyagl/tests/test_mediascanner.py b/pyagl/tests/test_mediascanner.py index 6a1d563..e908d6e 100644 --- a/pyagl/tests/test_mediascanner.py +++ b/pyagl/tests/test_mediascanner.py @@ -34,7 +34,7 @@ def event_loop(): async def service(): address = os.environ.get('AGL_TGT_IP', 'localhost') port = os.environ.get('AGL_TGT_PORT', None) - ns = await mss(ip=address, port=port, runservice=True) + ns = await mss(ip=address, port=port) yield ns await ns.websocket.close() diff --git a/pyagl/tests/test_signal_composer.py b/pyagl/tests/test_signal_composer.py index 30e10e3..0609072 100644 --- a/pyagl/tests/test_signal_composer.py +++ b/pyagl/tests/test_signal_composer.py @@ -22,7 +22,7 @@ from pyagl.services.base import AFBResponse, AFBT from pyagl.services.signal_composer import SignalComposerService as scs -pytestmark = [pytest.mark.asyncio, pytest.mark.can] +pytestmark = [pytest.mark.asyncio, pytest.mark.can_low_level] @pytest.fixture(scope='module') diff --git a/pyagl/tests/test_weather.py b/pyagl/tests/test_weather.py index 2a8df1c..c106492 100644 --- a/pyagl/tests/test_weather.py +++ b/pyagl/tests/test_weather.py @@ -45,7 +45,6 @@ async def test_apikey(event_loop, service: ws): assert resp.msgid == msgid assert resp.data['api_key'] == 'a860fa437924aec3d0360cc749e25f0e' -@pytest.mark.xfail(reason='expecting this to fail without internet connection') async def test_current_weather(event_loop, service: ws): msgid = await service.current_weather() resp = await service.afbresponse() @@ -71,8 +70,8 @@ async def test_subscribe_weather(event_loop, service: ws): msgid = await service.subscribe(event) resp = await service.afbresponse() assert resp.status == 'success' - # eventresp = await service.afbresponse() # immediately emits event after subscription - # assert eventresp.api == f'{service.api}/{event}' + eventresp = await service.afbresponse() # immediately emits event after subscription + assert eventresp.api == f'{service.api}/{event}' @pytest.mark.dependency(depends=['test_subscribe_weather']) |