| OLD | NEW |
| (Empty) | |
| 1 # Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. |
| 4 import base64 |
| 5 import copy |
| 6 from datetime import datetime |
| 7 from datetime import time |
| 8 from datetime import timedelta |
| 9 import json |
| 10 |
| 11 import webapp2 |
| 12 |
| 13 from testing_utils import testing |
| 14 |
| 15 from common import time_util |
| 16 from handlers.crash import fracas_dashboard |
| 17 from model import analysis_status |
| 18 from model import result_status |
| 19 from model import triage_status |
| 20 from model.crash.fracas_crash_analysis import FracasCrashAnalysis |
| 21 |
| 22 |
| 23 class FracasDashBoardTest(testing.AppengineTestCase): |
| 24 app_module = webapp2.WSGIApplication( |
| 25 [('/fracas-dashboard', fracas_dashboard.FracasDashBoard), ], debug=True) |
| 26 |
| 27 def setUp(self): |
| 28 super(FracasDashBoardTest, self).setUp() |
| 29 self.keys = self._AddAnalysisResults() |
| 30 self.fracas_crashes = [] |
| 31 for key in self.keys: |
| 32 self.fracas_crashes.append(self._GenerateDisplayData(key)) |
| 33 |
| 34 midnight_today = datetime.combine(datetime.utcnow(), time.min) |
| 35 midnight_yesterday = midnight_today - timedelta(days=1) |
| 36 midnight_tomorrow = midnight_today + timedelta(days=1) |
| 37 self.default_start_date = midnight_yesterday |
| 38 self.default_end_date = midnight_tomorrow |
| 39 |
| 40 def testFracasDashBoardHandler(self): |
| 41 response = self.test_app.get('/fracas-dashboard') |
| 42 self.assertEqual(200, response.status_int) |
| 43 |
| 44 def _CreateAnalysisResult(self, crash_identifiers): |
| 45 analysis = FracasCrashAnalysis.Create(crash_identifiers) |
| 46 analysis.status = analysis_status.RUNNING |
| 47 return analysis |
| 48 |
| 49 def _SetResultsTriageStatus(self, analysis, triage_status_value): |
| 50 result_types = ['regression_range', 'suspected_cls', 'suspected_project', |
| 51 'suspected_components'] |
| 52 for result_type in result_types: |
| 53 setattr(analysis, '%s_triage_status' % result_type, triage_status_value) |
| 54 |
| 55 def _AddAnalysisResults(self): |
| 56 """Create and store dummy data.""" |
| 57 analyses = [] |
| 58 keys = [] |
| 59 |
| 60 for i in range(0, 5): |
| 61 crash_identifiers = {'signature': 'sig%d' % i} |
| 62 keys.append(crash_identifiers) |
| 63 |
| 64 analysis = self._CreateAnalysisResult(crash_identifiers) |
| 65 analysis.signature = 'sig%d' % i |
| 66 analysis.crashed_version = '53.0.275%d.0' % i |
| 67 analysis.stack_trace = 'dummy\nframe1\nframe2' |
| 68 analysis.platform = 'android' |
| 69 analysis.channel = 'canary' |
| 70 analysis.client_id = 'fracas' |
| 71 analyses.append(analysis) |
| 72 |
| 73 analyses[0].status = analysis_status.COMPLETED |
| 74 analyses[1].status = analysis_status.COMPLETED |
| 75 analyses[2].status = analysis_status.ERROR |
| 76 analyses[3].status = analysis_status.COMPLETED |
| 77 analyses[4].status = analysis_status.ERROR |
| 78 |
| 79 suspected_cl = { |
| 80 'url': 'https://chromium.googlesource.com/chromium/src/+/346a', |
| 81 'review_url': 'https://review', |
| 82 'revision': '346a', |
| 83 'project_path': 'src/', |
| 84 'author': 'a@chromium.org', |
| 85 'time': '2016-06-04 00:00:00 UTC', |
| 86 'reason': 'some reason', |
| 87 'confidence': 1 |
| 88 } |
| 89 analyses[0].result = {'found': True, |
| 90 'suspected_cls': [suspected_cl], |
| 91 'suspected_components': ['Blink>API', 'Blink>DOM'], |
| 92 'suspected_project': 'chromium', |
| 93 'regression_range': None} |
| 94 analyses[0].found_suspects = True |
| 95 analyses[1].result = {'found': False, |
| 96 'suspected_cls': [], |
| 97 'suspected_components': ['Blink>API', 'Blink>DOM'], |
| 98 'suspected_project': 'chromium', |
| 99 'regression_range': None} |
| 100 analyses[1].found_suspects = False |
| 101 analyses[2].result = {'found': False, |
| 102 'suspected_cls': [], |
| 103 'suspected_components': ['Blink>API', 'Blink>DOM'], |
| 104 'suspected_project': 'chromium', |
| 105 'regression_range': ['53.0.2749.0', '53.0.2750.0']} |
| 106 analyses[2].found_suspects = False |
| 107 analyses[3].result = {'found': True, |
| 108 'suspected_cls': [suspected_cl], |
| 109 'suspected_components': ['Blink>API'], |
| 110 'suspected_project': 'chromium', |
| 111 'regression_range': ['53.0.2749.0', '53.0.2750.0']} |
| 112 analyses[3].found_suspects = True |
| 113 analyses[4].result = {'found': False, |
| 114 'suspected_cls': [], |
| 115 'suspected_components': ['Blink>API', 'Blink>DOM'], |
| 116 'suspected_project': 'chromium', |
| 117 'regression_range': ['53.0.2749.0', '53.0.2750.0']} |
| 118 analyses[4].found_suspects = False |
| 119 |
| 120 start_request_time = datetime.utcnow() |
| 121 for i, analysis in enumerate(analyses): |
| 122 analysis.requested_time = (start_request_time + |
| 123 timedelta(minutes=10 * i)) |
| 124 |
| 125 analysis.has_regression_range = not analysis.result[ |
| 126 'regression_range'] is None |
| 127 |
| 128 self._SetResultsTriageStatus(analyses[0], triage_status.TRIAGED_INCORRECT) |
| 129 self._SetResultsTriageStatus(analyses[1], triage_status.TRIAGED_CORRECT) |
| 130 self._SetResultsTriageStatus(analyses[3], triage_status.TRIAGED_CORRECT) |
| 131 self._SetResultsTriageStatus(analyses[4], triage_status.TRIAGED) |
| 132 |
| 133 for analysis in analyses: |
| 134 analysis.put() |
| 135 |
| 136 return keys |
| 137 |
| 138 def _GenerateDisplayData(self, crash_identifiers): |
| 139 crash = FracasCrashAnalysis.Get(crash_identifiers) |
| 140 return { |
| 141 'signature': crash.signature, |
| 142 'version': crash.crashed_version, |
| 143 'channel': crash.channel, |
| 144 'platform': crash.platform, |
| 145 'regression_range': ('' if not crash.has_regression_range else |
| 146 crash.result['regression_range']), |
| 147 'suspected_cls':crash.result['suspected_cls'], |
| 148 'suspected_project': crash.result['suspected_project'], |
| 149 'suspected_components': crash.result['suspected_components'], |
| 150 'stack_trace': crash.stack_trace, |
| 151 'historical_metadata': json.dumps(crash.historical_metadata), |
| 152 'crash_identifiers': base64.b64encode( |
| 153 json.dumps(crash.crash_identifiers)) |
| 154 } |
| 155 |
| 156 def testDisplayAllTodayAnalysisResults(self): |
| 157 expected_result = { |
| 158 'fracas_crashes': self.fracas_crashes, |
| 159 'end_date': time_util.FormatDatetime(self.default_end_date), |
| 160 'regression_range_triage_status': '-1', |
| 161 'suspected_cls_triage_status': '-1', |
| 162 'found_suspects': '-1', |
| 163 'has_regression_range': '-1', |
| 164 'start_date': time_util.FormatDatetime(self.default_start_date) |
| 165 } |
| 166 |
| 167 response_json = self.test_app.get('/fracas-dashboard?format=json') |
| 168 self.assertEqual(200, response_json.status_int) |
| 169 self.assertEqual(expected_result, response_json.json_body) |
| 170 |
| 171 def testFilterWithFoundSuspects(self): |
| 172 expected_result = { |
| 173 'fracas_crashes': [self.fracas_crashes[0], self.fracas_crashes[3]], |
| 174 'end_date': time_util.FormatDatetime(self.default_end_date), |
| 175 'regression_range_triage_status': '-1', |
| 176 'suspected_cls_triage_status': '-1', |
| 177 'found_suspects': '1', |
| 178 'has_regression_range': '-1', |
| 179 'start_date': time_util.FormatDatetime(self.default_start_date) |
| 180 } |
| 181 |
| 182 response_json = self.test_app.get( |
| 183 '/fracas-dashboard?found_suspects=1&format=json') |
| 184 self.assertEqual(200, response_json.status_int) |
| 185 self.assertEqual(expected_result, response_json.json_body) |
| 186 |
| 187 def testFilterWithHasRegression(self): |
| 188 expected_result = { |
| 189 'fracas_crashes': [self.fracas_crashes[2], |
| 190 self.fracas_crashes[3], |
| 191 self.fracas_crashes[4]], |
| 192 'end_date': time_util.FormatDatetime(self.default_end_date), |
| 193 'regression_range_triage_status': '-1', |
| 194 'suspected_cls_triage_status': '-1', |
| 195 'found_suspects': '-1', |
| 196 'has_regression_range': '1', |
| 197 'start_date': time_util.FormatDatetime(self.default_start_date) |
| 198 } |
| 199 |
| 200 response_json = self.test_app.get( |
| 201 '/fracas-dashboard?has_regression_range=1&format=json') |
| 202 self.assertEqual(200, response_json.status_int) |
| 203 self.assertEqual(expected_result, response_json.json_body) |
| 204 |
| 205 def testFilterWithSuspectsUntriaged(self): |
| 206 expected_result = { |
| 207 'fracas_crashes': [self.fracas_crashes[2]], |
| 208 'end_date': time_util.FormatDatetime(self.default_end_date), |
| 209 'regression_range_triage_status': '-1', |
| 210 'suspected_cls_triage_status': triage_status.UNTRIAGED, |
| 211 'found_suspects': '-1', |
| 212 'has_regression_range': '-1', |
| 213 'start_date': time_util.FormatDatetime(self.default_start_date) |
| 214 } |
| 215 |
| 216 response_json = self.test_app.get( |
| 217 '/fracas-dashboard?suspected_cls_triage_status=%s&format=json' % |
| 218 triage_status.UNTRIAGED) |
| 219 self.assertEqual(200, response_json.status_int) |
| 220 self.assertEqual(expected_result, response_json.json_body) |
| 221 |
| 222 def testFilterWithSuspectsTriaged(self): |
| 223 expected_result = { |
| 224 'fracas_crashes': [self.fracas_crashes[0], |
| 225 self.fracas_crashes[1], |
| 226 self.fracas_crashes[3], |
| 227 self.fracas_crashes[4]], |
| 228 'end_date': time_util.FormatDatetime(self.default_end_date), |
| 229 'regression_range_triage_status': '-1', |
| 230 'suspected_cls_triage_status': triage_status.TRIAGED, |
| 231 'found_suspects': '-1', |
| 232 'has_regression_range': '-1', |
| 233 'start_date': time_util.FormatDatetime(self.default_start_date) |
| 234 } |
| 235 |
| 236 response_json = self.test_app.get( |
| 237 '/fracas-dashboard?suspected_cls_triage_status=%s&format=json' % |
| 238 triage_status.TRIAGED) |
| 239 self.assertEqual(200, response_json.status_int) |
| 240 self.assertEqual(expected_result, response_json.json_body) |
| 241 |
| 242 def testFilterWithRegressionRangeTriaged(self): |
| 243 expected_result = { |
| 244 'fracas_crashes': [self.fracas_crashes[0], |
| 245 self.fracas_crashes[1], |
| 246 self.fracas_crashes[3], |
| 247 self.fracas_crashes[4]], |
| 248 'end_date': time_util.FormatDatetime(self.default_end_date), |
| 249 'regression_range_triage_status': triage_status.TRIAGED, |
| 250 'suspected_cls_triage_status': '-1', |
| 251 'found_suspects': '-1', |
| 252 'has_regression_range': '-1', |
| 253 'start_date': time_util.FormatDatetime(self.default_start_date) |
| 254 } |
| 255 |
| 256 response_json = self.test_app.get( |
| 257 '/fracas-dashboard?regression_range_triage_status=%s&format=json' % |
| 258 triage_status.TRIAGED) |
| 259 self.assertEqual(200, response_json.status_int) |
| 260 self.assertEqual(expected_result, response_json.json_body) |
| 261 |
| 262 def testGetTopCountResults(self): |
| 263 expected_result = { |
| 264 'fracas_crashes': [self.fracas_crashes[0], |
| 265 self.fracas_crashes[1]], |
| 266 'end_date': time_util.FormatDatetime(self.default_end_date), |
| 267 'regression_range_triage_status': '-1', |
| 268 'suspected_cls_triage_status': '-1', |
| 269 'found_suspects': '-1', |
| 270 'has_regression_range': '-1', |
| 271 'start_date': time_util.FormatDatetime(self.default_start_date) |
| 272 } |
| 273 |
| 274 response_json = self.test_app.get('/fracas-dashboard?count=2&format=json') |
| 275 self.assertEqual(200, response_json.status_int) |
| 276 self.assertEqual(expected_result, response_json.json_body) |
| OLD | NEW |