| OLD | NEW |
| 1 # Copyright 2016 The Chromium Authors. All rights reserved. | 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 | 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 import collections | 5 import collections |
| 6 import logging | 6 import logging |
| 7 import os | 7 import os |
| 8 | 8 |
| 9 from google.appengine.api import taskqueue | 9 from google.appengine.api import taskqueue |
| 10 from google.appengine.ext import ndb | 10 from google.appengine.ext import ndb |
| 11 | 11 |
| 12 from dashboard.common import utils | 12 from dashboard.common import utils |
| 13 from dashboard.pinpoint import mann_whitney_u | 13 from dashboard.pinpoint import mann_whitney_u |
| 14 from dashboard.pinpoint.models import attempt as attempt_module | 14 from dashboard.pinpoint.models import attempt as attempt_module |
| 15 from dashboard.pinpoint.models import change as change_module | 15 from dashboard.pinpoint.models import change as change_module |
| 16 from dashboard.pinpoint.models import quest as quest_module | |
| 17 from dashboard.services import issue_tracker_service | 16 from dashboard.services import issue_tracker_service |
| 18 | 17 |
| 19 | 18 |
| 20 # We want this to be fast to minimize overhead while waiting for tasks to | 19 # We want this to be fast to minimize overhead while waiting for tasks to |
| 21 # finish, but don't want to consume too many resources. | 20 # finish, but don't want to consume too many resources. |
| 22 _TASK_INTERVAL = 10 | 21 _TASK_INTERVAL = 10 |
| 23 | 22 |
| 24 | 23 |
| 25 _DEFAULT_REPEAT_COUNT = 10 | 24 _DEFAULT_REPEAT_COUNT = 10 |
| 26 _DEFAULT_ATTEMPT_COUNT = 1 | 25 _DEFAULT_ATTEMPT_COUNT = 1 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 51 | 50 |
| 52 # The name of the Task Queue task this job is running on. If it's present, the | 51 # The name of the Task Queue task this job is running on. If it's present, the |
| 53 # job is running. The task is also None for Task Queue retries. | 52 # job is running. The task is also None for Task Queue retries. |
| 54 task = ndb.StringProperty() | 53 task = ndb.StringProperty() |
| 55 | 54 |
| 56 # The string contents of any Exception that was thrown to the top level. | 55 # The string contents of any Exception that was thrown to the top level. |
| 57 # If it's present, the job failed. | 56 # If it's present, the job failed. |
| 58 exception = ndb.StringProperty() | 57 exception = ndb.StringProperty() |
| 59 | 58 |
| 60 # Request parameters. | 59 # Request parameters. |
| 61 configuration = ndb.StringProperty(required=True) | 60 arguments = ndb.JsonProperty(required=True) |
| 62 test_suite = ndb.StringProperty() | |
| 63 test = ndb.StringProperty() | |
| 64 metric = ndb.StringProperty() | |
| 65 | 61 |
| 66 # If True, the service should pick additional Changes to run (bisect). | 62 # If True, the service should pick additional Changes to run (bisect). |
| 67 # If False, only run the Changes explicitly added by the user. | 63 # If False, only run the Changes explicitly added by the user. |
| 68 auto_explore = ndb.BooleanProperty(required=True) | 64 auto_explore = ndb.BooleanProperty(required=True) |
| 69 | 65 |
| 70 # TODO: The bug id is only used for posting bug comments when a job starts and | 66 # TODO: The bug id is only used for posting bug comments when a job starts and |
| 71 # completes. This probably should not be the responsibility of Pinpoint. | 67 # completes. This probably should not be the responsibility of Pinpoint. |
| 72 bug_id = ndb.IntegerProperty() | 68 bug_id = ndb.IntegerProperty() |
| 73 | 69 |
| 74 state = ndb.PickleProperty(required=True) | 70 state = ndb.PickleProperty(required=True) |
| 75 | 71 |
| 76 @classmethod | 72 @classmethod |
| 77 def New(cls, configuration, test_suite, test, metric, auto_explore, bug_id): | 73 def New(cls, arguments, quests, auto_explore, bug_id): |
| 78 # Get list of quests. | |
| 79 quests = [quest_module.FindIsolate(configuration)] | |
| 80 if test_suite: | |
| 81 quests.append(quest_module.RunTest(configuration, test_suite, test, | |
| 82 _DEFAULT_REPEAT_COUNT)) | |
| 83 if metric: | |
| 84 quests.append(quest_module.ReadValue(metric, test)) | |
| 85 | |
| 86 # Create job. | 74 # Create job. |
| 87 return cls( | 75 return cls( |
| 88 configuration=configuration, | 76 arguments=arguments, |
| 89 test_suite=test_suite, | |
| 90 test=test, | |
| 91 metric=metric, | |
| 92 auto_explore=auto_explore, | 77 auto_explore=auto_explore, |
| 93 bug_id=bug_id, | 78 bug_id=bug_id, |
| 94 state=_JobState(quests, _DEFAULT_ATTEMPT_COUNT)) | 79 state=_JobState(quests, _DEFAULT_ATTEMPT_COUNT)) |
| 95 | 80 |
| 96 @property | 81 @property |
| 97 def job_id(self): | 82 def job_id(self): |
| 98 return self.key.urlsafe() | 83 return self.key.urlsafe() |
| 99 | 84 |
| 100 @property | 85 @property |
| 101 def status(self): | 86 def status(self): |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 156 else: | 141 else: |
| 157 self.Complete() | 142 self.Complete() |
| 158 except BaseException as e: | 143 except BaseException as e: |
| 159 self.Fail(e) | 144 self.Fail(e) |
| 160 raise | 145 raise |
| 161 | 146 |
| 162 def AsDict(self): | 147 def AsDict(self): |
| 163 return { | 148 return { |
| 164 'job_id': self.job_id, | 149 'job_id': self.job_id, |
| 165 | 150 |
| 166 'configuration': self.configuration, | 151 'arguments': self.arguments, |
| 167 'test_suite': self.test_suite, | |
| 168 'test': self.test, | |
| 169 'metric': self.metric, | |
| 170 'auto_explore': self.auto_explore, | 152 'auto_explore': self.auto_explore, |
| 171 | 153 |
| 172 'created': self.created.strftime('%Y-%m-%d %H:%M:%S %Z'), | 154 'created': self.created.strftime('%Y-%m-%d %H:%M:%S %Z'), |
| 173 'updated': self.updated.strftime('%Y-%m-%d %H:%M:%S %Z'), | 155 'updated': self.updated.strftime('%Y-%m-%d %H:%M:%S %Z'), |
| 174 'status': self.status, | 156 'status': self.status, |
| 175 | 157 |
| 176 'state': self.state.AsDict(), | 158 'state': self.state.AsDict(), |
| 177 } | 159 } |
| 178 | 160 |
| 179 | 161 |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 337 | 319 |
| 338 try: | 320 try: |
| 339 p_value = mann_whitney_u.MannWhitneyU(results_a, results_b) | 321 p_value = mann_whitney_u.MannWhitneyU(results_a, results_b) |
| 340 except ValueError: | 322 except ValueError: |
| 341 return _UNKNOWN | 323 return _UNKNOWN |
| 342 | 324 |
| 343 if p_value < _SIGNIFICANCE_LEVEL: | 325 if p_value < _SIGNIFICANCE_LEVEL: |
| 344 return _DIFFERENT | 326 return _DIFFERENT |
| 345 else: | 327 else: |
| 346 return _UNKNOWN | 328 return _UNKNOWN |
| OLD | NEW |