[LNT] r308019 - Fix missing "Produced by" field on Run causing UI crash.

Kristof Beyls via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 14 05:01:25 PDT 2017


Author: kbeyls
Date: Fri Jul 14 05:01:25 2017
New Revision: 308019

URL: http://llvm.org/viewvc/llvm-project?rev=308019&view=rev
Log:
Fix missing "Produced by" field on Run causing UI crash.

When a given run contains a "producer" value (usually an URL pointing to build
systems), the run details page can crash when displaying this run in cases when
the previous or baseline runs do not contain a valid value for the "producer"
field.

It is possible to see the following error message:

...
File "/sandbox/lnt/server/ui/filters.py", line 47, in filter_producerAsHTML
  if not producer:
jinja2.exceptions.UndefinedError: 'dict object' has no attribute 'producer'

This change prevents the UI to crash when "producer" is not found. It also adds
a test change to capture this situation.

Patch by Leandro Nunes.
Differential Revision: https://reviews.llvm.org/D35001


Modified:
    lnt/trunk/lnt/server/ui/templates/reporting/runs.html
    lnt/trunk/lnt/server/ui/util.py
    lnt/trunk/tests/server/ui/Inputs/V4Pages_extra_records.sql
    lnt/trunk/tests/server/ui/V4Pages.py

Modified: lnt/trunk/lnt/server/ui/templates/reporting/runs.html
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/lnt/server/ui/templates/reporting/runs.html?rev=308019&r1=308018&r2=308019&view=diff
==============================================================================
--- lnt/trunk/lnt/server/ui/templates/reporting/runs.html (original)
+++ lnt/trunk/lnt/server/ui/templates/reporting/runs.html Fri Jul 14 05:01:25 2017
@@ -94,7 +94,9 @@
       <td style="{{ styles['td'] }}"><span class="utctime">{{ r.start_time.isoformat() }}</span></td>
       <td style="{{ styles['td'] }}">{{ r.end_time - r.start_time }}</td>
       {% if show_producers %}
-        <td style="{{ styles['td'] }}">{{ r.parameters.producer|producerAsHTML }}</td>
+        <td style="{{ styles['td'] }}">
+          {{ r.parameters.producer|producerAsHTML|safe if 'producer' in r.parameters else "" }}
+        </td>
       {% endif %}
     </tr>
     {% else %}

Modified: lnt/trunk/lnt/server/ui/util.py
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/lnt/server/ui/util.py?rev=308019&r1=308018&r2=308019&view=diff
==============================================================================
--- lnt/trunk/lnt/server/ui/util.py (original)
+++ lnt/trunk/lnt/server/ui/util.py Fri Jul 14 05:01:25 2017
@@ -298,8 +298,8 @@ def renderProducerAsHTML(producer):
         builder = m.group(2)
         build = m.group(3)
 
-        png_url = 'http://%(url)s/png?builder=%(builder)s&number=%(build)s' % locals()
-        img = '<img src="%(png_url)s">' % locals()
+        png_url = 'http://%(url)s/png?builder=%(builder)s&number=%(build)s' % locals()
+        img = '<img src="%(png_url)s" />' % locals()
         return '<a href="%(producer)s">%(builder)s #%(build)s %(img)s</a>' % locals()
 
     elif producer.startswith('http://'):

Modified: lnt/trunk/tests/server/ui/Inputs/V4Pages_extra_records.sql
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/tests/server/ui/Inputs/V4Pages_extra_records.sql?rev=308019&r1=308018&r2=308019&view=diff
==============================================================================
--- lnt/trunk/tests/server/ui/Inputs/V4Pages_extra_records.sql (original)
+++ lnt/trunk/tests/server/ui/Inputs/V4Pages_extra_records.sql Fri Jul 14 05:01:25 2017
@@ -40,7 +40,8 @@ INSERT INTO "NT_Order" ("NextOrder", "Pr
 INSERT INTO "NT_Run" ("MachineID", "OrderID", "ImportedFrom", "StartTime",
                       "EndTime", "SimpleRunID", "Parameters")
  VALUES(2,5,'run5.json','2012-05-01 16:28:23.000000',
-        '2012-05-01 16:28:58.000000',NULL,'[]'); -- ID 5
+        '2012-05-01 16:28:58.000000',NULL,
+        '[["producer", "http://buildbot.server.url/builders/some-builder/builds/987"]]'); -- ID 5
 INSERT INTO "NT_Sample" ("RunID", "TestID", "compile_status",
                          "execution_status", "compile_time", "execution_time",
                          "score", "mem_bytes")
@@ -76,7 +77,8 @@ INSERT INTO "NT_Order" ("NextOrder", "Pr
 INSERT INTO "NT_Run" ("MachineID", "OrderID", "ImportedFrom", "StartTime",
                       "EndTime", "SimpleRunID", "Parameters")
  VALUES(2,6,'run7.json','2012-05-10 16:28:23.000000',
-        '2012-05-10 16:28:58.000000',NULL,'[]'); -- ID 7
+        '2012-05-10 16:28:58.000000',NULL,
+        '[["producer", "http://my.build.server/buildResult"]]'); -- ID 7
 INSERT INTO "NT_Run" ("MachineID", "OrderID", "ImportedFrom", "StartTime",
                       "EndTime", "SimpleRunID", "Parameters")
  VALUES(2,7,'run8.json','2012-05-11 16:28:23.000000',

Modified: lnt/trunk/tests/server/ui/V4Pages.py
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/tests/server/ui/V4Pages.py?rev=308019&r1=308018&r2=308019&view=diff
==============================================================================
--- lnt/trunk/tests/server/ui/V4Pages.py (original)
+++ lnt/trunk/tests/server/ui/V4Pages.py Fri Jul 14 05:01:25 2017
@@ -74,6 +74,16 @@ def get_xml_tree(html_string):
     return tree
 
 
+def find_table_by_thead_content(tree, table_head_contents):
+    all_tables = tree.findall(".//thead/..")
+    found_header = False
+    for table in all_tables:
+        for child in table.findall('./thead/tr/th'):
+            if child.text == table_head_contents:
+                return table
+    return None
+
+
 def find_table_with_heading(tree, table_heading):
     table_parent_elements = tree.findall(".//table/..")
     found_header = False
@@ -124,10 +134,21 @@ def get_results_table(client, url, field
     return get_table_by_header(client, url, table_header)
 
 
+def get_table_body_content(table):
+    return [[convert_html_to_text(cell).strip()
+             for cell in row.findall("./td")]
+             for row in table.findall("./tbody/tr")]
+
+
+def check_row_is_in_table(table, expected_row_content):
+    body_content = get_table_body_content(table)
+    assert expected_row_content in body_content, \
+        "Expected row content %s not found in %s" % \
+        (expected_row_content, body_content)
+
+
 def check_table_content(table, expected_content):
-    body_content = [[convert_html_to_text(cell).strip()
-                     for cell in row.findall("./td")]
-                    for row in table.findall("./tbody/tr")]
+    body_content = get_table_body_content(table)
     assert expected_content == body_content, \
         "Expected table content %s, found %s" % \
         (expected_content, body_content)
@@ -144,6 +165,14 @@ def check_body_nr_tests_table(client, ur
     check_table_content(table, expected_content)
 
 
+def check_producer_label(client, url, label):
+    table_header = "Produced by"
+    resp = check_code(client, url)
+    tree = get_xml_tree(resp.data)
+    table = find_table_by_thead_content(tree, table_header)
+    check_row_is_in_table(table, label)
+
+
 def get_sparkline(table, testname, machinename):
     body_content = [[cell
                      for cell in row.findall("./td")]
@@ -288,6 +317,16 @@ def main():
     check_redirect(client, '/v4/nts/1/graph?test.3=2',
                    'v4/nts/graph\?plot\.0=1\.3\.2&highlight_run=1$')
 
+    # Get a run that contains generic producer information
+    check_producer_label(client, '/v4/nts/7',
+                         ['Current', '152293', '2012-05-10T16:28:23',
+                          '0:00:35', 'Producer'])
+
+    # Get a run that contains Buildbot producer information
+    check_producer_label(client, '/v4/nts/7',
+                         ['Previous', '152292', '2012-05-01T16:28:23',
+                          '0:00:35', 'some-builder #987'])
+
     # Get the new graph page.
     check_code(client, '/v4/nts/graph?plot.0=1.3.2')
     # Don't crash when requesting non-existing data




More information about the llvm-commits mailing list