<!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>[180000] 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/180000">180000</a></dd>
<dt>Author</dt> <dd>rniwa@webkit.org</dd>
<dt>Date</dt> <dd>2015-02-12 10:50:53 -0800 (Thu, 12 Feb 2015)</dd>
</dl>
<h3>Log Message</h3>
<pre>Perf dashboard should show the results of A/B testing
https://bugs.webkit.org/show_bug.cgi?id=141500
Reviewed by Chris Dumez.
Added the support for fetching test_runs for a specific test group in /api/runs/, and used it in the
analysis task page to fetch results for each test group.
Merged App.createChartData into App.Manifest.fetchRunsWithPlatformAndMetric so that App.BuildRequest
can use the formatter.
* public/api/runs.php:
(fetch_runs_for_config_and_test_group): Added.
(fetch_runs_for_config): Just return the fetched rows since main will format them with RunsGenerator.
(main): Use fetch_runs_for_config_and_test_group to fetch rows when a test group id is specified. Also
use RunsGenerator to format results.
(RunsGenerator): Added.
(RunsGenerator::__construct): Added.
(RunsGenerator::add_runs): Added.
(RunsGenerator::format_run): Moved.
(RunsGenerator::parse_revisions_array): Moved.
* public/v2/analysis.js:
(App.TestGroup): Fixed a typo. The property on a test group that refers to an analysis task is "task".
(App.TestGroup._fetchChartData): Added. Fetches all A/B testing results for this group.
(App.BuildRequest.configLetter): Renamed from config since this returns a letter that identifies the
configuration associated with this build request such as "A" and "B".
(App.BuildRequest.statusLabel): Added the missing label for failed build requests.
(App.BuildRequest.url): Added. Returns the URL associated with this build request.
(App.BuildRequest._meanFetched): Added. Retrieve the mean and the build number for this request via
_fetchChartData.
* public/v2/app.js:
(App.Pane._fetch): Set chartData directly here.
(App.Pane._updateMovingAverageAndEnvelope): Renamed from _computeChartData. No longer sets chartData
now that it's done in App.Pane._fetch.
(App.AnalysisTaskController._fetchedRuns): Updated per createChartData merge.
* public/v2/data.js:
(Measurement.prototype.buildId): Added.
(TimeSeries.prototype.findPointByBuild): Added.
* public/v2/index.html: Fixed a bug that build status URL was broken. We can't use link-to helper since
url is not an Ember routed path.
* public/v2/manifest.js:
(App.Manifest.fetchRunsWithPlatformAndMetric): Takes testGroupId as the third argument. Merged
App.createChartData here so that App.BuildRequest can use the formatter</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkWebsitesperfwebkitorgChangeLog">trunk/Websites/perf.webkit.org/ChangeLog</a></li>
<li><a href="#trunkWebsitesperfwebkitorgpublicapirunsphp">trunk/Websites/perf.webkit.org/public/api/runs.php</a></li>
<li><a href="#trunkWebsitesperfwebkitorgpublicv2analysisjs">trunk/Websites/perf.webkit.org/public/v2/analysis.js</a></li>
<li><a href="#trunkWebsitesperfwebkitorgpublicv2appjs">trunk/Websites/perf.webkit.org/public/v2/app.js</a></li>
<li><a href="#trunkWebsitesperfwebkitorgpublicv2datajs">trunk/Websites/perf.webkit.org/public/v2/data.js</a></li>
<li><a href="#trunkWebsitesperfwebkitorgpublicv2indexhtml">trunk/Websites/perf.webkit.org/public/v2/index.html</a></li>
<li><a href="#trunkWebsitesperfwebkitorgpublicv2manifestjs">trunk/Websites/perf.webkit.org/public/v2/manifest.js</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 (179999 => 180000)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/ChangeLog        2015-02-12 18:42:21 UTC (rev 179999)
+++ trunk/Websites/perf.webkit.org/ChangeLog        2015-02-12 18:50:53 UTC (rev 180000)
</span><span class="lines">@@ -1,5 +1,56 @@
</span><span class="cx"> 2015-02-12 Ryosuke Niwa <rniwa@webkit.org>
</span><span class="cx">
</span><ins>+ Perf dashboard should show the results of A/B testing
+ https://bugs.webkit.org/show_bug.cgi?id=141500
+
+ Reviewed by Chris Dumez.
+
+ Added the support for fetching test_runs for a specific test group in /api/runs/, and used it in the
+ analysis task page to fetch results for each test group.
+
+ Merged App.createChartData into App.Manifest.fetchRunsWithPlatformAndMetric so that App.BuildRequest
+ can use the formatter.
+
+ * public/api/runs.php:
+ (fetch_runs_for_config_and_test_group): Added.
+ (fetch_runs_for_config): Just return the fetched rows since main will format them with RunsGenerator.
+ (main): Use fetch_runs_for_config_and_test_group to fetch rows when a test group id is specified. Also
+ use RunsGenerator to format results.
+ (RunsGenerator): Added.
+ (RunsGenerator::__construct): Added.
+ (RunsGenerator::add_runs): Added.
+ (RunsGenerator::format_run): Moved.
+ (RunsGenerator::parse_revisions_array): Moved.
+
+ * public/v2/analysis.js:
+ (App.TestGroup): Fixed a typo. The property on a test group that refers to an analysis task is "task".
+ (App.TestGroup._fetchChartData): Added. Fetches all A/B testing results for this group.
+ (App.BuildRequest.configLetter): Renamed from config since this returns a letter that identifies the
+ configuration associated with this build request such as "A" and "B".
+ (App.BuildRequest.statusLabel): Added the missing label for failed build requests.
+ (App.BuildRequest.url): Added. Returns the URL associated with this build request.
+ (App.BuildRequest._meanFetched): Added. Retrieve the mean and the build number for this request via
+ _fetchChartData.
+
+ * public/v2/app.js:
+ (App.Pane._fetch): Set chartData directly here.
+ (App.Pane._updateMovingAverageAndEnvelope): Renamed from _computeChartData. No longer sets chartData
+ now that it's done in App.Pane._fetch.
+ (App.AnalysisTaskController._fetchedRuns): Updated per createChartData merge.
+
+ * public/v2/data.js:
+ (Measurement.prototype.buildId): Added.
+ (TimeSeries.prototype.findPointByBuild): Added.
+
+ * public/v2/index.html: Fixed a bug that build status URL was broken. We can't use link-to helper since
+ url is not an Ember routed path.
+
+ * public/v2/manifest.js:
+ (App.Manifest.fetchRunsWithPlatformAndMetric): Takes testGroupId as the third argument. Merged
+ App.createChartData here so that App.BuildRequest can use the formatter
+
+2015-02-12 Ryosuke Niwa <rniwa@webkit.org>
+
</ins><span class="cx"> v2 UI should adjust the number of ticks on dashboards based on screen size
</span><span class="cx"> https://bugs.webkit.org/show_bug.cgi?id=141502
</span><span class="cx">
</span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgpublicapirunsphp"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/public/api/runs.php (179999 => 180000)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/public/api/runs.php        2015-02-12 18:42:21 UTC (rev 179999)
+++ trunk/Websites/perf.webkit.org/public/api/runs.php        2015-02-12 18:50:53 UTC (rev 180000)
</span><span class="lines">@@ -2,52 +2,27 @@
</span><span class="cx">
</span><span class="cx"> require('../include/json-header.php');
</span><span class="cx">
</span><ins>+function fetch_runs_for_config_and_test_group($db, $config, $test_group_id) {
+ return $db->query_and_fetch_all('
+ SELECT test_runs.*, builds.*, array_agg((commit_repository, commit_revision, commit_time)) AS revisions
+ FROM builds
+ LEFT OUTER JOIN build_commits ON commit_build = build_id
+ LEFT OUTER JOIN commits ON build_commit = commit_id,
+ test_runs, build_requests, analysis_test_groups
+ WHERE run_build = build_id AND run_config = $1 AND request_build = build_id AND request_group = $2
+ GROUP BY build_id, run_id', array($config['config_id'], $test_group_id));
+}
+
</ins><span class="cx"> function fetch_runs_for_config($db, $config) {
</span><del>- $raw_runs = $db->query_and_fetch_all('
</del><ins>+ return $db->query_and_fetch_all('
</ins><span class="cx"> SELECT test_runs.*, builds.*, array_agg((commit_repository, commit_revision, commit_time)) AS revisions
</span><span class="cx"> FROM builds
</span><span class="cx"> LEFT OUTER JOIN build_commits ON commit_build = build_id
</span><span class="cx"> LEFT OUTER JOIN commits ON build_commit = commit_id, test_runs
</span><span class="cx"> WHERE run_build = build_id AND run_config = $1 AND NOT EXISTS (SELECT * FROM build_requests WHERE request_build = build_id)
</span><span class="cx"> GROUP BY build_id, run_id', array($config['config_id']));
</span><del>-
- $formatted_runs = array();
- if (!$raw_runs)
- return $formatted_runs;
-
- foreach ($raw_runs as $run)
- array_push($formatted_runs, format_run($run));
-
- return $formatted_runs;
</del><span class="cx"> }
</span><span class="cx">
</span><del>-function parse_revisions_array($postgres_array) {
- // e.g. {"(WebKit,131456,\"2012-10-16 14:53:00\")","(Chromium,162004,)"}
- $outer_array = json_decode('[' . trim($postgres_array, '{}') . ']');
- $revisions = array();
- foreach ($outer_array as $item) {
- $name_and_revision = explode(',', trim($item, '()'));
- if (!$name_and_revision[0])
- continue;
- $time = strtotime(trim($name_and_revision[2], '"')) * 1000;
- $revisions[trim($name_and_revision[0], '"')] = array(trim($name_and_revision[1], '"'), $time);
- }
- return $revisions;
-}
-
-function format_run($run) {
- return array(
- 'id' => intval($run['run_id']),
- 'mean' => floatval($run['run_mean_cache']),
- 'iterationCount' => intval($run['run_iteration_count_cache']),
- 'sum' => floatval($run['run_sum_cache']),
- 'squareSum' => floatval($run['run_square_sum_cache']),
- 'revisions' => parse_revisions_array($run['revisions']),
- 'buildTime' => strtotime($run['build_time']) * 1000,
- 'buildNumber' => intval($run['build_number']),
- 'builder' => $run['build_builder']);
-}
-
</del><span class="cx"> function main($path) {
</span><span class="cx"> if (count($path) != 1)
</span><span class="cx"> exit_with_error('InvalidRequest');
</span><span class="lines">@@ -60,11 +35,6 @@
</span><span class="cx"> if (!$db->connect())
</span><span class="cx"> exit_with_error('DatabaseConnectionFailure');
</span><span class="cx">
</span><del>- // FIXME: We should support revalication as well as caching results in the server side.
- $maxage = config('jsonCacheMaxAge');
- header('Expires: ' . gmdate('D, d M Y H:i:s', time() + $maxage) . ' GMT');
- header("Cache-Control: maxage=$maxage");
-
</del><span class="cx"> $platform_id = intval($parts[0]);
</span><span class="cx"> $metric_id = intval($parts[1]);
</span><span class="cx"> $config_rows = $db->query_and_fetch_all('SELECT config_id, config_type, config_platform, config_metric
</span><span class="lines">@@ -72,15 +42,75 @@
</span><span class="cx"> if (!$config_rows)
</span><span class="cx"> exit_with_error('ConfigurationNotFound');
</span><span class="cx">
</span><del>- $results = array();
</del><ins>+ $test_group_id = array_get($_GET, 'testGroup');
+ if ($test_group_id)
+ $test_group_id = intval($test_group_id);
+ else {
+ // FIXME: We should support revalication as well as caching results in the server side.
+ $maxage = config('jsonCacheMaxAge');
+ header('Expires: ' . gmdate('D, d M Y H:i:s', time() + $maxage) . ' GMT');
+ header("Cache-Control: maxage=$maxage");
+ }
+
+ $generator = new RunsGenerator();
+
</ins><span class="cx"> foreach ($config_rows as $config) {
</span><del>- if ($runs = fetch_runs_for_config($db, $config))
- $results[$config['config_type']] = $runs;
</del><ins>+ if ($test_group_id)
+ $raw_runs = fetch_runs_for_config_and_test_group($db, $config, $test_group_id);
+ else
+ $raw_runs = fetch_runs_for_config($db, $config);
+ $generator->add_runs($config['config_type'], $raw_runs);
</ins><span class="cx"> }
</span><span class="cx">
</span><del>- exit_with_success($results);
</del><ins>+ exit_with_success($generator->results());
</ins><span class="cx"> }
</span><span class="cx">
</span><ins>+class RunsGenerator {
+ function __construct() {
+ $this->results = array();
+ }
+
+ function &results() { return $this->results; }
+
+ function add_runs($name, $raw_runs) {
+ $formatted_runs = array();
+ if ($raw_runs) {
+ foreach ($raw_runs as $run)
+ array_push($formatted_runs, self::format_run($run));
+ }
+ $this->results[$name] = $formatted_runs;
+ return $formatted_runs;
+ }
+
+ private static function format_run($run) {
+ return array(
+ 'id' => intval($run['run_id']),
+ 'mean' => floatval($run['run_mean_cache']),
+ 'iterationCount' => intval($run['run_iteration_count_cache']),
+ 'sum' => floatval($run['run_sum_cache']),
+ 'squareSum' => floatval($run['run_square_sum_cache']),
+ 'revisions' => self::parse_revisions_array($run['revisions']),
+ 'build' => $run['build_id'],
+ 'buildTime' => strtotime($run['build_time']) * 1000,
+ 'buildNumber' => intval($run['build_number']),
+ 'builder' => $run['build_builder']);
+ }
+
+ private static function parse_revisions_array($postgres_array) {
+ // e.g. {"(WebKit,131456,\"2012-10-16 14:53:00\")","(Chromium,162004,)"}
+ $outer_array = json_decode('[' . trim($postgres_array, '{}') . ']');
+ $revisions = array();
+ foreach ($outer_array as $item) {
+ $name_and_revision = explode(',', trim($item, '()'));
+ if (!$name_and_revision[0])
+ continue;
+ $time = strtotime(trim($name_and_revision[2], '"')) * 1000;
+ $revisions[trim($name_and_revision[0], '"')] = array(trim($name_and_revision[1], '"'), $time);
+ }
+ return $revisions;
+ }
+}
+
</ins><span class="cx"> main(array_key_exists('PATH_INFO', $_SERVER) ? explode('/', trim($_SERVER['PATH_INFO'], '/')) : array());
</span><span class="cx">
</span><span class="cx"> ?>
</span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgpublicv2analysisjs"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/public/v2/analysis.js (179999 => 180000)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/public/v2/analysis.js        2015-02-12 18:42:21 UTC (rev 179999)
+++ trunk/Websites/perf.webkit.org/public/v2/analysis.js        2015-02-12 18:50:53 UTC (rev 180000)
</span><span class="lines">@@ -66,7 +66,7 @@
</span><span class="cx"> });
</span><span class="cx">
</span><span class="cx"> App.TestGroup = App.NameLabelModel.extend({
</span><del>- analysisTask: DS.belongsTo('analysisTask'),
</del><ins>+ task: DS.belongsTo('analysisTask'),
</ins><span class="cx"> author: DS.attr('string'),
</span><span class="cx"> createdAt: DS.attr('date'),
</span><span class="cx"> buildRequests: DS.hasMany('buildRequests'),
</span><span class="lines">@@ -80,6 +80,21 @@
</span><span class="cx"> });
</span><span class="cx"> return rootSetIds;
</span><span class="cx"> }.property('buildRequests'),
</span><ins>+ _fetchChartData: function ()
+ {
+ var task = this.get('task');
+ if (!task)
+ return null;
+ var self = this;
+ return App.Manifest.fetchRunsWithPlatformAndMetric(this.store,
+ task.get('platform').get('id'), task.get('metric').get('id'), this.get('id')).then(
+ function (result) { self.set('chartData', result.data); },
+ function (error) {
+ // FIXME: Somehow this never gets called.
+ alert('Failed to fetch the results:' + error);
+ return null;
+ });
+ }.observes('task', 'task.platform', 'task.metric').on('init'),
</ins><span class="cx"> });
</span><span class="cx">
</span><span class="cx"> App.TestGroup.create = function (analysisTask, name, rootSets, repetitionCount)
</span><span class="lines">@@ -130,7 +145,7 @@
</span><span class="cx"> return this.get('order') + 1;
</span><span class="cx"> }.property('order'),
</span><span class="cx"> rootSet: DS.attr('number'),
</span><del>- config: function ()
</del><ins>+ configLetter: function ()
</ins><span class="cx"> {
</span><span class="cx"> var rootSets = this.get('testGroup').get('rootSets');
</span><span class="cx"> var index = rootSets.indexOf(this.get('rootSet'));
</span><span class="lines">@@ -146,9 +161,27 @@
</span><span class="cx"> return 'Scheduled';
</span><span class="cx"> case 'running':
</span><span class="cx"> return 'Running';
</span><ins>+ case 'failed':
+ return 'Failed';
</ins><span class="cx"> case 'completed':
</span><span class="cx"> return 'Finished';
</span><span class="cx"> }
</span><span class="cx"> }.property('status'),
</span><ins>+ url: DS.attr('string'),
</ins><span class="cx"> build: DS.attr('number'),
</span><ins>+ _fetchMean: function ()
+ {
+ var testGroup = this.get('testGroup');
+ if (!testGroup)
+ return;
+ var chartData = testGroup.get('chartData');
+ if (!chartData)
+ return;
+
+ var point = chartData.current.findPointByBuild(this.get('build'));
+ if (!point)
+ return;
+ this.set('mean', chartData.formatter(point.value) + (chartData.unit ? ' ' + chartData.unit : ''));
+ this.set('buildNumber', point.measurement.buildNumber());
+ }.observes('build', 'testGroup', 'testGroup.chartData').on('init'),
</ins><span class="cx"> });
</span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgpublicv2appjs"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/public/v2/app.js (179999 => 180000)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/public/v2/app.js        2015-02-12 18:42:21 UTC (rev 179999)
+++ trunk/Websites/perf.webkit.org/public/v2/app.js        2015-02-12 18:50:53 UTC (rev 180000)
</span><span class="lines">@@ -352,8 +352,8 @@
</span><span class="cx"> App.Manifest.fetchRunsWithPlatformAndMetric(this.get('store'), platformId, metricId).then(function (result) {
</span><span class="cx"> self.set('platform', result.platform);
</span><span class="cx"> self.set('metric', result.metric);
</span><del>- self.set('fetchedData', result);
- self._computeChartData();
</del><ins>+ self.set('chartData', result.data);
+ self._updateMovingAverageAndEnvelope();
</ins><span class="cx"> }, function (result) {
</span><span class="cx"> if (!result || typeof(result) === "string")
</span><span class="cx"> self.set('failure', 'Failed to fetch the JSON with an error: ' + result);
</span><span class="lines">@@ -471,13 +471,12 @@
</span><span class="cx">
</span><span class="cx"> return chosenStrategy;
</span><span class="cx"> },
</span><del>- _computeChartData: function ()
</del><ins>+ _updateMovingAverageAndEnvelope: function ()
</ins><span class="cx"> {
</span><del>- if (!this.get('fetchedData'))
</del><ins>+ var chartData = this.get('chartData');
+ if (!chartData)
</ins><span class="cx"> return;
</span><span class="cx">
</span><del>- var chartData = App.createChartData(this.get('fetchedData'));
-
</del><span class="cx"> var movingAverageStrategy = this.get('chosenMovingAverageStrategy');
</span><span class="cx"> this._updateStrategyConfigIfNeeded(movingAverageStrategy, 'movingAverageConfig');
</span><span class="cx">
</span><span class="lines">@@ -485,8 +484,6 @@
</span><span class="cx"> this._updateStrategyConfigIfNeeded(envelopingStrategy, 'envelopingConfig');
</span><span class="cx">
</span><span class="cx"> chartData.movingAverage = this._computeMovingAverageAndOutliers(chartData, movingAverageStrategy, envelopingStrategy);
</span><del>-
- this.set('chartData', chartData);
</del><span class="cx"> }.observes('chosenMovingAverageStrategy', 'chosenMovingAverageStrategy.parameterList.@each.value',
</span><span class="cx"> 'chosenEnvelopingStrategy', 'chosenEnvelopingStrategy.parameterList.@each.value'),
</span><span class="cx"> _computeMovingAverageAndOutliers: function (chartData, movingAverageStrategy, envelopingStrategy)
</span><span class="lines">@@ -543,20 +540,6 @@
</span><span class="cx"> },
</span><span class="cx"> });
</span><span class="cx">
</span><del>-App.createChartData = function (data)
-{
- var runs = data.runs;
- return {
- current: runs.current.timeSeriesByCommitTime(),
- baseline: runs.baseline ? runs.baseline.timeSeriesByCommitTime() : null,
- target: runs.target ? runs.target.timeSeriesByCommitTime() : null,
- unit: data.unit,
- formatter: data.useSI ? d3.format('.4s') : d3.format('.4g'),
- deltaFormatter: data.useSI ? d3.format('+.2s') : d3.format('+.2g'),
- smallerIsBetter: data.smallerIsBetter,
- };
-}
-
</del><span class="cx"> App.encodePrettifiedJSON = function (plain)
</span><span class="cx"> {
</span><span class="cx"> function numberIfPossible(string) {
</span><span class="lines">@@ -1027,11 +1010,10 @@
</span><span class="cx"> });
</span><span class="cx"> }));
</span><span class="cx"> },
</span><del>- _fetchedRuns: function (data)
</del><ins>+ _fetchedRuns: function (result)
</ins><span class="cx"> {
</span><del>- var runs = data.runs;
-
- var currentTimeSeries = runs.current.timeSeriesByCommitTime();
</del><ins>+ var chartData = result.data;
+ var currentTimeSeries = chartData.current;
</ins><span class="cx"> if (!currentTimeSeries)
</span><span class="cx"> return; // FIXME: Report an error.
</span><span class="cx">
</span><span class="lines">@@ -1044,13 +1026,12 @@
</span><span class="cx"> highlightedItems[start.measurement.id()] = true;
</span><span class="cx"> highlightedItems[end.measurement.id()] = true;
</span><span class="cx">
</span><del>- var chartData = App.createChartData(data);
</del><span class="cx"> var formatedPoints = currentTimeSeries.seriesBetweenPoints(start, end).map(function (point, index) {
</span><span class="cx"> return {
</span><span class="cx"> id: point.measurement.id(),
</span><span class="cx"> measurement: point.measurement,
</span><span class="cx"> label: 'Point ' + (index + 1),
</span><del>- value: chartData.formatter(point.value) + (data.unit ? ' ' + data.unit : ''),
</del><ins>+ value: chartData.formatter(point.value) + (chartData.unit ? ' ' + chartData.unit : ''),
</ins><span class="cx"> };
</span><span class="cx"> });
</span><span class="cx">
</span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgpublicv2datajs"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/public/v2/data.js (179999 => 180000)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/public/v2/data.js        2015-02-12 18:42:21 UTC (rev 179999)
+++ trunk/Websites/perf.webkit.org/public/v2/data.js        2015-02-12 18:50:53 UTC (rev 180000)
</span><span class="lines">@@ -242,6 +242,11 @@
</span><span class="cx"> return this._latestCommitTime || this._buildTime;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+Measurement.prototype.buildId = function()
+{
+ return this._raw['build'];
+}
+
</ins><span class="cx"> Measurement.prototype.buildNumber = function ()
</span><span class="cx"> {
</span><span class="cx"> return this._raw['buildNumber'];
</span><span class="lines">@@ -315,10 +320,13 @@
</span><span class="cx">
</span><span class="cx"> // FIXME: We need to devise a way to fetch runs in multiple chunks so that
</span><span class="cx"> // we don't have to fetch the entire time series to just show the last 3 days.
</span><del>-RunsData.fetchRuns = function (platformId, metricId)
</del><ins>+RunsData.fetchRuns = function (platformId, metricId, testGroupId)
</ins><span class="cx"> {
</span><span class="cx"> var filename = platformId + '-' + metricId + '.json';
</span><span class="cx">
</span><ins>+ if (testGroupId)
+ filename += '?testGroup=' + testGroupId;
+
</ins><span class="cx"> return new Ember.RSVP.Promise(function (resolve, reject) {
</span><span class="cx"> $.getJSON('../api/runs/' + filename, function (data) {
</span><span class="cx"> if (data.status != 'OK') {
</span><span class="lines">@@ -355,6 +363,11 @@
</span><span class="cx"> this._max = max;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+TimeSeries.prototype.findPointByBuild = function (buildId)
+{
+ return this._series.find(function (point) { return point.measurement.buildId() == buildId; })
+}
+
</ins><span class="cx"> TimeSeries.prototype.findPointByMeasurementId = function (measurementId)
</span><span class="cx"> {
</span><span class="cx"> return this._series.find(function (point) { return point.measurement.id() == measurementId; });
</span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgpublicv2indexhtml"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/public/v2/index.html (179999 => 180000)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/public/v2/index.html        2015-02-12 18:42:21 UTC (rev 179999)
+++ trunk/Websites/perf.webkit.org/public/v2/index.html        2015-02-12 18:50:53 UTC (rev 180000)
</span><span class="lines">@@ -580,9 +580,9 @@
</span><span class="cx"> {{#each buildRequests}}
</span><span class="cx"> <tr>
</span><span class="cx"> <td>{{orderLabel}}</td>
</span><del>- <td>{{config}}</td>
- <td>{{#if url}}{{#link-to url}}{{statusLabel}}{{/link-to}}{{else}}{{statusLabel}}{{/if}}</td>
- <td>{{build}}</td>
</del><ins>+ <td>{{configLetter}}</td>
+ <td><a {{bind-attr href=url}}>{{statusLabel}}</a></td>
+ <td>{{buildNumber}}</td>
</ins><span class="cx"> <td>{{mean}}</td>
</span><span class="cx"> </tr>
</span><span class="cx"> {{/each}}
</span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgpublicv2manifestjs"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/public/v2/manifest.js (179999 => 180000)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/public/v2/manifest.js        2015-02-12 18:42:21 UTC (rev 179999)
+++ trunk/Websites/perf.webkit.org/public/v2/manifest.js        2015-02-12 18:50:53 UTC (rev 180000)
</span><span class="lines">@@ -279,10 +279,10 @@
</span><span class="cx"> dashboards.forEach(function (dashboard) { self._dashboardByName[dashboard.get('name')] = dashboard; });
</span><span class="cx"> this._defaultDashboardName = dashboards.length ? dashboards[0].get('name') : null;
</span><span class="cx"> },
</span><del>- fetchRunsWithPlatformAndMetric: function (store, platformId, metricId)
</del><ins>+ fetchRunsWithPlatformAndMetric: function (store, platformId, metricId, testGroupId)
</ins><span class="cx"> {
</span><span class="cx"> return Ember.RSVP.all([
</span><del>- RunsData.fetchRuns(platformId, metricId),
</del><ins>+ RunsData.fetchRuns(platformId, metricId, testGroupId),
</ins><span class="cx"> this.fetch(store),
</span><span class="cx"> ]).then(function (values) {
</span><span class="cx"> var runs = values[0];
</span><span class="lines">@@ -301,7 +301,20 @@
</span><span class="cx"> }[suffix];
</span><span class="cx"> var smallerIsBetter = unit != 'fps' && unit != '/s'; // Assume smaller is better for unit-less metrics.
</span><span class="cx">
</span><del>- return {platform: platform, metric: metric, runs: runs, unit: unit, useSI: unit == 'bytes', smallerIsBetter: smallerIsBetter};
</del><ins>+ var useSI = unit == 'bytes';
+ return {
+ platform: platform,
+ metric: metric,
+ data: {
+ current: runs.current.timeSeriesByCommitTime(),
+ baseline: runs.baseline ? runs.baseline.timeSeriesByCommitTime() : null,
+ target: runs.target ? runs.target.timeSeriesByCommitTime() : null,
+ unit: unit,
+ formatter: useSI ? d3.format('.4s') : d3.format('.4g'),
+ deltaFormatter: useSI ? d3.format('+.2s') : d3.format('+.2g'),
+ smallerIsBetter: smallerIsBetter,
+ }
+ };
</ins><span class="cx"> });
</span><span class="cx"> },
</span><span class="cx"> }).create();
</span></span></pre>
</div>
</div>
</body>
</html>