diff mbox

[Branch,~linaro-validation/lava-dashboard/trunk] Rev 256: Rewrite image_status_detail template to show visual overview ala meego reports

Message ID 20110819041613.15284.94182.launchpad@ackee.canonical.com
State Accepted
Headers show

Commit Message

Zygmunt Krynicki Aug. 19, 2011, 4:16 a.m. UTC
------------------------------------------------------------
revno: 256
committer: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>
branch nick: pristine
timestamp: Fri 2011-08-19 04:19:06 +0200
message:
  Rewrite image_status_detail template to show visual overview ala meego reports
modified:
  dashboard_app/models.py
  dashboard_app/templates/dashboard_app/image_status_detail.html


--
lp:lava-dashboard
https://code.launchpad.net/~linaro-validation/lava-dashboard/trunk

You are subscribed to branch lp:lava-dashboard.
To unsubscribe from this branch go to https://code.launchpad.net/~linaro-validation/lava-dashboard/trunk/+edit-subscription
diff mbox

Patch

=== modified file 'dashboard_app/models.py'
--- dashboard_app/models.py	2011-07-22 00:57:44 +0000
+++ dashboard_app/models.py	2011-08-19 02:19:06 +0000
@@ -757,15 +757,21 @@ 
     def get_permalink(self):
         return reverse("dashboard_app.views.redirect_to_test_run", args=[self.analyzer_assigned_uuid])
 
-    def get_summary_results(self):
+    def _get_summary_results(self, factor=3):
         stats = self.test_results.values('result').annotate(
             count=models.Count('result')).order_by()
         result = dict([
             (TestResult.RESULT_MAP[item['result']], item['count'])
             for item in stats])
         result['total'] = sum(result.values())
+        result['total_multiplied'] = result['total'] * factor
         return result
 
+    def get_summary_results(self):
+        if not hasattr(self, '_cached_summary_results'):
+            self._cached_summary_results = self._get_summary_results()
+        return self._cached_summary_results
+
     class Meta:
         ordering = ['-import_assigned_date']
 
@@ -1234,6 +1240,28 @@ 
             "fail_percent": fail_percent,
         }
 
+    def get_recent_test_runs(self, last_n_days=7 * 2):
+        until = datetime.datetime.now()
+        since = until - datetime.timedelta(days=last_n_days)
+        return self.get_test_runs(
+        ).select_related(
+        ).filter(
+            analyzer_assigned_date__range=(since, until)
+        ).order_by('-analyzer_assigned_date')
+
+    def get_chart_data(self):
+        return TestResult.objects.filter(
+            test_run__in=self.get_recent_test_runs().order_by(),
+        ).values(
+            'test_run__analyzer_assigned_date'
+        ).extra(
+            select={'bucket': 'date(analyzer_assigned_date)'},
+        ).values(
+            'bucket', 'result'
+        ).annotate(
+            count=models.Count('result')
+        ).order_by('result')
+
     def get_test_runs(self):
         return TestRun.objects.filter(
             bundle__bundle_stream__pathname="/anonymous/lava-daily/"

=== modified file 'dashboard_app/templates/dashboard_app/image_status_detail.html'
--- dashboard_app/templates/dashboard_app/image_status_detail.html	2011-07-22 00:57:44 +0000
+++ dashboard_app/templates/dashboard_app/image_status_detail.html	2011-08-19 02:19:06 +0000
@@ -1,71 +1,180 @@ 
 {% extends "dashboard_app/_content.html" %}
 {% load call %}
+{% load i18n %}
+
+
+{% block extrahead %}
+{{ block.super }}
+<!--[if IE]><script type="text/javascript" src="{{ STATIC_URL }}dashboard_app/js/excanvas.min.js"></script><![endif]-->
+<script type="text/javascript" src="{{ STATIC_URL }}dashboard_app/js/jquery.flot.min.js"></script>
+<script type="text/javascript" src="{{ STATIC_URL }}dashboard_app/js/jquery.flot.stack.min.js"></script>
+<script type="text/javascript" src="{{ STATIC_URL }}dashboard_app/js/jquery.flot.axislabels.js"></script>
+{% endblock %}
+
 
 {% block content %}
-<script type="text/javascript" charset="utf-8"> 
-  $(document).ready(function() {
-    oTable = $('#tests').dataTable({
-      "bJQueryUI": true,
-      "bPaginate": false,
-    });
-  });
-</script> 
-<table class="demo_jui display" id="tests">
-  <thead>
-    <tr>
-      <th rowspan="2">Test</th>
-      <th colspan="5">Totals</th>
-      <th colspan="4" style="border-left: 1px solid black">Most Recent Test Run</th>
-      <th rowspan="2" style="width: 30%">Description</th>
-    </th>
-    <tr>
-      <th>PASS</th>
-      <th>FAIL</th>
-      <th>FAIL rate</th>
-      <th>Test Runs</th>
-      <th>Test Results</th>
-      <th>PASS</th>
-      <th>FAIL</th>
-      <th>FAIL rate</th>
-      <th>Test Results</th>
-    </tr>
-  </thead>
-  <tbody>
-    {% for test in image_health.get_tests %}
-    {% call image_health.current_health_for_test test as current_test_health %}
-    {% call image_health.overall_health_for_test test as overall_test_health %}
-    <tr
-      {% if current_test_health.fail_count > 0 %}
-        {% if current_test_health.pass_count == 0 %}
-          style="background-color: rgba(255, 0, 0, 0.5)"
-        {% else %}
-          style="background-color: rgba(255, 165, 0, 0.5)"
-        {% endif %}
+<h2>Test history for image {{ image_health.rootfs_type }} + {{ image_health.hwpack_type }}</h2>
+{% with image_health.get_recent_test_runs as recent_test_run_list %}
+{% if recent_test_run_list %}
+<div id="legend" style="margin: auto;"></div>
+<div id="placeholder" style="width: 80%; height: 250px; margin: auto;"></div>
+<script type="text/javascript">
+  $(function () {
+    var css_id = "#placeholder";
+
+    {% with image_health.get_chart_data as chart_data %} 
+
+    {% regroup chart_data|dictsort:"bucket" by bucket as bucket_list %}
+    var tick_list = [
+      {% spaceless %}
+      {% for bucket in bucket_list %}
+      "{{ bucket.grouper }}",
+      {% endfor %}
+      {% endspaceless %}
+    ];
+    var tick_label_list = [
+      {% spaceless %}
+      {% for bucket in bucket_list %}
+      [ {{ forloop.counter0 }}, "{{ bucket.grouper }}"],
+      {% endfor %}
+      {% endspaceless %}
+    ];
+
+    {% regroup chart_data|dictsort:"result" by result as series_group_list %}
+    var label_for = ["pass", "fail", "skip", "unknown"];
+    var color_for = ["#3aad3a", "#ff3800", "yellow", "#aaad9c"];
+    var data = [
+      {% for chart_series in series_group_list %}
+      {
+        label: label_for[{{ chart_series.grouper }}],
+        color: color_for[{{ chart_series.grouper }}],
+        data: [
+          {% spaceless %}
+          {% for sample in chart_series.list %}
+          [ tick_list.indexOf("{{ sample.bucket }}"), {{ sample.count }}],
+          {% endfor %}
+          {% endspaceless %}
+        ]
+      },
+      {% endfor %}
+    ];
+    
+    {% endwith %}
+
+    var options = {
+      legend: {
+        container: "#legend",
+      },
+      grid: {
+        show: true,
+        aboveData: false,
+        backgroundColor: 'white',
+        color: '#333',
+        borderColor: null
+      },
+      series: {
+        stack: 0,
+        lines: {
+          show: false,
+          fill: false,
+          steps: false
+        },
+        bars: {
+          show: true,
+          fill: true,
+          barWidth: 0.5
+        },
+      },
+      xaxis: {
+        ticks: tick_label_list,
+      },
+      yaxis: {
+        label: "Number of test cases",
+      },
+    };
+
+    $.plot($(css_id), data, options);
+  }); 
+</script>
+<table style="margin: auto">
+  <caption>
+    History of testing {{ image_health.rootfs_type }}+{{ image_health.hwpack_type }} on a weekly basis.
+  </caption>
+  <tr>
+    <th>Date</th>
+    <th>Test</th>
+    <th colspan='2'>Results</th>
+  </tr>
+  {% regroup recent_test_run_list by analyzer_assigned_date|date:"Y W" as test_run_cluster_list %}
+  {% for test_run_cluster in test_run_cluster_list %}
+  <tr>
+    <th colspan="4" style="text-align: left; border-bottom: 1px solid #333;"
+      >{{ test_run_cluster.grouper }}</th>
+  </tr>
+  {% for test_run in test_run_cluster.list %}
+  <tr>
+    <td style="width: 10ex"><a href="{{ test_run.get_absolute_url }}">{{ test_run.analyzer_assigned_date|date:"m.d" }}</a></td>
+    <td><a href="{{ test_run.test.get_absolute_urL}}">{{ test_run.test }}</a></td>
+    <td>{{ test_run.test_results.count }}</td>
+    <td>
+      {% with test_run.get_summary_results as summary %}
+      {% with 500 as max_width %}
+      {% if summary.total_multiplied > max_width %}
+        {% if summary.pass %}
+        <div
+          title="passed: {{ summary.pass }}" 
+          style="float:left; background-color: #3aad3a; height: 1em; width: {% widthratio summary.pass summary.total max_width %}px;"></div>
+        {% endif %}
+        {% if summary.fail %}
+        <div
+          title="failed: {{ summary.fail }}" 
+          style="margin-left: 1px; float:left; background-color: #ff3800; height: 1em; width: {% widthratio summary.fail summary.total max_width %}px;"></div>
+        {% endif %}
+        {% if summary.skip %}
+        <div
+          title="skipped: {{ summary.skip }}" 
+          style="margin-left: 1px; float:left; background-color: #ff3800; height: 1em; width: {% widthratio summary.skip summary.total max_width %}px;"></div>
+        {% endif %}
+        {% if summary.unknown %}
+        <div
+          title="unknown: {{ summary.unknown }}"
+          style="margin-left: 1px; float:left; background-color: #aaad9c; height: 1em; width: {% widthratio summary.unknown summary.total max_width %}px;"></div>
+        {% endif %}
+        <div
+          style="margin-left: 1em; float: left; font-size: 80%"
+          >{% trans "graph not to scale" %}</div>
       {% else %}
-        {% if current_test_health.pass_count > 0 %}
-          style="background-color: rgba(173, 255, 47, 0.5)"
+        {% if summary.pass %}
+        <div
+          title="passed: {{ summary.pass }}" 
+          style="float:left; background-color: #3aad3a; height: 1em; width: {% widthratio summary.pass summary.total summary.total_multiplied %}px;"></div>
+        {% endif %}
+        {% if summary.fail %}
+        <div
+          title="failed: {{ summary.fail }}" 
+          style="margin-left: 1px; iloat:left; background-color: #ff3800; height: 1em; width: {% widthratio summary.fail summary.total summary.total_multiplied %}px;"></div>
+        {% endif %} 
+        {% if summary.skip %}
+        <div
+          title="skipped: {{ summary.skip }}" 
+          style="margin-left: 1px; float:left; background-color: #ff3800; height: 1em; width: {% widthratio summary.skip summary.total summary.total_multiplied %}px;"></div>
+        {% endif %}
+        {% if summary.unknown %}
+        <div
+          title="unknown: {{ summary.unknown }}"
+          style="margin-left: 1px; float:left; background-color: #aaad9c; height: 1em; width: {% widthratio summary.unknown summary.total summary.total_multiplied %}px;"></div>
         {% endif %}
       {% endif %}
-      >
-      <td>{{ test.test_id }}</td>
-      <td>{{ overall_test_health.pass_count }}</td>
-      <td>{{ overall_test_health.fail_count }}</td>
-      <td>{{ overall_test_health.fail_percent|default_if_none:0|floatformat }}%</td>
-      <td><a 
-          href="{% url dashboard_app.views.image_test_history image_health.rootfs_type image_health.hwpack_type test.test_id %}"
-          >{{ overall_test_health.total_run_count }}</a></td>
-      <td>{{ overall_test_health.total_count }}</td>
-      <td>{{ current_test_health.pass_count|default:0 }}</td>
-      <td>{{ current_test_health.fail_count|default:0 }}</td>
-      <td>{{ current_test_health.fail_percent|default_if_none:0|floatformat }}%</td>
-      <td><a 
-          href="{{ current_test_health.test_run.get_absolute_url }}"
-          >{{ current_test_health.total_count|default:0 }}</a></td>
-      <td>{{ test.name|default:"<em>not set</em>" }}</td>
-    </tr>
-    {% endcall %}
-    {% endcall %}
-    {% endfor %}
-  </tbody>
+      {% endwith %}
+      {% endwith %}
+    </td>
+  </tr>
+  {% endfor %}
+  {% endfor %}
 </table>
+{% else %}
+<p>This combination of of root file system + hwardware pack was not tested in
+the last 14 days</p>
+{% endif %}
+{% endwith %}
 {% endblock %}