[LNT] r293985 - Add global, user selectable, baselines to LNT

Chris Matthews via llvm-commits llvm-commits at lists.llvm.org
Thu Feb 2 16:52:48 PST 2017


Author: cmatthews
Date: Thu Feb  2 18:52:47 2017
New Revision: 293985

URL: http://llvm.org/viewvc/llvm-project?rev=293985&view=rev
Log:
Add global, user selectable, baselines to LNT

This feature adds named baselines to LNT, and then switches
between them.  The motivation for this is to allow us to do better
tracking for many baselines, for example clang-3.9, and clang-4.0 at
the same time. Currently LNT supports one baseline per database, but
it is desirable to be able to compare with many known points in history.
The new baselines are named, to make it simpler to know what the meaning
of the baseline is.

The Order page has been updated to allow an order to be named and
promoted to a baseline.  Once promoted, that baseline will be shown in
a new global baseline dropdown.  Users can select a baseline from the
dropdown, which is stored in their session and will be used in all pages.

This commit changes the matrix page to use the new baselines. Future
commits will change other pages to use the new baselines, when the old
baseline data is no longer used I will remove the old config file
baseline.

Added:
    lnt/trunk/lnt/server/db/migrations/upgrade_10_to_11.py
Modified:
    lnt/trunk/lnt/server/db/testsuitedb.py
    lnt/trunk/lnt/server/ui/templates/layout.html
    lnt/trunk/lnt/server/ui/templates/utils.html
    lnt/trunk/lnt/server/ui/templates/v4_matrix.html
    lnt/trunk/lnt/server/ui/templates/v4_order.html
    lnt/trunk/lnt/server/ui/views.py
    lnt/trunk/tests/server/ui/V4Pages.py
    lnt/trunk/tests/server/ui/test_matrix_page.py

Added: lnt/trunk/lnt/server/db/migrations/upgrade_10_to_11.py
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/lnt/server/db/migrations/upgrade_10_to_11.py?rev=293985&view=auto
==============================================================================
--- lnt/trunk/lnt/server/db/migrations/upgrade_10_to_11.py (added)
+++ lnt/trunk/lnt/server/db/migrations/upgrade_10_to_11.py Thu Feb  2 18:52:47 2017
@@ -0,0 +1,68 @@
+# Version 8 of the database updates FieldChanges as well as adds tables
+# for Regression Tracking features.
+
+import sqlalchemy
+from sqlalchemy import *
+from sqlalchemy.orm import relation
+
+# Import the original schema from upgrade_0_to_1 since upgrade_1_to_2 does not
+# change the actual schema, but rather adds functionality vis-a-vis orders.
+import lnt.server.db.migrations.upgrade_0_to_1 as upgrade_0_to_1
+
+import lnt.server.db.migrations.upgrade_7_to_8 as upgrade_7_to_8
+
+
+def add_baselines(test_suite):
+    """Give test-suites a baseline order.
+    """
+    # Grab the Base for the previous schema so that we have all
+    # the definitions we need.
+    base = upgrade_7_to_8.add_regressions(test_suite)
+    # Grab our db_key_name for our test suite so we can properly
+    # prefix our fields/table names.
+
+    db_key_name = test_suite.db_key_name
+
+    class Baseline(base):
+        """Baselines to compare runs to."""
+        __tablename__ = db_key_name + '_Baseline'
+
+        id = Column("ID", Integer, primary_key=True)
+        name = Column("Name", String(32), unique=True)
+        comment = Column("Comment", String(256))
+        order_id = Column("OrderID", Integer,
+                          ForeignKey("%s_Order.ID" % db_key_name), index=True)
+
+    return base
+
+
+def upgrade_testsuite(engine, session, name):
+    # Grab Test Suite.
+    test_suite = session.query(upgrade_0_to_1.TestSuite). \
+        filter_by(name=name).first()
+    assert (test_suite is not None)
+
+    # Add FieldChange to the test suite.
+    base = add_baselines(test_suite)
+
+    # Create tables. We commit now since databases like Postgres run
+    # into deadlocking issues due to previous queries that we have run
+    # during the upgrade process. The commit closes all of the
+    # relevant transactions allowing us to then perform our upgrade.
+    session.commit()
+    base.metadata.create_all(engine)
+    # Commit changes (also closing all relevant transactions with
+    # respect to Postgres like databases).
+    session.commit()
+
+
+
+
+
+def upgrade(engine):
+    # Create a session.
+    session = sqlalchemy.orm.sessionmaker(engine)()
+
+    # Create our FieldChangeField table and commit.
+    upgrade_testsuite(engine, session, 'nts')
+    upgrade_testsuite(engine, session, 'compile')

Modified: lnt/trunk/lnt/server/db/testsuitedb.py
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/lnt/server/db/testsuitedb.py?rev=293985&r1=293984&r2=293985&view=diff
==============================================================================
--- lnt/trunk/lnt/server/db/testsuitedb.py (original)
+++ lnt/trunk/lnt/server/db/testsuitedb.py Thu Feb  2 18:52:47 2017
@@ -162,7 +162,6 @@ class TestSuiteDB(object):
             fields = sorted(self.order_fields,
                             key = lambda of: of.ordinal)
 
-
             id = Column("ID", Integer, primary_key=True)
 
             # Define two common columns which are used to store the previous and
@@ -590,6 +589,21 @@ class TestSuiteDB(object):
                 return '%s_%s%r' % (db_key_name, self.__class__.__name__,(
                                     self.id, self.field_change))
 
+        class Baseline(self.base, ParameterizedMixin):
+            """Baselines to compare runs to."""
+            __tablename__ = db_key_name + '_Baseline'
+
+            id = Column("ID", Integer, primary_key=True)
+            name = Column("Name", String(32), unique=True)
+            comment = Column("Comment", String(256))
+            order_id = Column("OrderID", Integer,
+                              ForeignKey("%s_Order.ID" % db_key_name),
+                              index=True)
+            order = sqlalchemy.orm.relation(Order)
+
+            def __str__(self):
+                return "Baseline({})".format(self.name)
+
         self.Machine = Machine
         self.Run = Run
         self.Test = Test
@@ -600,6 +614,7 @@ class TestSuiteDB(object):
         self.Regression = Regression
         self.RegressionIndicator = RegressionIndicator
         self.ChangeIgnore = ChangeIgnore
+        self.Baseline = Baseline
 
         # Create the compound index we cannot declare inline.
         sqlalchemy.schema.Index("ix_%s_Sample_RunID_TestID" % db_key_name,
@@ -620,6 +635,9 @@ class TestSuiteDB(object):
         self.query = self.v4db.query
         self.rollback = self.v4db.rollback
 
+    def _getBaselines(self):
+        return self.query(self.Baseline).all()
+
     def _getOrCreateMachine(self, machine_data):
         """
         _getOrCreateMachine(data) -> Machine, bool

Modified: lnt/trunk/lnt/server/ui/templates/layout.html
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/lnt/server/ui/templates/layout.html?rev=293985&r1=293984&r2=293985&view=diff
==============================================================================
--- lnt/trunk/lnt/server/ui/templates/layout.html (original)
+++ lnt/trunk/lnt/server/ui/templates/layout.html Thu Feb  2 18:52:47 2017
@@ -186,6 +186,27 @@
                             </ul>
                         </li>
                     </ul>
+                        {% endif %}
+                {% if ts is defined %}
+                <ul class="nav">
+                        <li class="dropdown">
+                            <a href="#" class="dropdown-toggle" data-toggle="dropdown">Baselines<b class="caret"></b></a>
+                            <ul class="dropdown-menu">
+                                <li class="nav-header">Select baseline:</li>
+                                {% for b in ts.query(ts.Baseline).all() %}
+                                {% set is_bold = b.id == session.get('baseline') %}
+                              <li><a href="{{ v4_url_for('v4_set_baseline', id=b.id) }}">
+                                  {% if is_bold %}
+                                      <b>{{ b.name }}</b>
+                                  {% else %}
+                                      {{ b.name }}
+                                  {% endif %}
+                              </a><p></p></li>
+                               {% endfor %}
+                                <li class="divider"></li>
+                            </ul>
+                        </li>
+                </ul>
                 {% endif %}
                 <ul class="nav pull-right">
                     <li class="dropdown">
@@ -207,6 +228,7 @@
                     {% endfor %}
                     <li class="active">{{self.title()}}</li>
                 </ul>
+
             </div>
         </div>
 

Modified: lnt/trunk/lnt/server/ui/templates/utils.html
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/lnt/server/ui/templates/utils.html?rev=293985&r1=293984&r2=293985&view=diff
==============================================================================
--- lnt/trunk/lnt/server/ui/templates/utils.html (original)
+++ lnt/trunk/lnt/server/ui/templates/utils.html Thu Feb  2 18:52:47 2017
@@ -103,3 +103,29 @@ $(document).ready(function() {
   {% endif %}
 
 {% endmacro %}
+
+
+{% macro render_field(field) %}
+    {%  if field.errors %}
+        <div class="control-group error">
+    {% else %}
+        <div>
+    {% endif %}
+
+    <dt>
+        <div class="control-label">
+            {{ field.label }}
+        </div>
+    </dt>
+    <div class="controls">
+        <dd>{{ field(**kwargs)|safe }}
+    </div>
+    <ul class="help-inline">
+    {% for error in field.errors %}
+      <li>{{ error }}</li>
+    {% endfor %}
+    </ul>
+
+    </div>
+    </dd>
+{% endmacro %}
\ No newline at end of file

Modified: lnt/trunk/lnt/server/ui/templates/v4_matrix.html
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/lnt/server/ui/templates/v4_matrix.html?rev=293985&r1=293984&r2=293985&view=diff
==============================================================================
--- lnt/trunk/lnt/server/ui/templates/v4_matrix.html (original)
+++ lnt/trunk/lnt/server/ui/templates/v4_matrix.html Thu Feb  2 18:52:47 2017
@@ -48,7 +48,7 @@
         <tr>
 
         <th>Order</th>
-        {% for r in associated_runs: %}
+        {% for r in associated_runs %}
             <th>
                 {% if not machine_name_common %}
                 <a href="{{ v4_url_for('v4_machine', id=r.machine.id) }}">{{ r.machine.name }}</a>
@@ -58,13 +58,21 @@
         <th>Geomean</th>
     </tr>
         </thead>
-        {% for order in orders: %}
+        {% for order in orders %}
             {% set baseline_class = "info" if order == baseline_rev else "" %}
+            {% set name = baseline_name if order == baseline_rev else order %}
+
             {% set baseline_rev = None if order == baseline_rev else "" %}
+
             <tr class="{{baseline_class}}">
-                <td><a href="{{v4_url_for('v4_order', id=order_to_id[order])}}">{{order}}</a>
+                <td>
+                    <a href="{{v4_url_for('v4_order', id=order_to_id[order])}}">
+                        {{name}}
+                    </a>
                     <br>
-                <span class="shortDateFormat" data-toggle="tooltip" title="{{order_to_date[order]}}">{{ order_to_date[order].isoformat() }}</span>
+                    <span class="shortDateFormat" data-toggle="tooltip" title="{{order_to_date[order]}}">
+                        {{ order_to_date[order].isoformat() }}
+                    </span>
                 </td>
                 {% for req in associated_runs: %}
                     {{ get_cell_value(req.change.get(order)) }}

Modified: lnt/trunk/lnt/server/ui/templates/v4_order.html
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/lnt/server/ui/templates/v4_order.html?rev=293985&r1=293984&r2=293985&view=diff
==============================================================================
--- lnt/trunk/lnt/server/ui/templates/v4_order.html (original)
+++ lnt/trunk/lnt/server/ui/templates/v4_order.html Thu Feb  2 18:52:47 2017
@@ -35,31 +35,83 @@
     <thead>
       <tr>
         <th>Name</th>
-        <th>Value</th>
+        <th>ID</th>
+        {% for field in order.fields %}
+           <th>{{field.name}}</th>
+        {% endfor %}
       </tr>
     </thead>
     <tbody>
       <tr>
-        <td>ID</td>
+        <td>Current Order</td>
         <td>{{order.id}}</td>
+        {% for field in order.fields %}
+                <td>{{order.get_field(field)}}</td>
+        {% endfor %}
       </tr>
+     {% if order.previous_order_id %}
       <tr>
-        <td>Previous Order ID</td>
-        <td>{{order.previous_order_id}}</td>
+        <td>Previous Order</td>
+          <td>
+              <a href="{{ v4_url_for("v4_order", id=order.previous_order_id) }}">
+                  {{order.previous_order_id}}
+              </a>
+          </td>
+          {% set previous_order = ts.query(ts.Order).filter(ts.Order.id == order.previous_order_id).one() %}
+            {% for field in previous_order.fields %}
+                <td>
+                    {{previous_order.get_field(field)}}
+                </td>
+          {% endfor %}
       </tr>
+      {% endif %}
+
+      {% if order.next_order_id %}
       <tr>
-        <td>Next ID</td>
-        <td>{{order.next_order_id}}</td>
-      </tr>
-      {% for field in order.fields %}
-      <tr>
-        <td>{{field.name}}</td>
-        <td>{{order.get_field(field)}}</td>
+        <td>Next Order</td>
+          <td><a href="{{ v4_url_for("v4_order", id=order.next_order_id) }}">{{order.next_order_id}}</a></td>
+          {% set next_order = ts.query(ts.Order).filter(ts.Order.id == order.next_order_id).one() %}
+          {% for field in next_order.fields %}
+                <td>{{next_order.get_field(field)}}</td>
+          {% endfor %}
       </tr>
-      {% endfor %}
+     {%  endif %}
     </tbody>
   </table>
 
+  <section id="baseline">
+  <div class="accordion" id="accordion">
+  <div class="accordion-group">
+    <div class="accordion-heading">
+      <a class="accordion-toggle" data-toggle="collapse" data-parent="#accordion" href="#collapseOne">
+         {% if form.name.data %}
+             Baseline - {{ form.name.data }}
+          {% else %}
+             Configure as a baseline
+          {% endif %}
+      </a>
+    </div>
+    <div id="collapseOne" class="accordion-body collapse">
+      <div class="accordion-inner">
+              <form method="POST" action="">
+          <div class="form-group">
+       {{ form.hidden_tag() }}
+          {{ utils.render_field(form.name) }}
+          {{ utils.render_field(form.description) }}
+         {% if form.name.data %}
+              {{ form.update }}
+              {{ form.demote }}
+              {% else %}
+              {{ form.promote }}
+        {% endif %}
+          </div>
+      </form>
+      </div>
+    </div>
+  </div>
+
+  </section>
+
   <section id="submissions" />
   {# List all submissions which reported for this order. #}
   <h3>Submissions</h3>

Modified: lnt/trunk/lnt/server/ui/views.py
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/lnt/server/ui/views.py?rev=293985&r1=293984&r2=293985&view=diff
==============================================================================
--- lnt/trunk/lnt/server/ui/views.py (original)
+++ lnt/trunk/lnt/server/ui/views.py Thu Feb  2 18:52:47 2017
@@ -5,6 +5,7 @@ import tempfile
 import time
 import copy
 import json
+from typing import List, Optional
 
 import flask
 from flask import session
@@ -17,13 +18,15 @@ from flask import render_template
 from flask import request
 from flask import url_for
 from flask import flash
-from lnt.server.ui.util import FLASH_DANGER
+
+from lnt.server.ui.util import FLASH_DANGER, FLASH_SUCCESS
 from lnt.testing.util.commands import warning, error, note
 import sqlalchemy.sql
 from sqlalchemy.orm.exc import NoResultFound
 
 from flask_wtf import Form
-from wtforms import SelectField
+from wtforms import SelectField, StringField, SubmitField
+from wtforms.validators import DataRequired, Length
 
 import lnt.util
 import lnt.util.ImportData
@@ -42,8 +45,27 @@ import lnt.server.db.search
 from lnt.server.ui.regression_views import PrecomputedCR
 from collections import namedtuple, defaultdict
 from lnt.util import async_ops
+from urlparse import urlparse, urljoin
+from flask import request, url_for
+
 integral_rex = re.compile(r"[\d]+")
 
+
+# http://flask.pocoo.org/snippets/62/
+def is_safe_url(target):
+    ref_url = urlparse(request.host_url)
+    test_url = urlparse(urljoin(request.host_url, target))
+    return test_url.scheme in ('http', 'https') and \
+        ref_url.netloc == test_url.netloc
+
+
+def get_redirect_target():
+    for target in request.values.get('next'), request.referrer:
+        if not target:
+            continue
+        if is_safe_url(target):
+            return target
+
 ###
 # Root-Only Routes
 
@@ -173,7 +195,8 @@ def v4_recent_activity():
     return render_template("v4_recent_activity.html",
                            testsuite_name=g.testsuite_name,
                            active_machines=active_machines,
-                           active_submissions=active_submissions)
+                           active_submissions=active_submissions,
+                           ts=ts)
 
 @v4_route("/machine/")
 def v4_machines():
@@ -437,17 +460,75 @@ def v4_run(id):
         request_info=info, urls=urls
 )
 
- at v4_route("/order/<int:id>")
+
+class PromoteOrderToBaseline(Form):
+    name = StringField('Name', validators=[DataRequired(), Length(max=32)])
+    description = StringField('Description', validators=[Length(max=256)])
+    promote = SubmitField('Promote')
+    update = SubmitField('Update')
+    demote = SubmitField('Demote')
+
+
+ at v4_route("/order/<int:id>", methods=['GET', 'POST'])
 def v4_order(id):
-    # Get the testsuite.
+    """Order page details order information, as well as runs that are in this
+    order as well setting this run as a baseline."""
     ts = request.get_testsuite()
+    form = PromoteOrderToBaseline()
+
+    if form.validate_on_submit():
+        try:
+            baseline = ts.query(ts.Baseline) \
+                .filter(ts.Baseline.order_id == id) \
+                .one()
+        except NoResultFound:
+            baseline = ts.Baseline()
+
+        if form.demote.data:
+            ts.session.delete(baseline)
+            ts.session.commit()
+
+            flash("Baseline demoted.", FLASH_SUCCESS)
+        else:
+            baseline.name = form.name.data
+            baseline.comment = form.description.data
+            baseline.order_id = id
+            ts.session.add(baseline)
+            ts.session.commit()
+
+            flash("Baseline {} updated.".format(baseline.name), FLASH_SUCCESS )
+        return redirect(v4_url_for("v4_order", id=id))
+    else:
+        print form.errors
+
+    try:
+        baseline = ts.query(ts.Baseline) \
+            .filter(ts.Baseline.order_id == id) \
+            .one()
+        form.name.data = baseline.name
+        form.description.data = baseline.comment
+    except NoResultFound:
+        pass
 
     # Get the order.
     order = ts.query(ts.Order).filter(ts.Order.id == id).first()
     if order is None:
         abort(404)
 
-    return render_template("v4_order.html", ts=ts, order=order)
+    return render_template("v4_order.html", ts=ts, order=order, form=form)
+
+
+ at v4_route("/set_baseline/<int:id>")
+def v4_set_baseline(id):
+    ts = request.get_testsuite()
+    base = ts.query(ts.Baseline).get(id)
+    if not base:
+        return abort(404)
+    flash("Baseline set to " + base.name, FLASH_SUCCESS)
+    session['baseline'] = id
+
+    return redirect(get_redirect_target())
+
 
 @v4_route("/all_orders")
 def v4_all_orders():
@@ -1309,10 +1390,27 @@ MATRIX_LIMITS = [('12', 'Small'),
                  ('250', 'Large'),
                  ('-1', 'All')]
 
+
 class MatrixOptions(Form):
     limit = SelectField('Size', choices=MATRIX_LIMITS)
 
 
+def baseline():
+    # type: () -> Optional[testsuitedb.Baseline]
+    """Get the baseline object from the user's current session baseline value
+    or None if one is not defined.
+    """
+    ts = request.get_testsuite()
+    base_id = session.get('baseline')
+    if not base_id:
+        return None
+    try:
+        base = ts.query(ts.Baseline).get(base_id)
+    except NoResultFound:
+        return None
+    return base
+
+
 @v4_route("/matrix", methods=['GET', 'POST'])
 def v4_matrix():
     """A table view for Run sample data, because *some* people really
@@ -1330,7 +1428,7 @@ def v4_matrix():
         post_limit = form.limit.data
     else:
         post_limit = MATRIX_LIMITS[0][0]
-    data_parameters = []
+    data_parameters = []  # type: List[MatrixDataRequest]
     for name, value in request.args.items():
         #  plot.<unused>=<machine id>.<test id>.<field index>
         if not name.startswith(str('plot.')):
@@ -1413,12 +1511,15 @@ def v4_matrix():
     if not all_orders:
         abort(404, "No data found.")
     # Now grab the baseline data.
-    baseline_rev = machine.DEFAULT_BASELINE_REVISION
+    user_baseline = baseline()
     backup_baseline = next(iter(all_orders))
-    if baseline_rev:
-        all_orders.add(baseline_rev)
+    if user_baseline:
+        all_orders.add(user_baseline.order.llvm_project_revision)
+        baseline_rev = user_baseline.order.llvm_project_revision
+        baseline_name = user_baseline.name
     else:
         baseline_rev = backup_baseline
+        baseline_name = backup_baseline
 
     for req in data_parameters:
         q_baseline = ts.query(req.field.column, ts.Order.llvm_project_revision, ts.Order.id) \
@@ -1437,11 +1538,11 @@ def v4_matrix():
         else:
             # Well, there is a baseline, but we did not find data for it...
             # So lets revert back to the first run.
-            print "Did not find baseline, switching to", backup_baseline
-            msg = "Did not find data for baseline {}. Switching to {}."
-            flash(msg.format(baseline_rev, backup_baseline), FLASH_DANGER)
+            msg = "Did not find data for {}. Showing {}."
+            flash(msg.format(user_baseline, backup_baseline), FLASH_DANGER)
             all_orders.remove(baseline_rev)
             baseline_rev = backup_baseline
+            baseline_name = backup_baseline
 
     all_orders = list(all_orders)
     all_orders.sort(reverse=True)
@@ -1516,6 +1617,7 @@ def v4_matrix():
                            order_to_id=order_to_id,
                            form=form,
                            baseline_rev=baseline_rev,
+                           baseline_name=baseline_name,
                            machine_name_common=machine_name_common,
                            machine_id_common=machine_id_common,
                            order_to_date=order_to_date)

Modified: lnt/trunk/tests/server/ui/V4Pages.py
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/tests/server/ui/V4Pages.py?rev=293985&r1=293984&r2=293985&view=diff
==============================================================================
--- lnt/trunk/tests/server/ui/V4Pages.py (original)
+++ lnt/trunk/tests/server/ui/V4Pages.py Thu Feb  2 18:52:47 2017
@@ -15,7 +15,7 @@ import re
 import sys
 import xml.etree.ElementTree as ET
 from htmlentitydefs import name2codepoint
-
+from flask import session
 import lnt.server.db.migrate
 import lnt.server.ui.app
 import json
@@ -32,7 +32,8 @@ def check_code(client, url, expected_cod
     """Call a flask url, and make sure the return code is good."""
     resp = client.get(url, follow_redirects=False, data=data_to_send)
     assert resp.status_code == expected_code, \
-        "Call to %s returned: %d, not the expected %d"%(url, resp.status_code, expected_code)
+        "Call to %s returned: %d, not the expected %d" % (url, resp.status_code,
+                                                          expected_code)
     return resp
 
 
@@ -204,6 +205,7 @@ def main():
 
     # Don't catch out exceptions.
     app.testing = True
+    app.config['WTF_CSRF_ENABLED'] = False
 
     # Create a test client.
     client = app.test_client()
@@ -232,6 +234,41 @@ def main():
     # Check invalid order gives error.
     check_code(client, '/v4/nts/order/9999', expected_code=HTTP_NOT_FOUND)
 
+    # Check that we can promote a baseline, then demote.
+    form_data = dict(name="foo_baseline",
+                     description="foo_descrimport iption",
+                     prmote=True)
+    r = client.post('/v4/nts/order/3', data=form_data)
+    # We should redirect to the last page and flash.
+    assert r.status_code == HTTP_REDIRECT
+
+    # Try with redirect.
+    r = client.post('/v4/nts/order/3',
+                    data=form_data,
+                    follow_redirects=True)
+    assert r.status_code == HTTP_OK
+    # Should see baseline displayed in page body.
+    assert "Baseline - foo_baseline" in r.data
+
+    # Now demote it.
+    data2 = dict(name="foo_baseline",
+                 description="foo_description",
+                 update=False,
+                 promote=False,
+                 demote=True)
+    r = client.post('/v4/nts/order/3', data=data2, follow_redirects=True)
+    assert r.status_code == HTTP_OK
+    # Baseline should no longer be shown in page baseline.
+    assert "Baseline - foo_baseline" not in r.data
+
+    # Leave a baseline in place for the rest of the tests.
+    client.post('/v4/nts/order/3', data=form_data)
+
+    check_code(client, '/v4/nts/set_baseline/1', expected_code=HTTP_REDIRECT)
+    with app.test_client() as c:
+        c.get('/v4/nts/set_baseline/1')
+        session.get('baseline') == 1
+
     # Get a run result page (and associated views).
     check_code(client, '/v4/nts/1')
     check_code(client, '/v4/nts/1?json=true')

Modified: lnt/trunk/tests/server/ui/test_matrix_page.py
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/tests/server/ui/test_matrix_page.py?rev=293985&r1=293984&r2=293985&view=diff
==============================================================================
--- lnt/trunk/tests/server/ui/test_matrix_page.py (original)
+++ lnt/trunk/tests/server/ui/test_matrix_page.py Thu Feb  2 18:52:47 2017
@@ -15,17 +15,9 @@ import lnt.server.db.migrate
 import lnt.server.ui.app
 
 from V4Pages import check_json, check_code
+from V4Pages import HTTP_REDIRECT, HTTP_OK, HTTP_BAD_REQUEST, HTTP_NOT_FOUND
 logging.basicConfig(level=logging.DEBUG)
 
-import json
-
-logging.basicConfig(level=logging.DEBUG)
-
-HTTP_BAD_REQUEST = 400
-HTTP_NOT_FOUND = 404
-HTTP_OK = 200
-
-
 class MatrixViewTester(unittest.TestCase):
     """Test the Matrix view."""
 
@@ -34,6 +26,7 @@ class MatrixViewTester(unittest.TestCase
         _, instance_path = sys.argv
         app = lnt.server.ui.app.App.create_standalone(instance_path)
         app.testing = True
+        app.config['WTF_CSRF_ENABLED'] = False
         self.client = app.test_client()
 
     def test_config_errors(self):
@@ -67,6 +60,16 @@ class MatrixViewTester(unittest.TestCase
         """
         client = self.client
         reply = check_code(client, '/v4/nts/matrix?plot.0=2.6.3')
+        # Set a baseline and run again.
+        form_data = dict(name="foo_baseline",
+                         description="foo_description",
+                         prmote=True)
+        rc = client.post('/v4/nts/order/6', data=form_data)
+        self.assertEquals(rc.status_code, HTTP_REDIRECT)
+        check_code(client, '/v4/nts/set_baseline/1',
+                   expected_code=HTTP_REDIRECT)
+
+        reply = check_code(client, '/v4/nts/matrix?plot.0=2.6.3')
         # Make sure the data is in the page.
         self.assertIn("test6", reply.data)
         self.assertIn("1.0000", reply.data)




More information about the llvm-commits mailing list