| OLD | NEW |
| 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 google.appengine.ext import ndb | 5 from google.appengine.ext import ndb |
| 6 | 6 |
| 7 from model.base_build_model import BaseBuildModel | 7 from model.base_build_model import BaseBuildModel |
| 8 from model import wf_analysis_status | 8 from model import analysis_status |
| 9 from model import wf_analysis_result_status | 9 from model import result_status |
| 10 | 10 |
| 11 | 11 |
| 12 class WfAnalysis(BaseBuildModel): | 12 class WfAnalysis(BaseBuildModel): |
| 13 """Represents an analysis of a build of a builder in a Chromium waterfall. | 13 """Represents an analysis of a build of a builder in a Chromium waterfall. |
| 14 | 14 |
| 15 'Wf' is short for waterfall. | 15 'Wf' is short for waterfall. |
| 16 """ | 16 """ |
| 17 @staticmethod | 17 @staticmethod |
| 18 def _CreateKey(master_name, builder_name, build_number): # pragma: no cover | 18 def _CreateKey(master_name, builder_name, build_number): # pragma: no cover |
| 19 return ndb.Key('WfAnalysis', | 19 return ndb.Key('WfAnalysis', |
| 20 BaseBuildModel.CreateBuildId( | 20 BaseBuildModel.CreateBuildId( |
| 21 master_name, builder_name, build_number)) | 21 master_name, builder_name, build_number)) |
| 22 | 22 |
| 23 @staticmethod | 23 @staticmethod |
| 24 def Create(master_name, builder_name, build_number): # pragma: no cover | 24 def Create(master_name, builder_name, build_number): # pragma: no cover |
| 25 return WfAnalysis( | 25 return WfAnalysis( |
| 26 key=WfAnalysis._CreateKey(master_name, builder_name, build_number)) | 26 key=WfAnalysis._CreateKey(master_name, builder_name, build_number)) |
| 27 | 27 |
| 28 @staticmethod | 28 @staticmethod |
| 29 def Get(master_name, builder_name, build_number): # pragma: no cover | 29 def Get(master_name, builder_name, build_number): # pragma: no cover |
| 30 return WfAnalysis._CreateKey(master_name, builder_name, build_number).get() | 30 return WfAnalysis._CreateKey(master_name, builder_name, build_number).get() |
| 31 | 31 |
| 32 @property | 32 @property |
| 33 def completed(self): | 33 def completed(self): |
| 34 return self.status in ( | 34 return self.status in ( |
| 35 wf_analysis_status.ANALYZED, wf_analysis_status.ERROR) | 35 analysis_status.COMPLETED, analysis_status.ERROR) |
| 36 | 36 |
| 37 @property | 37 @property |
| 38 def duration(self): | 38 def duration(self): |
| 39 if not self.completed or not self.end_time or not self.start_time: | 39 if not self.completed or not self.end_time or not self.start_time: |
| 40 return None | 40 return None |
| 41 | 41 |
| 42 return int((self.end_time - self.start_time).total_seconds()) | 42 return int((self.end_time - self.start_time).total_seconds()) |
| 43 | 43 |
| 44 @property | 44 @property |
| 45 def failed(self): | 45 def failed(self): |
| 46 return self.status == wf_analysis_status.ERROR | 46 return self.status == analysis_status.ERROR |
| 47 | 47 |
| 48 @property | 48 @property |
| 49 def status_description(self): | 49 def status_description(self): |
| 50 return wf_analysis_status.STATUS_TO_DESCRIPTION.get(self.status, 'Unknown') | 50 return analysis_status.STATUS_TO_DESCRIPTION.get(self.status, 'Unknown') |
| 51 | 51 |
| 52 @property | 52 @property |
| 53 def result_status_description(self): | 53 def result_status_description(self): |
| 54 return wf_analysis_result_status.RESULT_STATUS_TO_DESCRIPTION.get( | 54 return result_status.RESULT_STATUS_TO_DESCRIPTION.get( |
| 55 self.result_status, '') | 55 self.result_status, '') |
| 56 | 56 |
| 57 @property | 57 @property |
| 58 def correct(self): | 58 def correct(self): |
| 59 """Returns whether the analysis result is correct or not. | 59 """Returns whether the analysis result is correct or not. |
| 60 | 60 |
| 61 Returns: | 61 Returns: |
| 62 True: correct | 62 True: correct |
| 63 False: incorrect | 63 False: incorrect |
| 64 None: don't know yet. | 64 None: don't know yet. |
| 65 """ | 65 """ |
| 66 if not self.completed or self.failed: | 66 if not self.completed or self.failed: |
| 67 return None | 67 return None |
| 68 | 68 |
| 69 if self.result_status in ( | 69 if self.result_status in ( |
| 70 wf_analysis_result_status.FOUND_CORRECT, | 70 result_status.FOUND_CORRECT, |
| 71 wf_analysis_result_status.NOT_FOUND_CORRECT, | 71 result_status.NOT_FOUND_CORRECT, |
| 72 wf_analysis_result_status.FOUND_CORRECT_DUPLICATE): | 72 result_status.FOUND_CORRECT_DUPLICATE): |
| 73 return True | 73 return True |
| 74 | 74 |
| 75 if self.result_status in ( | 75 if self.result_status in ( |
| 76 wf_analysis_result_status.FOUND_INCORRECT, | 76 result_status.FOUND_INCORRECT, |
| 77 wf_analysis_result_status.NOT_FOUND_INCORRECT, | 77 result_status.NOT_FOUND_INCORRECT, |
| 78 wf_analysis_result_status.FOUND_INCORRECT_DUPLICATE): | 78 result_status.FOUND_INCORRECT_DUPLICATE): |
| 79 return False | 79 return False |
| 80 | 80 |
| 81 return None | 81 return None |
| 82 | 82 |
| 83 def Reset(self): # pragma: no cover | 83 def Reset(self): # pragma: no cover |
| 84 """Resets to the state as if no analysis is run.""" | 84 """Resets to the state as if no analysis is run.""" |
| 85 self.pipeline_status_path = None | 85 self.pipeline_status_path = None |
| 86 self.status = wf_analysis_status.PENDING | 86 self.status = analysis_status.PENDING |
| 87 self.request_time = None | 87 self.request_time = None |
| 88 self.start_time = None | 88 self.start_time = None |
| 89 self.end_time = None | 89 self.end_time = None |
| 90 | 90 |
| 91 # When the build cycle started. | 91 # When the build cycle started. |
| 92 build_start_time = ndb.DateTimeProperty(indexed=True) | 92 build_start_time = ndb.DateTimeProperty(indexed=True) |
| 93 build_completed = ndb.BooleanProperty(indexed=False) | 93 build_completed = ndb.BooleanProperty(indexed=False) |
| 94 | 94 |
| 95 # The url path to the pipeline status page. | 95 # The url path to the pipeline status page. |
| 96 pipeline_status_path = ndb.StringProperty(indexed=False) | 96 pipeline_status_path = ndb.StringProperty(indexed=False) |
| 97 # The status of the analysis. | 97 # The status of the analysis. |
| 98 status = ndb.IntegerProperty( | 98 status = ndb.IntegerProperty( |
| 99 default=wf_analysis_status.PENDING, indexed=False) | 99 default=analysis_status.PENDING, indexed=False) |
| 100 # When the analysis was requested. | 100 # When the analysis was requested. |
| 101 request_time = ndb.DateTimeProperty(indexed=False) | 101 request_time = ndb.DateTimeProperty(indexed=False) |
| 102 # When the analysis actually started. | 102 # When the analysis actually started. |
| 103 start_time = ndb.DateTimeProperty(indexed=False) | 103 start_time = ndb.DateTimeProperty(indexed=False) |
| 104 # When the analysis actually ended. | 104 # When the analysis actually ended. |
| 105 end_time = ndb.DateTimeProperty(indexed=False) | 105 end_time = ndb.DateTimeProperty(indexed=False) |
| 106 # When the analysis was updated. | 106 # When the analysis was updated. |
| 107 updated_time = ndb.DateTimeProperty(indexed=False, auto_now=True) | 107 updated_time = ndb.DateTimeProperty(indexed=False, auto_now=True) |
| 108 # Record which version of analysis. | 108 # Record which version of analysis. |
| 109 version = ndb.StringProperty(indexed=False) | 109 version = ndb.StringProperty(indexed=False) |
| 110 | 110 |
| 111 # Analysis result for the build failure. | 111 # Analysis result for the build failure. |
| 112 not_passed_steps = ndb.StringProperty(indexed=False, repeated=True) | 112 not_passed_steps = ndb.StringProperty(indexed=False, repeated=True) |
| 113 result = ndb.JsonProperty(indexed=False, compressed=True) | 113 result = ndb.JsonProperty(indexed=False, compressed=True) |
| 114 # Suspected CLs we found. | 114 # Suspected CLs we found. |
| 115 suspected_cls = ndb.JsonProperty(indexed=False, compressed=True) | 115 suspected_cls = ndb.JsonProperty(indexed=False, compressed=True) |
| 116 # Record the id of try job results of each failure. | 116 # Record the id of try job results of each failure. |
| 117 failure_result_map = ndb.JsonProperty(indexed=False, compressed=True) | 117 failure_result_map = ndb.JsonProperty(indexed=False, compressed=True) |
| 118 | 118 |
| 119 # The actual culprit CLs that are responsible for the failures. | 119 # The actual culprit CLs that are responsible for the failures. |
| 120 culprit_cls = ndb.JsonProperty(indexed=False, compressed=True) | 120 culprit_cls = ndb.JsonProperty(indexed=False, compressed=True) |
| 121 # Conclusion of analysis result for the build failure: 'Found' or 'Not Found'. | 121 # Conclusion of analysis result for the build failure: 'Found' or 'Not Found'. |
| 122 result_status = ndb.IntegerProperty(indexed=True) | 122 result_status = ndb.IntegerProperty(indexed=True) |
| 123 # Record the history of triage. | 123 # Record the history of triage. |
| 124 triage_history = ndb.JsonProperty(indexed=False, compressed=True) | 124 triage_history = ndb.JsonProperty(indexed=False, compressed=True) |
| OLD | NEW |