aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEdi Feschiyan <edi.feschiyan@konsulko.com>2020-06-12 22:44:25 +0300
committerEdi Feschiyan <edi.feschiyan@konsulko.com>2020-06-12 22:44:25 +0300
commit8a8b87e65c0b3d579f8ea420e23a9cd07528dfe1 (patch)
treed5ced56f53104781bf156b38dbad7aba48578ca1
parente2bb2d3ff3f909b9417040de4dd8ea876777a6ee (diff)
Adding cookiecutter, preparing for setuptools, new services
-rw-r--r--README.md0
-rw-r--r--services/audiomixer.py (renamed from audiomixer.py)0
-rw-r--r--services/base.py (renamed from aglbaseservice.py)3
-rw-r--r--services/bluetooth-map.py0
-rw-r--r--services/bluetooth-pbap.py0
-rw-r--r--services/bluetooth.py (renamed from bluetooth.py)3
-rw-r--r--services/geoclue.py (renamed from geoclue.py)0
-rw-r--r--services/gps.py (renamed from gps.py)0
-rw-r--r--services/mediaplayer.py (renamed from mediaplayer.py)0
-rw-r--r--services/network.py0
-rw-r--r--services/nfc.py (renamed from nfc.py)0
-rw-r--r--services/taskmanager.py0
-rw-r--r--services/weather.py (renamed from weather.py)0
-rw-r--r--setup.py0
-rw-r--r--templates/service/cookiecutter.json6
-rw-r--r--templates/service/{{cookiecutter.file_name}}.py9
-rw-r--r--templates/test/{{cookiecutter.file_name}}.py0
-rw-r--r--test_bluetooth.py50
-rw-r--r--tests/test_bluetooth.py104
-rw-r--r--tests/test_gps.py (renamed from test_gps.py)26
-rw-r--r--tests/test_weather.py0
21 files changed, 145 insertions, 56 deletions
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/README.md
diff --git a/audiomixer.py b/services/audiomixer.py
index e594471..e594471 100644
--- a/audiomixer.py
+++ b/services/audiomixer.py
diff --git a/aglbaseservice.py b/services/base.py
index 2146491..03d4793 100644
--- a/aglbaseservice.py
+++ b/services/base.py
@@ -241,6 +241,9 @@ class AGLBaseService:
except Exception as e:
self.logger.error("Unhandled seal: " + str(e))
+ async def afbresponse(self):
+ return AFBResponse(await self.response())
+
async def request(self, verb: str, values: Union[str, dict] = "", msgid: int = None):
msgid = next(newrand()) if msgid is None else msgid
l = json.dumps([AFBT.REQUEST, str(msgid), f'{self.api}/{verb}', values])
diff --git a/services/bluetooth-map.py b/services/bluetooth-map.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/services/bluetooth-map.py
diff --git a/services/bluetooth-pbap.py b/services/bluetooth-pbap.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/services/bluetooth-pbap.py
diff --git a/bluetooth.py b/services/bluetooth.py
index 658d2e7..b73f8a8 100644
--- a/bluetooth.py
+++ b/services/bluetooth.py
@@ -64,6 +64,9 @@ class BluetoothService(AGLBaseService):
async def confirm_pairing(self, pincode):
return await self.request('confirm_pairing', {'pincode': pincode})
+ async def remove_device(self, device):
+ return await self.request('remove_device', {'device': device})
+
async def avrcp_controls(self):
pass
diff --git a/geoclue.py b/services/geoclue.py
index df1afd6..df1afd6 100644
--- a/geoclue.py
+++ b/services/geoclue.py
diff --git a/gps.py b/services/gps.py
index 1905e0f..1905e0f 100644
--- a/gps.py
+++ b/services/gps.py
diff --git a/mediaplayer.py b/services/mediaplayer.py
index 9291981..9291981 100644
--- a/mediaplayer.py
+++ b/services/mediaplayer.py
diff --git a/services/network.py b/services/network.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/services/network.py
diff --git a/nfc.py b/services/nfc.py
index c966c4a..c966c4a 100644
--- a/nfc.py
+++ b/services/nfc.py
diff --git a/services/taskmanager.py b/services/taskmanager.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/services/taskmanager.py
diff --git a/weather.py b/services/weather.py
index f3c02d0..f3c02d0 100644
--- a/weather.py
+++ b/services/weather.py
diff --git a/setup.py b/setup.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/setup.py
diff --git a/templates/service/cookiecutter.json b/templates/service/cookiecutter.json
new file mode 100644
index 0000000..f37ea1f
--- /dev/null
+++ b/templates/service/cookiecutter.json
@@ -0,0 +1,6 @@
+{
+ "aglsystemdservice": "agl-service-something",
+ "classname": "NewService",
+ "api": "serviceapi",
+ "verblist": ["subscribe", "unsubscribe"]
+} \ No newline at end of file
diff --git a/templates/service/{{cookiecutter.file_name}}.py b/templates/service/{{cookiecutter.file_name}}.py
new file mode 100644
index 0000000..6defd28
--- /dev/null
+++ b/templates/service/{{cookiecutter.file_name}}.py
@@ -0,0 +1,9 @@
+from aglbaseservice import AGLBaseService, AFBResponse
+import asyncio
+import os
+
+class {{cookiecutter.classname}}(AGLBaseService):
+
+ def __init__(self, ip, port=None, service='{{cookiecutter.aglsystemdservice}}'):
+ super().__init__(api='{{cookiecutter.api}}', ip=ip, port=port, service=service)
+
diff --git a/templates/test/{{cookiecutter.file_name}}.py b/templates/test/{{cookiecutter.file_name}}.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/templates/test/{{cookiecutter.file_name}}.py
diff --git a/test_bluetooth.py b/test_bluetooth.py
deleted file mode 100644
index 1ccf499..0000000
--- a/test_bluetooth.py
+++ /dev/null
@@ -1,50 +0,0 @@
-import asyncio
-import os
-import pytest
-from bluetooth import BluetoothService as BTS
-import logging
-from aglbaseservice import AFBResponse, AFBT
-
-logger = logging.getLogger(f'pytest-{BTS.service}')
-logger.setLevel(logging.DEBUG)
-pytestmark = pytest.mark.asyncio
-
-
-@pytest.fixture(scope="module")
-def event_loop():
- loop = asyncio.get_event_loop()
- yield loop
- loop.close()
-
-
-@pytest.fixture(scope='module')
-async def service():
- address = os.environ.get('AGL_TGT_IP', 'localhost')
- port = os.environ.get('AGL_TGT_PORT', None)
-
- bts = await BTS(ip=address, port=port)
- yield bts
- await bts.websocket.close()
-
-
-async def test_default_adapter(event_loop, service: BTS):
- id = await service.default_adapter()
- resp = AFBResponse(await service.response())
- assert resp.status == 'success', resp
- assert 'adapter' in resp.data.keys()
- assert resp.data['adapter'] == 'hci0'
-
-
-async def test_managed_objects(event_loop, service: BTS):
- id = await service.managed_objects()
- resp = AFBResponse(await service.response())
- assert resp.status == 'success', str(resp)
-
-
-async def test_has_single_adapter(event_loop, service: BTS):
- id = await service.managed_objects()
- resp = AFBResponse(await service.response())
- assert len(resp.data['adapters']) == 1, \
- f'Detected {len(resp.data["adapters"])} adapters. Multiple adapters may also break testing'
-
-
diff --git a/tests/test_bluetooth.py b/tests/test_bluetooth.py
new file mode 100644
index 0000000..d6b899e
--- /dev/null
+++ b/tests/test_bluetooth.py
@@ -0,0 +1,104 @@
+import asyncio
+import os
+import pytest
+from bluetooth import BluetoothService as BTS
+import logging
+from aglbaseservice import AFBResponse, AFBT
+
+logger = logging.getLogger(f'pytest-{BTS.service}')
+logger.setLevel(logging.DEBUG)
+pytestmark = pytest.mark.asyncio
+
+
+@pytest.fixture(scope='module')
+def event_loop():
+ loop = asyncio.get_event_loop()
+ yield loop
+ loop.close()
+
+
+@pytest.fixture(scope='module')
+async def service():
+ address = os.environ.get('AGL_TGT_IP', 'localhost')
+ port = os.environ.get('AGL_TGT_PORT', None)
+
+ bts = await BTS(ip=address, port=port)
+ yield bts
+ await bts.websocket.close()
+
+
+@pytest.mark.xfail
+@pytest.fixture(scope='module')
+def btaddr():
+ bthtestaddr = os.environ.get('AGL_TEST_BT_ADDR', None)
+ if not bthtestaddr:
+ pytest.xfail('No test bluetooth test address set in environment variables')
+
+ return bthtestaddr
+
+
+@pytest.mark.dependency
+async def test_default_adapter(event_loop, service: BTS):
+ id = await service.default_adapter()
+ resp = AFBResponse(await service.response())
+ assert resp.status == 'success', resp
+ assert 'adapter' in resp.data.keys()
+ assert resp.data['adapter'] == 'hci0'
+
+
+@pytest.mark.dependency(depends=['test_default_adapter'])
+async def test_managed_objects(event_loop, service: BTS):
+ id = await service.managed_objects()
+ resp = AFBResponse(await service.response())
+ assert resp.status == 'success', str(resp)
+
+
+@pytest.mark.dependency(depends=['test_default_adapter'])
+async def test_has_single_adapter(event_loop, service: BTS):
+ id = await service.managed_objects()
+ resp = AFBResponse(await service.response())
+ assert len(resp.data['adapters']) == 1, \
+ f'Detected {len(resp.data["adapters"])} adapters. Multiple adapters may also break testing'
+
+
+@pytest.mark.dependency(depends=['test_default_adapter'])
+async def test_adapter_state(event_loop, service: BTS):
+ id = await service.adapter_state('hci0')
+ resp = AFBResponse(await service.response())
+ assert resp.status == 'success', 'adapter state verb failed'
+
+
+async def test_pairing_verb(event_loop, service: BTS, btaddr):
+ id = await service.pair(btaddr)
+ resp = await service.afbresponse()
+ assert id == resp.msgid
+ assert resp.status == 'success', f'pair verb failed - {resp.info}'
+
+
+async def test_connect_verb(event_loop, service: BTS, btaddr):
+ id = await service.connect(btaddr)
+ resp = await service.afbresponse()
+ assert id == resp.msgid
+ assert resp.status == 'success', f'connect verb failed - {resp.info}'
+
+
+async def test_disconnect_verb(event_loop, service: BTS, btaddr):
+ id = await service.disconnect(btaddr)
+ resp = await service.afbresponse()
+ assert id == resp.msgid
+ assert resp.status == 'success', f'disconnect verb failed - {resp.info}'
+
+
+async def test_remove_pairing_verb(event_loop, service: BTS, btaddr):
+ id = await service.remove_device(btaddr)
+ resp = await service.afbresponse()
+ assert id == resp.msgid
+ assert resp.status == 'success'
+
+
+@pytest.mark.xfail(reason='This is expected to fail because there has to be an ongoing pairing attempt')
+async def test_confirm_pairing_verb(event_loop, service: BTS, btaddr):
+ id = await service.confirm_pairing(pincode='123456')
+ resp = await service.afbresponse()
+ assert id == resp.msgid
+ assert resp.status == 'success', f'confirm_pairing verb failed - {resp.info}'
diff --git a/test_gps.py b/tests/test_gps.py
index e1ad15e..2e62405 100644
--- a/test_gps.py
+++ b/tests/test_gps.py
@@ -4,12 +4,13 @@ import pytest
from gps import GPSService as GPS
import logging
from aglbaseservice import AFBResponse, AFBT
+from concurrent.futures import TimeoutError
logger = logging.getLogger('pytest-gps')
logger.setLevel(logging.DEBUG)
pytestmark = pytest.mark.asyncio
-@pytest.fixture(scope="module")
+@pytest.fixture(scope='module')
def event_loop():
loop = asyncio.get_event_loop()
yield loop
@@ -18,7 +19,8 @@ def event_loop():
@pytest.fixture(scope='module')
async def service():
address = os.environ.get('AGL_TGT_IP', 'localhost')
- gpss = await GPS(ip=address)
+ port = os.environ.get('AGL_TGT_PORT', None)
+ gpss = await GPS(ip=address, port=port)
yield gpss
await gpss.websocket.close()
@@ -27,12 +29,19 @@ async def service():
# async for _response in service.listener():
# yield _response
+async def test_location_verb(event_loop, service: GPS):
+ id = await service.location()
+ resp = AFBResponse(await service.response())
+ assert resp.msgid == id
+
@pytest.mark.xfail # expecting this to fail because of "No 3D GNSS fix" and GPS is unavailable
-async def test_location(event_loop, service: GPS):
+async def test_location_result(event_loop, service: GPS):
id = await service.location()
resp = AFBResponse(await service.response())
assert resp.status == 'success'
+
+
async def test_subscribe_location(event_loop, service: GPS):
id = await service.subscribe('location')
resp = AFBResponse(await service.response())
@@ -45,13 +54,18 @@ async def test_unsubscribe(event_loop, service: GPS):
assert resp.msgid == id
assert resp.status == 'success'
+@pytest.mark.xfail # expecting this to fail because of "No 3D GNSS fix" and GPS is unavailable
async def test_location_events(event_loop, service: GPS):
id = await service.subscribe('location')
resp = AFBResponse(await service.response())
assert resp.msgid == id
assert resp.status == 'success' # successful subscription
+ try:
+ resp = await asyncio.wait_for(service.response(), 10)
+ resp = AFBResponse(resp)
+ assert resp.type == AFBT.EVENT, f'Expected EVENT response, got {resp.type.name} instead'
+ # TODO one more assert for the actual received event, haven't received a location event yet
+ except TimeoutError:
+ pytest.xfail("Did not receive location event")
- resp = await asyncio.wait_for(service.response(), 10)
- resp = AFBResponse(resp)
- assert resp.type == AFBT.EVENT, f'Expected EVENT response, got {resp.type.name} instead'
diff --git a/tests/test_weather.py b/tests/test_weather.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/test_weather.py