| OLD | NEW |
| 1 # coding=utf8 | 1 # coding=utf8 |
| 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 """Sends patches to the Try server and reads back results. | 5 """Sends patches to the Try server and reads back results. |
| 6 | 6 |
| 7 - RietveldTryJobs contains RietveldTryJob, one per try job on a builder. | 7 - RietveldTryJobs contains RietveldTryJob, one per try job on a builder. |
| 8 - TryRunnerRietveld uses Rietveld to signal and poll job results. | 8 - TryRunnerRietveld uses Rietveld to signal and poll job results. |
| 9 """ | 9 """ |
| 10 | 10 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 30 if timestamp < (time.time() - 4*24*60*60): | 30 if timestamp < (time.time() - 4*24*60*60): |
| 31 return True | 31 return True |
| 32 if checkout.revisions(revision, None) >= 200: | 32 if checkout.revisions(revision, None) >= 200: |
| 33 return True | 33 return True |
| 34 return False | 34 return False |
| 35 | 35 |
| 36 | 36 |
| 37 class RietveldTryJobPending(model.PersistentMixIn): | 37 class RietveldTryJobPending(model.PersistentMixIn): |
| 38 """Represents a pending try job for a pending commit that we care about. | 38 """Represents a pending try job for a pending commit that we care about. |
| 39 """ | 39 """ |
| 40 persistent = [ | 40 builder = str |
| 41 'builder', 'revision', 'requested_steps', | 41 revision = (None, str, int) |
| 42 'clobber', 'tries', | 42 requested_steps = list |
| 43 ] | 43 clobber = bool |
| 44 def __init__(self, builder, revision, requested_steps, clobber, tries): | 44 # Number of retries for this configuration. Initial try is 1. |
| 45 super(RietveldTryJobPending, self).__init__() | 45 tries = int |
| 46 self.builder = builder | |
| 47 self.revision = revision | |
| 48 self.requested_steps = requested_steps | |
| 49 self.clobber = clobber | |
| 50 # Number of retries for this configuration. Initial try is 1. | |
| 51 self.tries = tries | |
| 52 | 46 |
| 53 | 47 |
| 54 class RietveldTryJob(model.PersistentMixIn): | 48 class RietveldTryJob(model.PersistentMixIn): |
| 55 """Represents a try job for a pending commit that we care about. | 49 """Represents a try job for a pending commit that we care about. |
| 56 | 50 |
| 57 This data can be regenerated by parsing all the try job names but it is a bit | 51 This data can be regenerated by parsing all the try job names but it is a bit |
| 58 hard on the try server. | 52 hard on the try server. |
| 59 """ | 53 """ |
| 60 persistent = [ | 54 builder = str |
| 61 'builder', 'build', 'revision', 'requested_steps', 'started', | 55 build = int |
| 62 'steps_passed', 'steps_failed', 'clobber', 'completed', 'tries', | 56 revision = (None, str, int) |
| 63 'parent_key', 'init_time', | 57 requested_steps = list |
| 64 ] | 58 # The timestamp when the build started. |
| 59 started = int |
| 60 steps_passed = list |
| 61 steps_failed = list |
| 62 clobber = bool |
| 63 completed = bool |
| 64 # Number of retries for this configuration. Initial try is 1. |
| 65 tries = int |
| 66 parent_key = (None, str) |
| 67 init_time = int |
| 65 | 68 |
| 66 def __init__( | 69 def __init__(self, **kwargs): |
| 67 self, builder, build, revision, requested_steps, started, steps_passed, | 70 super(RietveldTryJob, self).__init__(init_time=time.time(), **kwargs) |
| 68 steps_failed, clobber, completed, tries, parent_key): | |
| 69 super(RietveldTryJob, self).__init__() | |
| 70 self.builder = builder | |
| 71 self.build = build | |
| 72 self.revision = revision | |
| 73 self.requested_steps = requested_steps | |
| 74 # The timestamp when the build started. | |
| 75 self.started = started | |
| 76 self.steps_passed = steps_passed | |
| 77 self.steps_failed = steps_failed | |
| 78 self.clobber = clobber | |
| 79 self.completed = completed | |
| 80 self.init_time = time.time() | |
| 81 # Number of retries for this configuration. Initial try is 1. | |
| 82 self.tries = tries | |
| 83 self.parent_key = parent_key | |
| 84 | 71 |
| 85 @property | 72 @property |
| 86 def result(self): | 73 def result(self): |
| 87 if self.steps_failed: | 74 if self.steps_failed: |
| 88 return buildbot_json.FAILURE | 75 return buildbot_json.FAILURE |
| 89 if self.completed: | 76 if self.completed: |
| 90 return buildbot_json.SUCCESS | 77 return buildbot_json.SUCCESS |
| 91 return None | 78 return None |
| 92 | 79 |
| 93 def stewed(self): | 80 def stewed(self): |
| 94 """Returns True if this job has had time to propagate.""" | 81 """Returns True if this job has had time to propagate.""" |
| 95 return time.time() - self.init_time > PROPOGATION_DELAY_S | 82 return time.time() - self.init_time > PROPOGATION_DELAY_S |
| 96 | 83 |
| 97 def __eq__(self, rhs): | 84 def __eq__(self, rhs): |
| 98 for i in self.persistent: | 85 for i in self._persistent_members(): |
| 99 if getattr(self, i) != getattr(rhs, i): | 86 if getattr(self, i) != getattr(rhs, i): |
| 100 return False | 87 return False |
| 101 return True | 88 return True |
| 102 | 89 |
| 103 def __ne__(self, rhs): | 90 def __ne__(self, rhs): |
| 104 return not self.__eq__(rhs) | 91 return not self.__eq__(rhs) |
| 105 | 92 |
| 106 | 93 |
| 107 class RietveldTryJobs(base.IVerifierStatus): | 94 class RietveldTryJobs(base.IVerifierStatus): |
| 108 """A set of try jobs that were sent for a specific patch. | 95 """A set of try jobs that were sent for a specific patch. |
| 109 | 96 |
| 110 Multiple concurrent try jobs can be sent on a single builder. For example, a | 97 Multiple concurrent try jobs can be sent on a single builder. For example, a |
| 111 previous valid try job could have been triggered by the user but was not | 98 previous valid try job could have been triggered by the user but was not |
| 112 completed so another was sent with the missing tests. | 99 completed so another was sent with the missing tests. |
| 113 Also, a try job is sent as soon as a test failure is detected. | 100 Also, a try job is sent as soon as a test failure is detected. |
| 114 """ | 101 """ |
| 115 persistent = base.IVerifierStatus.persistent + [ | 102 # An dict of RietveldTryJob objects per key. |
| 116 'try_jobs', 'irrelevant', 'skipped', 'builders_and_tests', 'pendings', | 103 try_jobs = dict |
| 117 'triggered_builders', | 104 # The try job keys we ignore because they can't be used to give a good |
| 118 ] | 105 # signal: either they are too old (old revision) or they were not triggerd |
| 119 | 106 # by Rietveld, so we don't know if the diff is 100% good. |
| 120 def __init__(self): | 107 irrelevant = list |
| 121 super(RietveldTryJobs, self).__init__() | 108 # When NOTRY=true is specified. |
| 122 # An dict of RietveldTryJob objects per key. | 109 skipped = bool |
| 123 self.try_jobs = {} | 110 # Mapping from builders to list of tests. |
| 124 # The try job keys we ignore because they can't be used to give a good | 111 builders_and_tests = dict |
| 125 # signal: either they are too old (old revision) or they were not triggerd | 112 # Mapping from triggered builders to their parent. Do not change this |
| 126 # by Rietveld, so we don't know if the diff is 100% good. | 113 # directly. Instead use self.update_triggered_builders() |
| 127 self.irrelevant = [] | 114 triggered_builders = dict |
| 128 # When NOTRY=true is specified. | 115 # Jobs that have been sent but are not found yet. Likely a builder is fully |
| 129 self.skipped = False | 116 # utilized or the try server hasn't polled Rietveld yet. list of |
| 130 # Mapping from builders to list of tests. | 117 # RietveldTryJobPending() instances. |
| 131 self.builders_and_tests = {} | 118 pendings = list |
| 132 # Mapping from triggered builders to their parent. Do not change this | |
| 133 # directly. Instead use self.update_triggered_builders() | |
| 134 self.triggered_builders = {} | |
| 135 # Jobs that have been sent but are not found yet. Likely a builder is fully | |
| 136 # utilized or the try server hasn't polled Rietveld yet. list of | |
| 137 # RietveldTryJobPending() instances. | |
| 138 self.pendings = [] | |
| 139 | 119 |
| 140 def update_triggered_builders(self, new_triggered_builders): | 120 def update_triggered_builders(self, new_triggered_builders): |
| 141 """Add triggered builders to verification list. | 121 """Add triggered builders to verification list. |
| 142 | 122 |
| 143 Args: | 123 Args: |
| 144 new_triggered_builders: list of (builder, parent_name, list of tests) | 124 new_triggered_builders: list of (builder, parent_name, list of tests) |
| 145 """ | 125 """ |
| 146 for builder, parent, tests in new_triggered_builders: | 126 for builder, parent, tests in new_triggered_builders: |
| 147 if builder in self.triggered_builders: | 127 if builder in self.triggered_builders: |
| 148 logging.warning( | 128 logging.warning( |
| (...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 598 return match and match.group(1).lower() == 'true' | 578 return match and match.group(1).lower() == 'true' |
| 599 | 579 |
| 600 def _update_jobs_from_rietveld(self, pending, jobs): | 580 def _update_jobs_from_rietveld(self, pending, jobs): |
| 601 """Grabs data from Rietveld and pass it to | 581 """Grabs data from Rietveld and pass it to |
| 602 RietveldTryJobs.update_jobs_from_rietveld(). | 582 RietveldTryJobs.update_jobs_from_rietveld(). |
| 603 """ | 583 """ |
| 604 data = self.context.rietveld.get_patchset_properties( | 584 data = self.context.rietveld.get_patchset_properties( |
| 605 pending.issue, pending.patchset) | 585 pending.issue, pending.patchset) |
| 606 return jobs.update_jobs_from_rietveld( | 586 return jobs.update_jobs_from_rietveld( |
| 607 data, self.status, self.context.checkout) | 587 data, self.status, self.context.checkout) |
| OLD | NEW |