[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