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

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

Issue 2398903002: [Findit] Display confidence score on result page. (Closed)
Patch Set: Created 4 years, 2 months 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 | « no previous file | 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
18 from model import analysis_status 19 from model import analysis_status
19 from model import cl_confidence 20 from model.cl_confidence import CLConfidence
stgao 2016/10/06 02:17:38 Maybe SuspectConfidence instead?
chanli 2016/10/08 00:41:10 Done.
20 from model import result_status as analysis_result_status 21 from model import result_status as analysis_result_status
21 from model import suspected_cl_status 22 from model import suspected_cl_status
22 from model.base_build_model import BaseBuildModel 23 from model.base_build_model import BaseBuildModel
23 from model.result_status import RESULT_STATUS_TO_DESCRIPTION 24 from model.result_status import RESULT_STATUS_TO_DESCRIPTION
24 from model.suspected_cl_status import CL_STATUS_TO_DESCRIPTION 25 from model.suspected_cl_status import CL_STATUS_TO_DESCRIPTION
25 from model.wf_analysis import WfAnalysis 26 from model.wf_analysis import WfAnalysis
26 from model.wf_suspected_cl import WfSuspectedCL 27 from model.wf_suspected_cl import WfSuspectedCL
27 from model.wf_try_job import WfTryJob 28 from model.wf_try_job import WfTryJob
28 from waterfall import build_failure_analysis_pipelines 29 from waterfall import build_failure_analysis_pipelines
29 from waterfall import buildbot 30 from waterfall import buildbot
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after
323 compile_failure = None 324 compile_failure = None
324 for failure in analysis.result.get('failures', []): 325 for failure in analysis.result.get('failures', []):
325 if failure['step_name'] == constants.COMPILE_STEP_NAME: 326 if failure['step_name'] == constants.COMPILE_STEP_NAME:
326 compile_failure = failure 327 compile_failure = failure
327 if compile_failure: # pragma: no branch. 328 if compile_failure: # pragma: no branch.
328 data['first_failure'] = compile_failure['first_failure'] 329 data['first_failure'] = compile_failure['first_failure']
329 data['last_pass'] = compile_failure['last_pass'] 330 data['last_pass'] = compile_failure['last_pass']
330 data['suspected_cls_by_heuristic'] = compile_failure['suspected_cls'] 331 data['suspected_cls_by_heuristic'] = compile_failure['suspected_cls']
331 332
332 333
334 def _GetMostRecentConfidence(): # pragma: no cover.
335 confidences = CLConfidence.query().order(-CLConfidence.end_date).fetch(1)
stgao 2016/10/06 02:17:38 As I mentioned in the other CL, making CLConfidenc
lijeffrey 2016/10/06 14:10:33 +1 if we make CLConfidence versioned then this co
chanli 2016/10/08 00:41:10 Done.
336
337 return confidences[0] if confidences else None
338
339
340 def _PercentFormat(float_number):
341 if not float_number or not isinstance(float_number, float):
342 return None
343 return '%.2f%%' % (float_number * 100)
stgao 2016/10/06 02:17:38 I guess 70% is better than 70.87%.
chanli 2016/10/08 00:41:10 Done.
344
345
346 def _GetConfidence(confidence, cl_build):
lijeffrey 2016/10/06 14:10:33 nit: rename this _GetConfidencePercentage or _GetC
chanli 2016/10/08 00:41:10 Done.
347
348 if not confidence:
349 return None
350
351 if cl_build['failure_type'] == failure_type.COMPILE:
352 if cl_build['approaches'] == [
353 analysis_approach_type.HEURISTIC, analysis_approach_type.TRY_JOB]:
354 return _PercentFormat(confidence.compile_heuristic_try_job['confidence'])
355 elif cl_build['approaches'] == [analysis_approach_type.TRY_JOB]:
356 return _PercentFormat(confidence.compile_try_job['confidence'])
357 elif (cl_build['approaches'] == [analysis_approach_type.HEURISTIC] and
358 cl_build['top_score']):
359 return _PercentFormat(
360 confidence.compile_heuristic.get(
361 str(cl_build['top_score']), {}).get('confidence'))
362 else:
363 return None
364 else:
365 if cl_build['approaches'] == [
366 analysis_approach_type.HEURISTIC, analysis_approach_type.TRY_JOB]:
367 return _PercentFormat(confidence.test_heuristic_try_job['confidence'])
368 elif cl_build['approaches'] == [analysis_approach_type.TRY_JOB]:
369 return _PercentFormat(confidence.test_try_job['confidence'])
370 elif (cl_build['approaches'] == [analysis_approach_type.HEURISTIC] and
371 cl_build['top_score']):
372 return _PercentFormat(confidence.test_heuristic.get(
373 str(cl_build['top_score']), {}).get('confidence'))
374 else: # pragma: no cover.
lijeffrey 2016/10/06 14:10:33 why is this one no cover whereas the compile one d
chanli 2016/10/08 00:41:10 Done.
375 return None
376
377
333 def _GetAllSuspectedCLsAndCheckStatus( 378 def _GetAllSuspectedCLsAndCheckStatus(
334 master_name, builder_name, build_number, analysis): 379 master_name, builder_name, build_number, analysis):
335 build_key = BaseBuildModel.CreateBuildId( 380 build_key = BaseBuildModel.CreateBuildId(
336 master_name, builder_name, build_number) 381 master_name, builder_name, build_number)
337 suspected_cls = copy.deepcopy(analysis.suspected_cls) 382 suspected_cls = copy.deepcopy(analysis.suspected_cls)
338 if not suspected_cls: 383 if not suspected_cls:
339 return [] 384 return []
340 385
386 cl_confidences = _GetMostRecentConfidence()
387
341 for cl in suspected_cls: 388 for cl in suspected_cls:
342 cl['status'] = _ANALYSIS_CL_STATUS_MAP.get(analysis.result_status, None) 389 cl['status'] = _ANALYSIS_CL_STATUS_MAP.get(analysis.result_status, None)
390 cl['confidence'] = None
391
343 suspected_cl = WfSuspectedCL.Get(cl['repo_name'], cl['revision']) 392 suspected_cl = WfSuspectedCL.Get(cl['repo_name'], cl['revision'])
344 if not suspected_cl: 393 if not suspected_cl:
345 continue 394 continue
346 395
347 build = suspected_cl.builds.get(build_key) 396 build = suspected_cl.builds.get(build_key)
348 if build: 397 if build:
349 cl['status'] = build['status'] 398 cl['status'] = build['status']
399 cl['confidence'] = _GetConfidence(cl_confidences, build)
350 400
351 return suspected_cls 401 return suspected_cls
352 402
353 403
354 class BuildFailure(BaseHandler): 404 class BuildFailure(BaseHandler):
355 PERMISSION_LEVEL = Permission.ANYONE 405 PERMISSION_LEVEL = Permission.ANYONE
356 406
357 def _ShowDebugInfo(self): 407 def _ShowDebugInfo(self):
358 # Show debug info only if the app is run locally during development, if the 408 # Show debug info only if the app is run locally during development, if the
359 # currently logged-in user is an admin, or if it is explicitly requested 409 # currently logged-in user is an admin, or if it is explicitly requested
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
461 else: 511 else:
462 self._PrepareDataForTestFailures( 512 self._PrepareDataForTestFailures(
463 analysis, build_info, data, self._ShowDebugInfo()) 513 analysis, build_info, data, self._ShowDebugInfo())
464 return { 514 return {
465 'template': 'waterfall/test_failure.html', 515 'template': 'waterfall/test_failure.html',
466 'data': data 516 'data': data
467 } 517 }
468 518
469 def HandlePost(self): # pragma: no cover 519 def HandlePost(self): # pragma: no cover
470 return self.HandleGet() 520 return self.HandleGet()
OLDNEW
« no previous file with comments | « no previous file | appengine/findit/handlers/test/build_failure_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698