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
|
import xmlrpclib
import urllib2
import json
import datetime
import re
import logging
xmlrpc_log = logging.getLogger("xmlrpclib")
class LoggingTransport(xmlrpclib.Transport):
def send_request(self, connection, handler, request_body):
xmlrpc_log.debug("%s", (connection, handler, request_body))
return xmlrpclib.Transport.send_request(self, connection, handler, request_body)
class LavaConnection:
def __init__(self, lava_server, lava_stream):
"""LAVA server e.g. http://validation.linaro.org/lava-server."""
self.lava_server = lava_server
"""LAVA stream to query e.g. /anonymous/android-daily/."""
self.lava_stream = lava_stream
"Cached results"
self.lava_results = None
self.log = logging.getLogger(self.__class__.__name__)
def get_server(self):
if not hasattr(self, "server"):
self.server = xmlrpclib.ServerProxy("%s/RPC2/" % (self.lava_server), transport=LoggingTransport())
return self.server
def request(self, url, data=None):
if "://" not in url:
url = self.lava_server + "/" + url
self.log.debug("LAVA request: %s", url)
req = urllib2.Request(url, data)
resp = urllib2.urlopen(req)
return resp.read()
def json_request(self, url, data=None):
res = self.request(url, data)
return json.loads(res)
def get_job_status(self, job):
url = "scheduler/job/%s/json" % job
return self.json_request(url)
def get_job_url(self, job):
url = "%s/scheduler/job/%s" % (self.lava_server, job)
return url
def get_bundle(self, bundle_id):
url = "dashboard/permalink/bundle/%s/json" % bundle_id
return self.json_request(url)
def parse_bundle_url(self, bundle_url):
# http://validation.linaro.org/lava-server/dashboard/permalink/bundle/f19c4669fc37b6907901e067f5e910cd4655e76a/
m = re.search(r"bundle/([0-9A-Fa-f]+)", bundle_url)
if not m:
return None
return m.group(1)
def get_lava_results(self):
""" Get lava results from all tests run in the last 2 days."""
self.get_server()
bundles = []
try:
bundles = self.server.dashboard.bundles("%s" % (self.lava_stream))
except xmlrpclib.Fault:
# Problem with LAVA xmlrpc call.
self.log.error("Error: Couldn't get test results from LAVA.")
except xmlrpclib.ProtocolError:
# Problem connecting to LAVA.
self.log.error("Error: Couldn't connect to LAVA.")
lava_results = []
# Since we're operating on fresh builds, we know the bundle will
# have been uploaded in the last 48 hrs, so prune out older ones.
for bundle in bundles:
if (datetime.datetime.strptime("%s" % (bundle["uploaded_on"]),
"%Y%m%dT%H:%M:%S") >
(datetime.datetime.now() - datetime.timedelta(2))):
try:
s = json.loads(
self.server.dashboard.get(bundle["content_sha1"])["content"])
if (s.has_key("test_runs") and
s["test_runs"][0].has_key("attributes")):
lava_results.append([s["test_runs"][0]["attributes"],
s["test_runs"][0]["test_results"],
bundle["content_sha1"]])
except xmlrpclib.Fault:
# Not a user-friendly identifier, but we'd need to download
# the bundle to work out which build it corresponds to
# and this error occurs when we can't do that.
self.log.error("Error: Couldn't fetch test results for %s" % (
bundle["content_sha1"]))
continue
except xmlrpclib.ProtocolError:
# Problem connecting to LAVA.
self.log.error("Error: Couldn't connect to LAVA.")
continue
return lava_results
def find_lava_result(self, build_url):
""" Check for LAVA result. """
if self.lava_results is None:
self.lava_results = self.get_lava_results()
overall_result = "not tested"
result_hash = ""
for lava_result in self.lava_results:
if lava_result[0]["android.url"] == build_url:
result_hash = lava_result[2]
overall_result = "pass"
for result in lava_result[1]:
if result["result"] != "pass":
overall_result = result["result"]
break
return overall_result, result_hash
|