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> |