Diff
Modified: trunk/Websites/perf.webkit.org/ChangeLog (210625 => 210626)
--- trunk/Websites/perf.webkit.org/ChangeLog 2017-01-12 06:50:16 UTC (rev 210625)
+++ trunk/Websites/perf.webkit.org/ChangeLog 2017-01-12 07:18:28 UTC (rev 210626)
@@ -1,3 +1,66 @@
+2017-01-12 Ryosuke Niwa <[email protected]>
+
+ Hide the UI to trigger an A/B testing when there are no triggerables
+ https://bugs.webkit.org/show_bug.cgi?id=166964
+
+ Reviewed by Yusuke Suzuki.
+
+ Hide the "Start A/B Testing" button on analysis task pages instead of showing it and failing later
+ when the user tries to create one it with a TriggerableNotFound error.
+
+ Added the list of triggerables to the manifest JSON so that we can determine this condition without
+ having to fetch /api/triggerable for each analysis task as done in v2 UI.
+
+ * public/admin/reprocess-report.php:
+ * public/api/manifest.php:
+ * public/api/report.php:
+ * public/include/admin-header.php:
+ * public/include/manifest-generator.php: Moved from public/include/manifest.php.
+ (ManifestGenerator::generate):
+ (ManifestGenerator::triggerables): Added. Include the list of repositories this triggerable accepts
+ as well as the list of (test, platform) pairs on which this triggerable is available.
+ Use [testId, platformId] instead of a dictionary to reduce the file size.
+ * public/v3/components/customizable-test-group-form.js:
+ (CustomizableTestGroupForm): Removed this._disabled. This variable was used in TestGroupFrom to
+ disable the "Start A/B Testing" button when no range is selected but this ended up racy. Compute
+ the visibility of the button in render() function instead.
+ (CustomizableTestGroupForm.prototype.setRootSetMap):
+ (CustomizableTestGroupForm.prototype._submitted):
+ (CustomizableTestGroupForm.prototype.render): Hide the customize link and the button as needed.
+ The "Start A/B Testing" button must be hidden when either no range is selected or no title is typed.
+ "Customize" button must be hidden when no range is selected.
+ * public/v3/components/test-group-form.js:
+ (TestGroupForm): Removed _disabled since it's no longer used.
+ (TestGroupForm.prototype.setDisabled): Ditto.
+ (TestGroupForm.prototype.render): Ditto.
+ * public/v3/index.html: Include triggerable.js.
+ * public/v3/models/manifest.js:
+ (Manifest._didFetchManifest): Modernized. Create Triggerable objects from the manifest JSON.
+ * public/v3/models/triggerable.js: Added.
+ (Triggerable): Add this triggerable object to the static map of (test id, platform id) pair.
+ (Triggerable.prototype.acceptedRepositories): Added.
+ (Triggerable.findByTestConfiguration): Added. Finds a triggerable in the aforementioned static map.
+ * public/v3/pages/analysis-task-page.js:
+ (AnalysisTaskChartPane.prototype._updateStatus): Added. Re-render the page since time series data
+ points that were previously not available may have become available. The lack of this update was
+ causing a race condition in which the "Start A/B Testing" button for the charts is disabled even
+ after a group name had been specified because setRootSetMap was never called with a valid set.
+ (AnalysisTaskPage): Added this._triggerable.
+ (AnalysisTaskPage.prototype._didFetchTask): Find the triggerable now that we've fetched the task.
+ (AnalysisTaskPage.prototype.render): Hide the group view (the table of A/B testing results) entirely
+ when there are no groups to show. Also hide the forms to start A/B testing when there are no matching
+ triggerable, which is the main feature of this patch.
+ * server-tests/api-manifest.js: Added a test for including a list of triggerables in the manifest JSON.
+ * server-tests/resources/mock-data.js:
+ (MockData.resetV3Models): Reset Triggerable's static map.
+ * server-tests/tools-buildbot-triggerable-tests.js: Assert that Triggerable objects are constructed
+ with appropriate list of repositories and (test, platform) associations.
+ * tools/js/database.js:
+ (tableToPrefixMap): Added triggerable_repositories's prefix.
+ * tools/js/remote.js:
+ (RemoteAPI.prototype.getJSON): Log the entire response to stderr when JSON.parse fails to aid debugging.
+ * tools/js/v3-models.js: Import triggerable.js.
+
2017-01-11 Ryosuke Niwa <[email protected]>
fetch-from-remote doesn’t work with some websites
Modified: trunk/Websites/perf.webkit.org/public/admin/reprocess-report.php (210625 => 210626)
--- trunk/Websites/perf.webkit.org/public/admin/reprocess-report.php 2017-01-12 06:50:16 UTC (rev 210625)
+++ trunk/Websites/perf.webkit.org/public/admin/reprocess-report.php 2017-01-12 07:18:28 UTC (rev 210626)
@@ -1,7 +1,7 @@
<?php
require_once('../include/json-header.php');
-require_once('../include/manifest.php');
+require_once('../include/manifest-generator.php');
require_once('../include/report-processor.php');
$db = new Database;
Modified: trunk/Websites/perf.webkit.org/public/api/manifest.php (210625 => 210626)
--- trunk/Websites/perf.webkit.org/public/api/manifest.php 2017-01-12 06:50:16 UTC (rev 210625)
+++ trunk/Websites/perf.webkit.org/public/api/manifest.php 2017-01-12 07:18:28 UTC (rev 210626)
@@ -1,7 +1,7 @@
<?php
require_once('../include/json-header.php');
-require_once('../include/manifest.php');
+require_once('../include/manifest-generator.php');
function main() {
$db = new Database;
Modified: trunk/Websites/perf.webkit.org/public/api/report.php (210625 => 210626)
--- trunk/Websites/perf.webkit.org/public/api/report.php 2017-01-12 06:50:16 UTC (rev 210625)
+++ trunk/Websites/perf.webkit.org/public/api/report.php 2017-01-12 07:18:28 UTC (rev 210626)
@@ -1,7 +1,7 @@
<?php
require_once('../include/json-header.php');
-require_once('../include/manifest.php');
+require_once('../include/manifest-generator.php');
require_once('../include/report-processor.php');
function main($post_data) {
Modified: trunk/Websites/perf.webkit.org/public/include/admin-header.php (210625 => 210626)
--- trunk/Websites/perf.webkit.org/public/include/admin-header.php 2017-01-12 06:50:16 UTC (rev 210625)
+++ trunk/Websites/perf.webkit.org/public/include/admin-header.php 2017-01-12 07:18:28 UTC (rev 210626)
@@ -1,7 +1,7 @@
<?php
require_once('db.php');
-require_once('manifest.php');
+require_once('manifest-generator.php');
?><!DOCTYPE html>
<html>
Copied: trunk/Websites/perf.webkit.org/public/include/manifest-generator.php (from rev 210625, trunk/Websites/perf.webkit.org/public/include/manifest.php) (0 => 210626)
--- trunk/Websites/perf.webkit.org/public/include/manifest-generator.php (rev 0)
+++ trunk/Websites/perf.webkit.org/public/include/manifest-generator.php 2017-01-12 07:18:28 UTC (rev 210626)
@@ -0,0 +1,218 @@
+<?php
+
+class ManifestGenerator {
+ private $db;
+ private $manifest;
+
+ // FIXME: Compute this value from config.json
+ const MANIFEST_PATH = '../data/manifest.json';
+
+ function __construct($db) {
+ $this->db = $db;
+ }
+
+ function generate() {
+ $start_time = microtime(true);
+
+ $platform_table = $this->db->fetch_table('platforms');
+ $repositories_table = $this->db->fetch_table('repositories');
+
+ $repositories_with_commit = $this->db->query_and_fetch_all(
+ 'SELECT DISTINCT(commit_repository) FROM commits WHERE commit_reported IS TRUE');
+ if (!$repositories_with_commit)
+ $repositories_with_commit = array();
+
+ foreach ($repositories_with_commit as &$row)
+ $row = $row['commit_repository'];
+
+ $tests = (object)$this->tests();
+ $metrics = (object)$this->metrics();
+ $platforms = (object)$this->platforms($platform_table, false);
+ $dashboard = (object)$this->platforms($platform_table, true);
+ $repositories = (object)$this->repositories($repositories_table, $repositories_with_commit);
+
+ $this->manifest = array(
+ 'siteTitle' => config('siteTitle', 'Performance Dashboard'),
+ 'tests' => &$tests,
+ 'metrics' => &$metrics,
+ 'all' => &$platforms,
+ 'dashboard' => &$dashboard,
+ 'repositories' => &$repositories,
+ 'builders' => (object)$this->builders(),
+ 'bugTrackers' => (object)$this->bug_trackers($repositories_table),
+ 'triggerables'=> (object)$this->triggerables(),
+ 'dashboards' => (object)config('dashboards'),
+ 'summaryPages' => config('summaryPages'),
+ );
+
+ $this->manifest['elapsedTime'] = (microtime(true) - $start_time) * 1000;
+
+ return TRUE;
+ }
+
+ function manifest() { return $this->manifest; }
+
+ function store() {
+ return generate_data_file('manifest.json', json_encode($this->manifest));
+ }
+
+ private function tests() {
+ $tests = array();
+ $tests_table = $this->db->fetch_table('tests');
+ if (!$tests_table)
+ return $tests;
+ foreach ($tests_table as $test_row) {
+ $tests[$test_row['test_id']] = array(
+ 'name' => $test_row['test_name'],
+ 'url' => $test_row['test_url'],
+ 'parentId' => $test_row['test_parent'],
+ );
+ }
+ return $tests;
+ }
+
+ private function metrics() {
+ $metrics = array();
+ $metrics_table = $this->db->query_and_fetch_all('SELECT * FROM test_metrics LEFT JOIN aggregators ON metric_aggregator = aggregator_id');
+ if (!$metrics_table)
+ return $metrics;
+ foreach ($metrics_table as $row) {
+ $metrics[$row['metric_id']] = array(
+ 'name' => $row['metric_name'],
+ 'test' => $row['metric_test'],
+ 'aggregator' => $row['aggregator_name']);
+ }
+ return $metrics;
+ }
+
+ private function platforms($platform_table, $is_dashboard) {
+ $metrics = $this->db->query_and_fetch_all('SELECT config_metric AS metric_id, config_platform AS platform_id,
+ extract(epoch from max(config_runs_last_modified) at time zone \'utc\') * 1000 AS last_modified, bool_or(config_is_in_dashboard) AS in_dashboard
+ FROM test_configurations GROUP BY config_metric, config_platform ORDER BY config_platform');
+
+ $platform_metrics = array();
+
+ if ($metrics) {
+ $current_platform_entry = null;
+ foreach ($metrics as $metric_row) {
+ if ($is_dashboard && !Database::is_true($metric_row['in_dashboard']))
+ continue;
+
+ $platform_id = $metric_row['platform_id'];
+ if (!$current_platform_entry || $current_platform_entry['id'] != $platform_id) {
+ $current_platform_entry = &array_ensure_item_has_array($platform_metrics, $platform_id);
+ $current_platform_entry['id'] = $platform_id;
+ array_ensure_item_has_array($current_platform_entry, 'metrics');
+ array_ensure_item_has_array($current_platform_entry, 'last_modified');
+ }
+
+ array_push($current_platform_entry['metrics'], $metric_row['metric_id']);
+ array_push($current_platform_entry['last_modified'], intval($metric_row['last_modified']));
+ }
+ }
+ $configurations = array();
+
+ $platforms = array();
+ if ($platform_table) {
+ foreach ($platform_table as $platform_row) {
+ if (Database::is_true($platform_row['platform_hidden']))
+ continue;
+ $id = $platform_row['platform_id'];
+ if (array_key_exists($id, $platform_metrics)) {
+ $platforms[$id] = array(
+ 'name' => $platform_row['platform_name'],
+ 'metrics' => $platform_metrics[$id]['metrics'],
+ 'lastModified' => $platform_metrics[$id]['last_modified']);
+ }
+ }
+ }
+ return $platforms;
+ }
+
+ private function repositories($repositories_table, $repositories_with_commit) {
+ $repositories = array();
+ if (!$repositories_table)
+ return $repositories;
+ foreach ($repositories_table as $row) {
+ $repositories[$row['repository_id']] = array(
+ 'name' => $row['repository_name'],
+ 'url' => $row['repository_url'],
+ 'blameUrl' => $row['repository_blame_url'],
+ 'hasReportedCommits' => in_array($row['repository_id'], $repositories_with_commit));
+ }
+
+ return $repositories;
+ }
+
+ private function builders() {
+ $builders_table = $this->db->fetch_table('builders');
+ if (!$builders_table)
+ return array();
+ $builders = array();
+ foreach ($builders_table as $row)
+ $builders[$row['builder_id']] = array('name' => $row['builder_name'], 'buildUrl' => $row['builder_build_url']);
+
+ return $builders;
+ }
+
+ private function bug_trackers($repositories_table) {
+ $tracker_id_to_repositories = array();
+ $tracker_repositories_table = $this->db->fetch_table('tracker_repositories');
+ if ($tracker_repositories_table) {
+ foreach ($tracker_repositories_table as $row) {
+ array_push(array_ensure_item_has_array($tracker_id_to_repositories, $row['tracrepo_tracker']),
+ $row['tracrepo_repository']);
+ }
+ }
+
+ $bug_trackers = array();
+ $bug_trackers_table = $this->db->fetch_table('bug_trackers');
+ if ($bug_trackers_table) {
+ foreach ($bug_trackers_table as $row) {
+ $bug_trackers[$row['tracker_id']] = array(
+ 'name' => $row['tracker_name'],
+ 'bugUrl' => $row['tracker_bug_url'],
+ 'newBugUrl' => $row['tracker_new_bug_url'],
+ 'repositories' => array_get($tracker_id_to_repositories, $row['tracker_id']));
+ }
+ }
+
+ return $bug_trackers;
+ }
+
+ private function triggerables() {
+
+ $triggerables = $this->db->fetch_table('build_triggerables');
+ if (!$triggerables)
+ return array();
+
+ $id_to_triggerable = array();
+ foreach ($triggerables as $row) {
+ $id = $row['triggerable_id'];
+ $id_to_triggerable[$id] = array(
+ 'name' => $row['triggerable_name'],
+ 'acceptedRepositories' => array(),
+ 'configurations' => array());
+ }
+
+ $repository_map = $this->db->fetch_table('triggerable_repositories');
+ if ($repository_map) {
+ foreach ($repository_map as $row) {
+ $triggerable = &$id_to_triggerable[$row['trigrepo_triggerable']];
+ array_push($triggerable['acceptedRepositories'], $row['trigrepo_repository']);
+ }
+ }
+
+ $configuration_map = $this->db->fetch_table('triggerable_configurations');
+ if ($configuration_map) {
+ foreach ($configuration_map as $row) {
+ $triggerable = &$id_to_triggerable[$row['trigconfig_triggerable']];
+ array_push($triggerable['configurations'], array($row['trigconfig_test'], $row['trigconfig_platform']));
+ }
+ }
+
+ return $id_to_triggerable;
+ }
+}
+
+?>
Deleted: trunk/Websites/perf.webkit.org/public/include/manifest.php (210625 => 210626)
--- trunk/Websites/perf.webkit.org/public/include/manifest.php 2017-01-12 06:50:16 UTC (rev 210625)
+++ trunk/Websites/perf.webkit.org/public/include/manifest.php 2017-01-12 07:18:28 UTC (rev 210626)
@@ -1,183 +0,0 @@
-<?php
-
-class ManifestGenerator {
- private $db;
- private $manifest;
-
- // FIXME: Compute this value from config.json
- const MANIFEST_PATH = '../data/manifest.json';
-
- function __construct($db) {
- $this->db = $db;
- }
-
- function generate() {
- $start_time = microtime(true);
-
- $platform_table = $this->db->fetch_table('platforms');
- $repositories_table = $this->db->fetch_table('repositories');
-
- $repositories_with_commit = $this->db->query_and_fetch_all(
- 'SELECT DISTINCT(commit_repository) FROM commits WHERE commit_reported IS TRUE');
- if (!$repositories_with_commit)
- $repositories_with_commit = array();
-
- foreach ($repositories_with_commit as &$row)
- $row = $row['commit_repository'];
-
- $tests = (object)$this->tests();
- $metrics = (object)$this->metrics();
- $platforms = (object)$this->platforms($platform_table, false);
- $dashboard = (object)$this->platforms($platform_table, true);
- $repositories = (object)$this->repositories($repositories_table, $repositories_with_commit);
-
- $this->manifest = array(
- 'siteTitle' => config('siteTitle', 'Performance Dashboard'),
- 'tests' => &$tests,
- 'metrics' => &$metrics,
- 'all' => &$platforms,
- 'dashboard' => &$dashboard,
- 'repositories' => &$repositories,
- 'builders' => (object)$this->builders(),
- 'bugTrackers' => (object)$this->bug_trackers($repositories_table),
- 'dashboards' => (object)config('dashboards'),
- 'summaryPages' => config('summaryPages'),
- );
-
- $this->manifest['elapsedTime'] = (microtime(true) - $start_time) * 1000;
-
- return TRUE;
- }
-
- function manifest() { return $this->manifest; }
-
- function store() {
- return generate_data_file('manifest.json', json_encode($this->manifest));
- }
-
- private function tests() {
- $tests = array();
- $tests_table = $this->db->fetch_table('tests');
- if (!$tests_table)
- return $tests;
- foreach ($tests_table as $test_row) {
- $tests[$test_row['test_id']] = array(
- 'name' => $test_row['test_name'],
- 'url' => $test_row['test_url'],
- 'parentId' => $test_row['test_parent'],
- );
- }
- return $tests;
- }
-
- private function metrics() {
- $metrics = array();
- $metrics_table = $this->db->query_and_fetch_all('SELECT * FROM test_metrics LEFT JOIN aggregators ON metric_aggregator = aggregator_id');
- if (!$metrics_table)
- return $metrics;
- foreach ($metrics_table as $row) {
- $metrics[$row['metric_id']] = array(
- 'name' => $row['metric_name'],
- 'test' => $row['metric_test'],
- 'aggregator' => $row['aggregator_name']);
- }
- return $metrics;
- }
-
- private function platforms($platform_table, $is_dashboard) {
- $metrics = $this->db->query_and_fetch_all('SELECT config_metric AS metric_id, config_platform AS platform_id,
- extract(epoch from max(config_runs_last_modified)) * 1000 AS last_modified, bool_or(config_is_in_dashboard) AS in_dashboard
- FROM test_configurations GROUP BY config_metric, config_platform ORDER BY config_platform');
-
- $platform_metrics = array();
-
- if ($metrics) {
- $current_platform_entry = null;
- foreach ($metrics as $metric_row) {
- if ($is_dashboard && !Database::is_true($metric_row['in_dashboard']))
- continue;
-
- $platform_id = $metric_row['platform_id'];
- if (!$current_platform_entry || $current_platform_entry['id'] != $platform_id) {
- $current_platform_entry = &array_ensure_item_has_array($platform_metrics, $platform_id);
- $current_platform_entry['id'] = $platform_id;
- array_ensure_item_has_array($current_platform_entry, 'metrics');
- array_ensure_item_has_array($current_platform_entry, 'last_modified');
- }
-
- array_push($current_platform_entry['metrics'], $metric_row['metric_id']);
- array_push($current_platform_entry['last_modified'], intval($metric_row['last_modified']));
- }
- }
- $configurations = array();
-
- $platforms = array();
- if ($platform_table) {
- foreach ($platform_table as $platform_row) {
- if (Database::is_true($platform_row['platform_hidden']))
- continue;
- $id = $platform_row['platform_id'];
- if (array_key_exists($id, $platform_metrics)) {
- $platforms[$id] = array(
- 'name' => $platform_row['platform_name'],
- 'metrics' => $platform_metrics[$id]['metrics'],
- 'lastModified' => $platform_metrics[$id]['last_modified']);
- }
- }
- }
- return $platforms;
- }
-
- private function repositories($repositories_table, $repositories_with_commit) {
- $repositories = array();
- if (!$repositories_table)
- return $repositories;
- foreach ($repositories_table as $row) {
- $repositories[$row['repository_id']] = array(
- 'name' => $row['repository_name'],
- 'url' => $row['repository_url'],
- 'blameUrl' => $row['repository_blame_url'],
- 'hasReportedCommits' => in_array($row['repository_id'], $repositories_with_commit));
- }
-
- return $repositories;
- }
-
- private function builders() {
- $builders_table = $this->db->fetch_table('builders');
- if (!$builders_table)
- return array();
- $builders = array();
- foreach ($builders_table as $row)
- $builders[$row['builder_id']] = array('name' => $row['builder_name'], 'buildUrl' => $row['builder_build_url']);
-
- return $builders;
- }
-
- private function bug_trackers($repositories_table) {
- $tracker_id_to_repositories = array();
- $tracker_repositories_table = $this->db->fetch_table('tracker_repositories');
- if ($tracker_repositories_table) {
- foreach ($tracker_repositories_table as $row) {
- array_push(array_ensure_item_has_array($tracker_id_to_repositories, $row['tracrepo_tracker']),
- $row['tracrepo_repository']);
- }
- }
-
- $bug_trackers = array();
- $bug_trackers_table = $this->db->fetch_table('bug_trackers');
- if ($bug_trackers_table) {
- foreach ($bug_trackers_table as $row) {
- $bug_trackers[$row['tracker_id']] = array(
- 'name' => $row['tracker_name'],
- 'bugUrl' => $row['tracker_bug_url'],
- 'newBugUrl' => $row['tracker_new_bug_url'],
- 'repositories' => array_get($tracker_id_to_repositories, $row['tracker_id']));
- }
- }
-
- return $bug_trackers;
- }
-}
-
-?>
Modified: trunk/Websites/perf.webkit.org/public/v3/components/customizable-test-group-form.js (210625 => 210626)
--- trunk/Websites/perf.webkit.org/public/v3/components/customizable-test-group-form.js 2017-01-12 06:50:16 UTC (rev 210625)
+++ trunk/Websites/perf.webkit.org/public/v3/components/customizable-test-group-form.js 2017-01-12 07:18:28 UTC (rev 210626)
@@ -5,9 +5,10 @@
{
super('customizable-test-group-form');
this._rootSetMap = null;
- this._disabled = true;
this._renderedRepositorylist = null;
this._customized = false;
+ this._nameControl = this.content().querySelector('.name');
+ this._nameControl._oninput_ = this.render.bind(this);
this.content().querySelector('a')._onclick_ = this._customize.bind(this);
}
@@ -15,13 +16,12 @@
{
this._rootSetMap = map;
this._customized = false;
- this.setDisabled(!map);
}
_submitted()
{
if (this._startCallback)
- this._startCallback(this.content().querySelector('.name').value, this._repetitionCount, this._computeRootSetMap());
+ this._startCallback(this._nameControl.value, this._repetitionCount, this._computeRootSetMap());
}
_customize(event)
@@ -56,13 +56,15 @@
render()
{
super.render();
- this.content().querySelector('.customize-link').style.display = this._disabled ? 'none' : null;
+ var map = this._rootSetMap;
+ this.content().querySelector('button').disabled = !(map && this._nameControl.value);
+ this.content().querySelector('.customize-link').style.display = !map ? 'none' : null;
+
if (!this._customized) {
this.renderReplace(this.content().querySelector('.custom-table-container'), []);
return;
}
- var map = this._rootSetMap;
console.assert(map);
var repositorySet = new Set;
Modified: trunk/Websites/perf.webkit.org/public/v3/components/test-group-form.js (210625 => 210626)
--- trunk/Websites/perf.webkit.org/public/v3/components/test-group-form.js 2017-01-12 06:50:16 UTC (rev 210625)
+++ trunk/Websites/perf.webkit.org/public/v3/components/test-group-form.js 2017-01-12 07:18:28 UTC (rev 210626)
@@ -5,7 +5,6 @@
{
super(name || 'test-group-form');
this._startCallback = null;
- this._disabled = false;
this._label = undefined;
this._repetitionCount = 4;
@@ -24,7 +23,6 @@
}
setStartCallback(callback) { this._startCallback = callback; }
- setDisabled(disabled) { this._disabled = !!disabled; }
setLabel(label) { this._label = label; }
setRepetitionCount(count) { this._repetitionCount = count; }
@@ -33,7 +31,6 @@
var button = this.content().querySelector('button');
if (this._label)
button.textContent = this._label;
- button.disabled = this._disabled;
this._repetitionCountControl.value = this._repetitionCount;
}
Modified: trunk/Websites/perf.webkit.org/public/v3/index.html (210625 => 210626)
--- trunk/Websites/perf.webkit.org/public/v3/index.html 2017-01-12 06:50:16 UTC (rev 210625)
+++ trunk/Websites/perf.webkit.org/public/v3/index.html 2017-01-12 07:18:28 UTC (rev 210626)
@@ -63,6 +63,7 @@
<script src=""
<script src=""
<script src=""
+ <script src=""
<script src=""
<script src=""
Modified: trunk/Websites/perf.webkit.org/public/v3/models/manifest.js (210625 => 210626)
--- trunk/Websites/perf.webkit.org/public/v3/models/manifest.js 2017-01-12 06:50:16 UTC (rev 210625)
+++ trunk/Websites/perf.webkit.org/public/v3/models/manifest.js 2017-01-12 07:18:28 UTC (rev 210626)
@@ -13,35 +13,41 @@
{
Instrumentation.startMeasuringTime('Manifest', '_didFetchManifest');
- var tests = [];
- var testParentMap = {};
- for (var testId in rawResponse.tests)
+ const tests = [];
+ const testParentMap = {};
+ for (let testId in rawResponse.tests)
tests.push(new Test(testId, rawResponse.tests[testId]));
function buildObjectsFromIdMap(idMap, constructor, resolver) {
- for (var id in idMap) {
+ for (let id in idMap) {
if (resolver)
resolver(idMap[id]);
new constructor(id, idMap[id]);
}
}
- buildObjectsFromIdMap(rawResponse.metrics, Metric, function (raw) {
+
+ buildObjectsFromIdMap(rawResponse.metrics, Metric, (raw) => {
raw.test = Test.findById(raw.test);
});
- buildObjectsFromIdMap(rawResponse.all, Platform, function (raw) {
+ buildObjectsFromIdMap(rawResponse.all, Platform, (raw) => {
raw.lastModifiedByMetric = {};
- raw.lastModified.forEach(function (lastModified, index) {
+ raw.lastModified.forEach((lastModified, index) => {
raw.lastModifiedByMetric[raw.metrics[index]] = lastModified;
});
- raw.metrics = raw.metrics.map(function (id) { return Metric.findById(id); });
+ raw.metrics = raw.metrics.map((id) => { return Metric.findById(id); });
});
buildObjectsFromIdMap(rawResponse.builders, Builder);
buildObjectsFromIdMap(rawResponse.repositories, Repository);
- buildObjectsFromIdMap(rawResponse.bugTrackers, BugTracker, function (raw) {
+ buildObjectsFromIdMap(rawResponse.bugTrackers, BugTracker, (raw) => {
if (raw.repositories)
- raw.repositories = raw.repositories.map(function (id) { return Repository.findById(id); });
+ raw.repositories = raw.repositories.map((id) => { return Repository.findById(id); });
});
+ buildObjectsFromIdMap(rawResponse.triggerables, Triggerable, (raw) => {
+ raw.acceptedRepositories = raw.acceptedRepositories.map((repositoryId) => {
+ return Repository.findById(repositoryId);
+ });
+ });
Instrumentation.endMeasuringTime('Manifest', '_didFetchManifest');
Added: trunk/Websites/perf.webkit.org/public/v3/models/triggerable.js (0 => 210626)
--- trunk/Websites/perf.webkit.org/public/v3/models/triggerable.js (rev 0)
+++ trunk/Websites/perf.webkit.org/public/v3/models/triggerable.js 2017-01-12 07:18:28 UTC (rev 210626)
@@ -0,0 +1,37 @@
+class Triggerable extends LabeledObject {
+
+ constructor(id, object)
+ {
+ super(id, object);
+ this._name = object.name;
+ this._acceptedRepositories = object.acceptedRepositories;
+ this._configurationList = object.configurations;
+
+ let configurationMap = this.ensureNamedStaticMap('testConfigurations');
+ for (const config of object.configurations) {
+ const [testId, platformId] = config;
+ const key = `${testId}-${platformId}`;
+ console.assert(!(key in configurationMap));
+ configurationMap[key] = this;
+ }
+ }
+
+ acceptedRepositories() { return this._acceptedRepositories; }
+
+ static findByTestConfiguration(test, platform)
+ {
+ let configurationMap = this.ensureNamedStaticMap('testConfigurations');
+ if (!configurationMap)
+ return null;
+ for (; test; test = test.parentTest()) {
+ const key = `${test.id()}-${platform.id()}`;
+ if (key in configurationMap)
+ return configurationMap[key];
+ }
+ return null;
+ }
+
+}
+
+if (typeof module != 'undefined')
+ module.exports.Triggerable = Triggerable;
Modified: trunk/Websites/perf.webkit.org/public/v3/pages/analysis-task-page.js (210625 => 210626)
--- trunk/Websites/perf.webkit.org/public/v3/pages/analysis-task-page.js 2017-01-12 06:50:16 UTC (rev 210625)
+++ trunk/Websites/perf.webkit.org/public/v3/pages/analysis-task-page.js 2017-01-12 07:18:28 UTC (rev 210626)
@@ -16,6 +16,12 @@
this._page._chartSelectionDidChange();
}
+ _updateStatus()
+ {
+ super._updateStatus();
+ this._page.render();
+ }
+
selectedPoints()
{
var selection = this._mainChart ? this._mainChart.currentSelection() : null;
@@ -33,6 +39,7 @@
{
super('Analysis Task');
this._task = null;
+ this._triggerable = null;
this._relatedTasks = null;
this._testGroups = null;
this._renderedTestGroups = null;
@@ -120,20 +127,22 @@
console.assert(!this._task);
this._task = task;
- var platform = task.platform();
- var metric = task.metric();
- var lastModified = platform.lastModified(metric);
+ const platform = task.platform();
+ const metric = task.metric();
+ const lastModified = platform.lastModified(metric);
+ this._triggerable = Triggerable.findByTestConfiguration(metric.test(), platform);
+
this._measurementSet = MeasurementSet.findSet(platform.id(), metric.id(), lastModified);
this._measurementSet.fetchBetween(task.startTime(), task.endTime(), this._didFetchMeasurement.bind(this));
- var formatter = metric.makeFormatter(4);
+ const formatter = metric.makeFormatter(4);
this._analysisResultsViewer.setValueFormatter(formatter);
this._testGroupResultsTable.setValueFormatter(formatter);
this._chartPane.configure(platform.id(), metric.id());
- var domain = ChartsPage.createDomainForAnalysisTask(task);
+ const domain = ChartsPage.createDomainForAnalysisTask(task);
this._chartPane.setOverviewDomain(domain[0], domain[1]);
this._chartPane.setMainDomain(domain[0], domain[1]);
@@ -265,7 +274,7 @@
this.content().querySelector('.analysis-task-status').style.display = this._task ? null : 'none';
this.content().querySelector('.overview-chart').style.display = this._task ? null : 'none';
- this.content().querySelector('.test-group-view').style.display = this._task ? null : 'none';
+ this.content().querySelector('.test-group-view').style.display = this._task && this._testGroups && this._testGroups.length ? null : 'none';
this._taskNameLabel.render();
if (this._relatedTasks && this._task) {
@@ -288,6 +297,7 @@
var b = selectedRange['B'];
this._newTestGroupFormForViewer.setRootSetMap(a && b ? {'A': a.rootSet(), 'B': b.rootSet()} : null);
this._newTestGroupFormForViewer.render();
+ this._newTestGroupFormForViewer.element().style.display = this._triggerable ? null : 'none';
this._renderTestGroupList();
this._renderTestGroupDetails();
@@ -299,6 +309,7 @@
this._newTestGroupFormForChart.setRootSetMap(points && points.length >= 2 ?
{'A': points[0].rootSet(), 'B': points[points.length - 1].rootSet()} : null);
this._newTestGroupFormForChart.render();
+ this._newTestGroupFormForChart.element().style.display = this._triggerable ? null : 'none';
this._analysisResultsViewer.setCurrentTestGroup(this._currentTestGroup);
this._analysisResultsViewer.render();
Modified: trunk/Websites/perf.webkit.org/server-tests/api-manifest.js (210625 => 210626)
--- trunk/Websites/perf.webkit.org/server-tests/api-manifest.js 2017-01-12 06:50:16 UTC (rev 210625)
+++ trunk/Websites/perf.webkit.org/server-tests/api-manifest.js 2017-01-12 07:18:28 UTC (rev 210626)
@@ -18,7 +18,7 @@
it("should generate an empty manifest when database is empty", function (done) {
TestServer.remoteAPI().getJSON('/api/manifest').then(function (manifest) {
assert.deepEqual(Object.keys(manifest).sort(), ['all', 'bugTrackers', 'builders', 'dashboard', 'dashboards',
- 'elapsedTime', 'metrics', 'repositories', 'siteTitle', 'status', 'summaryPages', 'tests']);
+ 'elapsedTime', 'metrics', 'repositories', 'siteTitle', 'status', 'summaryPages', 'tests', 'triggerables']);
assert.equal(typeof(manifest.elapsedTime), 'number');
delete manifest.elapsedTime;
@@ -33,6 +33,7 @@
metrics: {},
repositories: {},
tests: {},
+ triggerables: {},
summaryPages: [],
status: 'OK'
});
@@ -275,4 +276,78 @@
}).catch(done);
});
+ it("should generate manifest with triggerables", function (done) {
+ let db = TestServer.database();
+ db.connect();
+ Promise.all([
+ db.insert('repositories', {id: 11, name: 'WebKit', url: 'https://trac.webkit.org/$1'}),
+ db.insert('repositories', {id: 9, name: 'OS X'}),
+ db.insert('build_triggerables', {id: 200, name: 'build.webkit.org'}),
+ db.insert('build_triggerables', {id: 201, name: 'ios-build.webkit.org'}),
+ db.insert('tests', {id: 1, name: 'SomeTest'}),
+ db.insert('tests', {id: 2, name: 'SomeOtherTest'}),
+ db.insert('tests', {id: 3, name: 'ChildTest', parent: 1}),
+ db.insert('platforms', {id: 23, name: 'iOS 9 iPhone 5s'}),
+ db.insert('platforms', {id: 46, name: 'Trunk Mavericks'}),
+ db.insert('test_metrics', {id: 5, test: 1, name: 'Time'}),
+ db.insert('test_metrics', {id: 8, test: 2, name: 'FrameRate'}),
+ db.insert('test_metrics', {id: 9, test: 3, name: 'Time'}),
+ db.insert('test_configurations', {id: 101, metric: 5, platform: 46, type: 'current'}),
+ db.insert('test_configurations', {id: 102, metric: 8, platform: 46, type: 'current'}),
+ db.insert('test_configurations', {id: 103, metric: 9, platform: 46, type: 'current'}),
+ db.insert('test_configurations', {id: 104, metric: 5, platform: 23, type: 'current'}),
+ db.insert('test_configurations', {id: 105, metric: 8, platform: 23, type: 'current'}),
+ db.insert('test_configurations', {id: 106, metric: 9, platform: 23, type: 'current'}),
+ db.insert('triggerable_repositories', {triggerable: 200, repository: 11}),
+ db.insert('triggerable_repositories', {triggerable: 201, repository: 11}),
+ db.insert('triggerable_configurations', {triggerable: 200, test: 1, platform: 46}),
+ db.insert('triggerable_configurations', {triggerable: 200, test: 2, platform: 46}),
+ db.insert('triggerable_configurations', {triggerable: 201, test: 1, platform: 23}),
+ db.insert('triggerable_configurations', {triggerable: 201, test: 2, platform: 23}),
+ ]).then(function () {
+ return Manifest.fetch();
+ }).then(function () {
+ let webkit = Repository.findById(11);
+ assert.equal(webkit.name(), 'WebKit');
+ assert.equal(webkit.urlForRevision(123), 'https://trac.webkit.org/123');
+
+ let osx = Repository.findById(9);
+ assert.equal(osx.name(), 'OS X');
+
+ let someTest = Test.findById(1);
+ assert.equal(someTest.name(), 'SomeTest');
+
+ let someOtherTest = Test.findById(2);
+ assert.equal(someOtherTest.name(), 'SomeOtherTest');
+
+ let childTest = Test.findById(3);
+ assert.equal(childTest.name(), 'ChildTest');
+
+ let ios9iphone5s = Platform.findById(23);
+ assert.equal(ios9iphone5s.name(), 'iOS 9 iPhone 5s');
+
+ let mavericks = Platform.findById(46);
+ assert.equal(mavericks.name(), 'Trunk Mavericks');
+
+ assert.equal(Triggerable.all().length, 2);
+
+ let osxTriggerable = Triggerable.findByTestConfiguration(someTest, mavericks);
+ assert.equal(osxTriggerable.name(), 'build.webkit.org');
+ assert.deepEqual(osxTriggerable.acceptedRepositories(), [webkit]);
+
+ assert.equal(Triggerable.findByTestConfiguration(someOtherTest, mavericks), osxTriggerable);
+ assert.equal(Triggerable.findByTestConfiguration(childTest, mavericks), osxTriggerable);
+
+ let iosTriggerable = Triggerable.findByTestConfiguration(someOtherTest, ios9iphone5s);
+ assert.notEqual(iosTriggerable, osxTriggerable);
+ assert.equal(iosTriggerable.name(), 'ios-build.webkit.org');
+ assert.deepEqual(iosTriggerable.acceptedRepositories(), [webkit]);
+
+ assert.equal(Triggerable.findByTestConfiguration(someOtherTest, ios9iphone5s), iosTriggerable);
+ assert.equal(Triggerable.findByTestConfiguration(childTest, ios9iphone5s), iosTriggerable);
+
+ done();
+ }).catch(done);
+ });
+
});
Modified: trunk/Websites/perf.webkit.org/server-tests/resources/mock-data.js (210625 => 210626)
--- trunk/Websites/perf.webkit.org/server-tests/resources/mock-data.js 2017-01-12 06:50:16 UTC (rev 210625)
+++ trunk/Websites/perf.webkit.org/server-tests/resources/mock-data.js 2017-01-12 07:18:28 UTC (rev 210626)
@@ -15,6 +15,7 @@
RootSet.clearStaticMap();
Test.clearStaticMap();
TestGroup.clearStaticMap();
+ Triggerable.clearStaticMap();
},
someTestId() { return 200; },
somePlatformId() { return 65; },
Modified: trunk/Websites/perf.webkit.org/server-tests/tools-buildbot-triggerable-tests.js (210625 => 210626)
--- trunk/Websites/perf.webkit.org/server-tests/tools-buildbot-triggerable-tests.js 2017-01-12 06:50:16 UTC (rev 210625)
+++ trunk/Websites/perf.webkit.org/server-tests/tools-buildbot-triggerable-tests.js 2017-01-12 07:18:28 UTC (rev 210626)
@@ -910,23 +910,46 @@
it('should update available triggerables', function (done) {
let db = TestServer.database();
- MockData.addMockData(db).then(function () {
+ MockData.addMockData(db).then(() => {
return Manifest.fetch();
- }).then(function () {
+ }).then(() => {
return db.selectAll('triggerable_configurations', 'test');
- }).then(function (configurations) {
+ }).then((configurations) => {
assert.equal(configurations.length, 0);
+ assert.equal(Triggerable.all().length, 1);
+
+ let triggerable = Triggerable.all()[0];
+ assert.equal(triggerable.name(), 'build-webkit');
+ assert.deepEqual(triggerable.acceptedRepositories(), []);
+
+ let test = Test.findById(MockData.someTestId());
+ let platform = Platform.findById(MockData.somePlatformId());
+ assert.equal(Triggerable.findByTestConfiguration(test, platform), null);
+
let config = MockData.mockTestSyncConfigWithSingleBuilder();
let logger = new MockLogger;
let slaveInfo = {name: 'sync-slave', password: 'password'};
- let triggerable = new BuildbotTriggerable(config, TestServer.remoteAPI(), MockRemoteAPI, slaveInfo, logger);
- return triggerable.updateTriggerable();
- }).then(function () {
+ let buildbotTriggerable = new BuildbotTriggerable(config, TestServer.remoteAPI(), MockRemoteAPI, slaveInfo, logger);
+ return buildbotTriggerable.updateTriggerable();
+ }).then(() => {
+ MockData.resetV3Models();
+ assert.equal(Triggerable.all().length, 0);
+ return TestServer.remoteAPI().getJSON('/api/manifest');
+ }).then((manifestContent) => {
+ Manifest._didFetchManifest(manifestContent);
return db.selectAll('triggerable_configurations', 'test');
- }).then(function (configurations) {
+ }).then((configurations) => {
assert.equal(configurations.length, 1);
assert.equal(configurations[0].test, MockData.someTestId());
assert.equal(configurations[0].platform, MockData.somePlatformId());
+
+ assert.equal(Triggerable.all().length, 1);
+
+ let test = Test.findById(MockData.someTestId());
+ let platform = Platform.findById(MockData.somePlatformId());
+ let triggerable = Triggerable.findByTestConfiguration(test, platform);
+ assert.equal(triggerable.name(), 'build-webkit');
+
done();
}).catch(done);
});
Modified: trunk/Websites/perf.webkit.org/tools/js/database.js (210625 => 210626)
--- trunk/Websites/perf.webkit.org/tools/js/database.js 2017-01-12 06:50:16 UTC (rev 210625)
+++ trunk/Websites/perf.webkit.org/tools/js/database.js 2017-01-12 07:18:28 UTC (rev 210626)
@@ -143,6 +143,7 @@
'tests': 'test',
'tracker_repositories': 'tracrepo',
'triggerable_configurations': 'trigconfig',
+ 'triggerable_repositories': 'trigrepo',
'platforms': 'platform',
'reports': 'report',
'repositories': 'repository',
Modified: trunk/Websites/perf.webkit.org/tools/js/remote.js (210625 => 210626)
--- trunk/Websites/perf.webkit.org/tools/js/remote.js 2017-01-12 06:50:16 UTC (rev 210625)
+++ trunk/Websites/perf.webkit.org/tools/js/remote.js 2017-01-12 07:18:28 UTC (rev 210626)
@@ -56,7 +56,12 @@
getJSON(path)
{
return this.sendHttpRequest(path, 'GET', null, null).then(function (result) {
- return JSON.parse(result.responseText);
+ try {
+ return JSON.parse(result.responseText);
+ } catch (error) {
+ console.error(result.responseText);
+ throw error;
+ }
});
}
Modified: trunk/Websites/perf.webkit.org/tools/js/v3-models.js (210625 => 210626)
--- trunk/Websites/perf.webkit.org/tools/js/v3-models.js 2017-01-12 06:50:16 UTC (rev 210625)
+++ trunk/Websites/perf.webkit.org/tools/js/v3-models.js 2017-01-12 07:18:28 UTC (rev 210626)
@@ -27,6 +27,7 @@
importFromV3('models/test.js', 'Test');
importFromV3('models/test-group.js', 'TestGroup');
importFromV3('models/time-series.js', 'TimeSeries');
+importFromV3('models/triggerable.js', 'Triggerable');
importFromV3('privileged-api.js', 'PrivilegedAPI');
importFromV3('instrumentation.js', 'Instrumentation');