def _MakeBisectFYITryJob(test_name, bisect_config): """Creates a TryJob entity with the bisect config. Args: test_name: Name of the test case. bisect_config: A dictionary of parameters for a bisect job. Returns: A TryJob entity, which has not yet been put in the datastore. Raises: NotBisectableError: A valid bisect config could not be created. """ bisect_bot = bisect_config.get('recipe_tester_name') if not bisect_bot: raise auto_bisect.NotBisectableError('Could not select a bisect bot.') config_python_string = utils.BisectConfigPythonString(bisect_config) bisect_job = try_job.TryJob(bot=bisect_bot, config=config_python_string, bug_id=bisect_config.get('bug_id', -1), master_name=bisect_config.get( 'master_name', 'ChromiumPerf'), job_type='bisect-fyi', job_name=test_name) return bisect_job
def _PerformPerfTryJob(perf_job): """Performs the perf try job on the try bot. This creates a patch, uploads it, then tells Rietveld to try the patch. Args: perf_job: TryJob entity with initialized bot name and config. Returns: A dictionary containing the result; if successful, this dictionary contains the field "issue_id", otherwise it contains "error". """ assert perf_job.bot and perf_job.config if not perf_job.key: perf_job.put() bot = perf_job.bot email = perf_job.email config_dict = perf_job.GetConfigDict() config_dict['try_job_id'] = perf_job.key.id() perf_job.config = utils.BisectConfigPythonString(config_dict) # Get the base config file contents and make a patch. try: base_config = gitiles_service.FileContents( 'https://chromium.googlesource.com/chromium/src', 'master', _PERF_CONFIG_PATH) except (urlfetch.Error, gitiles_service.NotFoundError): base_config = None if not base_config: return {'error': 'Error downloading base config'} patch, base_checksum, base_hashes = _CreatePatch(base_config, perf_job.config, _PERF_CONFIG_PATH) # Upload the patch to Rietveld. server = rietveld_service.RietveldService() subject = 'Perf Try Job on behalf of %s' % email issue_id, patchset_id = server.UploadPatch(subject, patch, base_checksum, base_hashes, base_config, _PERF_CONFIG_PATH) if not issue_id: return {'error': 'Error uploading patch to rietveld_service.'} url = 'https://codereview.chromium.org/%s/' % issue_id # Tell Rietveld to try the patch. master = 'tryserver.chromium.perf' trypatch_success = server.TryPatch(master, issue_id, patchset_id, bot) if trypatch_success: # Create TryJob entity. The update_bug_with_results and auto_bisect # cron jobs will be tracking, or restarting the job. perf_job.rietveld_issue_id = int(issue_id) perf_job.rietveld_patchset_id = int(patchset_id) perf_job.SetStarted() return {'issue_id': issue_id} return {'error': 'Error starting try job. Try to fix at %s' % url}
def _MakeBisectTryJob(bug_id, test_anomaly, test): """Tries to automatically select parameters for a bisect job. Args: bug_id: A bug ID which some alerts are associated with. Returns: A TryJob entity, which has not yet been put in the datastore. Raises: NotBisectableError: A valid bisect config could not be created. """ good_revision = _GetRevisionForBisect(test_anomaly.start_revision - 1, test) bad_revision = _GetRevisionForBisect(test_anomaly.end_revision, test) if not can_bisect.IsValidRevisionForBisect(good_revision): raise NotBisectableError('Invalid "good" revision: %s.' % good_revision) if not can_bisect.IsValidRevisionForBisect(bad_revision): raise NotBisectableError('Invalid "bad" revision: %s.' % bad_revision) if test_anomaly.start_revision == test_anomaly.end_revision: raise NotBisectableError('Same "good"/"bad" revisions, bisect skipped') metric = start_try_job.GuessMetric(test.test_path) story_filter = start_try_job.GuessStoryFilter(test.test_path) bisect_bot = start_try_job.GuessBisectBot(test.master_name, test.bot_name) if not bisect_bot: raise NotBisectableError( 'Could not select a bisect bot: %s for (%s, %s)' % (bisect_bot, test.master_name, test.bot_name)) new_bisect_config = start_try_job.GetBisectConfig( bisect_bot=bisect_bot, master_name=test.master_name, suite=test.suite_name, metric=metric, story_filter=story_filter, good_revision=good_revision, bad_revision=bad_revision, repeat_count=10, max_time_minutes=20, bug_id=bug_id) if 'error' in new_bisect_config: raise NotBisectableError('Could not make a valid config.') config_python_string = utils.BisectConfigPythonString(new_bisect_config) bisect_job = try_job.TryJob(bot=bisect_bot, config=config_python_string, bug_id=bug_id, master_name=test.master_name, internal_only=test.internal_only, job_type='bisect') return bisect_job
def testFYI_Send_No_Email_On_Success(self): stored_object.Set( bisect_fyi._BISECT_FYI_CONFIGS_KEY, bisect_fyi_test.TEST_FYI_CONFIGS) test_config = bisect_fyi_test.TEST_FYI_CONFIGS['positive_culprit'] bisect_config = test_config.get('bisect_config') self._AddTryJob(12345, 'started', 'win_perf', results_data=_SAMPLE_BISECT_RESULTS_JSON, internal_only=True, config=utils.BisectConfigPythonString(bisect_config), job_type='bisect-fyi', job_name='positive_culprit', email='*****@*****.**') self.testapp.get('/update_bug_with_results') messages = self.mail_stub.get_sent_messages() self.assertEqual(0, len(messages))
def testFYI_Failed_Job_SendEmail_On_Exception(self): stored_object.Set( bisect_fyi._BISECT_FYI_CONFIGS_KEY, bisect_fyi_test.TEST_FYI_CONFIGS) test_config = bisect_fyi_test.TEST_FYI_CONFIGS['positive_culprit'] bisect_config = test_config.get('bisect_config') sample_bisect_results = copy.deepcopy(_SAMPLE_BISECT_RESULTS_JSON) sample_bisect_results['status'] = 'failed' self._AddTryJob(12345, 'started', 'win_perf', results_data=sample_bisect_results, internal_only=True, buildbucket_job_id='12345', config=utils.BisectConfigPythonString(bisect_config), job_type='bisect-fyi', job_name='positive_culprit', email='*****@*****.**') self.testapp.get('/update_bug_with_results') messages = self.mail_stub.get_sent_messages() self.assertEqual(1, len(messages))
def _MakeBisectTryJob(bug_id, run_count=0): """Tries to automatically select parameters for a bisect job. Args: bug_id: A bug ID which some alerts are associated with. run_count: An integer; this is supposed to represent the number of times that a bisect has been tried for this bug; it is used to try different config parameters on different re-try attempts. Returns: A TryJob entity, which has not yet been put in the datastore. Raises: NotBisectableError: A valid bisect config could not be created. """ anomalies = anomaly.Anomaly.query(anomaly.Anomaly.bug_id == bug_id).fetch() if not anomalies: raise NotBisectableError('No Anomaly alerts found for this bug.') good_revision, bad_revision = _ChooseRevisionRange(anomalies) if not can_bisect.IsValidRevisionForBisect(good_revision): raise NotBisectableError('Invalid "good" revision: %s.' % good_revision) if not can_bisect.IsValidRevisionForBisect(bad_revision): raise NotBisectableError('Invalid "bad" revision: %s.' % bad_revision) test = _ChooseTest(anomalies, run_count) if not test or not can_bisect.IsValidTestForBisect(test.test_path): raise NotBisectableError('Could not select a test.') metric = start_try_job.GuessMetric(test.test_path) story_filter = start_try_job.GuessStoryFilter(test.test_path) bisect_bot = start_try_job.GuessBisectBot(test.master_name, test.bot_name) if not bisect_bot or '_' not in bisect_bot: raise NotBisectableError('Could not select a bisect bot.') new_bisect_config = start_try_job.GetBisectConfig( bisect_bot=bisect_bot, master_name=test.master_name, suite=test.suite_name, metric=metric, story_filter=story_filter, good_revision=good_revision, bad_revision=bad_revision, repeat_count=10, max_time_minutes=20, bug_id=bug_id, use_archive='true') if 'error' in new_bisect_config: raise NotBisectableError('Could not make a valid config.') config_python_string = utils.BisectConfigPythonString(new_bisect_config) bisect_job = try_job.TryJob(bot=bisect_bot, config=config_python_string, bug_id=bug_id, master_name=test.master_name, internal_only=test.internal_only, job_type='bisect') return bisect_job