← Back to team overview

linaro-release team mailing list archive

[Merge] lp:~deeptik/lava-dashboard/kernel-ci-data-veiw-report into lp:lava-dashboard

 

Deepti B. Kalakeri has proposed merging lp:~deeptik/lava-dashboard/kernel-ci-data-veiw-report into lp:lava-dashboard.

Requested reviews:
  Linaro Validation Team (linaro-validation)

For more details, see:
https://code.launchpad.net/~deeptik/lava-dashboard/kernel-ci-data-veiw-report/+merge/74493

Adding the xml and html files to get a consolidated view of the kernel test run and
kernel build.     

Please note that there are some repetitive feilds and needs some improvisation.
Feedback will help me to improve it further and its welcome.

Thanks and Regards,
Deepti.
-- 
https://code.launchpad.net/~deeptik/lava-dashboard/kernel-ci-data-veiw-report/+merge/74493
Your team Linaro Validation Team is requested to review the proposed merge of lp:~deeptik/lava-dashboard/kernel-ci-data-veiw-report into lp:lava-dashboard.
=== added directory 'reports'
=== added file 'reports/android-runs.html'
--- reports/android-runs.html	1970-01-01 00:00:00 +0000
+++ reports/android-runs.html	2011-09-07 18:45:23 +0000
@@ -0,0 +1,9 @@
+<div id="placeholder"></div>
+<script type="text/javascript">
+  $().dashboard("init", "{{ API_URL }}", function (server) {
+    var data_view_name = "android-runs";
+    var data_view_arguments = {};
+    $("#placeholder").dashboard(
+      "render_to_table", data_view_name, data_view_arguments);
+  });
+</script>

=== added file 'reports/android-runs.xml'
--- reports/android-runs.xml	1970-01-01 00:00:00 +0000
+++ reports/android-runs.xml	2011-09-07 18:45:23 +0000
@@ -0,0 +1,4 @@
+<data-report name="android-runs">
+    <title>Anrdoid Runs</title>
+    <path>android-runs.html</path>
+</data-report>

=== added file 'reports/benchmark.html'
--- reports/benchmark.html	1970-01-01 00:00:00 +0000
+++ reports/benchmark.html	2011-09-07 18:45:23 +0000
@@ -0,0 +1,112 @@
+<style type="text/css">
+  .chart {
+    width: 600px;
+    height: 300px;
+    display: block;
+  }
+  .report {
+    width: 50em;
+  }
+  h1 {
+    border-bottom: 2pt solid gray;
+  }
+</style>
+<h1>Daily benchmarks for Panda and Beagle</h1>
+<div class="report">
+  <h2>Test 1: stream.Add</h2>
+  <div id="placeholder1" class="chart"></div>
+  <p>Most recent runs of stream.Add on Panda and Beagle. The X axis shows the
+  time of the test. The Y axis shows the MB/s.</p>
+
+  <h2>Test 2: stream.Scale</h2>
+  <div id="placeholder2" class="chart"></div>
+  <p>Pellentesque turpis massa, consectetur nec viverra in, molestie ut
+  velit.  Vivamus venenatis, sem quis dapibus imperdiet, felis est semper ipsum,
+  vitae scelerisque quam odio sed augue. Praesent sagittis ligula a augue
+  placerat porta. Mauris aliquet tincidunt nisl, vel lacinia odio venenatis
+  vitae. Morbi iaculis commodo ligula, ut vestibulum odio accumsan congue. Sed
+  at viverra ipsum. Duis accumsan accumsan posuere. Nulla quis tellus arcu, et
+  tempus lectus. Praesent sit amet dui nunc, at ultrices leo.</p>
+  <h2>Test 3: pybench.CompareUnicode</h2>
+  <div id="placeholder3" class="chart"></div>
+  <p>Pellentesque turpis massa, consectetur nec viverra in, molestie ut
+  velit.  Vivamus venenatis, sem quis dapibus imperdiet, felis est semper ipsum,
+  vitae scelerisque quam odio sed augue. Praesent sagittis ligula a augue
+  placerat porta. Mauris aliquet tincidunt nisl, vel lacinia odio venenatis
+  vitae. Morbi iaculis commodo ligula, ut vestibulum odio accumsan congue. Sed
+  at viverra ipsum. Duis accumsan accumsan posuere. Nulla quis tellus arcu, et
+  tempus lectus. Praesent sit amet dui nunc, at ultrices leo.</p>
+</div>
+<script type="text/javascript">
+  $(function () {
+    /* Configuration */
+    var pathname = "/anonymous/lava-daily/";
+    var count = 100;
+    var boards = Array("OMAP3 Beagle Board", "OMAP4 Panda board");
+
+    /* Setup charts */
+    $(".chart").dashboard("graph", {
+      lines: { show: true },
+      points: { show: true },
+      xaxis: {
+        mode: "time",
+        ticks: 10,
+        label: "Time",
+        labelPos: "low"
+      },
+      yaxis: {
+        min: 0,
+        label: "MB/s",
+        labelPos: "high"
+      }
+    });
+
+    /* Add data series to each chart */
+    $().dashboard("init", "{{ API_URL }}", function (server) {
+      $(boards).each(function (index, board) {
+        $("#placeholder1").dashboard("add_series", {
+          label: "Recent runs of stream.Add on " + board, 
+          data_view: {
+            name: "measurements",
+            args: {
+              board: board,
+              count: count,
+              test: "stream",
+              test_case: "Add",
+              pathname: pathname
+            }
+          }
+        });
+        $("#placeholder2").dashboard("add_series", {
+          label: "Recent runs of stream.Scale on " + board, 
+          data_view: {
+            name: "measurements",
+            args: {
+              board: board,
+              count: count,
+              test: "stream",
+              test_case: "Scale",
+              pathname: pathname
+            }
+          }
+        });
+      });
+
+      /* Add one more report */
+      $("#placeholder3").dashboard("add_series", {
+        label: "Past 100 runs of pybench.CompareUnicode on Panda", 
+        data_view: {
+          name: "measurements",
+          args: {
+            board: "OMAP4 Panda board",
+            test: "pybench",
+            test_case: "CompareUnicode",
+            pathname: pathname,
+            count: 100
+          }
+        }
+      });
+
+    });
+  });
+</script>

=== added file 'reports/benchmark.xml'
--- reports/benchmark.xml	1970-01-01 00:00:00 +0000
+++ reports/benchmark.xml	2011-09-07 18:45:23 +0000
@@ -0,0 +1,4 @@
+<data-report name="benchmark">
+  <title>Daily benchmarks for Panda and Beagle</title>
+    <path>benchmark.html</path>
+</data-report>

=== added file 'reports/board-activity.html'
--- reports/board-activity.html	1970-01-01 00:00:00 +0000
+++ reports/board-activity.html	2011-09-07 18:45:23 +0000
@@ -0,0 +1,11 @@
+<div id="placeholder"></div>
+<script type="text/javascript">
+  $().dashboard("init", "{{ API_URL }}", function (server) {
+    var data_view_name = "board-activity";
+    var data_view_arguments = {
+      pathname: "/anonymous/lava-daily/"
+    };
+    $("#placeholder").dashboard(
+      "render_to_table", data_view_name, data_view_arguments);
+  });
+</script>

=== added file 'reports/board-activity.xml'
--- reports/board-activity.xml	1970-01-01 00:00:00 +0000
+++ reports/board-activity.xml	2011-09-07 18:45:23 +0000
@@ -0,0 +1,4 @@
+<data-report name="board-activity">
+    <title>Board activity</title>
+    <path>board-activity.html</path>
+</data-report>

=== added file 'reports/boot-status-overview.html'
--- reports/boot-status-overview.html	1970-01-01 00:00:00 +0000
+++ reports/boot-status-overview.html	2011-09-07 18:45:23 +0000
@@ -0,0 +1,101 @@
+<h2>Image boot status by board</h2>
+
+<p>The following table shows image / hardware pack boot status. Please click on
+the icon in individual cell to see more details</p>
+
+<div id="placeholder"></div>
+<script type="text/javascript">
+  $().dashboard("init", "{{ API_URL }}", function (server) {
+    function query_data_view(data_view_name, data_view_arguments, callback) {
+      server.query_data_view(callback, data_view_name, data_view_arguments);
+    }
+    var pathname = "/anonymous/lava-daily/";
+    var hwpack_list = null;
+    var rootfs_list = null;
+
+
+    /* Function that renders the actual table */
+    function render_if_possible() {
+      if (hwpack_list != null && rootfs_list != null) {
+        //console.log("we can render now");
+        var html = "";
+        html += "<table class='data'>";
+        html += "<tr>";
+        html += "<th></th>";
+        $.each(hwpack_list, function (hwpack_index, hwpack_name) {
+          html += "<th>" + hwpack_name + "</th>";
+        });
+        html += "</tr>";
+        html += "<tr>";
+        $.each(rootfs_list, function (rootfs_index, rootfs_name) {
+          html += "<tr>";
+          html += "<th>" + rootfs_name + "</th>";
+          $.each(hwpack_list, function (hwpack_index, hwpack_name) {
+            html += "<td id='cell_" + rootfs_index + "_" + hwpack_index + "'></td>";
+            query_data_view(
+              "latest-job-complete-for-hwpack-and-rootfs", {
+                "pathname": pathname,
+                "hwpack": hwpack_name,
+                "rootfs": rootfs_name
+              }, 
+              function(response) {
+                //console.log("cell:", rootfs_index, hwpack_index, response.result.rows);
+                if (response && response.result && response.result.rows && response.result.rows.length == 1) {
+                  var outcome = response.result.rows[0][0];
+                  var uuid = response.result.rows[0][1];
+                  var datetime = response.result.rows[0][2];
+                  var cell_html = "";
+                  var cell_link = "{{ API_URL }}.." + "/permalink/test-run/" + uuid + "/";
+                  var _img = ""
+                  switch (outcome) {
+                    case 0:
+                      _img = "<img src='{{ STATIC_URL }}dashboard_app/images/icon-pass.png' alt='FAIL'/>";
+                      break;
+                    case 1:
+                      _img = "<img src='{{ STATIC_URL }}dashboard_app/images/icon-fail.png' alt='FAIL'/>";
+                      break;
+                  };
+                  cell_html = "<a href='" + cell_link + "'>" + _img + " "  + datetime + "</a>";
+                  $("#cell_" + rootfs_index + "_" + hwpack_index).html(cell_html);
+                }
+              }
+            );
+          });
+          html += "</tr>";
+        });
+        html += "</table>";
+        $("#placeholder").html(html)
+      }
+    }
+
+    /* Get a list of hardware pack types */
+    query_data_view("hwpack-type", {"pathname": pathname},
+      function(response) {
+        hwpack_list = new Array();
+        if (response && response.result && response.result.rows) {
+          $.each(response.result.rows, function (index, row) {
+            hwpack_list.push(row[0]);
+          });
+        }
+        //console.log("hwpack list:", hwpack_list);
+        render_if_possible();
+      }
+    );
+
+    /* Get a list of root file systems */
+    query_data_view("rootfs-type", {"pathname": pathname},
+      function(response) {
+        rootfs_list = new Array();
+        if (response && response.result && response.result.rows) {
+          $.each(response.result.rows, function (index, row) {
+            rootfs_list.push(row[0]);
+          });
+        }
+        //console.log("rootfs list:", rootfs_list);
+        render_if_possible();
+      }
+    );
+
+
+  });
+</script>

=== added file 'reports/boot-status-overview.xml'
--- reports/boot-status-overview.xml	1970-01-01 00:00:00 +0000
+++ reports/boot-status-overview.xml	2011-09-07 18:45:23 +0000
@@ -0,0 +1,4 @@
+<data-report name="boot-status-overview">
+    <title>Boot status overview</title>
+    <path>boot-status-overview.html</path>
+</data-report>

=== added file 'reports/boot-status.html'
--- reports/boot-status.html	1970-01-01 00:00:00 +0000
+++ reports/boot-status.html	2011-09-07 18:45:23 +0000
@@ -0,0 +1,15 @@
+<div id="placeholder"></div>
+<script type="text/javascript">
+  $().dashboard("init", "{{ API_URL }}", function (server) {
+    var data_view_name = "hostnames";
+    var data_view_arguments = {};
+    server.query_data_view(function (response) {
+      $(response.result.rows).each(function (index, row) {
+        var hostname = row[0];
+        $("#placeholder").append("<div id='placeholder_" + hostname + "'><div>");
+        $("#placeholder_" + hostname).dashboard(
+        "render_to_table", "boot-status", {"hostname": hostname}, {caption: "Boot history for " + hostname});
+      });
+    }, "hostnames", {}); 
+  });
+</script>

=== added file 'reports/boot-status.xml'
--- reports/boot-status.xml	1970-01-01 00:00:00 +0000
+++ reports/boot-status.xml	2011-09-07 18:45:23 +0000
@@ -0,0 +1,4 @@
+<data-report name="boot-status">
+    <title>Boot status</title>
+    <path>boot-status.html</path>
+</data-report>

=== added file 'reports/kernel-ci-data.html'
--- reports/kernel-ci-data.html	1970-01-01 00:00:00 +0000
+++ reports/kernel-ci-data.html	2011-09-07 18:45:23 +0000
@@ -0,0 +1,54 @@
+<div id="placeholder"></div>
+<script type="text/javascript">
+  $().dashboard("init", "{{ API_URL }}", function (server) {
+    var data_view_name = "CI Kernel Data";
+    var data_view_arguments = {
+      boot_pathname: "/anonymous/ci-linux-linaro-3_0/",
+      build_pathname: "/anonymous/ci-linux-linaro-3_0-build/"
+    };
+    server.query_data_view(function (response) {
+      if (response.result) {
+        var dataset = response.result;
+        var html = "<table class='demo_jui display' id='kernel_ci_results'>";
+        html += "<thead><tr>";
+        $.each(dataset.columns, function (index, column) {
+          html += "<th>" + column.name + "</th>";
+        });
+        html += "</tr></thead><tbody>";
+        $.each(dataset.rows, function (index, row) {
+          html += "<tr>";
+          $.each(row, function (index, cell) {
+            var column = dataset.columns[index];
+            var cell_link = null;
+            if (column.name.indexOf("UUID") > 0) {
+              /* This is a bit hacky but will work for now */
+              cell_link = "{{ API_URL }}../permalink/test-run/" + cell + "/";
+              cell_html = "go to test run"
+            } else {
+              cell_html = cell;
+            }
+            html += "<td>";
+            if (cell_link) {
+              html += "<a href='" + cell_link + "'>"
+              html += cell_html;
+              html += "</a>";
+            } else {
+              html += cell_html;
+            }
+            html += "</td>";
+          });
+          html += "</tr>";
+        });
+        html += "</tbody></table>";
+        $("#placeholder").html(html);
+        $("#kernel_ci_results").dataTable({
+          "bJQueryUI": true,
+          "sPaginationType": "full_numbers",
+        });
+      } else {
+        $this.html("Error code:" + response.error.faultCode + ", message: " + response.error.faultString);
+      }
+    }, data_view_name, data_view_arguments);
+  });
+</script>
+

=== added file 'reports/kernel-ci-data.xml'
--- reports/kernel-ci-data.xml	1970-01-01 00:00:00 +0000
+++ reports/kernel-ci-data.xml	2011-09-07 18:45:23 +0000
@@ -0,0 +1,4 @@
+<data-report name="kernel-ci-data">
+    <title>CI Kernel Data</title>
+    <path>kernel-ci-data.html</path>
+</data-report>

=== added file 'update.sh'
--- update.sh	1970-01-01 00:00:00 +0000
+++ update.sh	2011-09-07 18:45:23 +0000
@@ -0,0 +1,8 @@
+#!/bin/sh
+REPO=/srv/launch-control/data-views-and-reports
+old_revno=$(bzr revno -D $REPO)
+bzr up -D $REPO --quiet
+new_revno=$(bzr revno -D $REPO)
+if [ "$old_revno" != "$new_revno" ]; then
+    sudo apache2ctl restart
+fi

=== added directory 'views'
=== added file 'views/android-runs.xml'
--- views/android-runs.xml	1970-01-01 00:00:00 +0000
+++ views/android-runs.xml	2011-09-07 18:45:23 +0000
@@ -0,0 +1,33 @@
+<data-view name="android-runs">
+    <sql> 
+        SELECT
+            TestRun.analyzer_assigned_date AS "Analyzer Assigned Date",
+            NamedAttribute_AndroidURL.value AS "Android URL",
+            TestRun.analyzer_assigned_uuid AS "UUID"
+        FROM
+            dashboard_app_testrun AS TestRun
+            INNER JOIN dashboard_app_namedattribute AS NamedAttribute_AndroidURL ON (
+                NamedAttribute_AndroidURL.object_id = TestRun.id
+                AND NamedAttribute_AndroidURL.content_type_id = (
+                    SELECT
+                        django_content_type.id
+                    FROM
+                        django_content_type
+                    WHERE
+                        app_label = 'dashboard_app'
+                        AND model='testrun'
+                    )
+                AND NamedAttribute_AndroidURL.name = 'android.url'
+            )
+        ORDER BY
+            TestRun.analyzer_assigned_date DESC
+        LIMIT <value name="count"/>
+    </sql>
+    <arguments>
+        <argument name="count" default="10" type="number" help="Select this many test runs (query limit)"/>
+    </arguments>
+    <summary>
+    </summary>
+    <documentation>
+    </documentation>
+</data-view>

=== added file 'views/board-activity.xml'
--- views/board-activity.xml	1970-01-01 00:00:00 +0000
+++ views/board-activity.xml	2011-09-07 18:45:23 +0000
@@ -0,0 +1,122 @@
+<data-view name="board-activity">
+    <sql backend="postgresql"> 
+        SELECT
+            NamedAttribute_Target_Hostname.value AS "Hostname",
+            HardwareDevice_Board.description AS "Board",
+            NamedAttribute_HardwarePack_Type.value
+              || ' '
+              || to_char(CAST(NamedAttribute_HardwarePack_Date.value AS TIMESTAMP), 'YYYY-MM-DD')
+              AS "Hardware Pack",
+            NamedAttribute_RootFileSystem_Type.value
+              || ' '
+              || to_char(CAST(NamedAttribute_RootFileSystem_Date.value AS TIMESTAMP), 'YYYY-MM-DD')
+              AS "Root File System",
+            Test.test_id AS "Test",
+            (SELECT COUNT(*) FROM dashboard_app_testresult AS TestResult WHERE TestResult.test_run_id = TestRun.id) AS "Test Cases",
+            (SELECT COUNT(*) FROM dashboard_app_testresult AS TestResult WHERE TestResult.test_run_id = TestRun.id AND TestResult.result = 1) AS "Failures",
+            TestRun.analyzer_assigned_uuid AS "UUID",
+            TestRun.analyzer_assigned_date AS "Analyzer Assigned Date"
+        FROM
+            dashboard_app_testrun AS TestRun
+            INNER JOIN dashboard_app_bundle AS Bundle ON (
+                TestRun.bundle_id = Bundle.id
+            )
+            INNER JOIN dashboard_app_bundlestream AS BundleStream ON (
+                BundleStream.id = Bundle.bundle_stream_id
+            )
+            INNER JOIN dashboard_app_test AS Test ON (
+                Test.id = TestRun.test_id
+            )
+            INNER JOIN dashboard_app_namedattribute AS NamedAttribute_Target_Hostname ON (
+                NamedAttribute_Target_Hostname.object_id = TestRun.id
+                AND NamedAttribute_Target_Hostname.content_type_id = (
+                    SELECT
+                        django_content_type.id
+                    FROM
+                        django_content_type
+                    WHERE
+                        app_label = 'dashboard_app'
+                        AND model='testrun'
+                    )
+                AND NamedAttribute_Target_Hostname.name = 'target.hostname'
+            )
+            INNER JOIN dashboard_app_namedattribute AS NamedAttribute_HardwarePack_Type ON (
+                NamedAttribute_HardwarePack_Type.object_id = TestRun.id
+                AND NamedAttribute_HardwarePack_Type.content_type_id = (
+                    SELECT
+                        django_content_type.id
+                    FROM
+                        django_content_type
+                    WHERE
+                        app_label = 'dashboard_app'
+                        AND model='testrun'
+                    )
+                AND NamedAttribute_HardwarePack_Type.name = 'hwpack.type'
+            )
+            INNER JOIN dashboard_app_namedattribute AS NamedAttribute_HardwarePack_Date ON (
+                NamedAttribute_HardwarePack_Date.object_id = TestRun.id
+                AND NamedAttribute_HardwarePack_Date.content_type_id = (
+                    SELECT
+                        django_content_type.id
+                    FROM
+                        django_content_type
+                    WHERE
+                        app_label = 'dashboard_app'
+                        AND model='testrun'
+                    )
+                AND NamedAttribute_HardwarePack_Date.name = 'hwpack.date'
+            )
+            INNER JOIN dashboard_app_namedattribute AS NamedAttribute_RootFileSystem_Type ON (
+                NamedAttribute_RootFileSystem_Type.object_id = TestRun.id
+                AND NamedAttribute_RootFileSystem_Type.content_type_id = (
+                    SELECT
+                        django_content_type.id
+                    FROM
+                        django_content_type
+                    WHERE
+                        app_label = 'dashboard_app'
+                        AND model='testrun'
+                    )
+                AND NamedAttribute_RootFileSystem_Type.name = 'rootfs.type'
+            )
+            INNER JOIN dashboard_app_namedattribute AS NamedAttribute_RootFileSystem_Date ON (
+                NamedAttribute_RootFileSystem_Date.object_id = TestRun.id
+                AND NamedAttribute_RootFileSystem_Date.content_type_id = (
+                    SELECT
+                        django_content_type.id
+                    FROM
+                        django_content_type
+                    WHERE
+                        app_label = 'dashboard_app'
+                        AND model='testrun'
+                    )
+                AND NamedAttribute_RootFileSystem_Date.name = 'rootfs.date'
+            )
+            INNER JOIN dashboard_app_testrun_devices as TestRun_Devices ON (
+                TestRun_Devices.testrun_id = TestRun.id
+            )
+            INNER JOIN dashboard_app_hardwaredevice as HardwareDevice_Board ON (
+                HardwareDevice_Board.id = TestRun_Devices.hardwaredevice_id
+                AND HardwareDevice_Board.device_type = 'device.board'
+            )
+        WHERE
+            BundleStream.pathname = <value name="pathname"/>
+        ORDER BY
+            TestRun.analyzer_assigned_date DESC
+        LIMIT
+            <value name="count"/>
+    </sql>
+    <arguments>
+        <argument name="pathname" type="string" help="Pathname of a bundle stream to search"/>
+        <argument name="count" default="60" type="number" help="Select this many test runs (query limit)"/>
+    </arguments>
+    <summary>
+        List N most recent TestRuns specific bundle stream (sort by analyzer_assigned_date)
+    </summary>
+    <documentation>
+        This query joins three tables: TestRun + Bundle + BundleStream. The
+        filtering depends on the BundleStream.pathname property, the selected
+        value is TestRun.analyzer_assigned_uuid and
+        TestRun.analyzer_assigned_date.
+    </documentation>
+</data-view>

=== added file 'views/boot-status.xml'
--- views/boot-status.xml	1970-01-01 00:00:00 +0000
+++ views/boot-status.xml	2011-09-07 18:45:23 +0000
@@ -0,0 +1,115 @@
+<data-view name="boot-status">
+    <sql> 
+        SELECT
+            (CASE TestResult.result WHEN 0 THEN 'Success' ELSE 'Failure' END) AS "Boot Status",
+            NamedAttribute_HardwarePack_Type.value
+              || ' '
+              || to_char(CAST(NamedAttribute_HardwarePack_Date.value AS TIMESTAMP), 'YYYY-MM-DD')
+              AS "Hardware Pack",
+            NamedAttribute_RootFileSystem_Type.value
+              || ' '
+              || to_char(CAST(NamedAttribute_RootFileSystem_Date.value AS TIMESTAMP), 'YYYY-MM-DD')
+              AS "Root File System",
+            TestRun.analyzer_assigned_date AS "Analyzer Assigned Date",
+            TestRun.analyzer_assigned_uuid AS "UUID"
+        FROM
+            dashboard_app_testresult AS TestResult
+            INNER JOIN dashboard_app_testrun AS TestRun ON (
+                TestResult.test_run_id = TestRun.id
+            )
+            INNER JOIN dashboard_app_bundle AS Bundle ON (
+                Bundle.id = TestRun.bundle_id
+            )
+            INNER JOIN dashboard_app_bundlestream AS BundleStream ON (
+                Bundle.bundle_stream_id = BundleStream.id
+            )
+            INNER JOIN dashboard_app_namedattribute AS NamedAttribute_Target_Hostname ON (
+                NamedAttribute_Target_Hostname.object_id = TestRun.id
+                AND NamedAttribute_Target_Hostname.content_type_id = (
+                    SELECT
+                        django_content_type.id
+                    FROM
+                        django_content_type
+                    WHERE
+                        app_label = 'dashboard_app'
+                        AND model='testrun'
+                    )
+                AND NamedAttribute_Target_Hostname.name = 'target.hostname'
+            )
+            INNER JOIN dashboard_app_namedattribute AS NamedAttribute_HardwarePack_Type ON (
+                NamedAttribute_HardwarePack_Type.object_id = TestRun.id
+                AND NamedAttribute_HardwarePack_Type.content_type_id = (
+                    SELECT
+                        django_content_type.id
+                    FROM
+                        django_content_type
+                    WHERE
+                        app_label = 'dashboard_app'
+                        AND model='testrun'
+                    )
+                AND NamedAttribute_HardwarePack_Type.name = 'hwpack.type'
+            )
+            INNER JOIN dashboard_app_namedattribute AS NamedAttribute_HardwarePack_Date ON (
+                NamedAttribute_HardwarePack_Date.object_id = TestRun.id
+                AND NamedAttribute_HardwarePack_Date.content_type_id = (
+                    SELECT
+                        django_content_type.id
+                    FROM
+                        django_content_type
+                    WHERE
+                        app_label = 'dashboard_app'
+                        AND model='testrun'
+                    )
+                AND NamedAttribute_HardwarePack_Date.name = 'hwpack.date'
+            )
+            INNER JOIN dashboard_app_namedattribute AS NamedAttribute_RootFileSystem_Type ON (
+                NamedAttribute_RootFileSystem_Type.object_id = TestRun.id
+                AND NamedAttribute_RootFileSystem_Type.content_type_id = (
+                    SELECT
+                        django_content_type.id
+                    FROM
+                        django_content_type
+                    WHERE
+                        app_label = 'dashboard_app'
+                        AND model='testrun'
+                    )
+                AND NamedAttribute_RootFileSystem_Type.name = 'rootfs.type'
+            )
+            INNER JOIN dashboard_app_namedattribute AS NamedAttribute_RootFileSystem_Date ON (
+                NamedAttribute_RootFileSystem_Date.object_id = TestRun.id
+                AND NamedAttribute_RootFileSystem_Date.content_type_id = (
+                    SELECT
+                        django_content_type.id
+                    FROM
+                        django_content_type
+                    WHERE
+                        app_label = 'dashboard_app'
+                        AND model='testrun'
+                    )
+                AND NamedAttribute_RootFileSystem_Date.name = 'rootfs.date'
+            )
+            INNER JOIN dashboard_app_testcase AS TestCase ON (
+                TestResult.test_case_id = TestCase.id
+            )
+            INNER JOIN dashboard_app_test AS Test ON (
+                TestRun.test_id = Test.id
+            )
+        WHERE
+            BundleStream.pathname = <value name="pathname"/>
+            AND NamedAttribute_Target_Hostname.value = <value name="hostname"/>
+            AND Test.test_id = 'lava'
+            AND TestCase.test_case_id = 'job_complete'
+        ORDER BY
+            TestRun.analyzer_assigned_date DESC
+        LIMIT <value name="count"/>
+    </sql>
+    <arguments>
+        <argument name="hostname" type="string"/> 
+        <argument name="pathname" default="/anonymous/lava-daily/" type="string" help="Pathname of the bundle stream to check (BundleStream.pathname)"/>
+        <argument name="count" default="10" type="number" help="Select this many test runs (query limit)"/>
+    </arguments>
+    <summary>
+    </summary>
+    <documentation>
+    </documentation>
+</data-view>

=== added file 'views/hostnames.xml'
--- views/hostnames.xml	1970-01-01 00:00:00 +0000
+++ views/hostnames.xml	2011-09-07 18:45:23 +0000
@@ -0,0 +1,37 @@
+<data-view name="hostnames">
+    <sql> 
+        SELECT DISTINCT
+            NamedAttribute_Target_Hostname.value as "Hostname"
+        FROM
+            dashboard_app_testrun AS TestRun
+            INNER JOIN dashboard_app_namedattribute AS NamedAttribute_Target_Hostname ON (
+                NamedAttribute_Target_Hostname.object_id = TestRun.id
+                AND NamedAttribute_Target_Hostname.content_type_id = (
+                    SELECT
+                        django_content_type.id
+                    FROM
+                        django_content_type
+                    WHERE
+                        app_label = 'dashboard_app'
+                        AND model='testrun'
+                    )
+                AND NamedAttribute_Target_Hostname.name = 'target.hostname'
+            )
+            INNER JOIN dashboard_app_bundle AS Bundle ON (
+                Bundle.id = TestRun.bundle_id
+            )
+            INNER JOIN dashboard_app_bundlestream AS BundleStream ON (
+                BundleStream.id = Bundle.bundle_stream_id
+            )
+        WHERE
+            BundleStream.pathname = <value name="pathname"/>
+        ORDER BY
+            "Hostname"
+    </sql>
+    <arguments>
+        <argument name="pathname" default="/anonymous/lava-daily/" type="string" help="Pathname of the bundle stream to check (BundleStream.pathname)"/>
+    </arguments>
+    <summary>
+      List of hostnames
+    </summary>
+</data-view>

=== added file 'views/hwpack-type.xml'
--- views/hwpack-type.xml	1970-01-01 00:00:00 +0000
+++ views/hwpack-type.xml	2011-09-07 18:45:23 +0000
@@ -0,0 +1,45 @@
+<data-view name="hwpack-type">
+    <sql> 
+        SELECT DISTINCT
+            NamedAttribute_HardwarePack_Type.value
+        FROM
+            dashboard_app_testresult AS TestResult
+            INNER JOIN dashboard_app_testrun AS TestRun ON (
+                TestResult.test_run_id = TestRun.id
+            )
+            INNER JOIN dashboard_app_bundle AS Bundle ON (
+                Bundle.id = TestRun.bundle_id
+            )
+            INNER JOIN dashboard_app_bundlestream AS BundleStream ON (
+                Bundle.bundle_stream_id = BundleStream.id
+            )
+            INNER JOIN dashboard_app_namedattribute AS NamedAttribute_HardwarePack_Type ON (
+                NamedAttribute_HardwarePack_Type.object_id = TestRun.id
+                AND NamedAttribute_HardwarePack_Type.content_type_id = (
+                    SELECT
+                        django_content_type.id
+                    FROM
+                        django_content_type
+                    WHERE
+                        app_label = 'dashboard_app'
+                        AND model='testrun'
+                    )
+                AND NamedAttribute_HardwarePack_Type.name = 'hwpack.type'
+            )
+            INNER JOIN dashboard_app_testcase AS TestCase ON (
+                TestResult.test_case_id = TestCase.id
+            )
+        WHERE
+            BundleStream.pathname = <value name="pathname"/>
+    </sql>
+    <arguments>
+        <argument name="pathname" type="string" help="Pathname of the bundle stream to check (BundleStream.pathname)"/>
+    </arguments>
+    <summary>
+      List all the hardware pack types in a specified bundle stream
+    </summary>
+    <documentation>
+      This query simply selects all the distinct value of the hwpack.type
+      attribute for all the test runs in the specified bundle stream.
+    </documentation>
+</data-view>

=== added file 'views/kernel-ci-data.xml'
--- views/kernel-ci-data.xml	1970-01-01 00:00:00 +0000
+++ views/kernel-ci-data.xml	2011-09-07 18:45:23 +0000
@@ -0,0 +1,138 @@
+<data-view name="CI Kernel Data">
+    <sql>
+       SELECT
+            BuildNamedAttribute_BuildID.value AS "Jenkins build ID (build)",
+            BootNamedAttribute_BuildID.value AS "Jenkins build ID (boot)",
+            BuildSoftwareSource.branch_url AS "Git URL (build)",
+            BuildSoftwareSource.branch_revision AS "Git Commit ID (build)",
+            BuildNamedAttribute_KernelConfig.value AS "Kernel Config (build)",
+            BootNamedAttribute_GitURL.value AS "Git URL (boot)", 
+            BootNamedAttribute_GitCommitID.value AS "Git Commit ID (boot)",
+            (CASE WHEN BootTestResult.result=0 THEN 'pass' ELSE 'fail' END) AS "Boot result",
+            (CASE WHEN BuildTestResult.result=0 THEN 'pass' ELSE 'fail' END) AS "Build result",
+            BootNamedAttribute_TargetHostname.value AS "Boot target Hostname",
+            BootTestRun.analyzer_assigned_uuid AS "Boot test run UUID",
+            BuildTestRun.analyzer_assigned_uuid AS "Build test run UUID"
+        FROM
+            dashboard_app_testresult AS BuildTestResult
+            INNER JOIN dashboard_app_testrun AS BuildTestRun ON BuildTestResult.test_run_id = BuildTestRun.id
+            INNER JOIN dashboard_app_testrun_sources AS BuildSoftwareSources ON BuildSoftwareSources.testrun_id = BuildTestRun.id
+            INNER JOIN dashboard_app_softwaresource AS BuildSoftwareSource ON BuildSoftwareSources.softwaresource_id = BuildSoftwareSource.id
+            INNER JOIN dashboard_app_namedattribute AS BuildNamedAttribute_BuildID ON (
+                BuildNamedAttribute_BuildID.object_id = BuildTestRun.id
+                AND BuildNamedAttribute_BuildID.name = 'build.id'
+                AND BuildNamedAttribute_BuildID.content_type_id = (
+                    SELECT
+                        django_content_type.id
+                    FROM
+                        django_content_type
+                    WHERE
+                        app_label = 'dashboard_app'
+                        AND model='testrun'
+                    )
+            )
+            INNER JOIN dashboard_app_namedattribute AS BuildNamedAttribute_KernelConfig ON (
+                BuildNamedAttribute_KernelConfig.object_id = BuildTestRun.id
+                AND BuildNamedAttribute_KernelConfig.name = 'kernel.config'
+                AND BuildNamedAttribute_KernelConfig.content_type_id = (
+                    SELECT
+                        django_content_type.id
+                    FROM
+                        django_content_type
+                    WHERE
+                        app_label = 'dashboard_app'
+                        AND model='testrun'
+                    )
+            )
+            INNER JOIN dashboard_app_bundle AS BuildBundle ON BuildTestRun.bundle_id = BuildBundle.id
+            INNER JOIN dashboard_app_bundlestream AS BuildBundleStream ON BuildBundle.bundle_stream_id = BuildBundleStream.id
+            INNER JOIN dashboard_app_testcase AS BuildTestCase ON BuildTestResult.test_case_id = BuildTestCase.id
+            INNER JOIN dashboard_app_test AS BuildTest ON BuildTestRun.test_id = BuildTest.id
+,
+            dashboard_app_testresult AS BootTestResult
+            INNER JOIN dashboard_app_testrun AS BootTestRun ON BootTestResult.test_run_id = BootTestRun.id
+            INNER JOIN dashboard_app_namedattribute AS BootNamedAttribute_BuildID ON (
+                BootNamedAttribute_BuildID.object_id = BootTestRun.id
+                AND BootNamedAttribute_BuildID.name = 'build.id'
+                AND BootNamedAttribute_BuildID.content_type_id = (
+                    SELECT
+                        django_content_type.id
+                    FROM
+                        django_content_type
+                    WHERE
+                        app_label = 'dashboard_app'
+                        AND model='testrun'
+                    )
+            )
+            INNER JOIN dashboard_app_namedattribute AS BootNamedAttribute_TargetHostname ON (
+                BootNamedAttribute_TargetHostname.object_id = BootTestRun.id
+                AND BootNamedAttribute_TargetHostname.name = 'target.hostname'
+                AND BootNamedAttribute_TargetHostname.content_type_id = (
+                    SELECT
+                        django_content_type.id
+                    FROM
+                        django_content_type
+                    WHERE
+                        app_label = 'dashboard_app'
+                        AND model='testrun'
+                    )
+                AND BootNamedAttribute_TargetHostname.name = 'target.hostname'
+            )
+            INNER JOIN dashboard_app_namedattribute AS BootNamedAttribute_GitCommitID ON (
+                BootNamedAttribute_GitCommitID.object_id = BootTestRun.id
+                AND BootNamedAttribute_GitCommitID.name = 'git_commitid'
+                AND BootNamedAttribute_GitCommitID.content_type_id = (
+                    SELECT
+                        django_content_type.id
+                    FROM
+                        django_content_type
+                    WHERE
+                        app_label = 'dashboard_app'
+                        AND model='testrun'
+                    )
+            )
+            INNER JOIN dashboard_app_namedattribute AS BootNamedAttribute_GitURL ON (
+                BootNamedAttribute_GitURL.object_id = BootTestRun.id
+                AND BootNamedAttribute_GitURL.name = 'git_url'
+                AND BootNamedAttribute_GitURL.content_type_id = (
+                    SELECT
+                        django_content_type.id
+                    FROM
+                        django_content_type
+                    WHERE
+                        app_label = 'dashboard_app'
+                        AND model='testrun'
+                    )
+            )            
+            INNER JOIN dashboard_app_bundle AS BootBundle ON BootTestRun.bundle_id = BootBundle.id
+            INNER JOIN dashboard_app_bundlestream AS BootBundleStream ON BootBundle.bundle_stream_id = BootBundleStream.id
+            INNER JOIN dashboard_app_testcase AS BootTestCase ON BootTestResult.test_case_id = BootTestCase.id
+            INNER JOIN dashboard_app_test AS BootTest ON BootTestRun.test_id = BootTest.id
+        WHERE
+            BootBundleStream.pathname = <value name="boot_pathname"/>
+            AND BuildBundleStream.pathname = <value name="build_pathname"/>
+            AND BootTest.test_id = <value name="boot_test"/>
+            AND BuildTest.test_id = <value name="build_test"/>
+            AND BootTestCase.test_case_id = <value name="boot_test_case"/>
+            AND BuildTestCase.test_case_id = <value name="build_test_case"/>
+            AND BuildSoftwareSource.project_name = 'Linux Linaro'
+            AND BuildNamedAttribute_BuildID.value = BootNamedAttribute_BuildID.value
+        ORDER BY
+            BootTestRun.analyzer_assigned_uuid
+    </sql>
+    <arguments>
+        <argument name="boot_pathname" help="Bundle stream with boot results" type="string"/>
+        <argument name="boot_test" help="Identifier of the test to select" type="string" default="lava"/>
+        <argument name="boot_test_case" help="Identifier of the test case to select" type="string" default="boot_image"/>
+        <argument name="build_pathname" help="Bundle stream with boot results" type="string"/>
+        <argument name="build_test" help="Identifier of the test to select" type="string" default="kernel build"/>
+        <argument name="build_test_case" help="Identifier of the test case to select" type="string" default="linux-linaro-3_0"/>
+    </arguments>
+    <summary>
+        TODO: document this
+    </summary>
+    <documentation>
+        TODO: document this
+    </documentation>
+</data-view>
+

=== added file 'views/latest-job-complete-for-hwpack-and-rootfs.xml'
--- views/latest-job-complete-for-hwpack-and-rootfs.xml	1970-01-01 00:00:00 +0000
+++ views/latest-job-complete-for-hwpack-and-rootfs.xml	2011-09-07 18:45:23 +0000
@@ -0,0 +1,74 @@
+<data-view name="latest-job-complete-for-hwpack-and-rootfs">
+    <sql> 
+      <!--
+        EXPLAIN QUERY PLAN
+      -->
+        SELECT
+            TestResult.result AS "Outcome",
+            TestRun.analyzer_assigned_uuid AS "UUID",
+            TestRun.analyzer_assigned_date AS "Date"
+        FROM
+            dashboard_app_testresult AS TestResult
+            INNER JOIN dashboard_app_testcase AS TestCase ON (
+                TestCase.id = TestResult.test_case_id
+            )
+            INNER JOIN dashboard_app_testrun AS TestRun ON (
+                TestRun.id = TestResult.test_run_id
+            )
+            INNER JOIN dashboard_app_test AS Test ON (
+                Test.id = TestRun.test_id
+            )
+            INNER JOIN dashboard_app_namedattribute AS NamedAttribute_HardwarePack ON (
+                NamedAttribute_HardwarePack.object_id = TestRun.id
+                AND NamedAttribute_HardwarePack.name = 'hwpack.type'
+                AND NamedAttribute_HardwarePack.value = <value name="hwpack"/>
+                AND NamedAttribute_HardwarePack.content_type_id = (
+                    SELECT
+                        django_content_type.id
+                    FROM
+                        django_content_type
+                    WHERE
+                        app_label = 'dashboard_app'
+                        AND model='testrun'
+                    )
+            )
+            INNER JOIN dashboard_app_namedattribute AS NamedAttribute_RootFileSystem ON (
+                NamedAttribute_RootFileSystem.object_id = TestRun.id
+                AND NamedAttribute_RootFileSystem.name = 'rootfs.type'
+                AND NamedAttribute_RootFileSystem.value = <value name="rootfs"/>
+                AND NamedAttribute_RootFileSystem.content_type_id = (
+                    SELECT
+                        django_content_type.id
+                    FROM
+                        django_content_type
+                    WHERE
+                        app_label = 'dashboard_app'
+                        AND model='testrun'
+                    )
+            )
+            INNER JOIN dashboard_app_bundle AS Bundle ON (
+                Bundle.id = TestRun.bundle_id
+            )
+            INNER JOIN dashboard_app_bundlestream AS BundleStream ON (
+                BundleStream.id = Bundle.bundle_stream_id
+            )
+        WHERE
+            BundleStream.pathname = <value name="pathname"/>
+            AND TestCase.test_case_id = 'job_complete'
+            AND Test.test_id = 'lava'
+        ORDER BY
+            TestRun.analyzer_assigned_date DESC
+        LIMIT 1
+    </sql>
+    <arguments>
+        <argument name="pathname" type="string" help="Pathname of the bundle stream to check (BundleStream.pathname)"/>
+        <argument name="hwpack" type="string" help="Hardware pack to look for (TestRun.attributes['hwpack.type'])"/>
+        <argument name="rootfs" type="string" help="Root file system to look for (TestRun.attributes['rootfs.type'])"/>
+    </arguments>
+    <summary>
+      Select the most recent outcome of the job_complete test case in the lava test.
+    </summary>
+    <documentation>
+      TODO
+    </documentation>
+</data-view>

=== added file 'views/latest-test-runs.xml'
--- views/latest-test-runs.xml	1970-01-01 00:00:00 +0000
+++ views/latest-test-runs.xml	2011-09-07 18:45:23 +0000
@@ -0,0 +1,31 @@
+<data-view name="latest-test-runs">
+    <sql> 
+        SELECT
+            TestRun.analyzer_assigned_uuid AS "UUID",
+            TestRun.analyzer_assigned_date AS "Analyzer Assigned Date"
+        FROM
+            dashboard_app_testrun AS TestRun
+            INNER JOIN dashboard_app_bundle AS Bundle ON (
+                TestRun.bundle_id = Bundle.id)
+            INNER JOIN dashboard_app_bundlestream AS BundleStream ON (
+                BundleStream.id = Bundle.bundle_stream_id)
+        WHERE
+             BundleStream.pathname = <value name="pathname"/>
+        ORDER BY
+            TestRun.analyzer_assigned_date DESC
+        LIMIT <value name="count"/>
+    </sql>
+    <arguments>
+        <argument name="pathname" type="string" help="Pathname of a bundle stream to search"/>
+        <argument name="count" default="10" type="number" help="Select this many test runs (query limit)"/>
+    </arguments>
+    <summary>
+        List N most recent TestRuns specific bundle stream (sort by analyzer_assigned_date)
+    </summary>
+    <documentation>
+        This query joins three tables: TestRun + Bundle + BundleStream. The
+        filtering depends on the BundleStream.pathname property, the selected
+        value is TestRun.analyzer_assigned_uuid and
+        TestRun.analyzer_assigned_date.
+    </documentation>
+</data-view>

=== added file 'views/measurements.xml'
--- views/measurements.xml	1970-01-01 00:00:00 +0000
+++ views/measurements.xml	2011-09-07 18:45:23 +0000
@@ -0,0 +1,73 @@
+<data-view name="measurements">
+    <sql backend="sqlite">
+        SELECT
+            CAST(1000 * strftime('%s', TestRun.analyzer_assigned_date) AS TEXT) AS "Flot Timestamp",
+            TestResult.measurement AS "Measurement"
+        FROM
+            dashboard_app_testresult AS TestResult
+            INNER JOIN dashboard_app_testrun AS TestRun ON TestResult.test_run_id = TestRun.id
+            INNER JOIN dashboard_app_bundle AS Bundle ON TestRun.bundle_id = Bundle.id
+            INNER JOIN dashboard_app_bundlestream AS BundleStream ON Bundle.bundle_stream_id = BundleStream.id
+            INNER JOIN dashboard_app_testcase AS TestCase ON TestResult.test_case_id = TestCase.id
+            INNER JOIN dashboard_app_test AS Test ON TestRun.test_id = Test.id
+            INNER JOIN dashboard_app_testrun_devices as TestRun_Devices ON (
+                TestRun_Devices.testrun_id = TestRun.id
+            )
+            INNER JOIN dashboard_app_hardwaredevice as HardwareDevice_Board ON (
+                HardwareDevice_Board.id = TestRun_Devices.hardwaredevice_id
+                AND HardwareDevice_Board.device_type = 'device.board'
+            )
+        WHERE
+            BundleStream.pathname = <value name="pathname"/>
+            AND HardwareDevice_Board.description = <value name="board"/>
+            AND Test.test_id = <value name="test"/>
+            AND TestCase.test_case_id = <value name="test_case"/>
+            AND TestResult.measurement IS NOT NULL
+        ORDER BY
+            TestRun.analyzer_assigned_date DESC
+        LIMIT
+            <value name="count" />
+    </sql>
+    <sql backend="postgresql">
+        SELECT
+            CAST((EXTRACT(EPOCH FROM TestRun.analyzer_assigned_date)) * 1000 AS TEXT) AS "Flot Timestamp",
+            TestResult.measurement AS "Measurement"
+        FROM
+            dashboard_app_testresult AS TestResult
+            INNER JOIN dashboard_app_testrun AS TestRun ON TestResult.test_run_id = TestRun.id
+            INNER JOIN dashboard_app_bundle AS Bundle ON TestRun.bundle_id = Bundle.id
+            INNER JOIN dashboard_app_bundlestream AS BundleStream ON Bundle.bundle_stream_id = BundleStream.id
+            INNER JOIN dashboard_app_testcase AS TestCase ON TestResult.test_case_id = TestCase.id
+            INNER JOIN dashboard_app_test AS Test ON TestRun.test_id = Test.id
+            INNER JOIN dashboard_app_testrun_devices as TestRun_Devices ON (
+                TestRun_Devices.testrun_id = TestRun.id
+            )
+            INNER JOIN dashboard_app_hardwaredevice as HardwareDevice_Board ON (
+                HardwareDevice_Board.id = TestRun_Devices.hardwaredevice_id
+                AND HardwareDevice_Board.device_type = 'device.board'
+            )
+        WHERE
+            BundleStream.pathname = <value name="pathname"/>
+            AND HardwareDevice_Board.description = <value name="board"/>
+            AND Test.test_id = <value name="test"/>
+            AND TestCase.test_case_id = <value name="test_case"/>
+            AND TestResult.measurement IS NOT NULL
+        ORDER BY
+            TestRun.analyzer_assigned_date DESC
+        LIMIT
+            <value name="count" />
+    </sql>
+    <arguments>
+        <argument name="pathname" help="Bundle stream pathname" type="string"/>
+        <argument name="test" help="Identifier of the test to select" type="string"/>
+        <argument name="test_case" help="Identifier of the test case to select" type="string"/>
+        <argument name="board" help="Board to select" type="string"/>
+        <argument name="count" help="Select at most that many rows" type="number" default="10"/>
+    </arguments>
+    <summary>
+        Recent measurements of selected test case on a selected board
+    </summary>
+    <documentation>
+        Core data view for rendering charts
+    </documentation>
+</data-view>

=== added file 'views/recent-test-runs-for-board-and-hwpack-and-rootfs-1.xml'
--- views/recent-test-runs-for-board-and-hwpack-and-rootfs-1.xml	1970-01-01 00:00:00 +0000
+++ views/recent-test-runs-for-board-and-hwpack-and-rootfs-1.xml	2011-09-07 18:45:23 +0000
@@ -0,0 +1,93 @@
+<data-view name="recent-test-runs-for-board-and-hwpack-and-rootfs-1">
+    <sql> 
+        SELECT
+            TestRun.analyzer_assigned_uuid AS "UUID",
+            TestRun.analyzer_assigned_date AS "Analyzer Assigned Date"
+        FROM
+            dashboard_app_testrun as TestRun
+        WHERE
+            <!-- Filter for testruns in a specific bundle stream -->
+             TestRun.bundle_id IN (
+                SELECT
+                    Bundle.id
+                FROM
+                    dashboard_app_bundle AS Bundle
+                    INNER JOIN dashboard_app_bundlestream AS BundleStream ON (
+                        BundleStream.id = Bundle.bundle_stream_id)
+                WHERE
+                BundleStream.pathname = <value name="pathname"/>
+            )
+            AND TestRun.id IN (
+                    <!-- Limit to specific hardware pack -->
+                    SELECT
+                        NamedAttribute.object_id
+                    FROM
+                        dashboard_app_namedattribute AS NamedAttribute
+                    WHERE
+                        NamedAttribute.content_type_id = (
+                            SELECT
+                                django_content_type.id
+                            FROM
+                                django_content_type
+                            WHERE
+                                app_label = 'dashboard_app'
+                                AND model='testrun'
+                            )
+                        AND NamedAttribute.name = 'hwpack.type'
+                        AND NamedAttribute.value = <value name="hwpack"/>
+                INTERSECT
+                    <!-- Limit to specific root filesystem -->
+                    SELECT
+                        NamedAttribute.object_id
+                    FROM
+                        dashboard_app_namedattribute AS NamedAttribute
+                    WHERE
+                        NamedAttribute.content_type_id = (
+                            SELECT
+                                django_content_type.id
+                            FROM
+                                django_content_type
+                            WHERE
+                                app_label = 'dashboard_app'
+                                AND model='testrun'
+                            )
+                        AND NamedAttribute.name = 'rootfs.type'
+                        AND NamedAttribute.value = <value name="rootfs"/>
+                INTERSECT
+                    <!-- Limit to specific board -->
+                    SELECT
+                        TestRun_Devices.testrun_id
+                    FROM
+                        dashboard_app_hardwaredevice AS HardwareDevice
+                        INNER JOIN dashboard_app_testrun_devices AS TestRun_Devices ON (
+                            HardwareDevice.id = TestRun_Devices.hardwaredevice_id)
+                    WHERE
+                        HardwareDevice.device_type = 'device.board'
+                        AND HardwareDevice.description = <value name="board"/>
+            )
+        ORDER BY
+            TestRun.analyzer_assigned_date DESC
+        LIMIT <value name="count"/>
+    </sql>
+    <arguments>
+        <argument name="pathname" type="string" help="Pathname of the bundle stream to check (BundleStream.pathname)"/>
+        <argument name="board" type="string" help="Board to look for (HardwareDevice.description)"/>
+        <argument name="hwpack" type="string" help="Hardware pack to look for (TestRun.attributes['hwpack.type'])"/>
+        <argument name="rootfs" type="string" help="Root file system to look for (TestRun.attributes['rootfs.type'])"/>
+        <argument name="count" default="10" type="number" help="Select this many test runs (query limit)"/>
+    </arguments>
+    <summary>
+        Select recent test runs from a particular bundle stream that were
+        invoked on a particular board class with a particular hwardware pack.
+    </summary>
+    <documentation>
+        This query uses sub-queries to filter each test run against Bundle.id
+        and actual TestRun.id. The filtering for test run is complex and is
+        done as an intersection of: TestRun.id values that have particular
+        hardware pack (query 1), root fs (query 2) and board device (query 3) 
+
+        Based on my loose testing in SQLite it's the fastest version (5.21s
+        on my db). On PostgreSQL it's slightly slower than the second
+        variant (5.69s on the same db)
+    </documentation>
+</data-view>

=== added file 'views/recent-test-runs-for-board-and-hwpack-and-rootfs-2.xml'
--- views/recent-test-runs-for-board-and-hwpack-and-rootfs-2.xml	1970-01-01 00:00:00 +0000
+++ views/recent-test-runs-for-board-and-hwpack-and-rootfs-2.xml	2011-09-07 18:45:23 +0000
@@ -0,0 +1,77 @@
+<data-view name="recent-test-runs-for-board-and-hwpack-and-rootfs-2">
+    <sql> 
+        SELECT
+            TestRun.analyzer_assigned_uuid AS "UUID",
+            TestRun.analyzer_assigned_date AS "Analyzer Assigned Date"
+        FROM
+            dashboard_app_testrun as TestRun
+            INNER JOIN dashboard_app_namedattribute AS NamedAttribute_HardwarePack ON (
+                NamedAttribute_HardwarePack.object_id = TestRun.id
+                AND NamedAttribute_HardwarePack.content_type_id = (
+                    SELECT
+                        django_content_type.id
+                    FROM
+                        django_content_type
+                    WHERE
+                        app_label = 'dashboard_app'
+                        AND model='testrun'
+                    )
+                AND NamedAttribute_HardwarePack.name = 'hwpack.type'
+            )
+            INNER JOIN dashboard_app_namedattribute AS NamedAttribute_RootFileSystem ON (
+                NamedAttribute_RootFileSystem.object_id = TestRun.id
+                AND NamedAttribute_RootFileSystem.content_type_id = (
+                    SELECT
+                        django_content_type.id
+                    FROM
+                        django_content_type
+                    WHERE
+                        app_label = 'dashboard_app'
+                        AND model='testrun'
+                    )
+                AND NamedAttribute_RootFileSystem.name = 'rootfs.type'
+            )
+            INNER JOIN dashboard_app_testrun_devices as TestRun_Devices ON (
+                TestRun_Devices.testrun_id = TestRun.id
+            )
+            INNER JOIN dashboard_app_hardwaredevice as HardwareDevice_Board ON (
+                HardwareDevice_Board.id = TestRun_Devices.hardwaredevice_id
+                AND HardwareDevice_Board.device_type = 'device.board'
+            )
+            INNER JOIN dashboard_app_bundle AS Bundle ON (
+                Bundle.id = TestRun.bundle_id
+            )
+            INNER JOIN dashboard_app_bundlestream AS BundleStream ON (
+                BundleStream.id = Bundle.bundle_stream_id
+            )
+        WHERE
+            BundleStream.pathname = <value name="pathname"/>
+            AND HardwareDevice_Board.description = <value name="board"/>
+            AND NamedAttribute_RootFileSystem.value = <value name="rootfs"/>
+            AND NamedAttribute_HardwarePack.value = <value name="hwpack"/>
+        ORDER BY
+            TestRun.analyzer_assigned_date DESC
+        LIMIT <value name="count"/>
+    </sql>
+    <arguments>
+        <argument name="pathname" type="string" help="Pathname of the bundle stream to check (BundleStream.pathname)"/>
+        <argument name="board" type="string" help="Board to look for (HardwareDevice.description)"/>
+        <argument name="hwpack" type="string" help="Hardware pack to look for (TestRun.attributes['hwpack.type'])"/>
+        <argument name="rootfs" type="string" help="Root file system to look for (TestRun.attributes['rootfs.type'])"/>
+        <argument name="count" default="10" type="number" help="Select this many test runs (query limit)"/>
+    </arguments>
+    <summary>
+        Select recent test runs from a particular bundle stream that were
+        invoked on a particular board class with a particular hwardware pack.
+    </summary>
+    <documentation>
+        This query uses sub-queries to filter each test run against Bundle.id
+        and actual TestRun.id. The filtering for test run is complex and is
+        done as an intersection of: TestRun.id values that have particular
+        hardware pack (query 1), root fs (query 2) and board device (query 3) 
+
+        Based on my loose testing in SQLite it's the slowest version (13.76s on
+        my db). On PostgreSQL it's actually faster than -1 (5.57s on the same
+        db)
+    </documentation>
+</data-view>

=== added file 'views/recent-test-runs-for-board-and-hwpack-and-rootfs-3.xml'
--- views/recent-test-runs-for-board-and-hwpack-and-rootfs-3.xml	1970-01-01 00:00:00 +0000
+++ views/recent-test-runs-for-board-and-hwpack-and-rootfs-3.xml	2011-09-07 18:45:23 +0000
@@ -0,0 +1,76 @@
+<data-view name="recent-test-runs-for-board-and-hwpack-and-rootfs-3">
+    <sql backend="sqlite"> 
+        SELECT
+            TestRun.analyzer_assigned_uuid AS "UUID",
+            TestRun.analyzer_assigned_date AS "Analyzer Assigned Date"
+        FROM
+            dashboard_app_testrun as TestRun
+            INNER JOIN dashboard_app_namedattribute AS NamedAttribute_HardwarePack INDEXED BY dashboard_app_namedattribute_object_id_660530246aa47641 ON (
+                NamedAttribute_HardwarePack.object_id = TestRun.id
+                AND NamedAttribute_HardwarePack.content_type_id = (
+                    SELECT
+                        django_content_type.id
+                    FROM
+                        django_content_type
+                    WHERE
+                        app_label = 'dashboard_app'
+                        AND model='testrun'
+                    )
+                AND NamedAttribute_HardwarePack.name = 'hwpack.type'
+            )
+            INNER JOIN dashboard_app_namedattribute AS NamedAttribute_RootFileSystem INDEXED BY dashboard_app_namedattribute_object_id_660530246aa47641 ON (
+                NamedAttribute_RootFileSystem.object_id = TestRun.id
+                AND NamedAttribute_RootFileSystem.content_type_id = (
+                    SELECT
+                        django_content_type.id
+                    FROM
+                        django_content_type
+                    WHERE
+                        app_label = 'dashboard_app'
+                        AND model='testrun'
+                    )
+                AND NamedAttribute_RootFileSystem.name = 'rootfs.type'
+            )
+            INNER JOIN dashboard_app_testrun_devices as TestRun_Devices ON (
+                TestRun_Devices.testrun_id = TestRun.id
+            )
+            INNER JOIN dashboard_app_hardwaredevice as HardwareDevice_Board INDEXED BY dashboard_app_hardwaredevice_device_type_2f9d227c1c952d28 ON (
+                HardwareDevice_Board.id = TestRun_Devices.hardwaredevice_id
+                AND HardwareDevice_Board.device_type = 'device.board'
+            )
+            INNER JOIN dashboard_app_bundle AS Bundle ON (
+                Bundle.id = TestRun.bundle_id
+            )
+            INNER JOIN dashboard_app_bundlestream AS BundleStream ON (
+                BundleStream.id = Bundle.bundle_stream_id
+            )
+        WHERE
+            BundleStream.pathname = <value name="pathname"/>
+            AND HardwareDevice_Board.description = <value name="board"/>
+            AND NamedAttribute_RootFileSystem.value = <value name="rootfs"/>
+            AND NamedAttribute_HardwarePack.value = <value name="hwpack"/>
+        ORDER BY
+            TestRun.analyzer_assigned_date DESC
+        LIMIT <value name="count"/>
+    </sql>
+    <arguments>
+        <argument name="pathname" type="string" help="Pathname of the bundle stream to check (BundleStream.pathname)"/>
+        <argument name="board" type="string" help="Board to look for (HardwareDevice.description)"/>
+        <argument name="hwpack" type="string" help="Hardware pack to look for (TestRun.attributes['hwpack.type'])"/>
+        <argument name="rootfs" type="string" help="Root file system to look for (TestRun.attributes['rootfs.type'])"/>
+        <argument name="count" default="10" type="number" help="Select this many test runs (query limit)"/>
+    </arguments>
+    <summary>
+        Select recent test runs from a particular bundle stream that were
+        invoked on a particular board class with a particular hwardware pack.
+    </summary>
+    <documentation>
+        Same as -2 but using explicit index on named attributes and hardare
+        devices to speed things up. Requires migration level up to 0003 to
+        create the required indices.
+
+        Based on my loose testing in SQLite it's almost as fast as -1 but still
+        slower (6.43s on my db). It does not run on postgreSQL as the INDEXED
+        BY syntax is not supported there.
+    </documentation>
+</data-view>

=== added file 'views/recent-test-runs-for-board-and-hwpack-and-rootfs-4.xml'
--- views/recent-test-runs-for-board-and-hwpack-and-rootfs-4.xml	1970-01-01 00:00:00 +0000
+++ views/recent-test-runs-for-board-and-hwpack-and-rootfs-4.xml	2011-09-07 18:45:23 +0000
@@ -0,0 +1,77 @@
+<data-view name="recent-test-runs-for-board-and-hwpack-and-rootfs-4">
+    <sql> 
+        SELECT
+            TestRun.analyzer_assigned_uuid AS "UUID",
+            TestRun.analyzer_assigned_date AS "Analyzer Assigned Date"
+        FROM
+            dashboard_app_testrun as TestRun
+            INNER JOIN dashboard_app_namedattribute AS NamedAttribute_HardwarePack ON (
+                NamedAttribute_HardwarePack.object_id = TestRun.id
+                AND NamedAttribute_HardwarePack.content_type_id = (
+                    SELECT
+                        django_content_type.id
+                    FROM
+                        django_content_type
+                    WHERE
+                        app_label = 'dashboard_app'
+                        AND model='testrun'
+                    )
+            )
+            INNER JOIN dashboard_app_namedattribute AS NamedAttribute_RootFileSystem ON (
+                NamedAttribute_RootFileSystem.object_id = TestRun.id
+                AND NamedAttribute_RootFileSystem.content_type_id = (
+                    SELECT
+                        django_content_type.id
+                    FROM
+                        django_content_type
+                    WHERE
+                        app_label = 'dashboard_app'
+                        AND model='testrun'
+                    )
+            )
+            INNER JOIN dashboard_app_testrun_devices as TestRun_Devices ON (
+                TestRun_Devices.testrun_id = TestRun.id
+            )
+            INNER JOIN dashboard_app_hardwaredevice as HardwareDevice_Board ON (
+                HardwareDevice_Board.id = TestRun_Devices.hardwaredevice_id
+                AND HardwareDevice_Board.device_type = 'device.board'
+            )
+            INNER JOIN dashboard_app_bundle AS Bundle ON (
+                Bundle.id = TestRun.bundle_id
+            )
+            INNER JOIN dashboard_app_bundlestream AS BundleStream ON (
+                BundleStream.id = Bundle.bundle_stream_id
+            )
+        WHERE
+            BundleStream.pathname = <value name="pathname"/>
+            AND NamedAttribute_HardwarePack.name = 'hwpack.type'
+            AND NamedAttribute_HardwarePack.value = <value name="hwpack"/>
+            AND NamedAttribute_RootFileSystem.name = 'rootfs.type'
+            AND NamedAttribute_RootFileSystem.value = <value name="rootfs"/>
+            AND HardwareDevice_Board.description = <value name="board"/>
+        ORDER BY
+            TestRun.analyzer_assigned_date DESC
+        LIMIT <value name="count"/>
+    </sql>
+    <arguments>
+        <argument name="pathname" type="string" help="Pathname of the bundle stream to check (BundleStream.pathname)"/>
+        <argument name="board" type="string" help="Board to look for (HardwareDevice.description)"/>
+        <argument name="hwpack" type="string" help="Hardware pack to look for (TestRun.attributes['hwpack.type'])"/>
+        <argument name="rootfs" type="string" help="Root file system to look for (TestRun.attributes['rootfs.type'])"/>
+        <argument name="count" default="10" type="number" help="Select this many test runs (query limit)"/>
+    </arguments>
+    <summary>
+        Select recent test runs from a particular bundle stream that were
+        invoked on a particular board class with a particular hwardware pack.
+    </summary>
+    <documentation>
+        This query uses sub-queries to filter each test run against Bundle.id
+        and actual TestRun.id. The filtering for test run is complex and is
+        done as an intersection of: TestRun.id values that have particular
+        hardware pack (query 1), root fs (query 2) and board device (query 3) 
+
+        Based on my loose testing in SQLite it's the second slowest version
+        (14.06s on my db). On PostgreSQL it's tiny bit slower than -2 (5.65s on
+        the same db)
+    </documentation>
+</data-view>

=== added file 'views/rootfs-type.xml'
--- views/rootfs-type.xml	1970-01-01 00:00:00 +0000
+++ views/rootfs-type.xml	2011-09-07 18:45:23 +0000
@@ -0,0 +1,45 @@
+<data-view name="rootfs-type">
+    <sql> 
+        SELECT DISTINCT
+            NamedAttribute_RootFS_Type.value
+        FROM
+            dashboard_app_testresult AS TestResult
+            INNER JOIN dashboard_app_testrun AS TestRun ON (
+                TestResult.test_run_id = TestRun.id
+            )
+            INNER JOIN dashboard_app_bundle AS Bundle ON (
+                Bundle.id = TestRun.bundle_id
+            )
+            INNER JOIN dashboard_app_bundlestream AS BundleStream ON (
+                Bundle.bundle_stream_id = BundleStream.id
+            )
+            INNER JOIN dashboard_app_namedattribute AS NamedAttribute_RootFS_Type ON (
+                NamedAttribute_RootFS_Type.object_id = TestRun.id
+                AND NamedAttribute_RootFS_Type.content_type_id = (
+                    SELECT
+                        django_content_type.id
+                    FROM
+                        django_content_type
+                    WHERE
+                        app_label = 'dashboard_app'
+                        AND model='testrun'
+                    )
+                AND NamedAttribute_RootFS_Type.name = 'rootfs.type'
+            )
+            INNER JOIN dashboard_app_testcase AS TestCase ON (
+                TestResult.test_case_id = TestCase.id
+            )
+        WHERE
+            BundleStream.pathname = <value name="pathname"/>
+    </sql>
+    <arguments>
+        <argument name="pathname" type="string" help="Pathname of the bundle stream to check (BundleStream.pathname)"/>
+    </arguments>
+    <summary>
+      List all the root filesystem types in a specified bundle stream
+    </summary>
+    <documentation>
+      This query simply selects all the distinct value of the rootfs.type
+      attribute for all the test runs in the specified bundle stream.
+    </documentation>
+</data-view>