| 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_UNSURE) |
| 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 'key': crash.key.urlsafe() |
| 153 } |
| 154 |
| 155 def testDisplayAllAnalysisResults(self): |
| 156 expected_result = { |
| 157 'fracas_crashes': [self.fracas_crashes[4], |
| 158 self.fracas_crashes[3], |
| 159 self.fracas_crashes[2], |
| 160 self.fracas_crashes[1], |
| 161 self.fracas_crashes[0]], |
| 162 'end_date': time_util.FormatDatetime(self.default_end_date), |
| 163 'regression_range_triage_status': '-1', |
| 164 'suspected_cls_triage_status': '-1', |
| 165 'found_suspects': '-1', |
| 166 'has_regression_range': '-1', |
| 167 'start_date': time_util.FormatDatetime(self.default_start_date) |
| 168 } |
| 169 |
| 170 response_json = self.test_app.get('/fracas-dashboard?format=json') |
| 171 self.assertEqual(200, response_json.status_int) |
| 172 self.assertEqual(expected_result, response_json.json_body) |
| 173 |
| 174 def testFilterWithFoundSuspects(self): |
| 175 expected_result = { |
| 176 'fracas_crashes': [self.fracas_crashes[3], |
| 177 self.fracas_crashes[0]], |
| 178 'end_date': time_util.FormatDatetime(self.default_end_date), |
| 179 'regression_range_triage_status': '-1', |
| 180 'suspected_cls_triage_status': '-1', |
| 181 'found_suspects': '1', |
| 182 'has_regression_range': '-1', |
| 183 'start_date': time_util.FormatDatetime(self.default_start_date) |
| 184 } |
| 185 |
| 186 response_json = self.test_app.get( |
| 187 '/fracas-dashboard?found_suspects=1&format=json') |
| 188 self.assertEqual(200, response_json.status_int) |
| 189 self.assertEqual(expected_result, response_json.json_body) |
| 190 |
| 191 def testFilterWithHasRegression(self): |
| 192 expected_result = { |
| 193 'fracas_crashes': [self.fracas_crashes[4], |
| 194 self.fracas_crashes[3], |
| 195 self.fracas_crashes[2]], |
| 196 'end_date': time_util.FormatDatetime(self.default_end_date), |
| 197 'regression_range_triage_status': '-1', |
| 198 'suspected_cls_triage_status': '-1', |
| 199 'found_suspects': '-1', |
| 200 'has_regression_range': '1', |
| 201 'start_date': time_util.FormatDatetime(self.default_start_date) |
| 202 } |
| 203 |
| 204 response_json = self.test_app.get( |
| 205 '/fracas-dashboard?has_regression_range=1&format=json') |
| 206 self.assertEqual(200, response_json.status_int) |
| 207 self.assertEqual(expected_result, response_json.json_body) |
| 208 |
| 209 def testFilterWithSuspectsUntriaged(self): |
| 210 expected_result = { |
| 211 'fracas_crashes': [self.fracas_crashes[2]], |
| 212 'end_date': time_util.FormatDatetime(self.default_end_date), |
| 213 'regression_range_triage_status': '-1', |
| 214 'suspected_cls_triage_status': triage_status.UNTRIAGED, |
| 215 'found_suspects': '-1', |
| 216 'has_regression_range': '-1', |
| 217 'start_date': time_util.FormatDatetime(self.default_start_date) |
| 218 } |
| 219 |
| 220 response_json = self.test_app.get( |
| 221 '/fracas-dashboard?suspected_cls_triage_status=%s&format=json' % |
| 222 triage_status.UNTRIAGED) |
| 223 self.assertEqual(200, response_json.status_int) |
| 224 self.assertEqual(expected_result, response_json.json_body) |
| 225 |
| 226 def testFilterWithSuspectsTriagedUnsure(self): |
| 227 expected_result = { |
| 228 'fracas_crashes': [self.fracas_crashes[4]], |
| 229 'end_date': time_util.FormatDatetime(self.default_end_date), |
| 230 'regression_range_triage_status': '-1', |
| 231 'suspected_cls_triage_status': triage_status.TRIAGED_UNSURE, |
| 232 'found_suspects': '-1', |
| 233 'has_regression_range': '-1', |
| 234 'start_date': time_util.FormatDatetime(self.default_start_date) |
| 235 } |
| 236 |
| 237 response_json = self.test_app.get( |
| 238 '/fracas-dashboard?suspected_cls_triage_status=%s&format=json' % |
| 239 triage_status.TRIAGED_UNSURE) |
| 240 self.assertEqual(200, response_json.status_int) |
| 241 self.assertEqual(expected_result, response_json.json_body) |
| 242 |
| 243 def testFilterWithRegressionRangeTriagedUnsure(self): |
| 244 expected_result = { |
| 245 'fracas_crashes': [self.fracas_crashes[4]], |
| 246 'end_date': time_util.FormatDatetime(self.default_end_date), |
| 247 'regression_range_triage_status': triage_status.TRIAGED_UNSURE, |
| 248 'suspected_cls_triage_status': '-1', |
| 249 'found_suspects': '-1', |
| 250 'has_regression_range': '-1', |
| 251 'start_date': time_util.FormatDatetime(self.default_start_date) |
| 252 } |
| 253 |
| 254 response_json = self.test_app.get( |
| 255 '/fracas-dashboard?regression_range_triage_status=%s&format=json' % |
| 256 triage_status.TRIAGED_UNSURE) |
| 257 self.assertEqual(200, response_json.status_int) |
| 258 self.assertEqual(expected_result, response_json.json_body) |
| 259 |
| 260 def testGetTopCountResults(self): |
| 261 expected_result = { |
| 262 'fracas_crashes': [self.fracas_crashes[4], |
| 263 self.fracas_crashes[3]], |
| 264 'end_date': time_util.FormatDatetime(self.default_end_date), |
| 265 'regression_range_triage_status': '-1', |
| 266 'suspected_cls_triage_status': '-1', |
| 267 'found_suspects': '-1', |
| 268 'has_regression_range': '-1', |
| 269 'start_date': time_util.FormatDatetime(self.default_start_date) |
| 270 } |
| 271 |
| 272 response_json = self.test_app.get('/fracas-dashboard?count=2&format=json') |
| 273 self.assertEqual(200, response_json.status_int) |
| 274 self.assertEqual(expected_result, response_json.json_body) |
| OLD | NEW |