Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(682)

Side by Side Diff: appengine/findit/handlers/build_failure.py

Issue 2425853005: [Findit] Modify Findit API to return more information to Sheriff-O-Matic. (Closed)
Patch Set: rebase Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « appengine/findit/findit_api.py ('k') | appengine/findit/handlers/test/build_failure_test.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright 2014 The Chromium Authors. All rights reserved. 1 # Copyright 2014 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 from collections import defaultdict 5 from collections import defaultdict
6 import copy 6 import copy
7 from datetime import datetime 7 from datetime import datetime
8 8
9 from google.appengine.api import users 9 from google.appengine.api import users
10 10
11 from common import constants 11 from common import constants
12 from common.base_handler import BaseHandler 12 from common.base_handler import BaseHandler
13 from common.base_handler import Permission 13 from common.base_handler import Permission
14 from common.waterfall import failure_type 14 from common.waterfall import failure_type
15 from handlers import handlers_util 15 from handlers import handlers_util
16 from handlers import result_status 16 from handlers import result_status
17 from handlers.result_status import NO_TRY_JOB_REASON_MAP 17 from handlers.result_status import NO_TRY_JOB_REASON_MAP
18 from model import analysis_approach_type
19 from model import analysis_status 18 from model import analysis_status
20 from model import result_status as analysis_result_status 19 from model import result_status as analysis_result_status
21 from model import suspected_cl_status 20 from model import suspected_cl_status
22 from model.result_status import RESULT_STATUS_TO_DESCRIPTION 21 from model.result_status import RESULT_STATUS_TO_DESCRIPTION
23 from model.suspected_cl_confidence import SuspectedCLConfidence 22 from model.suspected_cl_confidence import SuspectedCLConfidence
24 from model.suspected_cl_status import CL_STATUS_TO_DESCRIPTION 23 from model.suspected_cl_status import CL_STATUS_TO_DESCRIPTION
25 from model.wf_analysis import WfAnalysis 24 from model.wf_analysis import WfAnalysis
26 from model.wf_suspected_cl import WfSuspectedCL 25 from model.wf_suspected_cl import WfSuspectedCL
27 from model.wf_try_job import WfTryJob 26 from model.wf_try_job import WfTryJob
28 from waterfall import build_failure_analysis_pipelines 27 from waterfall import build_failure_analysis_pipelines
29 from waterfall import build_util 28 from waterfall import build_util
30 from waterfall import buildbot 29 from waterfall import buildbot
30 from waterfall import suspected_cl_util
31 from waterfall import waterfall_config 31 from waterfall import waterfall_config
32 32
33 33
34 NON_SWARMING = object() 34 NON_SWARMING = object()
35 35
36 36
37 _ANALYSIS_CL_STATUS_MAP = { 37 _ANALYSIS_CL_STATUS_MAP = {
38 analysis_result_status.FOUND_CORRECT: suspected_cl_status.CORRECT, 38 analysis_result_status.FOUND_CORRECT: suspected_cl_status.CORRECT,
39 analysis_result_status.FOUND_INCORRECT: suspected_cl_status.INCORRECT 39 analysis_result_status.FOUND_INCORRECT: suspected_cl_status.INCORRECT
40 } 40 }
41 41
42 42
43 def _FormatDatetime(dt): 43 def _FormatDatetime(dt):
44 if not dt: 44 if not dt:
45 return None 45 return None
46 else: 46 else:
47 return dt.strftime('%Y-%m-%d %H:%M:%S UTC') 47 return dt.strftime('%Y-%m-%d %H:%M:%S UTC')
48 48
49 49
50 def _GetCLDict(analysis, cl_info): 50 def _GetCLDict(analysis, cl_info):
51 if not cl_info: 51 if not cl_info:
52 return {} 52 return {}
53 53
54 cl_keys = cl_info.split('/') 54 cl_keys = suspected_cl_util.GetCLInfo(cl_info)
55 repo_name = cl_keys[0] 55 repo_name = cl_keys[0]
56 revision = cl_keys[1] 56 revision = cl_keys[1]
57 for cl in analysis.suspected_cls: 57 for cl in analysis.suspected_cls:
58 if cl['repo_name'] == repo_name and cl['revision'] == revision: 58 if cl['repo_name'] == repo_name and cl['revision'] == revision:
59 return cl 59 return cl
60 return {} 60 return {}
61 61
62 62
63 def _GetTriageHistory(analysis): 63 def _GetTriageHistory(analysis):
64 if (not users.is_current_user_admin() or 64 if (not users.is_current_user_admin() or
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
324 compile_failure = None 324 compile_failure = None
325 for failure in analysis.result.get('failures', []): 325 for failure in analysis.result.get('failures', []):
326 if failure['step_name'] == constants.COMPILE_STEP_NAME: 326 if failure['step_name'] == constants.COMPILE_STEP_NAME:
327 compile_failure = failure 327 compile_failure = failure
328 if compile_failure: # pragma: no branch. 328 if compile_failure: # pragma: no branch.
329 data['first_failure'] = compile_failure['first_failure'] 329 data['first_failure'] = compile_failure['first_failure']
330 data['last_pass'] = compile_failure['last_pass'] 330 data['last_pass'] = compile_failure['last_pass']
331 data['suspected_cls_by_heuristic'] = compile_failure['suspected_cls'] 331 data['suspected_cls_by_heuristic'] = compile_failure['suspected_cls']
332 332
333 333
334 def _PercentFormat(float_number):
335 if not float_number or not isinstance(float_number, float):
336 return None
337 return '%d%%' % (round(float_number * 100))
338
339
340 def _GetConfidenceScore(confidence, cl_build):
341
342 if not confidence:
343 return None
344
345 if cl_build['failure_type'] == failure_type.COMPILE:
346 if cl_build['approaches'] == [
347 analysis_approach_type.HEURISTIC, analysis_approach_type.TRY_JOB]:
348 return _PercentFormat(confidence.compile_heuristic_try_job.confidence)
349 elif cl_build['approaches'] == [analysis_approach_type.TRY_JOB]:
350 return _PercentFormat(confidence.compile_try_job.confidence)
351 elif (cl_build['approaches'] == [analysis_approach_type.HEURISTIC] and
352 cl_build['top_score']):
353 for confidence_info in confidence.compile_heuristic:
354 if confidence_info.score == cl_build['top_score']:
355 return _PercentFormat(confidence_info.confidence)
356 return None
357 else:
358 if cl_build['approaches'] == [
359 analysis_approach_type.HEURISTIC, analysis_approach_type.TRY_JOB]:
360 return _PercentFormat(confidence.test_heuristic_try_job.confidence)
361 elif cl_build['approaches'] == [analysis_approach_type.TRY_JOB]:
362 return _PercentFormat(confidence.test_try_job.confidence)
363 elif (cl_build['approaches'] == [analysis_approach_type.HEURISTIC] and
364 cl_build['top_score']):
365 for confidence_info in confidence.test_heuristic:
366 if confidence_info.score == cl_build['top_score']:
367 return _PercentFormat(confidence_info.confidence)
368 return None
369
370
371 def _GetAllSuspectedCLsAndCheckStatus( 334 def _GetAllSuspectedCLsAndCheckStatus(
372 master_name, builder_name, build_number, analysis): 335 master_name, builder_name, build_number, analysis):
373 build_key = build_util.CreateBuildId( 336 build_key = build_util.CreateBuildId(
374 master_name, builder_name, build_number) 337 master_name, builder_name, build_number)
375 suspected_cls = copy.deepcopy(analysis.suspected_cls) 338 suspected_cls = copy.deepcopy(analysis.suspected_cls)
376 if not suspected_cls: 339 if not suspected_cls:
377 return [] 340 return []
378 341
379 cl_confidences = SuspectedCLConfidence.Get() 342 confidences = SuspectedCLConfidence.Get()
380 343
381 for cl in suspected_cls: 344 for cl in suspected_cls:
382 cl['status'] = _ANALYSIS_CL_STATUS_MAP.get(analysis.result_status, None) 345 cl['status'] = _ANALYSIS_CL_STATUS_MAP.get(analysis.result_status, None)
383 cl['confidence'] = None 346 cl['confidence'] = None
384 347
385 suspected_cl = WfSuspectedCL.Get(cl['repo_name'], cl['revision']) 348 suspected_cl = WfSuspectedCL.Get(cl['repo_name'], cl['revision'])
386 if not suspected_cl: 349 if not suspected_cl:
387 continue 350 continue
388 351
389 build = suspected_cl.builds.get(build_key) 352 build = suspected_cl.builds.get(build_key)
390 if build: 353 if build:
391 cl['status'] = build['status'] 354 cl['status'] = build['status']
392 cl['confidence'] = _GetConfidenceScore(cl_confidences, build) 355 cl['confidence'] = '%d%%' % (
356 suspected_cl_util.GetSuspectedCLConfidenceScore(confidences, build))
393 357
394 return suspected_cls 358 return suspected_cls
395 359
396 360
397 class BuildFailure(BaseHandler): 361 class BuildFailure(BaseHandler):
398 PERMISSION_LEVEL = Permission.ANYONE 362 PERMISSION_LEVEL = Permission.ANYONE
399 363
400 def _ShowTriageHelpButton(self): 364 def _ShowTriageHelpButton(self):
401 return users.is_current_user_admin() 365 return users.is_current_user_admin()
402 366
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
498 else: 462 else:
499 self._PrepareDataForTestFailures( 463 self._PrepareDataForTestFailures(
500 analysis, build_info, data, self._ShowDebugInfo()) 464 analysis, build_info, data, self._ShowDebugInfo())
501 return { 465 return {
502 'template': 'waterfall/test_failure.html', 466 'template': 'waterfall/test_failure.html',
503 'data': data 467 'data': data
504 } 468 }
505 469
506 def HandlePost(self): # pragma: no cover 470 def HandlePost(self): # pragma: no cover
507 return self.HandleGet() 471 return self.HandleGet()
OLDNEW
« no previous file with comments | « appengine/findit/findit_api.py ('k') | appengine/findit/handlers/test/build_failure_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698