| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2011 Google Inc. All rights reserved. | 2 * Copyright (C) 2011 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
| 8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
| 10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 92 | 92 |
| 93 model.takeExpectationUpdateQueue = function() | 93 model.takeExpectationUpdateQueue = function() |
| 94 { | 94 { |
| 95 var queue = model.state.expectationsUpdateQueue; | 95 var queue = model.state.expectationsUpdateQueue; |
| 96 model.state.expectationsUpdateQueue = []; | 96 model.state.expectationsUpdateQueue = []; |
| 97 return queue; | 97 return queue; |
| 98 }; | 98 }; |
| 99 | 99 |
| 100 var g_commitIndex = {}; | 100 var g_commitIndex = {}; |
| 101 | 101 |
| 102 model.updateRecentCommits = function(callback) | 102 model.updateRecentCommits = function() |
| 103 { | 103 { |
| 104 trac.recentCommitData('trunk', kCommitLogLength, function(commitDataList) { | 104 return trac.recentCommitData('trunk', kCommitLogLength).then(function(commit
DataList) { |
| 105 model.state.recentCommits = commitDataList; | 105 model.state.recentCommits = commitDataList; |
| 106 updateCommitIndex(); | 106 updateCommitIndex(); |
| 107 findAndMarkRevertedRevisions(model.state.recentCommits); | 107 findAndMarkRevertedRevisions(model.state.recentCommits); |
| 108 callback(); | |
| 109 }); | 108 }); |
| 110 }; | 109 }; |
| 111 | 110 |
| 112 function updateCommitIndex() | 111 function updateCommitIndex() |
| 113 { | 112 { |
| 114 model.state.recentCommits.forEach(function(commitData) { | 113 model.state.recentCommits.forEach(function(commitData) { |
| 115 g_commitIndex[commitData.revision] = commitData; | 114 g_commitIndex[commitData.revision] = commitData; |
| 116 }); | 115 }); |
| 117 } | 116 } |
| 118 | 117 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 134 var results = model.state.resultsByBuilder[builderName]; | 133 var results = model.state.resultsByBuilder[builderName]; |
| 135 if (parseInt(results.blink_revision) < revision) | 134 if (parseInt(results.blink_revision) < revision) |
| 136 builders[builderName] = { actual: 'BUILDING' }; | 135 builders[builderName] = { actual: 'BUILDING' }; |
| 137 }); | 136 }); |
| 138 return builders; | 137 return builders; |
| 139 }; | 138 }; |
| 140 | 139 |
| 141 model.latestRevision = function() | 140 model.latestRevision = function() |
| 142 { | 141 { |
| 143 return model.state.recentCommits[0].revision; | 142 return model.state.recentCommits[0].revision; |
| 144 } | 143 }; |
| 145 | 144 |
| 146 model.latestRevisionWithNoBuildersInFlight = function() | 145 model.latestRevisionWithNoBuildersInFlight = function() |
| 147 { | 146 { |
| 148 var revision = 0; | 147 var revision = 0; |
| 149 Object.keys(model.state.resultsByBuilder).forEach(function(builderName) { | 148 Object.keys(model.state.resultsByBuilder).forEach(function(builderName) { |
| 150 var results = model.state.resultsByBuilder[builderName]; | 149 var results = model.state.resultsByBuilder[builderName]; |
| 151 if (!results.blink_revision) | 150 if (!results.blink_revision) |
| 152 return; | 151 return; |
| 153 var testedRevision = parseInt(results.blink_revision); | 152 var testedRevision = parseInt(results.blink_revision); |
| 154 revision = revision ? Math.min(revision, testedRevision) : testedRevisio
n; | 153 revision = revision ? Math.min(revision, testedRevision) : testedRevisio
n; |
| 155 }); | 154 }); |
| 156 return revision; | 155 return revision; |
| 157 } | 156 } |
| 158 | 157 |
| 159 model.latestRevisionByBuilder = function() | 158 model.latestRevisionByBuilder = function() |
| 160 { | 159 { |
| 161 var revision = {}; | 160 var revision = {}; |
| 162 Object.keys(model.state.resultsByBuilder).forEach(function(builderName) { | 161 Object.keys(model.state.resultsByBuilder).forEach(function(builderName) { |
| 163 revision[builderName] = model.state.resultsByBuilder[builderName].blink_
revision; | 162 revision[builderName] = model.state.resultsByBuilder[builderName].blink_
revision; |
| 164 }); | 163 }); |
| 165 return revision; | 164 return revision; |
| 166 } | 165 } |
| 167 | 166 |
| 168 model.updateResultsByBuilder = function(callback) | 167 model.updateResultsByBuilder = function() |
| 169 { | 168 { |
| 170 results.fetchResultsByBuilder(Object.keys(config.builders), function(results
ByBuilder) { | 169 return results.fetchResultsByBuilder(Object.keys(config.builders)).then(func
tion(resultsByBuilder) { |
| 171 model.state.resultsByBuilder = resultsByBuilder; | 170 model.state.resultsByBuilder = resultsByBuilder; |
| 172 callback(); | |
| 173 }); | 171 }); |
| 174 }; | 172 }; |
| 175 | 173 |
| 176 model.analyzeUnexpectedFailures = function(callback, completionCallback) | 174 // failureCallback is called multiple times: once for each failure |
| 175 model.analyzeUnexpectedFailures = function(failureCallback) |
| 177 { | 176 { |
| 178 var unexpectedFailures = results.unexpectedFailuresByTest(model.state.result
sByBuilder); | 177 var unexpectedFailures = results.unexpectedFailuresByTest(model.state.result
sByBuilder); |
| 179 | 178 |
| 180 $.each(model.state.failureAnalysisByTest, function(testName, failureAnalysis
) { | 179 $.each(model.state.failureAnalysisByTest, function(testName, failureAnalysis
) { |
| 181 if (!(testName in unexpectedFailures)) | 180 if (!(testName in unexpectedFailures)) |
| 182 delete model.state.failureAnalysisByTest[testName]; | 181 delete model.state.failureAnalysisByTest[testName]; |
| 183 }); | 182 }); |
| 184 | 183 |
| 185 var tracker = new base.RequestTracker(Object.keys(unexpectedFailures).length
, completionCallback); | 184 var failurePromises = []; |
| 186 $.each(unexpectedFailures, function(testName, resultNodesByBuilder) { | 185 $.each(unexpectedFailures, function(testName, resultNodesByBuilder) { |
| 187 var builderNameList = Object.keys(resultNodesByBuilder); | 186 var builderNameList = Object.keys(resultNodesByBuilder); |
| 188 results.unifyRegressionRanges(builderNameList, testName, function(oldest
FailingRevision, newestPassingRevision) { | 187 failurePromises.push(results.unifyRegressionRanges(builderNameList, test
Name).then(function(result) { |
| 188 var oldestFailingRevision = result[0]; |
| 189 var newestPassingRevision = result[1]; |
| 189 var failureAnalysis = { | 190 var failureAnalysis = { |
| 190 'testName': testName, | 191 'testName': testName, |
| 191 'resultNodesByBuilder': resultNodesByBuilder, | 192 'resultNodesByBuilder': resultNodesByBuilder, |
| 192 'oldestFailingRevision': oldestFailingRevision, | 193 'oldestFailingRevision': oldestFailingRevision, |
| 193 'newestPassingRevision': newestPassingRevision, | 194 'newestPassingRevision': newestPassingRevision, |
| 194 }; | 195 }; |
| 195 | 196 |
| 196 heuristicallyNarrowRegressionRange(failureAnalysis); | 197 heuristicallyNarrowRegressionRange(failureAnalysis); |
| 197 | 198 |
| 198 var previousFailureAnalysis = model.state.failureAnalysisByTest[test
Name]; | 199 var previousFailureAnalysis = model.state.failureAnalysisByTest[test
Name]; |
| 199 if (previousFailureAnalysis | 200 if (previousFailureAnalysis |
| 200 && previousFailureAnalysis.oldestFailingRevision <= failureAnaly
sis.oldestFailingRevision | 201 && previousFailureAnalysis.oldestFailingRevision <= failureAnaly
sis.oldestFailingRevision |
| 201 && previousFailureAnalysis.newestPassingRevision >= failureAnaly
sis.newestPassingRevision) { | 202 && previousFailureAnalysis.newestPassingRevision >= failureAnaly
sis.newestPassingRevision) { |
| 202 failureAnalysis.oldestFailingRevision = previousFailureAnalysis.
oldestFailingRevision; | 203 failureAnalysis.oldestFailingRevision = previousFailureAnalysis.
oldestFailingRevision; |
| 203 failureAnalysis.newestPassingRevision = previousFailureAnalysis.
newestPassingRevision; | 204 failureAnalysis.newestPassingRevision = previousFailureAnalysis.
newestPassingRevision; |
| 204 } | 205 } |
| 205 | 206 |
| 206 model.state.failureAnalysisByTest[testName] = failureAnalysis; | 207 model.state.failureAnalysisByTest[testName] = failureAnalysis; |
| 207 | 208 |
| 208 callback(failureAnalysis); | 209 failureCallback(failureAnalysis); |
| 209 tracker.requestComplete(); | 210 })); |
| 210 }); | |
| 211 }); | 211 }); |
| 212 return Promise.all(failurePromises); |
| 212 }; | 213 }; |
| 213 | 214 |
| 214 model.unexpectedFailureInfoForTestName = function(testName) | 215 model.unexpectedFailureInfoForTestName = function(testName) |
| 215 { | 216 { |
| 216 var resultsByTest = results.unexpectedFailuresByTest(model.state.resultsByBu
ilder); | 217 var resultsByTest = results.unexpectedFailuresByTest(model.state.resultsByBu
ilder); |
| 217 | 218 |
| 218 return Object.keys(resultsByTest[testName]).map(function(builderName) { | 219 return Object.keys(resultsByTest[testName]).map(function(builderName) { |
| 219 return results.failureInfoForTestAndBuilder(resultsByTest, testName, bui
lderName); | 220 return results.failureInfoForTestAndBuilder(resultsByTest, testName, bui
lderName); |
| 220 }); | 221 }); |
| 221 }; | 222 }; |
| 222 | 223 |
| 223 model.analyzeexpectedFailures = function(callback) | 224 // failureCallback is called multiple times: once for each failure |
| 225 model.analyzeexpectedFailures = function(failureCallback) |
| 224 { | 226 { |
| 225 var expectedFailures = results.expectedFailuresByTest(model.state.resultsByB
uilder); | 227 var expectedFailures = results.expectedFailuresByTest(model.state.resultsByB
uilder); |
| 226 $.each(expectedFailures, function(testName, resultNodesByBuilder) { | 228 $.each(expectedFailures, function(testName, resultNodesByBuilder) { |
| 227 var failureAnalysis = { | 229 var failureAnalysis = { |
| 228 'testName': testName, | 230 'testName': testName, |
| 229 'resultNodesByBuilder': resultNodesByBuilder, | 231 'resultNodesByBuilder': resultNodesByBuilder, |
| 230 }; | 232 }; |
| 231 | 233 |
| 232 // FIXME: Consider looking at the history to see how long this test | 234 // FIXME: Consider looking at the history to see how long this test |
| 233 // has been failing. | 235 // has been failing. |
| 234 | 236 |
| 235 callback(failureAnalysis); | 237 failureCallback(failureAnalysis); |
| 236 }); | 238 }); |
| 237 }; | 239 }; |
| 238 | 240 |
| 239 })(); | 241 })(); |
| OLD | NEW |