From 6642aabf9b81564274802e120abb79e74a6f4b8b Mon Sep 17 00:00:00 2001 From: Scott Murray Date: Tue, 1 Sep 2020 16:28:40 -0400 Subject: Assume network connectivity Revert the xfail changes to the geoclue and weather tests, as it's been clarified that network connectivity is assumed present in AGL CI. Signed-off-by: Scott Murray --- pyagl/tests/test_geoclue.py | 7 +++---- pyagl/tests/test_weather.py | 5 ++--- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/pyagl/tests/test_geoclue.py b/pyagl/tests/test_geoclue.py index 7628042..50210d8 100644 --- a/pyagl/tests/test_geoclue.py +++ b/pyagl/tests/test_geoclue.py @@ -37,7 +37,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() @@ -55,9 +54,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_weather.py b/pyagl/tests/test_weather.py index cbf4b64..0b2ff9e 100644 --- a/pyagl/tests/test_weather.py +++ b/pyagl/tests/test_weather.py @@ -44,7 +44,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() @@ -70,8 +69,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']) -- cgit 1.2.3-korg From e98f1c8e26c1173c6c2684e09e3a926fc92d08a0 Mon Sep 17 00:00:00 2001 From: Scott Murray Date: Tue, 1 Sep 2020 16:31:59 -0400 Subject: Rework per-binding test marking Rework the test marking to allow deriving the test mark name for a given binding from the binding name, i.e. agl-service-X. Due to dashes not being valid in pytest marks, underscores have been used instead, i.e. agl-service-can-low-level -> can_low_level. The intent is to allow CI tooling to easily work up a pytest -k option to run the tests for a specific binding. Signed-off-by: Scott Murray --- pyagl/pytest.ini | 9 +++++---- pyagl/tests/test_bluetooth_map.py | 2 +- pyagl/tests/test_bluetooth_pbap.py | 2 +- pyagl/tests/test_can.py | 2 +- pyagl/tests/test_homescreen.py | 2 +- pyagl/tests/test_signal_composer.py | 2 +- 6 files changed, 10 insertions(+), 9 deletions(-) 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/tests/test_bluetooth_map.py b/pyagl/tests/test_bluetooth_map.py index fee0916..d7bc3d9 100644 --- a/pyagl/tests/test_bluetooth_map.py +++ b/pyagl/tests/test_bluetooth_map.py @@ -21,7 +21,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 b70c914..bd91258 100644 --- a/pyagl/tests/test_bluetooth_pbap.py +++ b/pyagl/tests/test_bluetooth_pbap.py @@ -21,7 +21,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 1283939..ef66f2c 100644 --- a/pyagl/tests/test_can.py +++ b/pyagl/tests/test_can.py @@ -5,7 +5,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_homescreen.py b/pyagl/tests/test_homescreen.py index 35ffd0d..521fcc3 100644 --- a/pyagl/tests/test_homescreen.py +++ b/pyagl/tests/test_homescreen.py @@ -21,7 +21,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_signal_composer.py b/pyagl/tests/test_signal_composer.py index cafa052..a306fdf 100644 --- a/pyagl/tests/test_signal_composer.py +++ b/pyagl/tests/test_signal_composer.py @@ -21,7 +21,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') -- cgit 1.2.3-korg From 4cf3dafb9573ba18b1e06d9cbd0ed12d6348df91 Mon Sep 17 00:00:00 2001 From: Scott Murray Date: Tue, 1 Sep 2020 16:37:11 -0400 Subject: audiomixer and mediascanner bindings do not need to be started The changes in AGL for SPECs 3557 and 3558 mean that the audiomixer and mediascanner bindings do not need to be started before running tests, disable doing so. Signed-off-by: Scott Murray --- pyagl/services/audiomixer.py | 2 +- pyagl/services/base.py | 3 ++- pyagl/services/mediascanner.py | 4 ++-- pyagl/tests/test_mediascanner.py | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/pyagl/services/audiomixer.py b/pyagl/services/audiomixer.py index 7d14cc8..6e447b7 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 320abde..cd69f55 100644 --- a/pyagl/services/base.py +++ b/pyagl/services/base.py @@ -133,7 +133,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 diff --git a/pyagl/services/mediascanner.py b/pyagl/services/mediascanner.py index b40457f..3a6e876 100644 --- a/pyagl/services/mediascanner.py +++ b/pyagl/services/mediascanner.py @@ -25,8 +25,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_mediascanner.py b/pyagl/tests/test_mediascanner.py index 9aba4b0..a4d57ee 100644 --- a/pyagl/tests/test_mediascanner.py +++ b/pyagl/tests/test_mediascanner.py @@ -33,7 +33,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() -- cgit 1.2.3-korg From f86056e7ee3cec7122cea2590d949f495883237e Mon Sep 17 00:00:00 2001 From: Scott Murray Date: Tue, 1 Sep 2020 16:40:56 -0400 Subject: Add timeout for binding responses To ensure automated use of the tests cannot get hung, add a timeout on waiting for binding responses. The default value is 5 seconds, it may be over-riden by setting the AGL_TEST_TIMEOUT environment variable. Signed-off-by: Scott Murray --- README.md | 1 + pyagl/services/base.py | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d81cf82..6f690e5 100644 --- a/README.md +++ b/README.md @@ -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/services/base.py b/pyagl/services/base.py index cd69f55..b7f76d0 100644 --- a/pyagl/services/base.py +++ b/pyagl/services/base.py @@ -144,6 +144,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 +328,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 +346,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)) -- cgit 1.2.3-korg