LAVA supports two methods of extracting data: the REST API and XML-RPC. Results are made available while the job is running; this is a new feature compared to LAVA V1 where results were only published at the end of a job.
In addition to these methods of pulling data out of LAVA, there are also two methods for pushing information about its activity: notifications and publishing events.
LAVA makes the test results available directly from the instance,
without needing to go through lava-tool
. The results for any test
job which the user can view can be downloaded in CSV or YAML format.
For example, the results for test job number 123 are available in CSV
format using: https://validation.linaro.org/results/123/csv
. The
same results for job number 123 are available in YAML format using:
https://validation.linaro.org/results/123/yaml
If you know the test definition name, you can also download the
results for that specific test definition only in a similar way:
https://validation.linaro.org/results/123/singlenode-advanced/csv
for the data in CSV format and
https://validation.linaro.org/results/123/singlenode-advanced/yaml
for the YAML format.
Some test jobs can be restricted to particular users or groups of users. The results of these test jobs will be restricted in the same way. To download these results, you will need to specify your username and one of your Authentication Tokens when using the REST API. Remember to quote the URL if using it on the command line, to avoid the & character being mis-interpreted by your shell, for example:
$ curl 'https://validation.linaro.org/results/123/singlenode-advanced/yaml?user=user.name&token=yourtokentextgoeshereononeverylongline'
Use the Username as specified in your Profile - this may differ from the username you use if logging in via LDAP.
Caution
Take care of your tokens - avoid using personal tokens in
scripts and test definitions, or any other files that end up in
public git repositories. Wherever supported, use https://
when
using a token to avoid it being sent in plain-text.
Lots of methods are available to query various information in LAVA.
Warning
When using XML-RPC to communicate with a remote server,
check whether https://
can be used to protect the
token. http://
connections to a remote XML-RPC server will
transmit the token in plain-text. Not all servers have https://
configured. If a token becomes compromised, log in to that LAVA
instance and delete the token before creating a new one.
The general structure of an XML-RPC call can be shown in this python snippet:
import xmlrpclib
import json
config = json.dumps({ ... })
server=xmlrpclib.ServerProxy("http://username:API-Key@localhost:8001/RPC2/")
jobid=server.scheduler.submit_job(config)
XML-RPC can also be used to query data anonymously:
import xmlrpclib
server = xmlrpclib.ServerProxy("http://sylvester.codehelp/RPC2")
print server.system.listMethods()
Individual XML-RPC commands are documented on the API Help page.
Users can request notifications about submitted test jobs by adding a notify block to their test job submission.
The basic setup of the notifications in job definitions will have criteria, verbosity, recipients and compare blocks.
Here is an example notification setup. For more detailed information see User notifications in LAVA.
notify: criteria: status: incomplete verbosity: quiet recipients: - to: user: neil.williams method: irc
Event notifications are handled by the lava-publisher
service on
the master. By default, event notifications are disabled.
Note
lava-publisher
is distinct from the publishing API. Publishing events covers status
changes for devices and test jobs. The publishing API covers
copying files from test jobs to external sites.
http://ivoire.dinauz.org/linaro/bus/ is the home of ReactOWeb
. It
shows an example of the status change information which can be made
available using lava-publisher
. Events include:
org.linaro.validation.staging.device
)The topic
field is configurable by lab administrators. Its
intended use is to allow receivers of events to filter incoming
events.
{
"device": "staging-qemu05",
"device_type": "qemu",
"health_status": "Pass",
"job": 156223,
"pipeline": true,
"status": "Idle"
}
Event notifications are disabled by default and must be configured before being enabled.
See also
It is quite straightforward to communicate with lava-publisher
to
listen for events. This example code shows how to connect and
subscribe to lava-publisher
job events. It includes a simple
main function to run on the command line if you wish:
python zmq_client.py -j 357 -p tcp://127.0.0.1:5500 -t 1200
zmq_client.py script:
import argparse
import yaml
import signal
import zmq
import xmlrpclib
from urlparse import urlsplit
FINISHED_JOB_STATUS = ["Complete", "Incomplete", "Canceled"]
class JobEndTimeoutError(Exception):
""" Raise when the specified job does not finish in certain timeframe. """
class Timeout(object):
""" Timeout error class with ALARM signal. Accepts time in seconds. """
class TimeoutError(Exception):
pass
def __init__(self, sec):
self.sec = sec
def __enter__(self):
signal.signal(signal.SIGALRM, self.timeout_raise)
signal.alarm(self.sec)
def __exit__(self, *args):
signal.alarm(0)
def timeout_raise(self, *args):
raise Timeout.TimeoutError()
class JobListener(object):
def __init__(self, url):
self.context = zmq.Context.instance()
self.sock = self.context.socket(zmq.SUB)
self.sock.setsockopt(zmq.SUBSCRIBE, b"")
self.sock.connect(url)
def wait_for_job_end(self, job_id, timeout=None):
try:
with Timeout(timeout):
while True:
msg = self.sock.recv_multipart()
try:
(topic, uuid, dt, username, data) = msg[:]
except IndexError:
# Droping invalid message
continue
data = yaml.safe_load(data)
if "job" in data:
if data["job"] == job_id:
if data["status"] in FINISHED_JOB_STATUS:
return data
except Timeout.TimeoutError:
raise JobEndTimeoutError(
"JobListener timed out after %s seconds." % timeout)
def lookup_publisher(hostname):
"""
Lookup the publisher details using XML-RPC
on the specified hostname.
"""
xmlrpc_url = "http://%s/RPC2" % (hostname)
server = xmlrpclib.ServerProxy(xmlrpc_url)
socket = server.scheduler.get_publisher_event_socket()
port = urlsplit(socket).port
listener_url = 'tcp://%s:%s' % (hostname, port)
print("Using %s" % listener_url)
return listener_url
def main():
"""
Parse the command line
For simplicity, this script does not handle usernames
and tokens so needs a job ID. For support submitting
a test job as well as watching the events, use lava-tool.
"""
parser = argparse.ArgumentParser()
parser.add_argument("-j", "--job-id", type=int,
help="Job ID to wait for")
parser.add_argument("-t", "--timeout", type=int,
help="Timeout in seconds")
parser.add_argument("--hostname", help="hostname of the instance")
options = parser.parse_args()
publisher = lookup_publisher(options.hostname)
listener = JobListener(publisher)
print listener.wait_for_job_end(options.job_id, options.timeout)
print('\n')
if __name__ == '__main__':
main()
Download or view zmq_client.py
If you are interested in using event notifications for a custom frontend, you may want also to look at the code for the ReactOWeb example website: https://github.com/ivoire/ReactOWeb
A common request from LAVA users is the ability to submit a test job, wait for the job to start and then monitor it directly as it runs. Recent versions of lava-tool support this directly - look at its source code if you want to do something similar in your own code.