| Index: Tools/GardeningServer/model/ct-failures.html
|
| diff --git a/Tools/GardeningServer/model/ct-failures.html b/Tools/GardeningServer/model/ct-failures.html
|
| deleted file mode 100644
|
| index 9f08a2e842ad73d84b794fd16624341425898987..0000000000000000000000000000000000000000
|
| --- a/Tools/GardeningServer/model/ct-failures.html
|
| +++ /dev/null
|
| @@ -1,258 +0,0 @@
|
| -<!--
|
| -Copyright 2014 The Chromium Authors. All rights reserved.
|
| -Use of this source code is governed by a BSD-style license that can be
|
| -found in the LICENSE file.
|
| --->
|
| -
|
| -<link rel="import" href="../lib/net.html">
|
| -<link rel="import" href="../lib/update-util.html">
|
| -<link rel="import" href="ct-builder-failure.html">
|
| -<link rel="import" href="ct-step-failure.html">
|
| -<link rel="import" href="ct-failure-group.html">
|
| -<link rel="import" href="ct-builder-failure-group-data.html">
|
| -<link rel="import" href="ct-master-failure.html">
|
| -<link rel="import" href="ct-master-failure-group-data.html">
|
| -<link rel="import" href="ct-step-failure-group-data.html">
|
| -<link rel="import" href="ct-trooper-failure-group-data.html">
|
| -<link rel="import" href="ct-commit-list.html">
|
| -
|
| -<script>
|
| -function CTFailures(commitLog) {
|
| - this.commitLog = commitLog;
|
| - // Maps a tree id to an array of CTFailureGroups within that tree.
|
| - this.failures = null;
|
| - this.lastUpdateDate = null;
|
| -}
|
| -
|
| -(function() {
|
| -'use strict';
|
| -
|
| -// FIXME: This could potentially move onto CTStepFailureGroupData as it isn't relevant to
|
| -// trooper failures.
|
| -// Reverse sorting order, if a > b, return a negative number.
|
| -CTFailures.prototype._failureByTreeListComparator = function(tree, a, b) {
|
| - if (tree === undefined)
|
| - tree = 'chromium';
|
| -
|
| - // Always bubble master alerts to the top
|
| - if (a.category =='master') {
|
| - if (b.category == 'master')
|
| - return 0;
|
| - return -1;
|
| - } else if (b.category == 'master') {
|
| - return 1;
|
| - }
|
| -
|
| - if (!a.data.commitList)
|
| - return 1;
|
| - if (!b.data.commitList)
|
| - return -1;
|
| -
|
| - var rev_a = a.data.commitList.revisions;
|
| - var rev_b = b.data.commitList.revisions;
|
| -
|
| - if (!rev_a || !Object.keys(rev_a).length) {
|
| - if (!rev_b || !Object.keys(rev_b).length)
|
| - return 0;
|
| - return 1;
|
| - } else if (!rev_b || !Object.keys(rev_b).length) {
|
| - return -1;
|
| - }
|
| -
|
| - // Prioritize the tree's revision, if they are unequal (else, fallback below)
|
| - if (rev_a[tree] && rev_b[tree] &&
|
| - rev_a[tree].last() != rev_b[tree].last()) {
|
| - return rev_b[tree].last() - rev_a[tree].last();
|
| - }
|
| -
|
| - // Compare other revisions in alphabetical order.
|
| - var keys = Object.keys(rev_a).sort();
|
| - for (var i = 0; i < keys.length; i++) {
|
| - if (keys[i] == tree) // Already taken care of, above.
|
| - continue;
|
| -
|
| - var a_list = rev_a[keys[i]];
|
| - var b_list = rev_b[keys[i]];
|
| - if (!b_list)
|
| - return -1;
|
| -
|
| - if (a_list.last() != b_list.last())
|
| - return b_list.last() - a_list.last();
|
| - }
|
| - return 0;
|
| -};
|
| -
|
| -// Updates the format of the alerts array to be easier to parse.
|
| -CTFailures.prototype._mungeAlerts = function(alerts) {
|
| - alerts.forEach(function(failure) {
|
| - // FIXME: Have the server store the actual failure type in a different
|
| - // field instead of smashing it into the reason.
|
| - if (failure.failureType) {
|
| - // The server has been fixed.
|
| - } else {
|
| - if (failure.reason) {
|
| - var parts = failure.reason.split(':');
|
| - failure.reason = parts[0];
|
| - failure.failureType = parts[1] || 'FAIL';
|
| - } else {
|
| - failure.failureType = 'UNKNOWN';
|
| - }
|
| - }
|
| - });
|
| -};
|
| -
|
| -CTFailures.prototype.update = function() {
|
| - var annotationPromise = CTFailureGroup.fetchAnnotations();
|
| - return Promise.all([annotationPromise, net.json('https://sheriff-o-matic.appspot.com/alerts'),
|
| - net.json('https://trooper-o-matic.appspot.com/alerts')]).then(function(data_array) {
|
| - var annotations = data_array[0];
|
| - var sheriff_data = data_array[1];
|
| - var trooper_data = data_array[2];
|
| -
|
| - var newFailures = {};
|
| - this.lastUpdateDate = new Date(sheriff_data.date * 1000);
|
| - this._mungeAlerts(sheriff_data.alerts);
|
| - // FIXME: Change builder_alerts to expose the alerts as a map instead of an array.
|
| - var alertsByKey = {}
|
| - sheriff_data.alerts.forEach(function(alert) {
|
| - alertsByKey[alert.key] = alert;
|
| - });
|
| - // Update |failures| with the appropriate CTFailureGroup's for each
|
| - // tree.
|
| - sheriff_data.range_groups.forEach(function(rangeGroup) {
|
| - this._processFailuresForRangeGroup(newFailures, rangeGroup, alertsByKey, annotations);
|
| - }.bind(this));
|
| -
|
| - sheriff_data.stale_builder_alerts.forEach(function(alert) {
|
| - this._processBuilderFailure(newFailures, alert);
|
| - }.bind(this));
|
| -
|
| - // Sort failure groups so that newer failures are shown at the top
|
| - // of the UI.
|
| - Object.keys(newFailures, function (tree, failuresByTree) {
|
| - failuresByTree.sort(this._failureByTreeListComparator.bind(this, tree));
|
| - }.bind(this));
|
| -
|
| - this.failures = updateUtil.updateLeft(this.failures, newFailures);
|
| - this._processTrooperFailures(newFailures, trooper_data);
|
| - }.bind(this));
|
| -};
|
| -
|
| -CTFailures.prototype._failureComparator = function(a, b) {
|
| - if (a.step > b.step)
|
| - return 1;
|
| - if (a.step < b.step)
|
| - return -1
|
| - if (a.testName > b.testName)
|
| - return 1;
|
| - if (a.testName < b.testName)
|
| - return -1
|
| - return 0;
|
| -};
|
| -
|
| -CTFailures.prototype._processTrooperFailures = function(all_failures,
|
| - trooper_data) {
|
| - var trooper_failures = [];
|
| - Object.keys(trooper_data, function(failureType, failuresByTree) {
|
| - Object.keys(failuresByTree, function(tree, failure) {
|
| - if (failure.should_alert) {
|
| - trooper_failures.push(new CTFailureGroup('trooper',
|
| - new CTTrooperFailureGroupData(failure.details, failure.url, failure,
|
| - failureType, tree)));
|
| - }
|
| - });
|
| - });
|
| -
|
| - Object.keys(all_failures, function(tree, failuresByTree) {
|
| - failuresByTree.forEach(function(failure) {
|
| - if (failure.category == 'builder' || failure.category == 'master') {
|
| - trooper_failures.push(failure);
|
| - }
|
| - });
|
| - });
|
| - this.failures['trooper'] = trooper_failures;
|
| -};
|
| -
|
| -CTFailures.prototype._groupFailuresByTreeAndReason = function(failures, annotations) {
|
| - var failuresByTree = {};
|
| - failures.forEach(function(failure) {
|
| - // Establish the key to uniquely identify a failure by reason.
|
| - var failureKey = CTStepFailure.createKey(failure);
|
| -
|
| - var reasonKey = JSON.stringify({
|
| - step: failure.step_name,
|
| - reason: failure.reason,
|
| - });
|
| -
|
| - // FIXME: Use a model class instead of a dumb object.
|
| - if (!failuresByTree[failure.tree])
|
| - failuresByTree[failure.tree] = {};
|
| - if (!failuresByTree[failure.tree][reasonKey])
|
| - failuresByTree[failure.tree][reasonKey] = {};
|
| - failuresByTree[failure.tree][reasonKey][failure.builder_name] = {
|
| - key: failureKey,
|
| - // FIXME: Rename to failureType.
|
| - actual: failure.failureType,
|
| - lastFailingBuild: failure.last_failing_build,
|
| - masterUrl: failure.master_url,
|
| - failingBuildCount: (1 + failure.last_failing_build - failure.failing_build),
|
| - annotation: annotations[failureKey],
|
| - isTreeCloser: failure.would_close_tree,
|
| - };
|
| - });
|
| - return failuresByTree
|
| -};
|
| -
|
| -CTFailures.prototype._processFailuresForRangeGroup = function(newFailures, rangeGroup, alerts, annotations) {
|
| - // A rangeGroup may be related to multiple alerts (via |failure_keys|). Categorize
|
| - // these failures by reason (cause of failure), so that they can be grouped in the UI
|
| - // (via a CTFailureGroup).
|
| - var failures = rangeGroup.failure_keys.map(function(failure_key) {
|
| - return alerts[failure_key];
|
| - });
|
| - var failuresByTree = this._groupFailuresByTreeAndReason(failures, annotations);
|
| -
|
| - if (Object.isEmpty(failuresByTree))
|
| - return;
|
| -
|
| - Object.keys(failuresByTree, function(tree, resultsByReason) {
|
| - var treeFailures = [];
|
| - Object.keys(resultsByReason, function(reasonKey, resultsByBuilder) {
|
| - var failure = JSON.parse(reasonKey);
|
| - treeFailures.push(
|
| - new CTStepFailure(failure.step, failure.reason, resultsByBuilder));
|
| - })
|
| - treeFailures.sort(this._failureComparator);
|
| -
|
| - if (!newFailures[tree])
|
| - newFailures[tree] = [];
|
| - var commitList = new CTCommitList(this.commitLog, rangeGroup.likely_revisions);
|
| - newFailures[tree].push(new CTFailureGroup(tree, new CTStepFailureGroupData(treeFailures, commitList)));
|
| - }.bind(this));
|
| -};
|
| -
|
| -CTFailures.prototype._processBuilderFailure = function(newFailures, alert) {
|
| - var timeSinceLastUpdate = (this.lastUpdateDate.valueOf() / 1000) - alert.last_update_time;
|
| -
|
| - var failure;
|
| - var data;
|
| - var category;
|
| - if (alert.hasOwnProperty('builder_name')) {
|
| - category = 'builder';
|
| - failure = new CTBuilderFailure(alert.tree, alert.master_url, alert.builder_name, alert.state,
|
| - timeSinceLastUpdate, alert.pending_builds, alert.hasOwnProperty('isMaster'));
|
| - data = new CTBuilderFailureGroupData(failure, alert.builder_name,
|
| - alert.master_url + "/builders/" + alert.builder_name);
|
| - } else {
|
| - category = 'master';
|
| - failure = new CTMasterFailure(alert.tree, alert.master_url, timeSinceLastUpdate);
|
| - data = new CTMasterFailureGroupData(failure, alert.master_url);
|
| - }
|
| - if (!newFailures[alert.tree])
|
| - newFailures[alert.tree] = [];
|
| - newFailures[alert.tree].push(new CTFailureGroup(alert.tree, data, category));
|
| -};
|
| -
|
| -})();
|
| -
|
| -</script>
|
|
|