aboutsummaryrefslogtreecommitdiffstats
path: root/README.md
blob: e4d66251a46a023d05d9769a169a02d6994e8455 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#pyagl

## Basic info
Python library with bindings and tests for Automotive Grade Linux services

Currently the library works only with images built with `aglsetup.sh agl-devel`,  
the non-agl-devel image does not expose websockets on TCP ports.
 
The library implements CLI-callable main() methods and argparse with --help supplements in most modules.  
When installing the library into a new virtualenv, the modules should be executable with   
`python3 -m pyagl.services.<service> --help` - which should return CLI usage of the invoked module  
First positional argument is IP Address of the target board

## Examples:
```shell script
$ python3 -m pyagl.services.bluetooth_pbap --help
usage: bluetooth_pbap.py [-h] [-l {CRITICAL,FATAL,ERROR,WARN,WARNING,INFO,DEBUG,NOTSET}] [--port PORT] [--listener] [--subscribe event] [--unsubscribe event] [--json JSON] [--verb VERB] [--api API] [--import_contacts] [--status] [--contacts] [--history HISTORY] ipaddr

Utility to interact with agl-service-* via it's websocket

positional arguments:
  ipaddr                AGL host address

optional arguments:
  -h, --help            show this help message and exit
  -l {CRITICAL,FATAL,ERROR,WARN,WARNING,INFO,DEBUG,NOTSET}, --loglevel {CRITICAL,FATAL,ERROR,WARN,WARNING,INFO,DEBUG,NOTSET}
                        Level of logging verbosity
  --port PORT           AGL service websocket port
  --listener            Register a listener for incoming events
  --subscribe event     Subscribe to event type
  --unsubscribe event   Unsubscribe from event type
  --import_contacts
  --status
  --contacts
  --history HISTORY     Request call history - ICH/OCH/MCH/CCH
```
```shell script
$ python3 -m pyagl.services.bluetooth_pbap 192.168.234.251 --contacts 
Sent contacts request with messageid 896503218
[RESPONSE][Status: success][896503218][Info: contacts][Data: {'vcards': [{'fn': 'John Smith', 'telephone': [{'HOME': '+15557028324'}]}...]},
```  

Until the package is uploaded onto PyPI, either:
* `git clone` the repository
* `cd` into the cloned directory
* `pip install .`

or
* `pip install` the generated zip from the repository(when public)

or
* git clone \<repo\>
* mkdir packages && cd packages
* pip wheel ../\<repo\>

which creates "wheels" for pyagl and the dependencies it needs 
\- specified in setup.py - and are pip installable
 

---
## Creating new modules
Creating a new modules and tests can be done with a few steps:
1. clone the repository
2. cd \<repo\>/pyagl
3. cookiecutter -f ../templates/ 

## Running the tests
The tests can be run on target if installed, directly from the cloned repository, or if installed locally on a development host, from the default Python site-packages directory or a configured virtualenv.  On target the tests will be in /usr/lib/python3.8/site-packages/pyagl/tests.  If installed locally on a development machine:
* on Debian systems the default site packages directory should be in /usr/local/lib/python3.8/dist-packages/pyagl/tests
* for virtualenv, the directory will be <virtualenv_dir>/lib/python3.8/site-packages/pyagl/tests

### Invoking pytest
The tests may be run with `pytest` by passing it the tests directory:
```
pytest <tests directory>
```
On target, the command would be:
```
pytest /usr/lib/python3.8/site-packages/pyagl/tests
```
Note that the tests have been labelled with `pytest` markers to allow selecting or deselecting tests with the `pytest` '-k' option.  Each binding's test are marked with the name of the binding, with additional markers that include:
* hwrequired - verb tests requiring available physical hardware
* can_j1939 - CAN binding tests specific to J1939 protocol

#### Examples
Running just the tests for a single binding (audiomixer):
```
pytest -k "audiomixer" /usr/lib/python3.8/site-packages/pyagl/tests
```
Note that the per-binding markers cannot use dashes ('-') in their names, so generating the marker for a specific binding can be done with something like:
```
echo agl-service-can-low-level | cut -d- -f3- | tr - _
```
Running tests with LAVA compatible output:
```
pytest --lava "audiomixer" /usr/lib/python3.8/site-packages/pyagl/tests
```
Note that `--lava` and `-L` are equivalent, either will activate LAVA compatible output.  As well, note that when using LAVA output, the `pytest` `-v` verbose option is ignored.

### Test Configuration
 Running the tests remotely involves the export of the following environment variables:
* AGL_TGT_IP - required - point at an IP Address with AGL instance
* AGL_TGT_PORT - optional - if not exported, the library wil connect to the IP address via ssh to find out the service's listening TCP port

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.
* AGL_CAN_INTERFACE - optional, specify the CAN interface to use for CAN testing, default value is "can0".
* AGL_PBAP_PHONENUM - optional , when running Bluetooth PBAP tests, this phone number will be used to .search().
* AGL_PBAP_VCF - optional, for the Bluetooh PBAP tests query a contact entry out of the phonebook.
* AGL_BT_TEST_ADDR - optional, for the Bluetooth tests pair/connect/disconnect with an actual Bluetooth device(phone)'s address .  The address should have the DBus address style as "dev_00_01_02_03_04_05" instead of a regular colon-separated MAC address.

Should some of the optional variables be omitted, the fixtures and their dependent tests should fail gracefully with a "XFAIL" (expected fail) or "SKIP" result.  There are tests that are dependent on other tests, therefore if the dependent tests fail, the whole test chain will be skipped.

### Running Inside QEMU
To run `QEMU` from inside the AGL build environment to be able to run tests, the `runqemu` command can be used.  For example:
```
$ runqemu kvm publicvnc serial slirp audio
```
A note on some of the `runqemu` options:
 - serial - enables a serial console
 - slirp - enables user networking (no root login / `sudo` required)
 - audio - enables audio

The tests can then be invoked after logging in:
```
 AGL_AVAILABLE_INTERFACES=ethernet pytest -k "not hwrequired" /usr/lib/python3.8/site-packages/pyagl/tests
```
If running `QEMU` outside of the AGL build environment, note that you will likely want to pass the `-soundhw hda` option to enable audio support if running the audiomixer tests, and an appropriate `-netdev` option to enable some form of networking for the network binding tests.