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

Proposed by Deepti B. Kalakeri
Status: Superseded
Proposed branch: lp:~deeptik/lava-dashboard/kernel-ci-data-veiw-report
Merge into: lp:lava-dashboard
Diff against target: 1506 lines (+1370/-0)
27 files modified
reports/android-runs.html (+9/-0)
reports/android-runs.xml (+4/-0)
reports/benchmark.html (+112/-0)
reports/benchmark.xml (+4/-0)
reports/board-activity.html (+11/-0)
reports/board-activity.xml (+4/-0)
reports/boot-status-overview.html (+101/-0)
reports/boot-status-overview.xml (+4/-0)
reports/boot-status.html (+15/-0)
reports/boot-status.xml (+4/-0)
reports/kernel-ci-data.html (+54/-0)
reports/kernel-ci-data.xml (+4/-0)
update.sh (+8/-0)
views/android-runs.xml (+33/-0)
views/board-activity.xml (+122/-0)
views/boot-status.xml (+115/-0)
views/hostnames.xml (+37/-0)
views/hwpack-type.xml (+45/-0)
views/kernel-ci-data.xml (+138/-0)
views/latest-job-complete-for-hwpack-and-rootfs.xml (+74/-0)
views/latest-test-runs.xml (+31/-0)
views/measurements.xml (+73/-0)
views/recent-test-runs-for-board-and-hwpack-and-rootfs-1.xml (+93/-0)
views/recent-test-runs-for-board-and-hwpack-and-rootfs-2.xml (+77/-0)
views/recent-test-runs-for-board-and-hwpack-and-rootfs-3.xml (+76/-0)
views/recent-test-runs-for-board-and-hwpack-and-rootfs-4.xml (+77/-0)
views/rootfs-type.xml (+45/-0)
To merge this branch: bzr merge lp:~deeptik/lava-dashboard/kernel-ci-data-veiw-report
Reviewer Review Type Date Requested Status
Zygmunt Krynicki (community) Needs Resubmitting
Review via email: mp+74493@code.launchpad.net

Description of the change

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.

To post a comment you must log in.
Revision history for this message
Zygmunt Krynicki (zyga) wrote :

Please target this merge request at lp:~linaro-validation/lava-dashboard/data-views-and-reports. We keep it separate from dashbaord code base for easier review process.

review: Needs Resubmitting
Revision history for this message
Deepti B. Kalakeri (deeptik) wrote :

Done.

Thanks and Regards,
Deepti.

On Thu, Sep 8, 2011 at 3:38 AM, Zygmunt Krynicki <
<email address hidden>> wrote:

> Review: Resubmit
>
> Please target this merge request at
> lp:~linaro-validation/lava-dashboard/data-views-and-reports. We keep it
> separate from dashbaord code base for easier review process.
> --
>
> https://code.launchpad.net/~deeptik/lava-dashboard/kernel-ci-data-veiw-report/+merge/74493<https://code.launchpad.net/%7Edeeptik/lava-dashboard/kernel-ci-data-veiw-report/+merge/74493>
> You are the owner of lp:~deeptik/lava-dashboard/kernel-ci-data-veiw-report.
>

Unmerged revisions

29. By Deepti B. Kalakeri

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.

wq

28. By Zygmunt Krynicki

Add if-else guard around accesses to result.rows

27. By Zygmunt Krynicki

Fix lin to test run in boot-status-overview

26. By Zygmunt Krynicki

Use dashboard_app prefix for accessing STATIC_URL files

25. By Zygmunt Krynicki

Use STATIC_URL to refer to images

24. By Zygmunt Krynicki

Add sqlite version of measurements

23. By Zygmunt Krynicki

Update caption, handle missing data better, show the date, comment out the console.log() calls that might fail without developer tools

22. By Zygmunt Krynicki

Use single quotes, damn you sqlite

21. By Zygmunt Krynicki

Actually look at job_complete from lava, not some arbitrary random test result

20. By Zygmunt Krynicki

Add new boot status report

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added directory 'reports'
2=== added file 'reports/android-runs.html'
3--- reports/android-runs.html 1970-01-01 00:00:00 +0000
4+++ reports/android-runs.html 2011-09-07 18:45:23 +0000
5@@ -0,0 +1,9 @@
6+<div id="placeholder"></div>
7+<script type="text/javascript">
8+ $().dashboard("init", "{{ API_URL }}", function (server) {
9+ var data_view_name = "android-runs";
10+ var data_view_arguments = {};
11+ $("#placeholder").dashboard(
12+ "render_to_table", data_view_name, data_view_arguments);
13+ });
14+</script>
15
16=== added file 'reports/android-runs.xml'
17--- reports/android-runs.xml 1970-01-01 00:00:00 +0000
18+++ reports/android-runs.xml 2011-09-07 18:45:23 +0000
19@@ -0,0 +1,4 @@
20+<data-report name="android-runs">
21+ <title>Anrdoid Runs</title>
22+ <path>android-runs.html</path>
23+</data-report>
24
25=== added file 'reports/benchmark.html'
26--- reports/benchmark.html 1970-01-01 00:00:00 +0000
27+++ reports/benchmark.html 2011-09-07 18:45:23 +0000
28@@ -0,0 +1,112 @@
29+<style type="text/css">
30+ .chart {
31+ width: 600px;
32+ height: 300px;
33+ display: block;
34+ }
35+ .report {
36+ width: 50em;
37+ }
38+ h1 {
39+ border-bottom: 2pt solid gray;
40+ }
41+</style>
42+<h1>Daily benchmarks for Panda and Beagle</h1>
43+<div class="report">
44+ <h2>Test 1: stream.Add</h2>
45+ <div id="placeholder1" class="chart"></div>
46+ <p>Most recent runs of stream.Add on Panda and Beagle. The X axis shows the
47+ time of the test. The Y axis shows the MB/s.</p>
48+
49+ <h2>Test 2: stream.Scale</h2>
50+ <div id="placeholder2" class="chart"></div>
51+ <p>Pellentesque turpis massa, consectetur nec viverra in, molestie ut
52+ velit. Vivamus venenatis, sem quis dapibus imperdiet, felis est semper ipsum,
53+ vitae scelerisque quam odio sed augue. Praesent sagittis ligula a augue
54+ placerat porta. Mauris aliquet tincidunt nisl, vel lacinia odio venenatis
55+ vitae. Morbi iaculis commodo ligula, ut vestibulum odio accumsan congue. Sed
56+ at viverra ipsum. Duis accumsan accumsan posuere. Nulla quis tellus arcu, et
57+ tempus lectus. Praesent sit amet dui nunc, at ultrices leo.</p>
58+ <h2>Test 3: pybench.CompareUnicode</h2>
59+ <div id="placeholder3" class="chart"></div>
60+ <p>Pellentesque turpis massa, consectetur nec viverra in, molestie ut
61+ velit. Vivamus venenatis, sem quis dapibus imperdiet, felis est semper ipsum,
62+ vitae scelerisque quam odio sed augue. Praesent sagittis ligula a augue
63+ placerat porta. Mauris aliquet tincidunt nisl, vel lacinia odio venenatis
64+ vitae. Morbi iaculis commodo ligula, ut vestibulum odio accumsan congue. Sed
65+ at viverra ipsum. Duis accumsan accumsan posuere. Nulla quis tellus arcu, et
66+ tempus lectus. Praesent sit amet dui nunc, at ultrices leo.</p>
67+</div>
68+<script type="text/javascript">
69+ $(function () {
70+ /* Configuration */
71+ var pathname = "/anonymous/lava-daily/";
72+ var count = 100;
73+ var boards = Array("OMAP3 Beagle Board", "OMAP4 Panda board");
74+
75+ /* Setup charts */
76+ $(".chart").dashboard("graph", {
77+ lines: { show: true },
78+ points: { show: true },
79+ xaxis: {
80+ mode: "time",
81+ ticks: 10,
82+ label: "Time",
83+ labelPos: "low"
84+ },
85+ yaxis: {
86+ min: 0,
87+ label: "MB/s",
88+ labelPos: "high"
89+ }
90+ });
91+
92+ /* Add data series to each chart */
93+ $().dashboard("init", "{{ API_URL }}", function (server) {
94+ $(boards).each(function (index, board) {
95+ $("#placeholder1").dashboard("add_series", {
96+ label: "Recent runs of stream.Add on " + board,
97+ data_view: {
98+ name: "measurements",
99+ args: {
100+ board: board,
101+ count: count,
102+ test: "stream",
103+ test_case: "Add",
104+ pathname: pathname
105+ }
106+ }
107+ });
108+ $("#placeholder2").dashboard("add_series", {
109+ label: "Recent runs of stream.Scale on " + board,
110+ data_view: {
111+ name: "measurements",
112+ args: {
113+ board: board,
114+ count: count,
115+ test: "stream",
116+ test_case: "Scale",
117+ pathname: pathname
118+ }
119+ }
120+ });
121+ });
122+
123+ /* Add one more report */
124+ $("#placeholder3").dashboard("add_series", {
125+ label: "Past 100 runs of pybench.CompareUnicode on Panda",
126+ data_view: {
127+ name: "measurements",
128+ args: {
129+ board: "OMAP4 Panda board",
130+ test: "pybench",
131+ test_case: "CompareUnicode",
132+ pathname: pathname,
133+ count: 100
134+ }
135+ }
136+ });
137+
138+ });
139+ });
140+</script>
141
142=== added file 'reports/benchmark.xml'
143--- reports/benchmark.xml 1970-01-01 00:00:00 +0000
144+++ reports/benchmark.xml 2011-09-07 18:45:23 +0000
145@@ -0,0 +1,4 @@
146+<data-report name="benchmark">
147+ <title>Daily benchmarks for Panda and Beagle</title>
148+ <path>benchmark.html</path>
149+</data-report>
150
151=== added file 'reports/board-activity.html'
152--- reports/board-activity.html 1970-01-01 00:00:00 +0000
153+++ reports/board-activity.html 2011-09-07 18:45:23 +0000
154@@ -0,0 +1,11 @@
155+<div id="placeholder"></div>
156+<script type="text/javascript">
157+ $().dashboard("init", "{{ API_URL }}", function (server) {
158+ var data_view_name = "board-activity";
159+ var data_view_arguments = {
160+ pathname: "/anonymous/lava-daily/"
161+ };
162+ $("#placeholder").dashboard(
163+ "render_to_table", data_view_name, data_view_arguments);
164+ });
165+</script>
166
167=== added file 'reports/board-activity.xml'
168--- reports/board-activity.xml 1970-01-01 00:00:00 +0000
169+++ reports/board-activity.xml 2011-09-07 18:45:23 +0000
170@@ -0,0 +1,4 @@
171+<data-report name="board-activity">
172+ <title>Board activity</title>
173+ <path>board-activity.html</path>
174+</data-report>
175
176=== added file 'reports/boot-status-overview.html'
177--- reports/boot-status-overview.html 1970-01-01 00:00:00 +0000
178+++ reports/boot-status-overview.html 2011-09-07 18:45:23 +0000
179@@ -0,0 +1,101 @@
180+<h2>Image boot status by board</h2>
181+
182+<p>The following table shows image / hardware pack boot status. Please click on
183+the icon in individual cell to see more details</p>
184+
185+<div id="placeholder"></div>
186+<script type="text/javascript">
187+ $().dashboard("init", "{{ API_URL }}", function (server) {
188+ function query_data_view(data_view_name, data_view_arguments, callback) {
189+ server.query_data_view(callback, data_view_name, data_view_arguments);
190+ }
191+ var pathname = "/anonymous/lava-daily/";
192+ var hwpack_list = null;
193+ var rootfs_list = null;
194+
195+
196+ /* Function that renders the actual table */
197+ function render_if_possible() {
198+ if (hwpack_list != null && rootfs_list != null) {
199+ //console.log("we can render now");
200+ var html = "";
201+ html += "<table class='data'>";
202+ html += "<tr>";
203+ html += "<th></th>";
204+ $.each(hwpack_list, function (hwpack_index, hwpack_name) {
205+ html += "<th>" + hwpack_name + "</th>";
206+ });
207+ html += "</tr>";
208+ html += "<tr>";
209+ $.each(rootfs_list, function (rootfs_index, rootfs_name) {
210+ html += "<tr>";
211+ html += "<th>" + rootfs_name + "</th>";
212+ $.each(hwpack_list, function (hwpack_index, hwpack_name) {
213+ html += "<td id='cell_" + rootfs_index + "_" + hwpack_index + "'></td>";
214+ query_data_view(
215+ "latest-job-complete-for-hwpack-and-rootfs", {
216+ "pathname": pathname,
217+ "hwpack": hwpack_name,
218+ "rootfs": rootfs_name
219+ },
220+ function(response) {
221+ //console.log("cell:", rootfs_index, hwpack_index, response.result.rows);
222+ if (response && response.result && response.result.rows && response.result.rows.length == 1) {
223+ var outcome = response.result.rows[0][0];
224+ var uuid = response.result.rows[0][1];
225+ var datetime = response.result.rows[0][2];
226+ var cell_html = "";
227+ var cell_link = "{{ API_URL }}.." + "/permalink/test-run/" + uuid + "/";
228+ var _img = ""
229+ switch (outcome) {
230+ case 0:
231+ _img = "<img src='{{ STATIC_URL }}dashboard_app/images/icon-pass.png' alt='FAIL'/>";
232+ break;
233+ case 1:
234+ _img = "<img src='{{ STATIC_URL }}dashboard_app/images/icon-fail.png' alt='FAIL'/>";
235+ break;
236+ };
237+ cell_html = "<a href='" + cell_link + "'>" + _img + " " + datetime + "</a>";
238+ $("#cell_" + rootfs_index + "_" + hwpack_index).html(cell_html);
239+ }
240+ }
241+ );
242+ });
243+ html += "</tr>";
244+ });
245+ html += "</table>";
246+ $("#placeholder").html(html)
247+ }
248+ }
249+
250+ /* Get a list of hardware pack types */
251+ query_data_view("hwpack-type", {"pathname": pathname},
252+ function(response) {
253+ hwpack_list = new Array();
254+ if (response && response.result && response.result.rows) {
255+ $.each(response.result.rows, function (index, row) {
256+ hwpack_list.push(row[0]);
257+ });
258+ }
259+ //console.log("hwpack list:", hwpack_list);
260+ render_if_possible();
261+ }
262+ );
263+
264+ /* Get a list of root file systems */
265+ query_data_view("rootfs-type", {"pathname": pathname},
266+ function(response) {
267+ rootfs_list = new Array();
268+ if (response && response.result && response.result.rows) {
269+ $.each(response.result.rows, function (index, row) {
270+ rootfs_list.push(row[0]);
271+ });
272+ }
273+ //console.log("rootfs list:", rootfs_list);
274+ render_if_possible();
275+ }
276+ );
277+
278+
279+ });
280+</script>
281
282=== added file 'reports/boot-status-overview.xml'
283--- reports/boot-status-overview.xml 1970-01-01 00:00:00 +0000
284+++ reports/boot-status-overview.xml 2011-09-07 18:45:23 +0000
285@@ -0,0 +1,4 @@
286+<data-report name="boot-status-overview">
287+ <title>Boot status overview</title>
288+ <path>boot-status-overview.html</path>
289+</data-report>
290
291=== added file 'reports/boot-status.html'
292--- reports/boot-status.html 1970-01-01 00:00:00 +0000
293+++ reports/boot-status.html 2011-09-07 18:45:23 +0000
294@@ -0,0 +1,15 @@
295+<div id="placeholder"></div>
296+<script type="text/javascript">
297+ $().dashboard("init", "{{ API_URL }}", function (server) {
298+ var data_view_name = "hostnames";
299+ var data_view_arguments = {};
300+ server.query_data_view(function (response) {
301+ $(response.result.rows).each(function (index, row) {
302+ var hostname = row[0];
303+ $("#placeholder").append("<div id='placeholder_" + hostname + "'><div>");
304+ $("#placeholder_" + hostname).dashboard(
305+ "render_to_table", "boot-status", {"hostname": hostname}, {caption: "Boot history for " + hostname});
306+ });
307+ }, "hostnames", {});
308+ });
309+</script>
310
311=== added file 'reports/boot-status.xml'
312--- reports/boot-status.xml 1970-01-01 00:00:00 +0000
313+++ reports/boot-status.xml 2011-09-07 18:45:23 +0000
314@@ -0,0 +1,4 @@
315+<data-report name="boot-status">
316+ <title>Boot status</title>
317+ <path>boot-status.html</path>
318+</data-report>
319
320=== added file 'reports/kernel-ci-data.html'
321--- reports/kernel-ci-data.html 1970-01-01 00:00:00 +0000
322+++ reports/kernel-ci-data.html 2011-09-07 18:45:23 +0000
323@@ -0,0 +1,54 @@
324+<div id="placeholder"></div>
325+<script type="text/javascript">
326+ $().dashboard("init", "{{ API_URL }}", function (server) {
327+ var data_view_name = "CI Kernel Data";
328+ var data_view_arguments = {
329+ boot_pathname: "/anonymous/ci-linux-linaro-3_0/",
330+ build_pathname: "/anonymous/ci-linux-linaro-3_0-build/"
331+ };
332+ server.query_data_view(function (response) {
333+ if (response.result) {
334+ var dataset = response.result;
335+ var html = "<table class='demo_jui display' id='kernel_ci_results'>";
336+ html += "<thead><tr>";
337+ $.each(dataset.columns, function (index, column) {
338+ html += "<th>" + column.name + "</th>";
339+ });
340+ html += "</tr></thead><tbody>";
341+ $.each(dataset.rows, function (index, row) {
342+ html += "<tr>";
343+ $.each(row, function (index, cell) {
344+ var column = dataset.columns[index];
345+ var cell_link = null;
346+ if (column.name.indexOf("UUID") > 0) {
347+ /* This is a bit hacky but will work for now */
348+ cell_link = "{{ API_URL }}../permalink/test-run/" + cell + "/";
349+ cell_html = "go to test run"
350+ } else {
351+ cell_html = cell;
352+ }
353+ html += "<td>";
354+ if (cell_link) {
355+ html += "<a href='" + cell_link + "'>"
356+ html += cell_html;
357+ html += "</a>";
358+ } else {
359+ html += cell_html;
360+ }
361+ html += "</td>";
362+ });
363+ html += "</tr>";
364+ });
365+ html += "</tbody></table>";
366+ $("#placeholder").html(html);
367+ $("#kernel_ci_results").dataTable({
368+ "bJQueryUI": true,
369+ "sPaginationType": "full_numbers",
370+ });
371+ } else {
372+ $this.html("Error code:" + response.error.faultCode + ", message: " + response.error.faultString);
373+ }
374+ }, data_view_name, data_view_arguments);
375+ });
376+</script>
377+
378
379=== added file 'reports/kernel-ci-data.xml'
380--- reports/kernel-ci-data.xml 1970-01-01 00:00:00 +0000
381+++ reports/kernel-ci-data.xml 2011-09-07 18:45:23 +0000
382@@ -0,0 +1,4 @@
383+<data-report name="kernel-ci-data">
384+ <title>CI Kernel Data</title>
385+ <path>kernel-ci-data.html</path>
386+</data-report>
387
388=== added file 'update.sh'
389--- update.sh 1970-01-01 00:00:00 +0000
390+++ update.sh 2011-09-07 18:45:23 +0000
391@@ -0,0 +1,8 @@
392+#!/bin/sh
393+REPO=/srv/launch-control/data-views-and-reports
394+old_revno=$(bzr revno -D $REPO)
395+bzr up -D $REPO --quiet
396+new_revno=$(bzr revno -D $REPO)
397+if [ "$old_revno" != "$new_revno" ]; then
398+ sudo apache2ctl restart
399+fi
400
401=== added directory 'views'
402=== added file 'views/android-runs.xml'
403--- views/android-runs.xml 1970-01-01 00:00:00 +0000
404+++ views/android-runs.xml 2011-09-07 18:45:23 +0000
405@@ -0,0 +1,33 @@
406+<data-view name="android-runs">
407+ <sql>
408+ SELECT
409+ TestRun.analyzer_assigned_date AS "Analyzer Assigned Date",
410+ NamedAttribute_AndroidURL.value AS "Android URL",
411+ TestRun.analyzer_assigned_uuid AS "UUID"
412+ FROM
413+ dashboard_app_testrun AS TestRun
414+ INNER JOIN dashboard_app_namedattribute AS NamedAttribute_AndroidURL ON (
415+ NamedAttribute_AndroidURL.object_id = TestRun.id
416+ AND NamedAttribute_AndroidURL.content_type_id = (
417+ SELECT
418+ django_content_type.id
419+ FROM
420+ django_content_type
421+ WHERE
422+ app_label = 'dashboard_app'
423+ AND model='testrun'
424+ )
425+ AND NamedAttribute_AndroidURL.name = 'android.url'
426+ )
427+ ORDER BY
428+ TestRun.analyzer_assigned_date DESC
429+ LIMIT <value name="count"/>
430+ </sql>
431+ <arguments>
432+ <argument name="count" default="10" type="number" help="Select this many test runs (query limit)"/>
433+ </arguments>
434+ <summary>
435+ </summary>
436+ <documentation>
437+ </documentation>
438+</data-view>
439
440=== added file 'views/board-activity.xml'
441--- views/board-activity.xml 1970-01-01 00:00:00 +0000
442+++ views/board-activity.xml 2011-09-07 18:45:23 +0000
443@@ -0,0 +1,122 @@
444+<data-view name="board-activity">
445+ <sql backend="postgresql">
446+ SELECT
447+ NamedAttribute_Target_Hostname.value AS "Hostname",
448+ HardwareDevice_Board.description AS "Board",
449+ NamedAttribute_HardwarePack_Type.value
450+ || ' '
451+ || to_char(CAST(NamedAttribute_HardwarePack_Date.value AS TIMESTAMP), 'YYYY-MM-DD')
452+ AS "Hardware Pack",
453+ NamedAttribute_RootFileSystem_Type.value
454+ || ' '
455+ || to_char(CAST(NamedAttribute_RootFileSystem_Date.value AS TIMESTAMP), 'YYYY-MM-DD')
456+ AS "Root File System",
457+ Test.test_id AS "Test",
458+ (SELECT COUNT(*) FROM dashboard_app_testresult AS TestResult WHERE TestResult.test_run_id = TestRun.id) AS "Test Cases",
459+ (SELECT COUNT(*) FROM dashboard_app_testresult AS TestResult WHERE TestResult.test_run_id = TestRun.id AND TestResult.result = 1) AS "Failures",
460+ TestRun.analyzer_assigned_uuid AS "UUID",
461+ TestRun.analyzer_assigned_date AS "Analyzer Assigned Date"
462+ FROM
463+ dashboard_app_testrun AS TestRun
464+ INNER JOIN dashboard_app_bundle AS Bundle ON (
465+ TestRun.bundle_id = Bundle.id
466+ )
467+ INNER JOIN dashboard_app_bundlestream AS BundleStream ON (
468+ BundleStream.id = Bundle.bundle_stream_id
469+ )
470+ INNER JOIN dashboard_app_test AS Test ON (
471+ Test.id = TestRun.test_id
472+ )
473+ INNER JOIN dashboard_app_namedattribute AS NamedAttribute_Target_Hostname ON (
474+ NamedAttribute_Target_Hostname.object_id = TestRun.id
475+ AND NamedAttribute_Target_Hostname.content_type_id = (
476+ SELECT
477+ django_content_type.id
478+ FROM
479+ django_content_type
480+ WHERE
481+ app_label = 'dashboard_app'
482+ AND model='testrun'
483+ )
484+ AND NamedAttribute_Target_Hostname.name = 'target.hostname'
485+ )
486+ INNER JOIN dashboard_app_namedattribute AS NamedAttribute_HardwarePack_Type ON (
487+ NamedAttribute_HardwarePack_Type.object_id = TestRun.id
488+ AND NamedAttribute_HardwarePack_Type.content_type_id = (
489+ SELECT
490+ django_content_type.id
491+ FROM
492+ django_content_type
493+ WHERE
494+ app_label = 'dashboard_app'
495+ AND model='testrun'
496+ )
497+ AND NamedAttribute_HardwarePack_Type.name = 'hwpack.type'
498+ )
499+ INNER JOIN dashboard_app_namedattribute AS NamedAttribute_HardwarePack_Date ON (
500+ NamedAttribute_HardwarePack_Date.object_id = TestRun.id
501+ AND NamedAttribute_HardwarePack_Date.content_type_id = (
502+ SELECT
503+ django_content_type.id
504+ FROM
505+ django_content_type
506+ WHERE
507+ app_label = 'dashboard_app'
508+ AND model='testrun'
509+ )
510+ AND NamedAttribute_HardwarePack_Date.name = 'hwpack.date'
511+ )
512+ INNER JOIN dashboard_app_namedattribute AS NamedAttribute_RootFileSystem_Type ON (
513+ NamedAttribute_RootFileSystem_Type.object_id = TestRun.id
514+ AND NamedAttribute_RootFileSystem_Type.content_type_id = (
515+ SELECT
516+ django_content_type.id
517+ FROM
518+ django_content_type
519+ WHERE
520+ app_label = 'dashboard_app'
521+ AND model='testrun'
522+ )
523+ AND NamedAttribute_RootFileSystem_Type.name = 'rootfs.type'
524+ )
525+ INNER JOIN dashboard_app_namedattribute AS NamedAttribute_RootFileSystem_Date ON (
526+ NamedAttribute_RootFileSystem_Date.object_id = TestRun.id
527+ AND NamedAttribute_RootFileSystem_Date.content_type_id = (
528+ SELECT
529+ django_content_type.id
530+ FROM
531+ django_content_type
532+ WHERE
533+ app_label = 'dashboard_app'
534+ AND model='testrun'
535+ )
536+ AND NamedAttribute_RootFileSystem_Date.name = 'rootfs.date'
537+ )
538+ INNER JOIN dashboard_app_testrun_devices as TestRun_Devices ON (
539+ TestRun_Devices.testrun_id = TestRun.id
540+ )
541+ INNER JOIN dashboard_app_hardwaredevice as HardwareDevice_Board ON (
542+ HardwareDevice_Board.id = TestRun_Devices.hardwaredevice_id
543+ AND HardwareDevice_Board.device_type = 'device.board'
544+ )
545+ WHERE
546+ BundleStream.pathname = <value name="pathname"/>
547+ ORDER BY
548+ TestRun.analyzer_assigned_date DESC
549+ LIMIT
550+ <value name="count"/>
551+ </sql>
552+ <arguments>
553+ <argument name="pathname" type="string" help="Pathname of a bundle stream to search"/>
554+ <argument name="count" default="60" type="number" help="Select this many test runs (query limit)"/>
555+ </arguments>
556+ <summary>
557+ List N most recent TestRuns specific bundle stream (sort by analyzer_assigned_date)
558+ </summary>
559+ <documentation>
560+ This query joins three tables: TestRun + Bundle + BundleStream. The
561+ filtering depends on the BundleStream.pathname property, the selected
562+ value is TestRun.analyzer_assigned_uuid and
563+ TestRun.analyzer_assigned_date.
564+ </documentation>
565+</data-view>
566
567=== added file 'views/boot-status.xml'
568--- views/boot-status.xml 1970-01-01 00:00:00 +0000
569+++ views/boot-status.xml 2011-09-07 18:45:23 +0000
570@@ -0,0 +1,115 @@
571+<data-view name="boot-status">
572+ <sql>
573+ SELECT
574+ (CASE TestResult.result WHEN 0 THEN 'Success' ELSE 'Failure' END) AS "Boot Status",
575+ NamedAttribute_HardwarePack_Type.value
576+ || ' '
577+ || to_char(CAST(NamedAttribute_HardwarePack_Date.value AS TIMESTAMP), 'YYYY-MM-DD')
578+ AS "Hardware Pack",
579+ NamedAttribute_RootFileSystem_Type.value
580+ || ' '
581+ || to_char(CAST(NamedAttribute_RootFileSystem_Date.value AS TIMESTAMP), 'YYYY-MM-DD')
582+ AS "Root File System",
583+ TestRun.analyzer_assigned_date AS "Analyzer Assigned Date",
584+ TestRun.analyzer_assigned_uuid AS "UUID"
585+ FROM
586+ dashboard_app_testresult AS TestResult
587+ INNER JOIN dashboard_app_testrun AS TestRun ON (
588+ TestResult.test_run_id = TestRun.id
589+ )
590+ INNER JOIN dashboard_app_bundle AS Bundle ON (
591+ Bundle.id = TestRun.bundle_id
592+ )
593+ INNER JOIN dashboard_app_bundlestream AS BundleStream ON (
594+ Bundle.bundle_stream_id = BundleStream.id
595+ )
596+ INNER JOIN dashboard_app_namedattribute AS NamedAttribute_Target_Hostname ON (
597+ NamedAttribute_Target_Hostname.object_id = TestRun.id
598+ AND NamedAttribute_Target_Hostname.content_type_id = (
599+ SELECT
600+ django_content_type.id
601+ FROM
602+ django_content_type
603+ WHERE
604+ app_label = 'dashboard_app'
605+ AND model='testrun'
606+ )
607+ AND NamedAttribute_Target_Hostname.name = 'target.hostname'
608+ )
609+ INNER JOIN dashboard_app_namedattribute AS NamedAttribute_HardwarePack_Type ON (
610+ NamedAttribute_HardwarePack_Type.object_id = TestRun.id
611+ AND NamedAttribute_HardwarePack_Type.content_type_id = (
612+ SELECT
613+ django_content_type.id
614+ FROM
615+ django_content_type
616+ WHERE
617+ app_label = 'dashboard_app'
618+ AND model='testrun'
619+ )
620+ AND NamedAttribute_HardwarePack_Type.name = 'hwpack.type'
621+ )
622+ INNER JOIN dashboard_app_namedattribute AS NamedAttribute_HardwarePack_Date ON (
623+ NamedAttribute_HardwarePack_Date.object_id = TestRun.id
624+ AND NamedAttribute_HardwarePack_Date.content_type_id = (
625+ SELECT
626+ django_content_type.id
627+ FROM
628+ django_content_type
629+ WHERE
630+ app_label = 'dashboard_app'
631+ AND model='testrun'
632+ )
633+ AND NamedAttribute_HardwarePack_Date.name = 'hwpack.date'
634+ )
635+ INNER JOIN dashboard_app_namedattribute AS NamedAttribute_RootFileSystem_Type ON (
636+ NamedAttribute_RootFileSystem_Type.object_id = TestRun.id
637+ AND NamedAttribute_RootFileSystem_Type.content_type_id = (
638+ SELECT
639+ django_content_type.id
640+ FROM
641+ django_content_type
642+ WHERE
643+ app_label = 'dashboard_app'
644+ AND model='testrun'
645+ )
646+ AND NamedAttribute_RootFileSystem_Type.name = 'rootfs.type'
647+ )
648+ INNER JOIN dashboard_app_namedattribute AS NamedAttribute_RootFileSystem_Date ON (
649+ NamedAttribute_RootFileSystem_Date.object_id = TestRun.id
650+ AND NamedAttribute_RootFileSystem_Date.content_type_id = (
651+ SELECT
652+ django_content_type.id
653+ FROM
654+ django_content_type
655+ WHERE
656+ app_label = 'dashboard_app'
657+ AND model='testrun'
658+ )
659+ AND NamedAttribute_RootFileSystem_Date.name = 'rootfs.date'
660+ )
661+ INNER JOIN dashboard_app_testcase AS TestCase ON (
662+ TestResult.test_case_id = TestCase.id
663+ )
664+ INNER JOIN dashboard_app_test AS Test ON (
665+ TestRun.test_id = Test.id
666+ )
667+ WHERE
668+ BundleStream.pathname = <value name="pathname"/>
669+ AND NamedAttribute_Target_Hostname.value = <value name="hostname"/>
670+ AND Test.test_id = 'lava'
671+ AND TestCase.test_case_id = 'job_complete'
672+ ORDER BY
673+ TestRun.analyzer_assigned_date DESC
674+ LIMIT <value name="count"/>
675+ </sql>
676+ <arguments>
677+ <argument name="hostname" type="string"/>
678+ <argument name="pathname" default="/anonymous/lava-daily/" type="string" help="Pathname of the bundle stream to check (BundleStream.pathname)"/>
679+ <argument name="count" default="10" type="number" help="Select this many test runs (query limit)"/>
680+ </arguments>
681+ <summary>
682+ </summary>
683+ <documentation>
684+ </documentation>
685+</data-view>
686
687=== added file 'views/hostnames.xml'
688--- views/hostnames.xml 1970-01-01 00:00:00 +0000
689+++ views/hostnames.xml 2011-09-07 18:45:23 +0000
690@@ -0,0 +1,37 @@
691+<data-view name="hostnames">
692+ <sql>
693+ SELECT DISTINCT
694+ NamedAttribute_Target_Hostname.value as "Hostname"
695+ FROM
696+ dashboard_app_testrun AS TestRun
697+ INNER JOIN dashboard_app_namedattribute AS NamedAttribute_Target_Hostname ON (
698+ NamedAttribute_Target_Hostname.object_id = TestRun.id
699+ AND NamedAttribute_Target_Hostname.content_type_id = (
700+ SELECT
701+ django_content_type.id
702+ FROM
703+ django_content_type
704+ WHERE
705+ app_label = 'dashboard_app'
706+ AND model='testrun'
707+ )
708+ AND NamedAttribute_Target_Hostname.name = 'target.hostname'
709+ )
710+ INNER JOIN dashboard_app_bundle AS Bundle ON (
711+ Bundle.id = TestRun.bundle_id
712+ )
713+ INNER JOIN dashboard_app_bundlestream AS BundleStream ON (
714+ BundleStream.id = Bundle.bundle_stream_id
715+ )
716+ WHERE
717+ BundleStream.pathname = <value name="pathname"/>
718+ ORDER BY
719+ "Hostname"
720+ </sql>
721+ <arguments>
722+ <argument name="pathname" default="/anonymous/lava-daily/" type="string" help="Pathname of the bundle stream to check (BundleStream.pathname)"/>
723+ </arguments>
724+ <summary>
725+ List of hostnames
726+ </summary>
727+</data-view>
728
729=== added file 'views/hwpack-type.xml'
730--- views/hwpack-type.xml 1970-01-01 00:00:00 +0000
731+++ views/hwpack-type.xml 2011-09-07 18:45:23 +0000
732@@ -0,0 +1,45 @@
733+<data-view name="hwpack-type">
734+ <sql>
735+ SELECT DISTINCT
736+ NamedAttribute_HardwarePack_Type.value
737+ FROM
738+ dashboard_app_testresult AS TestResult
739+ INNER JOIN dashboard_app_testrun AS TestRun ON (
740+ TestResult.test_run_id = TestRun.id
741+ )
742+ INNER JOIN dashboard_app_bundle AS Bundle ON (
743+ Bundle.id = TestRun.bundle_id
744+ )
745+ INNER JOIN dashboard_app_bundlestream AS BundleStream ON (
746+ Bundle.bundle_stream_id = BundleStream.id
747+ )
748+ INNER JOIN dashboard_app_namedattribute AS NamedAttribute_HardwarePack_Type ON (
749+ NamedAttribute_HardwarePack_Type.object_id = TestRun.id
750+ AND NamedAttribute_HardwarePack_Type.content_type_id = (
751+ SELECT
752+ django_content_type.id
753+ FROM
754+ django_content_type
755+ WHERE
756+ app_label = 'dashboard_app'
757+ AND model='testrun'
758+ )
759+ AND NamedAttribute_HardwarePack_Type.name = 'hwpack.type'
760+ )
761+ INNER JOIN dashboard_app_testcase AS TestCase ON (
762+ TestResult.test_case_id = TestCase.id
763+ )
764+ WHERE
765+ BundleStream.pathname = <value name="pathname"/>
766+ </sql>
767+ <arguments>
768+ <argument name="pathname" type="string" help="Pathname of the bundle stream to check (BundleStream.pathname)"/>
769+ </arguments>
770+ <summary>
771+ List all the hardware pack types in a specified bundle stream
772+ </summary>
773+ <documentation>
774+ This query simply selects all the distinct value of the hwpack.type
775+ attribute for all the test runs in the specified bundle stream.
776+ </documentation>
777+</data-view>
778
779=== added file 'views/kernel-ci-data.xml'
780--- views/kernel-ci-data.xml 1970-01-01 00:00:00 +0000
781+++ views/kernel-ci-data.xml 2011-09-07 18:45:23 +0000
782@@ -0,0 +1,138 @@
783+<data-view name="CI Kernel Data">
784+ <sql>
785+ SELECT
786+ BuildNamedAttribute_BuildID.value AS "Jenkins build ID (build)",
787+ BootNamedAttribute_BuildID.value AS "Jenkins build ID (boot)",
788+ BuildSoftwareSource.branch_url AS "Git URL (build)",
789+ BuildSoftwareSource.branch_revision AS "Git Commit ID (build)",
790+ BuildNamedAttribute_KernelConfig.value AS "Kernel Config (build)",
791+ BootNamedAttribute_GitURL.value AS "Git URL (boot)",
792+ BootNamedAttribute_GitCommitID.value AS "Git Commit ID (boot)",
793+ (CASE WHEN BootTestResult.result=0 THEN 'pass' ELSE 'fail' END) AS "Boot result",
794+ (CASE WHEN BuildTestResult.result=0 THEN 'pass' ELSE 'fail' END) AS "Build result",
795+ BootNamedAttribute_TargetHostname.value AS "Boot target Hostname",
796+ BootTestRun.analyzer_assigned_uuid AS "Boot test run UUID",
797+ BuildTestRun.analyzer_assigned_uuid AS "Build test run UUID"
798+ FROM
799+ dashboard_app_testresult AS BuildTestResult
800+ INNER JOIN dashboard_app_testrun AS BuildTestRun ON BuildTestResult.test_run_id = BuildTestRun.id
801+ INNER JOIN dashboard_app_testrun_sources AS BuildSoftwareSources ON BuildSoftwareSources.testrun_id = BuildTestRun.id
802+ INNER JOIN dashboard_app_softwaresource AS BuildSoftwareSource ON BuildSoftwareSources.softwaresource_id = BuildSoftwareSource.id
803+ INNER JOIN dashboard_app_namedattribute AS BuildNamedAttribute_BuildID ON (
804+ BuildNamedAttribute_BuildID.object_id = BuildTestRun.id
805+ AND BuildNamedAttribute_BuildID.name = 'build.id'
806+ AND BuildNamedAttribute_BuildID.content_type_id = (
807+ SELECT
808+ django_content_type.id
809+ FROM
810+ django_content_type
811+ WHERE
812+ app_label = 'dashboard_app'
813+ AND model='testrun'
814+ )
815+ )
816+ INNER JOIN dashboard_app_namedattribute AS BuildNamedAttribute_KernelConfig ON (
817+ BuildNamedAttribute_KernelConfig.object_id = BuildTestRun.id
818+ AND BuildNamedAttribute_KernelConfig.name = 'kernel.config'
819+ AND BuildNamedAttribute_KernelConfig.content_type_id = (
820+ SELECT
821+ django_content_type.id
822+ FROM
823+ django_content_type
824+ WHERE
825+ app_label = 'dashboard_app'
826+ AND model='testrun'
827+ )
828+ )
829+ INNER JOIN dashboard_app_bundle AS BuildBundle ON BuildTestRun.bundle_id = BuildBundle.id
830+ INNER JOIN dashboard_app_bundlestream AS BuildBundleStream ON BuildBundle.bundle_stream_id = BuildBundleStream.id
831+ INNER JOIN dashboard_app_testcase AS BuildTestCase ON BuildTestResult.test_case_id = BuildTestCase.id
832+ INNER JOIN dashboard_app_test AS BuildTest ON BuildTestRun.test_id = BuildTest.id
833+,
834+ dashboard_app_testresult AS BootTestResult
835+ INNER JOIN dashboard_app_testrun AS BootTestRun ON BootTestResult.test_run_id = BootTestRun.id
836+ INNER JOIN dashboard_app_namedattribute AS BootNamedAttribute_BuildID ON (
837+ BootNamedAttribute_BuildID.object_id = BootTestRun.id
838+ AND BootNamedAttribute_BuildID.name = 'build.id'
839+ AND BootNamedAttribute_BuildID.content_type_id = (
840+ SELECT
841+ django_content_type.id
842+ FROM
843+ django_content_type
844+ WHERE
845+ app_label = 'dashboard_app'
846+ AND model='testrun'
847+ )
848+ )
849+ INNER JOIN dashboard_app_namedattribute AS BootNamedAttribute_TargetHostname ON (
850+ BootNamedAttribute_TargetHostname.object_id = BootTestRun.id
851+ AND BootNamedAttribute_TargetHostname.name = 'target.hostname'
852+ AND BootNamedAttribute_TargetHostname.content_type_id = (
853+ SELECT
854+ django_content_type.id
855+ FROM
856+ django_content_type
857+ WHERE
858+ app_label = 'dashboard_app'
859+ AND model='testrun'
860+ )
861+ AND BootNamedAttribute_TargetHostname.name = 'target.hostname'
862+ )
863+ INNER JOIN dashboard_app_namedattribute AS BootNamedAttribute_GitCommitID ON (
864+ BootNamedAttribute_GitCommitID.object_id = BootTestRun.id
865+ AND BootNamedAttribute_GitCommitID.name = 'git_commitid'
866+ AND BootNamedAttribute_GitCommitID.content_type_id = (
867+ SELECT
868+ django_content_type.id
869+ FROM
870+ django_content_type
871+ WHERE
872+ app_label = 'dashboard_app'
873+ AND model='testrun'
874+ )
875+ )
876+ INNER JOIN dashboard_app_namedattribute AS BootNamedAttribute_GitURL ON (
877+ BootNamedAttribute_GitURL.object_id = BootTestRun.id
878+ AND BootNamedAttribute_GitURL.name = 'git_url'
879+ AND BootNamedAttribute_GitURL.content_type_id = (
880+ SELECT
881+ django_content_type.id
882+ FROM
883+ django_content_type
884+ WHERE
885+ app_label = 'dashboard_app'
886+ AND model='testrun'
887+ )
888+ )
889+ INNER JOIN dashboard_app_bundle AS BootBundle ON BootTestRun.bundle_id = BootBundle.id
890+ INNER JOIN dashboard_app_bundlestream AS BootBundleStream ON BootBundle.bundle_stream_id = BootBundleStream.id
891+ INNER JOIN dashboard_app_testcase AS BootTestCase ON BootTestResult.test_case_id = BootTestCase.id
892+ INNER JOIN dashboard_app_test AS BootTest ON BootTestRun.test_id = BootTest.id
893+ WHERE
894+ BootBundleStream.pathname = <value name="boot_pathname"/>
895+ AND BuildBundleStream.pathname = <value name="build_pathname"/>
896+ AND BootTest.test_id = <value name="boot_test"/>
897+ AND BuildTest.test_id = <value name="build_test"/>
898+ AND BootTestCase.test_case_id = <value name="boot_test_case"/>
899+ AND BuildTestCase.test_case_id = <value name="build_test_case"/>
900+ AND BuildSoftwareSource.project_name = 'Linux Linaro'
901+ AND BuildNamedAttribute_BuildID.value = BootNamedAttribute_BuildID.value
902+ ORDER BY
903+ BootTestRun.analyzer_assigned_uuid
904+ </sql>
905+ <arguments>
906+ <argument name="boot_pathname" help="Bundle stream with boot results" type="string"/>
907+ <argument name="boot_test" help="Identifier of the test to select" type="string" default="lava"/>
908+ <argument name="boot_test_case" help="Identifier of the test case to select" type="string" default="boot_image"/>
909+ <argument name="build_pathname" help="Bundle stream with boot results" type="string"/>
910+ <argument name="build_test" help="Identifier of the test to select" type="string" default="kernel build"/>
911+ <argument name="build_test_case" help="Identifier of the test case to select" type="string" default="linux-linaro-3_0"/>
912+ </arguments>
913+ <summary>
914+ TODO: document this
915+ </summary>
916+ <documentation>
917+ TODO: document this
918+ </documentation>
919+</data-view>
920+
921
922=== added file 'views/latest-job-complete-for-hwpack-and-rootfs.xml'
923--- views/latest-job-complete-for-hwpack-and-rootfs.xml 1970-01-01 00:00:00 +0000
924+++ views/latest-job-complete-for-hwpack-and-rootfs.xml 2011-09-07 18:45:23 +0000
925@@ -0,0 +1,74 @@
926+<data-view name="latest-job-complete-for-hwpack-and-rootfs">
927+ <sql>
928+ <!--
929+ EXPLAIN QUERY PLAN
930+ -->
931+ SELECT
932+ TestResult.result AS "Outcome",
933+ TestRun.analyzer_assigned_uuid AS "UUID",
934+ TestRun.analyzer_assigned_date AS "Date"
935+ FROM
936+ dashboard_app_testresult AS TestResult
937+ INNER JOIN dashboard_app_testcase AS TestCase ON (
938+ TestCase.id = TestResult.test_case_id
939+ )
940+ INNER JOIN dashboard_app_testrun AS TestRun ON (
941+ TestRun.id = TestResult.test_run_id
942+ )
943+ INNER JOIN dashboard_app_test AS Test ON (
944+ Test.id = TestRun.test_id
945+ )
946+ INNER JOIN dashboard_app_namedattribute AS NamedAttribute_HardwarePack ON (
947+ NamedAttribute_HardwarePack.object_id = TestRun.id
948+ AND NamedAttribute_HardwarePack.name = 'hwpack.type'
949+ AND NamedAttribute_HardwarePack.value = <value name="hwpack"/>
950+ AND NamedAttribute_HardwarePack.content_type_id = (
951+ SELECT
952+ django_content_type.id
953+ FROM
954+ django_content_type
955+ WHERE
956+ app_label = 'dashboard_app'
957+ AND model='testrun'
958+ )
959+ )
960+ INNER JOIN dashboard_app_namedattribute AS NamedAttribute_RootFileSystem ON (
961+ NamedAttribute_RootFileSystem.object_id = TestRun.id
962+ AND NamedAttribute_RootFileSystem.name = 'rootfs.type'
963+ AND NamedAttribute_RootFileSystem.value = <value name="rootfs"/>
964+ AND NamedAttribute_RootFileSystem.content_type_id = (
965+ SELECT
966+ django_content_type.id
967+ FROM
968+ django_content_type
969+ WHERE
970+ app_label = 'dashboard_app'
971+ AND model='testrun'
972+ )
973+ )
974+ INNER JOIN dashboard_app_bundle AS Bundle ON (
975+ Bundle.id = TestRun.bundle_id
976+ )
977+ INNER JOIN dashboard_app_bundlestream AS BundleStream ON (
978+ BundleStream.id = Bundle.bundle_stream_id
979+ )
980+ WHERE
981+ BundleStream.pathname = <value name="pathname"/>
982+ AND TestCase.test_case_id = 'job_complete'
983+ AND Test.test_id = 'lava'
984+ ORDER BY
985+ TestRun.analyzer_assigned_date DESC
986+ LIMIT 1
987+ </sql>
988+ <arguments>
989+ <argument name="pathname" type="string" help="Pathname of the bundle stream to check (BundleStream.pathname)"/>
990+ <argument name="hwpack" type="string" help="Hardware pack to look for (TestRun.attributes['hwpack.type'])"/>
991+ <argument name="rootfs" type="string" help="Root file system to look for (TestRun.attributes['rootfs.type'])"/>
992+ </arguments>
993+ <summary>
994+ Select the most recent outcome of the job_complete test case in the lava test.
995+ </summary>
996+ <documentation>
997+ TODO
998+ </documentation>
999+</data-view>
1000
1001=== added file 'views/latest-test-runs.xml'
1002--- views/latest-test-runs.xml 1970-01-01 00:00:00 +0000
1003+++ views/latest-test-runs.xml 2011-09-07 18:45:23 +0000
1004@@ -0,0 +1,31 @@
1005+<data-view name="latest-test-runs">
1006+ <sql>
1007+ SELECT
1008+ TestRun.analyzer_assigned_uuid AS "UUID",
1009+ TestRun.analyzer_assigned_date AS "Analyzer Assigned Date"
1010+ FROM
1011+ dashboard_app_testrun AS TestRun
1012+ INNER JOIN dashboard_app_bundle AS Bundle ON (
1013+ TestRun.bundle_id = Bundle.id)
1014+ INNER JOIN dashboard_app_bundlestream AS BundleStream ON (
1015+ BundleStream.id = Bundle.bundle_stream_id)
1016+ WHERE
1017+ BundleStream.pathname = <value name="pathname"/>
1018+ ORDER BY
1019+ TestRun.analyzer_assigned_date DESC
1020+ LIMIT <value name="count"/>
1021+ </sql>
1022+ <arguments>
1023+ <argument name="pathname" type="string" help="Pathname of a bundle stream to search"/>
1024+ <argument name="count" default="10" type="number" help="Select this many test runs (query limit)"/>
1025+ </arguments>
1026+ <summary>
1027+ List N most recent TestRuns specific bundle stream (sort by analyzer_assigned_date)
1028+ </summary>
1029+ <documentation>
1030+ This query joins three tables: TestRun + Bundle + BundleStream. The
1031+ filtering depends on the BundleStream.pathname property, the selected
1032+ value is TestRun.analyzer_assigned_uuid and
1033+ TestRun.analyzer_assigned_date.
1034+ </documentation>
1035+</data-view>
1036
1037=== added file 'views/measurements.xml'
1038--- views/measurements.xml 1970-01-01 00:00:00 +0000
1039+++ views/measurements.xml 2011-09-07 18:45:23 +0000
1040@@ -0,0 +1,73 @@
1041+<data-view name="measurements">
1042+ <sql backend="sqlite">
1043+ SELECT
1044+ CAST(1000 * strftime('%s', TestRun.analyzer_assigned_date) AS TEXT) AS "Flot Timestamp",
1045+ TestResult.measurement AS "Measurement"
1046+ FROM
1047+ dashboard_app_testresult AS TestResult
1048+ INNER JOIN dashboard_app_testrun AS TestRun ON TestResult.test_run_id = TestRun.id
1049+ INNER JOIN dashboard_app_bundle AS Bundle ON TestRun.bundle_id = Bundle.id
1050+ INNER JOIN dashboard_app_bundlestream AS BundleStream ON Bundle.bundle_stream_id = BundleStream.id
1051+ INNER JOIN dashboard_app_testcase AS TestCase ON TestResult.test_case_id = TestCase.id
1052+ INNER JOIN dashboard_app_test AS Test ON TestRun.test_id = Test.id
1053+ INNER JOIN dashboard_app_testrun_devices as TestRun_Devices ON (
1054+ TestRun_Devices.testrun_id = TestRun.id
1055+ )
1056+ INNER JOIN dashboard_app_hardwaredevice as HardwareDevice_Board ON (
1057+ HardwareDevice_Board.id = TestRun_Devices.hardwaredevice_id
1058+ AND HardwareDevice_Board.device_type = 'device.board'
1059+ )
1060+ WHERE
1061+ BundleStream.pathname = <value name="pathname"/>
1062+ AND HardwareDevice_Board.description = <value name="board"/>
1063+ AND Test.test_id = <value name="test"/>
1064+ AND TestCase.test_case_id = <value name="test_case"/>
1065+ AND TestResult.measurement IS NOT NULL
1066+ ORDER BY
1067+ TestRun.analyzer_assigned_date DESC
1068+ LIMIT
1069+ <value name="count" />
1070+ </sql>
1071+ <sql backend="postgresql">
1072+ SELECT
1073+ CAST((EXTRACT(EPOCH FROM TestRun.analyzer_assigned_date)) * 1000 AS TEXT) AS "Flot Timestamp",
1074+ TestResult.measurement AS "Measurement"
1075+ FROM
1076+ dashboard_app_testresult AS TestResult
1077+ INNER JOIN dashboard_app_testrun AS TestRun ON TestResult.test_run_id = TestRun.id
1078+ INNER JOIN dashboard_app_bundle AS Bundle ON TestRun.bundle_id = Bundle.id
1079+ INNER JOIN dashboard_app_bundlestream AS BundleStream ON Bundle.bundle_stream_id = BundleStream.id
1080+ INNER JOIN dashboard_app_testcase AS TestCase ON TestResult.test_case_id = TestCase.id
1081+ INNER JOIN dashboard_app_test AS Test ON TestRun.test_id = Test.id
1082+ INNER JOIN dashboard_app_testrun_devices as TestRun_Devices ON (
1083+ TestRun_Devices.testrun_id = TestRun.id
1084+ )
1085+ INNER JOIN dashboard_app_hardwaredevice as HardwareDevice_Board ON (
1086+ HardwareDevice_Board.id = TestRun_Devices.hardwaredevice_id
1087+ AND HardwareDevice_Board.device_type = 'device.board'
1088+ )
1089+ WHERE
1090+ BundleStream.pathname = <value name="pathname"/>
1091+ AND HardwareDevice_Board.description = <value name="board"/>
1092+ AND Test.test_id = <value name="test"/>
1093+ AND TestCase.test_case_id = <value name="test_case"/>
1094+ AND TestResult.measurement IS NOT NULL
1095+ ORDER BY
1096+ TestRun.analyzer_assigned_date DESC
1097+ LIMIT
1098+ <value name="count" />
1099+ </sql>
1100+ <arguments>
1101+ <argument name="pathname" help="Bundle stream pathname" type="string"/>
1102+ <argument name="test" help="Identifier of the test to select" type="string"/>
1103+ <argument name="test_case" help="Identifier of the test case to select" type="string"/>
1104+ <argument name="board" help="Board to select" type="string"/>
1105+ <argument name="count" help="Select at most that many rows" type="number" default="10"/>
1106+ </arguments>
1107+ <summary>
1108+ Recent measurements of selected test case on a selected board
1109+ </summary>
1110+ <documentation>
1111+ Core data view for rendering charts
1112+ </documentation>
1113+</data-view>
1114
1115=== added file 'views/recent-test-runs-for-board-and-hwpack-and-rootfs-1.xml'
1116--- views/recent-test-runs-for-board-and-hwpack-and-rootfs-1.xml 1970-01-01 00:00:00 +0000
1117+++ views/recent-test-runs-for-board-and-hwpack-and-rootfs-1.xml 2011-09-07 18:45:23 +0000
1118@@ -0,0 +1,93 @@
1119+<data-view name="recent-test-runs-for-board-and-hwpack-and-rootfs-1">
1120+ <sql>
1121+ SELECT
1122+ TestRun.analyzer_assigned_uuid AS "UUID",
1123+ TestRun.analyzer_assigned_date AS "Analyzer Assigned Date"
1124+ FROM
1125+ dashboard_app_testrun as TestRun
1126+ WHERE
1127+ <!-- Filter for testruns in a specific bundle stream -->
1128+ TestRun.bundle_id IN (
1129+ SELECT
1130+ Bundle.id
1131+ FROM
1132+ dashboard_app_bundle AS Bundle
1133+ INNER JOIN dashboard_app_bundlestream AS BundleStream ON (
1134+ BundleStream.id = Bundle.bundle_stream_id)
1135+ WHERE
1136+ BundleStream.pathname = <value name="pathname"/>
1137+ )
1138+ AND TestRun.id IN (
1139+ <!-- Limit to specific hardware pack -->
1140+ SELECT
1141+ NamedAttribute.object_id
1142+ FROM
1143+ dashboard_app_namedattribute AS NamedAttribute
1144+ WHERE
1145+ NamedAttribute.content_type_id = (
1146+ SELECT
1147+ django_content_type.id
1148+ FROM
1149+ django_content_type
1150+ WHERE
1151+ app_label = 'dashboard_app'
1152+ AND model='testrun'
1153+ )
1154+ AND NamedAttribute.name = 'hwpack.type'
1155+ AND NamedAttribute.value = <value name="hwpack"/>
1156+ INTERSECT
1157+ <!-- Limit to specific root filesystem -->
1158+ SELECT
1159+ NamedAttribute.object_id
1160+ FROM
1161+ dashboard_app_namedattribute AS NamedAttribute
1162+ WHERE
1163+ NamedAttribute.content_type_id = (
1164+ SELECT
1165+ django_content_type.id
1166+ FROM
1167+ django_content_type
1168+ WHERE
1169+ app_label = 'dashboard_app'
1170+ AND model='testrun'
1171+ )
1172+ AND NamedAttribute.name = 'rootfs.type'
1173+ AND NamedAttribute.value = <value name="rootfs"/>
1174+ INTERSECT
1175+ <!-- Limit to specific board -->
1176+ SELECT
1177+ TestRun_Devices.testrun_id
1178+ FROM
1179+ dashboard_app_hardwaredevice AS HardwareDevice
1180+ INNER JOIN dashboard_app_testrun_devices AS TestRun_Devices ON (
1181+ HardwareDevice.id = TestRun_Devices.hardwaredevice_id)
1182+ WHERE
1183+ HardwareDevice.device_type = 'device.board'
1184+ AND HardwareDevice.description = <value name="board"/>
1185+ )
1186+ ORDER BY
1187+ TestRun.analyzer_assigned_date DESC
1188+ LIMIT <value name="count"/>
1189+ </sql>
1190+ <arguments>
1191+ <argument name="pathname" type="string" help="Pathname of the bundle stream to check (BundleStream.pathname)"/>
1192+ <argument name="board" type="string" help="Board to look for (HardwareDevice.description)"/>
1193+ <argument name="hwpack" type="string" help="Hardware pack to look for (TestRun.attributes['hwpack.type'])"/>
1194+ <argument name="rootfs" type="string" help="Root file system to look for (TestRun.attributes['rootfs.type'])"/>
1195+ <argument name="count" default="10" type="number" help="Select this many test runs (query limit)"/>
1196+ </arguments>
1197+ <summary>
1198+ Select recent test runs from a particular bundle stream that were
1199+ invoked on a particular board class with a particular hwardware pack.
1200+ </summary>
1201+ <documentation>
1202+ This query uses sub-queries to filter each test run against Bundle.id
1203+ and actual TestRun.id. The filtering for test run is complex and is
1204+ done as an intersection of: TestRun.id values that have particular
1205+ hardware pack (query 1), root fs (query 2) and board device (query 3)
1206+
1207+ Based on my loose testing in SQLite it's the fastest version (5.21s
1208+ on my db). On PostgreSQL it's slightly slower than the second
1209+ variant (5.69s on the same db)
1210+ </documentation>
1211+</data-view>
1212
1213=== added file 'views/recent-test-runs-for-board-and-hwpack-and-rootfs-2.xml'
1214--- views/recent-test-runs-for-board-and-hwpack-and-rootfs-2.xml 1970-01-01 00:00:00 +0000
1215+++ views/recent-test-runs-for-board-and-hwpack-and-rootfs-2.xml 2011-09-07 18:45:23 +0000
1216@@ -0,0 +1,77 @@
1217+<data-view name="recent-test-runs-for-board-and-hwpack-and-rootfs-2">
1218+ <sql>
1219+ SELECT
1220+ TestRun.analyzer_assigned_uuid AS "UUID",
1221+ TestRun.analyzer_assigned_date AS "Analyzer Assigned Date"
1222+ FROM
1223+ dashboard_app_testrun as TestRun
1224+ INNER JOIN dashboard_app_namedattribute AS NamedAttribute_HardwarePack ON (
1225+ NamedAttribute_HardwarePack.object_id = TestRun.id
1226+ AND NamedAttribute_HardwarePack.content_type_id = (
1227+ SELECT
1228+ django_content_type.id
1229+ FROM
1230+ django_content_type
1231+ WHERE
1232+ app_label = 'dashboard_app'
1233+ AND model='testrun'
1234+ )
1235+ AND NamedAttribute_HardwarePack.name = 'hwpack.type'
1236+ )
1237+ INNER JOIN dashboard_app_namedattribute AS NamedAttribute_RootFileSystem ON (
1238+ NamedAttribute_RootFileSystem.object_id = TestRun.id
1239+ AND NamedAttribute_RootFileSystem.content_type_id = (
1240+ SELECT
1241+ django_content_type.id
1242+ FROM
1243+ django_content_type
1244+ WHERE
1245+ app_label = 'dashboard_app'
1246+ AND model='testrun'
1247+ )
1248+ AND NamedAttribute_RootFileSystem.name = 'rootfs.type'
1249+ )
1250+ INNER JOIN dashboard_app_testrun_devices as TestRun_Devices ON (
1251+ TestRun_Devices.testrun_id = TestRun.id
1252+ )
1253+ INNER JOIN dashboard_app_hardwaredevice as HardwareDevice_Board ON (
1254+ HardwareDevice_Board.id = TestRun_Devices.hardwaredevice_id
1255+ AND HardwareDevice_Board.device_type = 'device.board'
1256+ )
1257+ INNER JOIN dashboard_app_bundle AS Bundle ON (
1258+ Bundle.id = TestRun.bundle_id
1259+ )
1260+ INNER JOIN dashboard_app_bundlestream AS BundleStream ON (
1261+ BundleStream.id = Bundle.bundle_stream_id
1262+ )
1263+ WHERE
1264+ BundleStream.pathname = <value name="pathname"/>
1265+ AND HardwareDevice_Board.description = <value name="board"/>
1266+ AND NamedAttribute_RootFileSystem.value = <value name="rootfs"/>
1267+ AND NamedAttribute_HardwarePack.value = <value name="hwpack"/>
1268+ ORDER BY
1269+ TestRun.analyzer_assigned_date DESC
1270+ LIMIT <value name="count"/>
1271+ </sql>
1272+ <arguments>
1273+ <argument name="pathname" type="string" help="Pathname of the bundle stream to check (BundleStream.pathname)"/>
1274+ <argument name="board" type="string" help="Board to look for (HardwareDevice.description)"/>
1275+ <argument name="hwpack" type="string" help="Hardware pack to look for (TestRun.attributes['hwpack.type'])"/>
1276+ <argument name="rootfs" type="string" help="Root file system to look for (TestRun.attributes['rootfs.type'])"/>
1277+ <argument name="count" default="10" type="number" help="Select this many test runs (query limit)"/>
1278+ </arguments>
1279+ <summary>
1280+ Select recent test runs from a particular bundle stream that were
1281+ invoked on a particular board class with a particular hwardware pack.
1282+ </summary>
1283+ <documentation>
1284+ This query uses sub-queries to filter each test run against Bundle.id
1285+ and actual TestRun.id. The filtering for test run is complex and is
1286+ done as an intersection of: TestRun.id values that have particular
1287+ hardware pack (query 1), root fs (query 2) and board device (query 3)
1288+
1289+ Based on my loose testing in SQLite it's the slowest version (13.76s on
1290+ my db). On PostgreSQL it's actually faster than -1 (5.57s on the same
1291+ db)
1292+ </documentation>
1293+</data-view>
1294
1295=== added file 'views/recent-test-runs-for-board-and-hwpack-and-rootfs-3.xml'
1296--- views/recent-test-runs-for-board-and-hwpack-and-rootfs-3.xml 1970-01-01 00:00:00 +0000
1297+++ views/recent-test-runs-for-board-and-hwpack-and-rootfs-3.xml 2011-09-07 18:45:23 +0000
1298@@ -0,0 +1,76 @@
1299+<data-view name="recent-test-runs-for-board-and-hwpack-and-rootfs-3">
1300+ <sql backend="sqlite">
1301+ SELECT
1302+ TestRun.analyzer_assigned_uuid AS "UUID",
1303+ TestRun.analyzer_assigned_date AS "Analyzer Assigned Date"
1304+ FROM
1305+ dashboard_app_testrun as TestRun
1306+ INNER JOIN dashboard_app_namedattribute AS NamedAttribute_HardwarePack INDEXED BY dashboard_app_namedattribute_object_id_660530246aa47641 ON (
1307+ NamedAttribute_HardwarePack.object_id = TestRun.id
1308+ AND NamedAttribute_HardwarePack.content_type_id = (
1309+ SELECT
1310+ django_content_type.id
1311+ FROM
1312+ django_content_type
1313+ WHERE
1314+ app_label = 'dashboard_app'
1315+ AND model='testrun'
1316+ )
1317+ AND NamedAttribute_HardwarePack.name = 'hwpack.type'
1318+ )
1319+ INNER JOIN dashboard_app_namedattribute AS NamedAttribute_RootFileSystem INDEXED BY dashboard_app_namedattribute_object_id_660530246aa47641 ON (
1320+ NamedAttribute_RootFileSystem.object_id = TestRun.id
1321+ AND NamedAttribute_RootFileSystem.content_type_id = (
1322+ SELECT
1323+ django_content_type.id
1324+ FROM
1325+ django_content_type
1326+ WHERE
1327+ app_label = 'dashboard_app'
1328+ AND model='testrun'
1329+ )
1330+ AND NamedAttribute_RootFileSystem.name = 'rootfs.type'
1331+ )
1332+ INNER JOIN dashboard_app_testrun_devices as TestRun_Devices ON (
1333+ TestRun_Devices.testrun_id = TestRun.id
1334+ )
1335+ INNER JOIN dashboard_app_hardwaredevice as HardwareDevice_Board INDEXED BY dashboard_app_hardwaredevice_device_type_2f9d227c1c952d28 ON (
1336+ HardwareDevice_Board.id = TestRun_Devices.hardwaredevice_id
1337+ AND HardwareDevice_Board.device_type = 'device.board'
1338+ )
1339+ INNER JOIN dashboard_app_bundle AS Bundle ON (
1340+ Bundle.id = TestRun.bundle_id
1341+ )
1342+ INNER JOIN dashboard_app_bundlestream AS BundleStream ON (
1343+ BundleStream.id = Bundle.bundle_stream_id
1344+ )
1345+ WHERE
1346+ BundleStream.pathname = <value name="pathname"/>
1347+ AND HardwareDevice_Board.description = <value name="board"/>
1348+ AND NamedAttribute_RootFileSystem.value = <value name="rootfs"/>
1349+ AND NamedAttribute_HardwarePack.value = <value name="hwpack"/>
1350+ ORDER BY
1351+ TestRun.analyzer_assigned_date DESC
1352+ LIMIT <value name="count"/>
1353+ </sql>
1354+ <arguments>
1355+ <argument name="pathname" type="string" help="Pathname of the bundle stream to check (BundleStream.pathname)"/>
1356+ <argument name="board" type="string" help="Board to look for (HardwareDevice.description)"/>
1357+ <argument name="hwpack" type="string" help="Hardware pack to look for (TestRun.attributes['hwpack.type'])"/>
1358+ <argument name="rootfs" type="string" help="Root file system to look for (TestRun.attributes['rootfs.type'])"/>
1359+ <argument name="count" default="10" type="number" help="Select this many test runs (query limit)"/>
1360+ </arguments>
1361+ <summary>
1362+ Select recent test runs from a particular bundle stream that were
1363+ invoked on a particular board class with a particular hwardware pack.
1364+ </summary>
1365+ <documentation>
1366+ Same as -2 but using explicit index on named attributes and hardare
1367+ devices to speed things up. Requires migration level up to 0003 to
1368+ create the required indices.
1369+
1370+ Based on my loose testing in SQLite it's almost as fast as -1 but still
1371+ slower (6.43s on my db). It does not run on postgreSQL as the INDEXED
1372+ BY syntax is not supported there.
1373+ </documentation>
1374+</data-view>
1375
1376=== added file 'views/recent-test-runs-for-board-and-hwpack-and-rootfs-4.xml'
1377--- views/recent-test-runs-for-board-and-hwpack-and-rootfs-4.xml 1970-01-01 00:00:00 +0000
1378+++ views/recent-test-runs-for-board-and-hwpack-and-rootfs-4.xml 2011-09-07 18:45:23 +0000
1379@@ -0,0 +1,77 @@
1380+<data-view name="recent-test-runs-for-board-and-hwpack-and-rootfs-4">
1381+ <sql>
1382+ SELECT
1383+ TestRun.analyzer_assigned_uuid AS "UUID",
1384+ TestRun.analyzer_assigned_date AS "Analyzer Assigned Date"
1385+ FROM
1386+ dashboard_app_testrun as TestRun
1387+ INNER JOIN dashboard_app_namedattribute AS NamedAttribute_HardwarePack ON (
1388+ NamedAttribute_HardwarePack.object_id = TestRun.id
1389+ AND NamedAttribute_HardwarePack.content_type_id = (
1390+ SELECT
1391+ django_content_type.id
1392+ FROM
1393+ django_content_type
1394+ WHERE
1395+ app_label = 'dashboard_app'
1396+ AND model='testrun'
1397+ )
1398+ )
1399+ INNER JOIN dashboard_app_namedattribute AS NamedAttribute_RootFileSystem ON (
1400+ NamedAttribute_RootFileSystem.object_id = TestRun.id
1401+ AND NamedAttribute_RootFileSystem.content_type_id = (
1402+ SELECT
1403+ django_content_type.id
1404+ FROM
1405+ django_content_type
1406+ WHERE
1407+ app_label = 'dashboard_app'
1408+ AND model='testrun'
1409+ )
1410+ )
1411+ INNER JOIN dashboard_app_testrun_devices as TestRun_Devices ON (
1412+ TestRun_Devices.testrun_id = TestRun.id
1413+ )
1414+ INNER JOIN dashboard_app_hardwaredevice as HardwareDevice_Board ON (
1415+ HardwareDevice_Board.id = TestRun_Devices.hardwaredevice_id
1416+ AND HardwareDevice_Board.device_type = 'device.board'
1417+ )
1418+ INNER JOIN dashboard_app_bundle AS Bundle ON (
1419+ Bundle.id = TestRun.bundle_id
1420+ )
1421+ INNER JOIN dashboard_app_bundlestream AS BundleStream ON (
1422+ BundleStream.id = Bundle.bundle_stream_id
1423+ )
1424+ WHERE
1425+ BundleStream.pathname = <value name="pathname"/>
1426+ AND NamedAttribute_HardwarePack.name = 'hwpack.type'
1427+ AND NamedAttribute_HardwarePack.value = <value name="hwpack"/>
1428+ AND NamedAttribute_RootFileSystem.name = 'rootfs.type'
1429+ AND NamedAttribute_RootFileSystem.value = <value name="rootfs"/>
1430+ AND HardwareDevice_Board.description = <value name="board"/>
1431+ ORDER BY
1432+ TestRun.analyzer_assigned_date DESC
1433+ LIMIT <value name="count"/>
1434+ </sql>
1435+ <arguments>
1436+ <argument name="pathname" type="string" help="Pathname of the bundle stream to check (BundleStream.pathname)"/>
1437+ <argument name="board" type="string" help="Board to look for (HardwareDevice.description)"/>
1438+ <argument name="hwpack" type="string" help="Hardware pack to look for (TestRun.attributes['hwpack.type'])"/>
1439+ <argument name="rootfs" type="string" help="Root file system to look for (TestRun.attributes['rootfs.type'])"/>
1440+ <argument name="count" default="10" type="number" help="Select this many test runs (query limit)"/>
1441+ </arguments>
1442+ <summary>
1443+ Select recent test runs from a particular bundle stream that were
1444+ invoked on a particular board class with a particular hwardware pack.
1445+ </summary>
1446+ <documentation>
1447+ This query uses sub-queries to filter each test run against Bundle.id
1448+ and actual TestRun.id. The filtering for test run is complex and is
1449+ done as an intersection of: TestRun.id values that have particular
1450+ hardware pack (query 1), root fs (query 2) and board device (query 3)
1451+
1452+ Based on my loose testing in SQLite it's the second slowest version
1453+ (14.06s on my db). On PostgreSQL it's tiny bit slower than -2 (5.65s on
1454+ the same db)
1455+ </documentation>
1456+</data-view>
1457
1458=== added file 'views/rootfs-type.xml'
1459--- views/rootfs-type.xml 1970-01-01 00:00:00 +0000
1460+++ views/rootfs-type.xml 2011-09-07 18:45:23 +0000
1461@@ -0,0 +1,45 @@
1462+<data-view name="rootfs-type">
1463+ <sql>
1464+ SELECT DISTINCT
1465+ NamedAttribute_RootFS_Type.value
1466+ FROM
1467+ dashboard_app_testresult AS TestResult
1468+ INNER JOIN dashboard_app_testrun AS TestRun ON (
1469+ TestResult.test_run_id = TestRun.id
1470+ )
1471+ INNER JOIN dashboard_app_bundle AS Bundle ON (
1472+ Bundle.id = TestRun.bundle_id
1473+ )
1474+ INNER JOIN dashboard_app_bundlestream AS BundleStream ON (
1475+ Bundle.bundle_stream_id = BundleStream.id
1476+ )
1477+ INNER JOIN dashboard_app_namedattribute AS NamedAttribute_RootFS_Type ON (
1478+ NamedAttribute_RootFS_Type.object_id = TestRun.id
1479+ AND NamedAttribute_RootFS_Type.content_type_id = (
1480+ SELECT
1481+ django_content_type.id
1482+ FROM
1483+ django_content_type
1484+ WHERE
1485+ app_label = 'dashboard_app'
1486+ AND model='testrun'
1487+ )
1488+ AND NamedAttribute_RootFS_Type.name = 'rootfs.type'
1489+ )
1490+ INNER JOIN dashboard_app_testcase AS TestCase ON (
1491+ TestResult.test_case_id = TestCase.id
1492+ )
1493+ WHERE
1494+ BundleStream.pathname = <value name="pathname"/>
1495+ </sql>
1496+ <arguments>
1497+ <argument name="pathname" type="string" help="Pathname of the bundle stream to check (BundleStream.pathname)"/>
1498+ </arguments>
1499+ <summary>
1500+ List all the root filesystem types in a specified bundle stream
1501+ </summary>
1502+ <documentation>
1503+ This query simply selects all the distinct value of the rootfs.type
1504+ attribute for all the test runs in the specified bundle stream.
1505+ </documentation>
1506+</data-view>

Subscribers

People subscribed via source and target branches