[LNT] r305722 - Enhance APIs
Chris Matthews via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 19 10:58:14 PDT 2017
Author: cmatthews
Date: Mon Jun 19 12:58:14 2017
New Revision: 305722
URL: http://llvm.org/viewvc/llvm-project?rev=305722&view=rev
Log:
Enhance APIs
Export more data via the APIs. For runs and machines show their
property data. As well, export the real run list into the machine
detail listing.
Modified:
lnt/trunk/lnt/server/db/testsuitedb.py
lnt/trunk/lnt/server/ui/api.py
lnt/trunk/tests/server/ui/test_api.py
Modified: lnt/trunk/lnt/server/db/testsuitedb.py
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/lnt/server/db/testsuitedb.py?rev=305722&r1=305721&r2=305722&view=diff
==============================================================================
--- lnt/trunk/lnt/server/db/testsuitedb.py (original)
+++ lnt/trunk/lnt/server/db/testsuitedb.py Mon Jun 19 12:58:14 2017
@@ -223,6 +223,10 @@ class TestSuiteDB(object):
', '.join(self.get_field(field)
for field in self.fields),)
+ @property
+ def name(self):
+ return self.as_ordered_string()
+
def __cmp__(self, b):
# SA occassionally uses comparison to check model instances
# verse some sentinels, so we ensure we support comparison
@@ -250,6 +254,7 @@ class TestSuiteDB(object):
order = dict((item.name, self.get_field(item))
for item in self.fields)
order[u'id'] = self.id
+ order[u'name'] = self.as_ordered_string()
return strip(order)
Modified: lnt/trunk/lnt/server/ui/api.py
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/lnt/server/ui/api.py?rev=305722&r1=305721&r2=305722&view=diff
==============================================================================
--- lnt/trunk/lnt/server/ui/api.py (original)
+++ lnt/trunk/lnt/server/ui/api.py Mon Jun 19 12:58:14 2017
@@ -1,9 +1,13 @@
+import json
+
from flask import current_app, g
from flask import request
-from sqlalchemy.orm.exc import NoResultFound
from flask_restful import Resource, reqparse, fields, marshal_with, abort
+from sqlalchemy.orm import joinedload
+from sqlalchemy.orm.exc import NoResultFound
+
from lnt.testing import PASS
-import json
+
parser = reqparse.RequestParser()
parser.add_argument('db', type=str)
@@ -11,6 +15,7 @@ parser.add_argument('db', type=str)
def in_db(func):
"""Extract the database information off the request and attach to
particular test suite and database."""
+
def wrap(*args, **kwargs):
db = kwargs.pop('db')
ts = kwargs.pop('ts')
@@ -25,6 +30,7 @@ def in_db(func):
# Make sure that any transactions begun by this request are finished.
request.get_db().rollback()
return result
+
return wrap
@@ -55,7 +61,6 @@ def with_ts(obj):
# This date format is what the JavaScript in the LNT frontend likes.
DATE_FORMAT = "iso8601"
-
machines_fields = {
'id': fields.Integer,
'name': fields.String,
@@ -75,36 +80,17 @@ class Machines(Resource):
return changes
-machine_fields = {
+order_fields = {
'id': fields.Integer,
'name': fields.String,
- 'os': fields.String,
- 'hardware': fields.String,
- 'runs': fields.List(fields.Url('runs')),
+ 'next_order_id': fields.Integer,
+ 'previous_order_id': fields.Integer,
}
-class Machine(Resource):
- """Detailed results about a particular machine, including runs on it."""
- method_decorators = [in_db]
-
- @marshal_with(machine_fields)
- def get(self, machine_id):
-
- ts = request.get_testsuite()
- try:
- machine = ts.query(ts.Machine).filter(
- ts.Machine.id == machine_id).one()
- except NoResultFound:
- abort(404, message="Invalid machine.")
-
- machine = with_ts(machine)
- machine_runs = ts.query(ts.Run.id).join(ts.Machine).filter(
- ts.Machine.id == machine_id).all()
-
- machine['runs'] = with_ts([dict(run_id=x[0]) for x in machine_runs])
- print machine['runs']
- return machine
+class ParameterItem(fields.Raw):
+ def output(self, key, value):
+ return dict(json.loads(value['parameters_data']))
run_fields = {
@@ -114,7 +100,19 @@ run_fields = {
'machine_id': fields.Integer,
'machine': fields.Url("machine"),
'order_id': fields.Integer,
- 'order': fields.Url("order"),
+ 'order_url': fields.Url("order"),
+ 'parameters': ParameterItem
+}
+
+run_fields['order'] = fields.Nested(order_fields)
+
+machine_fields = {
+ 'id': fields.Integer,
+ 'name': fields.String,
+ 'os': fields.String,
+ 'hardware': fields.String,
+ 'runs': fields.List(fields.Nested(run_fields)),
+ 'parameters': ParameterItem
}
@@ -125,21 +123,46 @@ class Runs(Resource):
def get(self, run_id):
ts = request.get_testsuite()
try:
- changes = ts.query(ts.Run).join(ts.Machine).filter(
- ts.Run.id == run_id).one()
+ run = ts.query(ts.Run) \
+ .join(ts.Machine) \
+ .join(ts.Order) \
+ .filter(ts.Run.id == run_id) \
+ .options(joinedload('order')) \
+ .options(joinedload('machine')) \
+ .one()
except NoResultFound:
abort(404, message="Invalid run.")
- changes = with_ts(changes)
- return changes
+ run = with_ts(run)
+ return run
-order_fields = {
- 'id': fields.Integer,
- 'llvm_project_revision': fields.String,
- 'next_order_id': fields.Integer,
- 'previous_order_id': fields.Integer,
-}
+class Machine(Resource):
+ """Detailed results about a particular machine, including runs on it."""
+ method_decorators = [in_db]
+
+ @marshal_with(machine_fields)
+ def get(self, machine_id):
+
+ ts = request.get_testsuite()
+ try:
+ machine = ts.query(ts.Machine).filter(
+ ts.Machine.id == machine_id).one()
+ except NoResultFound:
+ abort(404, message="Invalid machine.")
+
+ machine = with_ts(machine)
+ machine_runs = ts.query(ts.Run) \
+ .join(ts.Machine) \
+ .join(ts.Order) \
+ .filter(ts.Machine.id == machine_id) \
+ .options(joinedload('order')) \
+ .all()
+
+ machine['runs'] = with_ts(machine_runs)
+ machine['a'] = [m.parameters for m in machine_runs]
+
+ return machine
class Order(Resource):
@@ -149,10 +172,10 @@ class Order(Resource):
def get(self, order_id):
ts = request.get_testsuite()
try:
- changes = ts.query(ts.Order).filter(ts.Order.id == order_id).one()
+ order = ts.query(ts.Order).filter(ts.Order.id == order_id).one()
except NoResultFound:
abort(404, message="Invalid order.")
- return changes
+ return order
class Graph(Resource):
@@ -185,14 +208,15 @@ class Graph(Resource):
if field.status_field:
q = q.filter((field.status_field.column == PASS) |
(field.status_field.column == None))
-
+
limit = request.args.get('limit', None)
if limit:
limit = int(limit)
if limit:
q = q.limit(limit)
-
- samples = [[rev, val, {'label': rev, 'date': str(time), 'runID': str(rid)}] for val, rev, time, rid in q.all()[::-1]]
+
+ samples = [[rev, val, {'label': rev, 'date': str(time), 'runID': str(rid)}] for val, rev, time, rid in
+ q.all()[::-1]]
return samples
@@ -228,13 +252,14 @@ class Regression(Resource):
return abort(404)
# I think we found nothing.
return []
- regressions = ts.query(ts.Regression.title, ts.Regression.id, ts.RegressionIndicator.field_change_id, ts.Regression.state) \
+ regressions = ts.query(ts.Regression.title, ts.Regression.id, ts.RegressionIndicator.field_change_id,
+ ts.Regression.state) \
.join(ts.RegressionIndicator) \
.filter(ts.RegressionIndicator.field_change_id.in_(fc_ids)) \
.all()
results = [{'title': r.title,
- 'id': r.id,
- 'state': r.state,
+ 'id': r.id,
+ 'state': r.state,
'end_point': fc_mappings[r.field_change_id]} for r in regressions]
return results
Modified: lnt/trunk/tests/server/ui/test_api.py
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/tests/server/ui/test_api.py?rev=305722&r1=305721&r2=305722&view=diff
==============================================================================
--- lnt/trunk/tests/server/ui/test_api.py (original)
+++ lnt/trunk/tests/server/ui/test_api.py Mon Jun 19 12:58:14 2017
@@ -7,14 +7,14 @@
#
# RUN: python %s %t.instance
-import unittest
import logging
import sys
+import unittest
import lnt.server.db.migrate
import lnt.server.ui.app
-
from V4Pages import check_json
+
logging.basicConfig(level=logging.DEBUG)
machines_expected_response = [{u'hardware': u'x86_64',
@@ -30,34 +30,8 @@ machines_expected_response = [{u'hardwar
u'id': 3,
u'name': u'machine3'}]
-# Machine add some extra fields, so add them.
-machine_expected_response = list(machines_expected_response)
-machine_expected_response[0] = machines_expected_response[0].copy()
-machine_expected_response[0][u'runs'] = [u'/api/db_default/v4/nts/run/1',
- u'/api/db_default/v4/nts/run/2']
-
-machine_expected_response[1] = machines_expected_response[1].copy()
-machine_expected_response[1][u'runs'] = [u'/api/db_default/v4/nts/run/3',
- u'/api/db_default/v4/nts/run/5',
- u'/api/db_default/v4/nts/run/6',
- u'/api/db_default/v4/nts/run/7',
- u'/api/db_default/v4/nts/run/8',
- u'/api/db_default/v4/nts/run/9']
-
-machine_expected_response[2] = machines_expected_response[2].copy()
-machine_expected_response[2][u'runs'] = [u'/api/db_default/v4/nts/run/4']
-
-
-run_expected_response = [{u'end_time': u'2012-04-11T16:28:58',
- u'id': 1,
- u'machine_id': 1,
- u'machine': u'/api/db_default/v4/nts/machine/1',
- u'order_id': 1,
- u'order': u'/api/db_default/v4/nts/order/1',
- u'start_time': u'2012-04-11T16:28:23'}]
-
order_expected_response = {u'id': 1,
- u'llvm_project_revision': "154331",
+ u'name': "154331",
u'next_order_id': 0,
u'previous_order_id': 2}
@@ -71,9 +45,9 @@ graph_data = [[u'152292', 1.0,
u'runID': u'6'}]]
graph_data2 = [[u'152293', 10.0,
- {u'date': u'2012-05-03 16:28:24',
- u'label': u'152293',
- u'runID': u'6'}]]
+ {u'date': u'2012-05-03 16:28:24',
+ u'label': u'152293',
+ u'runID': u'6'}]]
class JSONAPITester(unittest.TestCase):
@@ -93,20 +67,31 @@ class JSONAPITester(unittest.TestCase):
client = self.client
j = check_json(client, 'api/db_default/v4/nts/machines')
self.assertEquals(j, machines_expected_response)
- for i in xrange(0, len(machine_expected_response)):
- j = check_json(client, 'api/db_default/v4/nts/machine/' +
- str(i + 1))
- self.assertEquals(j, machine_expected_response[i])
+ j = check_json(client, 'api/db_default/v4/nts/machine/1')
+ self.assertEqual(j.keys(), [u'runs', u'name', u'parameters', u'hardware', u'os', u'id'])
+ expected = {"hardware": "x86_64", "os": "Darwin 11.3.0", "id": 1}
+ self.assertDictContainsSubset(expected, j)
def test_run_api(self):
"""Check /run/n returns expected run information."""
client = self.client
j = check_json(client, 'api/db_default/v4/nts/run/1')
- self.assertEquals(j, run_expected_response[0])
-
- for i in xrange(0, len(run_expected_response)):
- j = check_json(client, 'api/db_default/v4/nts/run/' + str(i + 1))
- self.assertEquals(j, run_expected_response[i])
+ expected = {"machine": "/api/db_default/v4/nts/machine/1",
+ "order_url": "/api/db_default/v4/nts/order/1",
+ "end_time": "2012-04-11T16:28:58",
+
+ "order_id": 1,
+ "start_time": "2012-04-11T16:28:23",
+ "machine_id": 1,
+ "id": 1,
+ "order": {
+ "previous_order_id": 2,
+ "next_order_id": 0,
+ "id": 1,
+ "name": "154331"
+ }
+ }
+ self.assertDictContainsSubset(expected, j)
def test_order_api(self):
""" Check /order/n returns the expected order information."""
@@ -120,10 +105,11 @@ class JSONAPITester(unittest.TestCase):
j = check_json(client, 'api/db_default/v4/nts/graph/2/4/3')
self.assertEqual(graph_data, j)
-
+
# Now check that limit works.
j2 = check_json(client, 'api/db_default/v4/nts/graph/2/4/3?limit=1')
self.assertEqual(graph_data2, j2)
+
if __name__ == '__main__':
unittest.main(argv=[sys.argv[0], ])
More information about the llvm-commits
mailing list