[LNT] r255970 - Show other regressions in regression graphs

Chris Matthews via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 17 18:12:36 PST 2015


Author: cmatthews
Date: Thu Dec 17 20:12:35 2015
New Revision: 255970

URL: http://llvm.org/viewvc/llvm-project?rev=255970&view=rev
Log:
Show other regressions in regression graphs

Expose an API for getting regression based on a graph. Fetch those regression with JS, then render them into the graph. Hyperlink them.

Modified:
    lnt/trunk/lnt/server/ui/api.py
    lnt/trunk/lnt/server/ui/static/lnt_graph.js
    lnt/trunk/lnt/server/ui/templates/v4_regression_detail.html

Modified: lnt/trunk/lnt/server/ui/api.py
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/lnt/server/ui/api.py?rev=255970&r1=255969&r2=255970&view=diff
==============================================================================
--- lnt/trunk/lnt/server/ui/api.py (original)
+++ lnt/trunk/lnt/server/ui/api.py Thu Dec 17 20:12:35 2015
@@ -190,6 +190,48 @@ class Graph(Resource):
         return samples
 
 
+class Regression(Resource):
+    """List all the machines and give summary information."""
+    method_decorators = [in_db]
+
+    def get(self, machine_id, test_id, field_index):
+        """Get the regressions for a particular line in a graph."""
+        ts = request.get_testsuite()
+        field = ts.sample_fields[field_index]
+        # Maybe we don't need to do this?
+        fcs = ts.query(ts.FieldChange) \
+            .filter(ts.FieldChange.machine_id == machine_id) \
+            .filter(ts.FieldChange.test_id == test_id) \
+            .filter(ts.FieldChange.field_id == field.id) \
+            .all()
+        fc_ids = [x.id for x in fcs]
+        fc_mappings = dict([(x.id, (x.end_order.as_ordered_string(), x.new_value)) for x in fcs])
+        if len(fcs) == 0:
+            # If we don't find anything, lets see if we are even looking
+            # for a valid thing to provide a nice error.
+            try:
+                machine = ts.query(ts.Machine) \
+                    .filter(ts.Machine.id == machine_id) \
+                    .one()
+                test = ts.query(ts.Test) \
+                    .filter(ts.Test.id == test_id) \
+                    .one()
+                field = ts.sample_fields[field_index]
+            except NoResultFound:
+                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) \
+            .join(ts.RegressionIndicator) \
+            .filter(ts.RegressionIndicator.field_change_id.in_(fc_ids)) \
+            .all()
+        results = [{'title': r.title,
+                    'id': r.id, 
+                    'state': r.state, 
+                    'end_point': fc_mappings[r.field_change_id]} for r in regressions]
+        return results
+
+
 def load_api_resources(api):
     api.add_resource(Machines, ts_path("machines"))
     api.add_resource(Machine, ts_path("machine/<int:machine_id>"))
@@ -197,3 +239,5 @@ def load_api_resources(api):
     api.add_resource(Order, ts_path("order/<int:order_id>"))
     graph_url = "graph/<int:machine_id>/<int:test_id>/<int:field_index>"
     api.add_resource(Graph, ts_path(graph_url))
+    regression_url = "regression/<int:machine_id>/<int:test_id>/<int:field_index>"
+    api.add_resource(Regression, ts_path(regression_url))

Modified: lnt/trunk/lnt/server/ui/static/lnt_graph.js
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/lnt/server/ui/static/lnt_graph.js?rev=255970&r1=255969&r2=255970&view=diff
==============================================================================
--- lnt/trunk/lnt/server/ui/static/lnt_graph.js (original)
+++ lnt/trunk/lnt/server/ui/static/lnt_graph.js Thu Dec 17 20:12:35 2015
@@ -5,6 +5,28 @@ var is_checked = []; // The current list
 var normalize = false;
 var MAX_TO_DRAW = 25;
 
+var STATE_NAMES = {0: 'Detected',
+                   1: 'Staged',
+                   10: 'Active',
+                   20: 'Not to be Fixed',
+                   21: 'Ignored',
+                   23: 'Verify',
+                   22: 'Fixed'};
+
+var regression_cache = [];
+
+// Grab the graph API url for this line.
+function get_api_url(kind, db, ts, mtf) {
+    return ["/api", "db_"+ db, "v4", ts, kind, mtf].join('/');
+}
+
+// Grab the URL for a regression by id.
+function get_regression_url(db, ts, regression) {
+    return ["", "db_"+ db, "v4", ts, "regressions", regression].join('/');
+}
+
+
+
 function try_normal(data_array, end_rev) {
     $("#graph_range").prop("min", 0);
     var max = $("#graph_range").prop("max");
@@ -53,15 +75,25 @@ function normalize_data(data_array) {
     
 }
 
-function make_graph_point_entry(data, color) {
+function make_graph_point_entry(data, color, regression) {
+    var radius = 0.25;
+    var fill = true;
+    if (regression) {
+        radius = 5.0;
+        fill = false;
+        color = "red";
+    }
     var entry = {"color": color,
                  "data": data,
                  "lines": {"show": false},
-                 "points": {"fill": true,
-                            "radius": 0.25,
+                 "points": {"fill": fill,
+                            "radius": radius,
                             "show": true
                            }
                 };
+    if (regression) {
+            entry["points"]["symbol"] = "cross";
+    }
     return entry;
 }
 
@@ -80,6 +112,38 @@ function new_graph_data_callback(data, i
     update_graph();
 }
 
+function get_regression_id() {
+    var path = window.location.pathname.split("/");
+    if (path[path.length - 2] == "regressions") {
+        return parseInt(path[path.length - 1]);
+    } else {
+        return null;
+    }
+}
+
+
+
+function new_graph_regression_callback(data, index) {
+    $.each(data, function (i, d) {
+
+        if (get_regression_id() != null) {
+            if (get_regression_id() == d['id'] || d['state'] == 21) {
+                return;
+            }
+        }
+        if ( ! (regression_cache[index])) {
+            regression_cache[index] = [];
+        }
+        metadata = {'label': d['end_point'][0],
+                    'title': d['title'],
+                    'link': get_regression_url(db_name, test_suite_name, d['id']),
+                    'state': STATE_NAMES[d['state']]}
+        regression_cache[index].push([parseInt(d['end_point'][0]), d['end_point'][1],metadata]);
+    });
+    update_graph();
+}
+
+
 NOT_DRAWING = '<div class="alert alert-success" role="alert">' +
             'Too many to graph.<a href="#" class="close" data-dismiss="alert" aria-label="close">×</a>' + 
                         '</div>';
@@ -87,6 +151,7 @@ function update_graph() {
     var to_draw = [];
     var starts = [];
     var ends = [];
+    // Data.
     for ( var i = 0; i < changes.length; i++) {
             
             if (is_checked[i] && data_cache[i]) {
@@ -94,12 +159,26 @@ function update_graph() {
                     ends.push(changes[i].end);
                     var color = color_codes[i % color_codes.length];
                     var data = try_normal(data_cache[i], changes[i].end);
-                    to_draw.push(make_graph_point_entry(data, color));
+
+                    to_draw.push(make_graph_point_entry(data, color, false));
                     to_draw.push({"color": color, "data": data});
+                
+            }
+    }
+    // Regressions.
+    for ( var i = 0; i < changes.length; i++) {
+            
+            if (is_checked[i] && data_cache[i]) {
+                    if (regression_cache[i]) {
+                        var regressions = try_normal(regression_cache[i], changes[i].end);
+                        to_draw.push(make_graph_point_entry(regressions, color, true));
+                    }
+                
             }
     }
     var lowest_rev = Math.min.apply(Math, starts);
     var highest_rev = Math.max.apply(Math, ends);
+    console.log(to_draw);
     init(to_draw, lowest_rev, highest_rev);    
 }
 
@@ -111,8 +190,11 @@ function add_data_to_graph(URL, index) {
         is_checked[index] = true;
         return;
     }
-    $.getJSON(URL, function(data) {
+    $.getJSON(get_api_url("graph", db_name, test_suite_name, URL), function(data) {
         new_graph_data_callback(data, index);
         });
+    $.getJSON(get_api_url("regression", db_name, test_suite_name, URL), function(data) {
+        new_graph_regression_callback(data, index);
+        });
     is_checked[index] = true;
 }

Modified: lnt/trunk/lnt/server/ui/templates/v4_regression_detail.html
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/lnt/server/ui/templates/v4_regression_detail.html?rev=255970&r1=255969&r2=255970&view=diff
==============================================================================
--- lnt/trunk/lnt/server/ui/templates/v4_regression_detail.html (original)
+++ lnt/trunk/lnt/server/ui/templates/v4_regression_detail.html Thu Dec 17 20:12:35 2015
@@ -12,6 +12,9 @@
   <script language="javascript" type="text/javascript"
           src="{{ url_for('.static',
                           filename='flot/jquery.flot.min.js') }}"> </script>
+                          <script language="javascript" type="text/javascript"
+                                  src="{{ url_for('.static',
+                                                  filename='flot/jquery.flot.symbol.min.js') }}"> </script>  
   <script language="javascript" type="text/javascript"
           src="{{ url_for('.static',
                           filename='flot/jquery.flot.errorbars.min.js') }}"> </script>
@@ -32,17 +35,20 @@
 
 {% block javascript %}
 var g = {}
-{% set api_graph = "api/db_default/v4/" + testsuite_name + "/graph"%}
+
 var changes = [
 {% for form_change in form.field_changes%}
     {% set fc = changes[loop.index -1] %}
-    {"url": "/{{api_graph}}/{{ fc.ri.machine.id}}/{{fc.ri.test.id}}/{{fc.ri.field.index}}",
+    {"url": "{{fc.ri.machine.id}}/{{fc.ri.test.id}}/{{fc.ri.field.index}}",
      "start": {{fc.ri.start_order.llvm_project_revision}},
      "end": {{fc.ri.end_order.llvm_project_revision}}
  },
 {% endfor %}
 ];
 
+var test_suite_name = "{{ testsuite_name }}";
+var db_name = "{{ request.view_args.db_name }}";
+
 /* Bind events to the zoom bar buttons, so that 
  * the zoom buttons work, then position them
  * over top of the main graph.
@@ -95,13 +101,14 @@ function init(data, start_highlight, end
       pan : { interactive : true,
               frameRate: 60 },
       grid : {
-        hoverable : true }
+        hoverable : true,
+        clickable: true}
       };
 
   var main_plot = $.plot("#graph", graph_plots, graph_options);
 
   // Add tooltips.
-  $("#graph").bind("plothover", function(e,p,i) {
+  $("#graph").bind("plotclick", function(e,p,i) {
     update_tooltip(e, p, i, show_tooltip, graph_plots); });
   bind_zoom_bar(main_plot);
  
@@ -117,7 +124,7 @@ function show_tooltip(x, y, item, pos, g
         var index = item.dataIndex;
         var series_index = item.seriesIndex;
         // Graph data is formatted as [x, y, meta_data].
-        var meta_data = item.series.data[series_index][2];
+        var meta_data = item.series.data[index][2];
         return meta_data;
 
     }
@@ -125,6 +132,10 @@ function show_tooltip(x, y, item, pos, g
     var meta_data = extract_metadata(item, graph_data);
     var tip_body = '<div id="tooltip">';
 
+    if ("title" in meta_data) {    
+        tip_body +=  "<b><a href=\"" + metadata.link + "\">" + meta_data.title + "</a></b></br>";
+    }
+
     if ("test_name" in meta_data) {
         tip_body += "<b>Test:</b> " + meta_data.test_name + "<br>";
     }
@@ -137,6 +148,10 @@ function show_tooltip(x, y, item, pos, g
     if ("date" in meta_data) {
         tip_body += "<b>Date:</b> " + meta_data.date;
     }
+    if ("state" in meta_data) {
+        tip_body += "<b>State:</b> " + meta_data.state;
+    }
+
     tip_body += "</div>";
     var tooltip_div = $(tip_body).css( {
         position: 'absolute',
@@ -146,7 +161,8 @@ function show_tooltip(x, y, item, pos, g
         border: '1px solid #fdd',
         padding: '2px',
         'background-color': '#fee',
-        opacity: 0.80
+        opacity: 0.80,
+        'z-index': 100000
     }).appendTo("body").fadeIn(200);
 
     // Now make sure the tool tip is on the graph canvas.
@@ -174,7 +190,9 @@ function show_tooltip(x, y, item, pos, g
 // Event handler function to update the tooltop.
 function update_tooltip(event, pos, item, show_fn, graph_data) {
     if (!item) {
-        $("#tooltip").remove();
+        $("#tooltip").fadeOut(200, function () {
+            $("#tooltip").remove();    
+        });
         g.current_tip_point = null;
         return;
     }




More information about the llvm-commits mailing list