Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 # Copyright 2016 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 | |
| 5 """This module is to handle manual triage of a suspected CL. | |
| 6 | |
| 7 This handler will flag the suspected cl as correct or incorrect. | |
| 8 """ | |
| 9 | |
| 10 from datetime import timedelta | |
| 11 | |
| 12 from google.appengine.api import users | |
| 13 from google.appengine.ext import ndb | |
| 14 | |
| 15 from common import time_util | |
| 16 from common.base_handler import BaseHandler | |
| 17 from common.base_handler import Permission | |
| 18 from model import result_status | |
| 19 from model import suspected_cl_status | |
| 20 from model.base_build_model import BaseBuildModel | |
| 21 from model.wf_analysis import WfAnalysis | |
| 22 from model.wf_suspected_cl import WfSuspectedCL | |
| 23 from waterfall import buildbot | |
| 24 from waterfall.suspected_cl_util import GetCLInfo | |
| 25 | |
| 26 @ndb.transactional | |
| 27 def _UpdateSuspectedCL(repo_name, revision, build_key, cl_status): | |
| 28 suspected_cl = WfSuspectedCL.Get(repo_name, revision) | |
| 29 if (not suspected_cl or not suspected_cl.builds or | |
| 30 not suspected_cl.builds.get(build_key)): | |
| 31 return False | |
| 32 | |
| 33 suspected_cl.builds[build_key]['status'] = cl_status | |
| 34 | |
| 35 cl_correct = True | |
| 36 cl_incorrect = True | |
| 37 partial_triaged = False | |
| 38 # Checks if all the builds have been triaged and checks the status of the cl | |
| 39 # on each build. | |
|
stgao
2016/09/28 00:21:27
This comment is basically how to code does, but it
chanli
2016/10/03 00:00:28
Done.
| |
| 40 for build in suspected_cl.builds.values(): | |
| 41 if build['status'] is None: | |
| 42 partial_triaged = True | |
| 43 elif build['status'] == suspected_cl_status.CORRECT: | |
| 44 cl_incorrect = False | |
| 45 else: | |
| 46 cl_correct = False | |
| 47 | |
| 48 if partial_triaged: | |
| 49 suspected_cl.status = suspected_cl_status.PARTIALLY_TRIAGED | |
| 50 elif cl_correct: | |
| 51 suspected_cl.status = suspected_cl_status.CORRECT | |
| 52 elif cl_incorrect: | |
| 53 suspected_cl.status = suspected_cl_status.INCORRECT | |
| 54 else: | |
| 55 suspected_cl.status = suspected_cl_status.PARTIALLY_CORRECT | |
| 56 | |
| 57 suspected_cl.put() | |
| 58 return True | |
| 59 | |
| 60 | |
| 61 @ndb.transactional | |
| 62 def _UpdateAnalysis( | |
| 63 master_name, builder_name, build_number, repo_name, revision, cl_status): | |
| 64 analysis = WfAnalysis.Get(master_name, builder_name, build_number) | |
| 65 if not analysis or not analysis.suspected_cls: | |
| 66 return False | |
| 67 | |
| 68 num_correct = 0 | |
| 69 num_incorrect = 0 | |
| 70 for cl in analysis.suspected_cls: | |
| 71 if cl['repo_name'] == repo_name and cl['revision'] == revision: | |
| 72 # Updates this cl's status. | |
| 73 cl['status'] = cl_status | |
| 74 | |
| 75 # Checks if all the cls have been triaged and checks the status of each cl | |
| 76 # on the build. | |
| 77 if cl.get('status') == suspected_cl_status.CORRECT: | |
| 78 num_correct += 1 | |
| 79 elif cl.get('status') == suspected_cl_status.INCORRECT: | |
| 80 num_incorrect += 1 | |
| 81 | |
| 82 if num_correct + num_incorrect == len(analysis.suspected_cls): # All triaged. | |
| 83 if num_correct == 0: | |
| 84 analysis.result_status = result_status.FOUND_INCORRECT | |
| 85 elif num_incorrect == 0: | |
| 86 analysis.result_status = result_status.FOUND_CORRECT | |
| 87 else: | |
| 88 analysis.result_status = result_status.PARTIALLY_CORRECT_FOUND | |
| 89 | |
| 90 analysis.put() | |
| 91 return True | |
| 92 | |
| 93 | |
| 94 def _AppendTriageHistoryRecord( | |
| 95 master_name, builder_name, build_number, cl_info, cl_status, user_name): | |
| 96 | |
| 97 analysis = WfAnalysis.Get(master_name, builder_name, build_number) | |
| 98 if not analysis: # pragma: no cover | |
| 99 return | |
| 100 | |
| 101 triage_record = { | |
| 102 'triage_timestamp': time_util.GetUTCNowTimestamp(), | |
| 103 'user_name': user_name, | |
| 104 'cl_status': cl_status, | |
| 105 'version': analysis.version, | |
| 106 'triaged_cl': cl_info | |
| 107 } | |
| 108 if not analysis.triage_history: | |
| 109 analysis.triage_history = [] | |
| 110 analysis.triage_history.append(triage_record) | |
| 111 | |
| 112 analysis.put() | |
| 113 | |
| 114 | |
| 115 def _UpdateSuspectedCLAndAnalysis( | |
| 116 master_name, builder_name, build_number, cl_info, cl_status, user_name): | |
| 117 repo_name, revision = GetCLInfo(cl_info) | |
| 118 build_key = BaseBuildModel.CreateBuildId( | |
| 119 master_name, builder_name, build_number) | |
| 120 | |
| 121 success = ( | |
| 122 _UpdateSuspectedCL(repo_name, revision, build_key, cl_status) and | |
| 123 _UpdateAnalysis(master_name, builder_name, build_number, | |
| 124 repo_name, revision, cl_status)) | |
| 125 | |
| 126 if success: | |
| 127 _AppendTriageHistoryRecord( | |
| 128 master_name, builder_name, build_number, cl_info, cl_status, user_name) | |
| 129 | |
| 130 return success | |
| 131 | |
| 132 | |
| 133 class TriageSuspectedCl(BaseHandler): | |
| 134 PERMISSION_LEVEL = Permission.CORP_USER | |
| 135 | |
| 136 def HandleGet(self): # pragma: no cover | |
| 137 """Sets the manual triage result for the cl.""" | |
| 138 url = self.request.get('url').strip() | |
| 139 build_info = buildbot.ParseBuildUrl(url) | |
| 140 if not build_info: | |
| 141 return {'data': {'success': False}} | |
| 142 master_name, builder_name, build_number = build_info | |
| 143 | |
| 144 cl_status = int(self.request.get('status')) | |
| 145 cl_info = self.request.get('cl_info') | |
| 146 # As the permission level is CORP_USER, we could assume the current user | |
| 147 # already logged in. | |
| 148 user_name = users.get_current_user().email().split('@')[0] | |
| 149 success = _UpdateSuspectedCLAndAnalysis( | |
| 150 master_name, builder_name, build_number, cl_info, cl_status, user_name) | |
| 151 | |
| 152 return {'data': {'success': success}} | |
| 153 | |
| 154 | |
| 155 def HandlePost(self): # pragma: no cover | |
| 156 return self.HandleGet() | |
| OLD | NEW |