[prev in list] [next in list] [prev in thread] [next in thread] 

List:       webkit-changes
Subject:    [webkit-changes] [177614] trunk/Websites/perf.webkit.org
From:       rniwa () webkit ! org
Date:       2014-12-20 2:38:04
Message-ID: 20141220023805.0E2BD306B91 () svn ! webkit ! org
[Download RAW message or body]

[Attachment #2 (text/html)]

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[177614] trunk/Websites/perf.webkit.org</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: \
verdana,arial,helvetica,sans-serif; font-size: 10pt;  } #msg dl a { font-weight: \
bold} #msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: \
bold; } #msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: \
6px; } #logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em \
0; } #logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg \
h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; } \
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; \
} #logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: \
-1.5em; padding-left: 1.5em; } #logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em \
1em 0 1em; background: white;} #logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid \
#fa0; border-bottom: 1px solid #fa0; background: #fff; } #logmsg table th { \
text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted \
#fa0; } #logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: \
0.2em 0.5em; } #logmsg table thead th { text-align: center; border-bottom: 1px solid \
#fa0; } #logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: \
6px; } #patch { width: 100%; }
#patch h4 {font-family: \
verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
 #patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, \
#patch .copfile {border:1px solid #ccc;margin:10px 0;} #patch ins \
{background:#dfd;text-decoration:none;display:block;padding:0 10px;} #patch del \
{background:#fdd;text-decoration:none;display:block;padding:0 10px;} #patch .lines, \
                .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a \
href="http://trac.webkit.org/projects/webkit/changeset/177614">177614</a></dd> \
<dt>Author</dt> <dd>rniwa@webkit.org</dd> <dt>Date</dt> <dd>2014-12-19 18:38:04 -0800 \
(Fri, 19 Dec 2014)</dd> </dl>

<h3>Log Message</h3>
<pre>Perf dashboard should support authentication via a slave password
https://bugs.webkit.org/show_bug.cgi?id=139837

Reviewed by Andreas Kling.

For historical reasons, perf dashboard conflated builders and build slaves. As a \
result we ended up having to add multiple builders with the same password when a \
single build slave is shared among them.

This patch introduces the concept of build_slave into the perf dashboard to end this \
madness.

* init-database.sql: Added build_slave table as well as references to it in builds \
and reports.

* public/admin/build-slaves.php: Added.

* public/admin/builders.php: Added the support for updating passwords.

* public/include/admin-header.php:
(update_field): Takes an extra argument when a new value needs to be supplied by the \
caller instead of being retrieved from $_POST.
(AdministrativePage::render_table): Use array_get to retrieve a value out of the \
database row since the raw may not exist (e.g. new_password).
(AdministrativePage::render_form_to_add): Added the support for post_insertion. Don't \
render the form control here when this flag evaluates to TRUE.

* public/include/report-processor.php:
(ReportProcessor::process): Added the logic to authenticate with slaveName and \
slavePassword if those values are present in the report. In addition, try \
authenticating builderName with slavePassword if builderPassword is not specified. \
When neither password is specified, exit with BuilderNotFound. Also insert the slave \
or the builder whichever is missing after we've successfully authenticated. \
(ReportProcessor::construct_build_data): Takes a builder ID and an optional slave ID \
instead of a builder row.
(ReportProcessor::store_report): Store the slave ID with the report.
(ReportProcessor::resolve_build_id): Exit with MismatchingBuildSlave when the slave \
associated with the matching build is different from what's being reported.

* tests/api-report.js: Added a bunch of tests to test the new features of \
/api/report. (.addSlave): Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkWebsitesperfwebkitorgChangeLog">trunk/Websites/perf.webkit.org/ChangeLog</a></li>
 <li><a href="#trunkWebsitesperfwebkitorginitdatabasesql">trunk/Websites/perf.webkit.org/init-database.sql</a></li>
 <li><a href="#trunkWebsitesperfwebkitorgpublicadminbuildersphp">trunk/Websites/perf.webkit.org/public/admin/builders.php</a></li>
 <li><a href="#trunkWebsitesperfwebkitorgpublicincludeadminheaderphp">trunk/Websites/perf.webkit.org/public/include/admin-header.php</a></li>
 <li><a href="#trunkWebsitesperfwebkitorgpublicincludereportprocessorphp">trunk/Websites/perf.webkit.org/public/include/report-processor.php</a></li>
 <li><a href="#trunkWebsitesperfwebkitorgtestsapireportjs">trunk/Websites/perf.webkit.org/tests/api-report.js</a></li>
 </ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkWebsitesperfwebkitorgpublicadminbuildslavesphp">trunk/Websites/perf.webkit.org/public/admin/build-slaves.php</a></li>
 </ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkWebsitesperfwebkitorgChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/ChangeLog (177613 \
=> 177614)</h4> <pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/ChangeLog	2014-12-20 01:21:38 \
                UTC (rev 177613)
+++ trunk/Websites/perf.webkit.org/ChangeLog	2014-12-20 02:38:04 UTC (rev 177614)
</span><span class="lines">@@ -1,3 +1,43 @@
</span><ins>+2014-12-19  Ryosuke Niwa  &lt;rniwa@webkit.org&gt;
+
+        Perf dashboard should support authentication via a slave password
+        https://bugs.webkit.org/show_bug.cgi?id=139837
+
+        Reviewed by Andreas Kling.
+
+        For historical reasons, perf dashboard conflated builders and build slaves. \
As a result we ended up +        having to add multiple builders with the same \
password when a single build slave is shared among them. +
+        This patch introduces the concept of build_slave into the perf dashboard to \
end this madness. +
+        * init-database.sql: Added build_slave table as well as references to it in \
builds and reports. +
+        * public/admin/build-slaves.php: Added.
+
+        * public/admin/builders.php: Added the support for updating passwords.
+
+        * public/include/admin-header.php:
+        (update_field): Takes an extra argument when a new value needs to be \
supplied by the caller instead of +        being retrieved from $_POST.
+        (AdministrativePage::render_table): Use array_get to retrieve a value out of \
the database row since +        the raw may not exist (e.g. new_password).
+        (AdministrativePage::render_form_to_add): Added the support for \
post_insertion. Don't render the form +        control here when this flag evaluates \
to TRUE. +
+        * public/include/report-processor.php:
+        (ReportProcessor::process): Added the logic to authenticate with slaveName \
and slavePassword if those +        values are present in the report. In addition, \
try authenticating builderName with slavePassword if +        builderPassword is not \
specified. When neither password is specified, exit with BuilderNotFound. +        \
Also insert the slave or the builder whichever is missing after we've successfully \
authenticated. +        (ReportProcessor::construct_build_data): Takes a builder ID \
and an optional slave ID instead of +        a builder row.
+        (ReportProcessor::store_report): Store the slave ID with the report.
+        (ReportProcessor::resolve_build_id): Exit with MismatchingBuildSlave when \
the slave associated with +        the matching build is different from what's being \
reported. +
+        * tests/api-report.js: Added a bunch of tests to test the new features of \
/api/report. +        (.addSlave): Added.
+
</ins><span class="cx"> 2014-12-18  Ryosuke Niwa  &lt;rniwa@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         New perf dashboard should not duplicate author \
information in each commit </span></span></pre></div>
<a id="trunkWebsitesperfwebkitorginitdatabasesql"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/init-database.sql \
(177613 => 177614)</h4> <pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/init-database.sql	2014-12-20 \
                01:21:38 UTC (rev 177613)
+++ trunk/Websites/perf.webkit.org/init-database.sql	2014-12-20 02:38:04 UTC (rev \
177614) </span><span class="lines">@@ -7,6 +7,7 @@
</span><span class="cx"> DROP TABLE committers CASCADE;
</span><span class="cx"> DROP TABLE commits CASCADE;
</span><span class="cx"> DROP TABLE build_commits CASCADE;
</span><ins>+DROP TABLE build_slaves CASCADE;
</ins><span class="cx"> DROP TABLE builders CASCADE;
</span><span class="cx"> DROP TABLE repositories CASCADE;
</span><span class="cx"> DROP TABLE platforms CASCADE;
</span><span class="lines">@@ -46,12 +47,18 @@
</span><span class="cx"> CREATE TABLE builders (
</span><span class="cx">     builder_id serial PRIMARY KEY,
</span><span class="cx">     builder_name varchar(64) NOT NULL UNIQUE,
</span><del>-    builder_password_hash character(64) NOT NULL,
</del><ins>+    builder_password_hash character(64),
</ins><span class="cx">     builder_build_url varchar(1024));
</span><span class="cx"> 
</span><ins>+CREATE TABLE build_slaves (
+    slave_id serial PRIMARY KEY,
+    slave_name varchar(64) NOT NULL UNIQUE,
+    slave_password_hash character(64));
+
</ins><span class="cx"> CREATE TABLE builds (
</span><span class="cx">     build_id serial PRIMARY KEY,
</span><span class="cx">     build_builder integer REFERENCES builders ON DELETE \
CASCADE, </span><ins>+    build_slave integer REFERENCES build_slaves ON DELETE \
CASCADE, </ins><span class="cx">     build_number integer NOT NULL,
</span><span class="cx">     build_time timestamp NOT NULL,
</span><span class="cx">     build_latest_revision timestamp,
</span><span class="lines">@@ -135,6 +142,7 @@
</span><span class="cx"> CREATE TABLE reports (
</span><span class="cx">     report_id serial PRIMARY KEY,
</span><span class="cx">     report_builder integer NOT NULL REFERENCES builders ON \
DELETE RESTRICT, </span><ins>+    report_slave integer REFERENCES build_slaves ON \
DELETE RESTRICT, </ins><span class="cx">     report_build_number integer,
</span><span class="cx">     report_build integer REFERENCES builds,
</span><span class="cx">     report_created_at timestamp NOT NULL DEFAULT \
(CURRENT_TIMESTAMP AT TIME ZONE 'UTC'), </span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgpublicadminbuildslavesphp"></a>
<div class="addfile"><h4>Added: \
trunk/Websites/perf.webkit.org/public/admin/build-slaves.php (0 => 177614)</h4> <pre \
class="diff"><span> <span class="info">--- \
trunk/Websites/perf.webkit.org/public/admin/build-slaves.php	                        \
                (rev 0)
+++ trunk/Websites/perf.webkit.org/public/admin/build-slaves.php	2014-12-20 02:38:04 \
UTC (rev 177614) </span><span class="lines">@@ -0,0 +1,35 @@
</span><ins>+&lt;?php
+
+require('../include/admin-header.php');
+
+if ($db) {
+
+    if ($action == 'add') {
+        if ($db-&gt;insert_row('build_slaves', 'slave', array('name' =&gt; \
$_POST['name'], 'password_hash' =&gt; hash('sha256', $_POST['password'])))) { +       \
notice('Inserted the new slave.'); +            regenerate_manifest();
+        } else
+            notice('Could not add the slave.');
+    } else if ($action == 'update') {
+        if (update_field('build_slaves', 'slave', 'name'))
+            regenerate_manifest();
+        else if (update_field('build_slaves', 'slave', 'password_hash', \
hash('sha256', $_POST['new_password']))) +            regenerate_manifest();
+        else
+            notice('Invalid parameters.');
+    }
+
+    $page = new AdministrativePage($db, 'build_slaves', 'slave', array(
+        'name' =&gt; array('size' =&gt; 50, 'editing_mode' =&gt; 'string'),
+        'password_hash' =&gt; array(),
+        'password' =&gt; array('pre_insertion' =&gt; TRUE, 'editing_mode' =&gt; \
'string'), +        'new_password' =&gt; array('post_insertion' =&gt; TRUE, \
'editing_mode' =&gt; 'string'), +    ));
+
+    $page-&gt;render_table('name');
+    $page-&gt;render_form_to_add();
+}
+
+require('../include/admin-footer.php');
+
+?&gt;
</ins></span></pre></div>
<a id="trunkWebsitesperfwebkitorgpublicadminbuildersphp"></a>
<div class="modfile"><h4>Modified: \
trunk/Websites/perf.webkit.org/public/admin/builders.php (177613 => 177614)</h4> <pre \
class="diff"><span> <span class="info">--- \
trunk/Websites/perf.webkit.org/public/admin/builders.php	2014-12-20 01:21:38 UTC (rev \
                177613)
+++ trunk/Websites/perf.webkit.org/public/admin/builders.php	2014-12-20 02:38:04 UTC \
(rev 177614) </span><span class="lines">@@ -14,6 +14,8 @@
</span><span class="cx">     } else if ($action == 'update') {
</span><span class="cx">         if (update_field('builders', 'builder', 'name') || \
update_field('builders', 'builder', 'build_url')) </span><span class="cx">            \
regenerate_manifest(); </span><ins>+        else if (update_field('build_slaves', \
'slave', 'password_hash', hash('sha256', $_POST['new_password']))) +            \
regenerate_manifest(); </ins><span class="cx">         else
</span><span class="cx">             notice('Invalid parameters.');
</span><span class="cx">     }
</span><span class="lines">@@ -22,6 +24,7 @@
</span><span class="cx">         'name' =&gt; array('size' =&gt; 50, 'editing_mode' \
=&gt; 'string'), </span><span class="cx">         'password_hash' =&gt; array(),
</span><span class="cx">         'password' =&gt; array('pre_insertion' =&gt; TRUE, \
'editing_mode' =&gt; 'string'), </span><ins>+        'new_password' =&gt; \
array('post_insertion' =&gt; TRUE, 'editing_mode' =&gt; 'string'), </ins><span \
class="cx">         'build_url' =&gt; array('label' =&gt; 'Build URL', 'size' =&gt; \
100, 'editing_mode' =&gt; 'url'), </span><span class="cx">     ));
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgpublicincludeadminheaderphp"></a>
<div class="modfile"><h4>Modified: \
trunk/Websites/perf.webkit.org/public/include/admin-header.php (177613 => \
177614)</h4> <pre class="diff"><span>
<span class="info">--- \
trunk/Websites/perf.webkit.org/public/include/admin-header.php	2014-12-20 01:21:38 \
                UTC (rev 177613)
+++ trunk/Websites/perf.webkit.org/public/include/admin-header.php	2014-12-20 \
02:38:04 UTC (rev 177614) </span><span class="lines">@@ -18,6 +18,7 @@
</span><span class="cx">     &lt;li&gt;&lt;a \
href=&quot;/admin/tests&quot;&gt;Tests&lt;/a&gt;&lt;/li&gt; </span><span class="cx">  \
&lt;li&gt;&lt;a href=&quot;/admin/aggregators&quot;&gt;Aggregators&lt;/a&gt;&lt;/li&gt;
 </span><span class="cx">     &lt;li&gt;&lt;a \
href=&quot;/admin/builders&quot;&gt;Builders&lt;/a&gt;&lt;/li&gt; </span><ins>+    \
&lt;li&gt;&lt;a href=&quot;/admin/build-slaves&quot;&gt;Slaves&lt;/a&gt;&lt;/li&gt; \
</ins><span class="cx">     &lt;li&gt;&lt;a \
href=&quot;/admin/repositories&quot;&gt;Repositories&lt;/a&gt;&lt;/li&gt; \
</span><span class="cx">     &lt;li&gt;&lt;a \
href=&quot;/admin/bug-trackers&quot;&gt;Bug Trackers&lt;/a&gt;&lt;/li&gt; \
</span><span class="cx"> &lt;/ul&gt; </span><span class="lines">@@ -56,18 +57,24 @@
</span><span class="cx">     return false;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-function update_field($table, $prefix, $field_name) {
</del><ins>+function update_field($table, $prefix, $field_name, $new_value = NULL) {
</ins><span class="cx">     global $db;
</span><span class="cx"> 
</span><del>-    if (!array_key_exists('id', $_POST) || (array_get($_POST, \
'updated-column') != $field_name &amp;&amp; !array_key_exists($field_name, $_POST))) \
</del><ins>+    if (!array_key_exists('id', $_POST)) </ins><span class="cx">         \
return FALSE; </span><span class="cx"> 
</span><span class="cx">     $id = intval($_POST['id']);
</span><span class="cx">     $prefixed_field_name = $prefix . '_' . $field_name;
</span><span class="cx">     $id_field_name = $prefix . '_id';
</span><span class="cx"> 
</span><ins>+    if ($new_value == NULL) {
+        if (array_get($_POST, 'updated-column') != $field_name &amp;&amp; \
!array_key_exists($field_name, $_POST)) +            return FALSE;
+        $new_value = array_get($_POST, $field_name);
+    }
+
</ins><span class="cx">     \
execute_query_and_expect_one_row_to_be_affected(&quot;UPDATE $table SET \
$prefixed_field_name = \$2 WHERE $id_field_name = \$1&quot;, </span><del>-        \
array($id, array_get($_POST, $field_name)), </del><ins>+        array($id, \
$new_value), </ins><span class="cx">         &quot;Updated the $prefix $id&quot;,
</span><span class="cx">         &quot;Could not update $prefix $id&quot;);
</span><span class="cx"> 
</span><span class="lines">@@ -226,7 +233,7 @@
</span><span class="cx">                         continue;
</span><span class="cx">                     }
</span><span class="cx"> 
</span><del>-                    $value = htmlspecialchars($row[$this-&gt;prefix . \
'_' . $name], ENT_QUOTES); </del><ins>+                    $value = \
htmlspecialchars(array_get($row, $this-&gt;prefix . '_' . $name), ENT_QUOTES); \
</ins><span class="cx">                     $editing_mode = \
array_get($this-&gt;column_info[$name], 'editing_mode'); </span><span class="cx">     \
if (!$editing_mode) { </span><span class="cx">                         echo \
&quot;&lt;td$rowspan_if_needed&gt;$value&lt;/td&gt;\n&quot;; </span><span \
class="lines">@@ -295,6 +302,8 @@ </span><span class="cx">             $editing_mode \
= array_get($this-&gt;column_info[$name], 'editing_mode'); </span><span class="cx">   \
if (array_get($this-&gt;column_info[$name], 'custom') || !$editing_mode) </span><span \
class="cx">                 continue; </span><ins>+            if \
(array_get($this-&gt;column_info[$name], 'post_insertion')) +                \
continue; </ins><span class="cx"> 
</span><span class="cx">             $label = \
htmlspecialchars($this-&gt;column_label($name)); </span><span class="cx">             \
echo &quot;&lt;label&gt;$label&lt;br&gt;\n&quot;; </span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgpublicincludereportprocessorphp"></a>
<div class="modfile"><h4>Modified: \
trunk/Websites/perf.webkit.org/public/include/report-processor.php (177613 => \
177614)</h4> <pre class="diff"><span>
<span class="info">--- \
trunk/Websites/perf.webkit.org/public/include/report-processor.php	2014-12-20 \
                01:21:38 UTC (rev 177613)
+++ trunk/Websites/perf.webkit.org/public/include/report-processor.php	2014-12-20 \
02:38:04 UTC (rev 177614) </span><span class="lines">@@ -39,16 +39,42 @@
</span><span class="cx">         array_key_exists('buildTime', $report) or \
$this-&gt;exit_with_error('MissingBuildTime'); </span><span class="cx"> 
</span><span class="cx">         $builder_info = array('name' =&gt; \
$report['builderName']); </span><del>-        if (!$existing_report_id)
-            $builder_info['password_hash'] = hash('sha256', \
$report['builderPassword']); </del><ins>+        $slave_name = array_get($report, \
'slaveName', NULL); +        $slave_id = NULL;
+        if (!$existing_report_id) {
+            $hash = NULL;
+            if ($slave_name &amp;&amp; array_key_exists('slavePassword', $report)) {
+                $hash = hash('sha256', $report['slavePassword']);
+                $slave = $this-&gt;db-&gt;select_first_row('build_slaves', 'slave', \
array('name' =&gt; $slave_name, 'password_hash' =&gt; $hash)); +                if \
($slave) +                    $slave_id = $slave['slave_id'];
+            } else if (array_key_exists('builderPassword', $report))
+                $hash = hash('sha256', $report['builderPassword']);
+
+            if (!$hash)
+                $this-&gt;exit_with_error('BuilderNotFound');
+            if (!$slave_id)
+                $builder_info['password_hash'] = $hash;
+        }
+
</ins><span class="cx">         if (array_key_exists('builderPassword', $report))
</span><span class="cx">             unset($report['builderPassword']);
</span><ins>+        if (array_key_exists('slavePassword', $report))
+            unset($report['slavePassword']);
</ins><span class="cx"> 
</span><del>-        $matched_builder = $this-&gt;db-&gt;select_first_row('builders', \
                'builder', $builder_info);
-        if (!$matched_builder)
-            $this-&gt;exit_with_error('BuilderNotFound', array('name' =&gt; \
$builder_info['name'])); </del><ins>+        $builder_id = NULL;
+        if ($slave_id)
+            $builder_id = $this-&gt;db-&gt;select_or_insert_row('builders', \
'builder', $builder_info); +        else {
+            $builder = $this-&gt;db-&gt;select_first_row('builders', 'builder', \
$builder_info); +            if (!$builder)
+                $this-&gt;exit_with_error('BuilderNotFound', array('name' =&gt; \
$builder_info['name'])); +            $builder_id = $builder['builder_id'];
+            if ($slave_name)
+                $slave_id = $this-&gt;db-&gt;select_or_insert_row('build_slaves', \
'slave', array('name' =&gt; $slave_name)); +        }
</ins><span class="cx"> 
</span><del>-        $build_data = $this-&gt;construct_build_data($report, \
$matched_builder); </del><ins>+        $build_data = \
$this-&gt;construct_build_data($report, $builder_id, $slave_id); </ins><span \
class="cx">         if (!$existing_report_id) </span><span class="cx">             \
$this-&gt;store_report($report, $build_data); </span><span class="cx"> 
</span><span class="lines">@@ -67,16 +93,19 @@
</span><span class="cx">         $this-&gt;runs-&gt;commit($platform_id, $build_id);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    private function construct_build_data($report, $builder) {
</del><ins>+    private function construct_build_data($report, $builder_id, \
$slave_id) { </ins><span class="cx">         array_key_exists('buildNumber', $report) \
or $this-&gt;exit_with_error('MissingBuildNumber'); </span><span class="cx">         \
array_key_exists('buildTime', $report) or \
$this-&gt;exit_with_error('MissingBuildTime'); </span><span class="cx"> 
</span><del>-        return array('builder' =&gt; $builder['builder_id'], 'number' \
=&gt; $report['buildNumber'], 'time' =&gt; $report['buildTime']); </del><ins>+        \
return array('builder' =&gt; $builder_id, 'slave' =&gt; $slave_id, 'number' =&gt; \
$report['buildNumber'], 'time' =&gt; $report['buildTime']); </ins><span class="cx">   \
} </span><span class="cx"> 
</span><span class="cx">     private function store_report($report, $build_data) {
</span><span class="cx">         assert(!$this-&gt;report_id);
</span><del>-        $this-&gt;report_id = $this-&gt;db-&gt;insert_row('reports', \
'report', array('builder' =&gt; $build_data['builder'], 'build_number' =&gt; \
$build_data['number'], </del><ins>+        $this-&gt;report_id = \
$this-&gt;db-&gt;insert_row('reports', 'report', array( +            'builder' =&gt; \
$build_data['builder'], +            'slave' =&gt; $build_data['slave'],
+            'build_number' =&gt; $build_data['number'],
</ins><span class="cx">             'content' =&gt; json_encode($report)));
</span><span class="cx">         if (!$this-&gt;report_id)
</span><span class="cx">             \
$this-&gt;exit_with_error('FailedToStoreRunReport'); </span><span class="lines">@@ \
-84,11 +113,15 @@ </span><span class="cx"> 
</span><span class="cx">     private function resolve_build_id($build_data, \
$revisions) { </span><span class="cx">         // FIXME: This code has a race \
condition. See &lt;rdar://problem/15876303&gt;. </span><del>-        $results = \
$this-&gt;db-&gt;query_and_fetch_all(&quot;SELECT build_id FROM builds WHERE \
build_builder = $1 AND build_number = $2 AND build_time &lt;= $3 AND build_time + \
interval '1 day' &gt; $3&quot;, </del><ins>+        $results = \
$this-&gt;db-&gt;query_and_fetch_all(&quot;SELECT build_id, build_slave FROM builds + \
WHERE build_builder = $1 AND build_number = $2 AND build_time &lt;= $3 AND build_time \
+ interval '1 day' &gt; $3&quot;, </ins><span class="cx">             \
array($build_data['builder'], $build_data['number'], $build_data['time'])); \
                </span><del>-        if ($results)
-            $build_id = $results[0]['build_id'];
-        else
</del><ins>+        if ($results) {
+            $first_result = $results[0];
+            if ($first_result['build_slave'] != $build_data['slave'])
+                $this-&gt;exit_with_error('MismatchingBuildSlave', \
array('storedBuild' =&gt; $results, 'reportedBuildData' =&gt; $build_data)); +        \
$build_id = $first_result['build_id']; +        } else
</ins><span class="cx">             $build_id = $this-&gt;db-&gt;insert_row('builds', \
'build', $build_data); </span><span class="cx">         if (!$build_id)
</span><span class="cx">             $this-&gt;exit_with_error('FailedToInsertBuild', \
$build_data); </span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgtestsapireportjs"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/tests/api-report.js \
(177613 => 177614)</h4> <pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/tests/api-report.js	2014-12-20 \
                01:21:38 UTC (rev 177613)
+++ trunk/Websites/perf.webkit.org/tests/api-report.js	2014-12-20 02:38:04 UTC (rev \
177614) </span><span class="lines">@@ -3,6 +3,7 @@
</span><span class="cx">         &quot;buildNumber&quot;: &quot;123&quot;,
</span><span class="cx">         &quot;buildTime&quot;: \
&quot;2013-02-28T10:12:03.388304&quot;, </span><span class="cx">         \
&quot;builderName&quot;: &quot;someBuilder&quot;, </span><ins>+        \
&quot;slaveName&quot;: &quot;someSlave&quot;, </ins><span class="cx">         \
&quot;builderPassword&quot;: &quot;somePassword&quot;, </span><span class="cx">       \
&quot;platform&quot;: &quot;Mountain Lion&quot;, </span><span class="cx">         \
&quot;tests&quot;: {}, </span><span class="lines">@@ -16,11 +17,35 @@
</span><span class="cx">             }
</span><span class="cx">         }}];
</span><span class="cx"> 
</span><ins>+    var emptySlaveReport = [{
+        &quot;buildNumber&quot;: &quot;123&quot;,
+        &quot;buildTime&quot;: &quot;2013-02-28T10:12:03.388304&quot;,
+        &quot;builderName&quot;: &quot;someBuilder&quot;,
+        &quot;builderPassword&quot;: &quot;somePassword&quot;,
+        &quot;slaveName&quot;: &quot;someSlave&quot;,
+        &quot;slavePassword&quot;: &quot;otherPassword&quot;,
+        &quot;platform&quot;: &quot;Mountain Lion&quot;,
+        &quot;tests&quot;: {},
+        &quot;revisions&quot;: {
+            &quot;OS X&quot;: {
+                &quot;revision&quot;: &quot;10.8.2 12C60&quot;
+            },
+            &quot;WebKit&quot;: {
+                &quot;revision&quot;: &quot;141977&quot;,
+                &quot;timestamp&quot;: &quot;2013-02-06T08:55:20.9Z&quot;
+            }
+        }}];
+
</ins><span class="cx">     function addBuilder(report, callback) {
</span><span class="cx">         queryAndFetchAll('INSERT INTO builders \
(builder_name, builder_password_hash) values ($1, $2)', </span><span class="cx">      \
[report[0].builderName, sha256(report[0].builderPassword)], callback); </span><span \
class="cx">     } </span><span class="cx"> 
</span><ins>+    function addSlave(report, callback) {
+        queryAndFetchAll('INSERT INTO build_slaves (slave_name, slave_password_hash) \
values ($1, $2)', +            [report[0].slaveName, \
sha256(report[0].slavePassword)], callback); +    }
+
</ins><span class="cx">     it(&quot;should reject error when builder name is \
missing&quot;, function () { </span><span class="cx">         \
postJSON('/api/report/', [{&quot;buildTime&quot;: \
&quot;2013-02-28T10:12:03.388304&quot;}], function (response) { </span><span \
class="cx">             assert.equal(response.statusCode, 200); </span><span \
class="lines">@@ -53,6 +78,28 @@ </span><span class="cx">         });
</span><span class="cx">     });
</span><span class="cx"> 
</span><ins>+    it(&quot;should reject a report without a builder password&quot;, \
function () { +        addBuilder(emptyReport, function () {
+            var report = [{
+                &quot;buildNumber&quot;: &quot;123&quot;,
+                &quot;buildTime&quot;: &quot;2013-02-28T10:12:03.388304&quot;,
+                &quot;builderName&quot;: &quot;someBuilder&quot;,
+                &quot;tests&quot;: {},
+                &quot;revisions&quot;: {}}];
+            postJSON('/api/report/', report, function (response) {
+                assert.equal(response.statusCode, 200);
+                assert.notEqual(JSON.parse(response.responseText)['status'], 'OK');
+                assert.equal(JSON.parse(response.responseText)['failureStored'], \
false); +                \
assert.equal(JSON.parse(response.responseText)['processedRuns'], 0); +
+                queryAndFetchAll('SELECT COUNT(*) from reports', [], function (rows) \
{ +                    assert.equal(rows[0].count, 0);
+                    notifyDone();
+                });
+            });
+        });
+    });
+
</ins><span class="cx">     it(&quot;should store a report from a valid \
builder&quot;, function () { </span><span class="cx">         addBuilder(emptyReport, \
function () { </span><span class="cx">             postJSON('/api/report/', \
emptyReport, function (response) { </span><span class="lines">@@ -68,6 +115,41 @@
</span><span class="cx">         });
</span><span class="cx">     });
</span><span class="cx"> 
</span><ins>+    it(&quot;should treat the slave password as the builder password if \
there is no matching slave&quot;, function () { +        addBuilder(emptyReport, \
function () { +            emptyReport[0]['slavePassword'] = \
emptyReport[0]['builderPassword']; +            delete \
emptyReport[0]['builderPassword']; +            postJSON('/api/report/', emptyReport, \
function (response) { +                emptyReport[0]['builderPassword'] = \
emptyReport[0]['slavePassword']; +                delete \
emptyReport[0]['slavePassword']; +
+                assert.equal(response.statusCode, 200);
+                assert.equal(JSON.parse(response.responseText)['status'], 'OK');
+                assert.equal(JSON.parse(response.responseText)['failureStored'], \
false); +                \
assert.equal(JSON.parse(response.responseText)['processedRuns'], 1); +                \
queryAndFetchAll('SELECT COUNT(*) from reports', [], function (rows) { +              \
assert.equal(rows[0].count, 1); +                    notifyDone();
+                });
+            });
+        });
+    });
+
+    it(&quot;should store a report from a valid slave&quot;, function () {
+        addSlave(emptySlaveReport, function () {
+            postJSON('/api/report/', emptySlaveReport, function (response) {
+                assert.equal(response.statusCode, 200);
+                assert.equal(JSON.parse(response.responseText)['status'], 'OK');
+                assert.equal(JSON.parse(response.responseText)['failureStored'], \
false); +                \
assert.equal(JSON.parse(response.responseText)['processedRuns'], 1); +                \
queryAndFetchAll('SELECT COUNT(*) from reports', [], function (rows) { +              \
assert.equal(rows[0].count, 1); +                    notifyDone();
+                });
+            });
+        });
+    });
+
</ins><span class="cx">     it(&quot;should store the builder name but not the \
builder password&quot;, function () { </span><span class="cx">         \
addBuilder(emptyReport, function () { </span><span class="cx">             \
postJSON('/api/report/', emptyReport, function (response) { </span><span \
class="lines">@@ -81,6 +163,28 @@ </span><span class="cx">         });
</span><span class="cx">     });
</span><span class="cx"> 
</span><ins>+    it(&quot;should add a slave if there isn't one and the report was \
authenticated by a builder&quot;, function () { +        addBuilder(emptyReport, \
function () { +            postJSON('/api/report/', emptyReport, function (response) \
{ +                queryAndFetchAll('SELECT * from build_slaves', [], function (rows) \
{ +                    assert.strictEqual(rows[0].slave_name, \
emptyReport[0].slaveName); +                    notifyDone();
+                });
+            });
+        });
+    });
+
+    it(&quot;should add a builder if there isn't one and the report was \
authenticated by a slave&quot;, function () { +        addSlave(emptySlaveReport, \
function () { +            postJSON('/api/report/', emptySlaveReport, function \
(response) { +                queryAndFetchAll('SELECT * from builders', [], function \
(rows) { +                    assert.strictEqual(rows[0].builder_name, \
emptyReport[0].builderName); +                    notifyDone();
+                });
+            });
+        });
+    });
+
</ins><span class="cx">     it(&quot;should add a build&quot;, function () {
</span><span class="cx">         addBuilder(emptyReport, function () {
</span><span class="cx">             postJSON('/api/report/', emptyReport, function \
(response) { </span></span></pre>
</div>
</div>

</body>
</html>



_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic