def DownloadBuildData(master_name, builder_name, build_number): """Downloads build data and returns a WfBuild instance.""" build = WfBuild.Get(master_name, builder_name, build_number) if not build: build = WfBuild.Create(master_name, builder_name, build_number) # Cache the data to avoid pulling from master again. if _BuildDataNeedUpdating(build): use_cbe = waterfall_config.GetDownloadBuildDataSettings().get( 'use_chrome_build_extract') if use_cbe: # Retrieve build data from build archive first. build.data = buildbot.GetBuildDataFromArchive( master_name, builder_name, build_number, HTTP_CLIENT_NO_404_ERROR) if build.data: build.data_source = CHROME_BUILD_EXTRACT elif not lock_util.WaitUntilDownloadAllowed( master_name): # pragma: no cover return None if not build.data or not use_cbe: # Retrieve build data from build master. build.data = buildbot.GetBuildDataFromBuildMaster( master_name, builder_name, build_number, HTTP_CLIENT_LOGGING_ERRORS) build.data_source = BUILDBOT_MASTER build.last_crawled_time = time_util.GetUTCNow() build.put() return build
def _DownloadBuildData(self, master_name, builder_name, build_number): """Downloads build data and returns a WfBuild instance.""" build = WfBuild.Get(master_name, builder_name, build_number) if not build: build = WfBuild.Create(master_name, builder_name, build_number) # Cache the data to avoid pulling from master again. if self._BuildDataNeedUpdating(build): # Retrieve build data from build archive first. build.data = buildbot.GetBuildDataFromArchive( build.master_name, build.builder_name, build.build_number, self.HTTP_CLIENT_NO_404_ERROR) if build.data is None: if not lock_util.WaitUntilDownloadAllowed( master_name): # pragma: no cover raise pipeline.Retry('Too many download from %s' % master_name) # Retrieve build data from build master. build.data = buildbot.GetBuildDataFromBuildMaster( build.master_name, build.builder_name, build.build_number, self.HTTP_CLIENT_LOGGING_ERRORS) build.last_crawled_time = datetime.utcnow() build.put() return build
def _MockDownloadBuildData(self, master_name, builder_name, build_number): build = WfBuild.Get(master_name, builder_name, build_number) if not build: # pragma: no cover build = WfBuild.Create(master_name, builder_name, build_number) build.data = self._GetBuildInfo(master_name, builder_name, build_number) build.put() return build
def NeedANewWaterfallTryJob(master_name, builder_name, build_number, failure_info, signals, heuristic_result, force_try_job=False): tryserver_mastername, tryserver_buildername = ( waterfall_config.GetWaterfallTrybot(master_name, builder_name)) try_job_type = failure_info['failure_type'] if not tryserver_mastername or not tryserver_buildername: logging.info('%s, %s is not supported yet.', master_name, builder_name) return False, None if not force_try_job: build = WfBuild.Get(master_name, builder_name, build_number) if _ShouldBailOutForOutdatedBuild(build): logging.error('Build time %s is more than 24 hours old. ' 'Try job will not be triggered.' % build.start_time) return False, None if try_job_type == failure_type.COMPILE: need_new_try_job = _NeedANewCompileTryJob(master_name, builder_name, build_number, failure_info) else: need_new_try_job = _NeedANewTestTryJob(master_name, builder_name, build_number, failure_info, force_try_job) # TODO(chanli): enable the feature to trigger single try job for a group # when notification is ready. # We still call _IsBuildFailureUniqueAcrossPlatforms just so we have data for # failure groups. # TODO(chanli): Add checking for culprits of the group when enabling # single try job: add current build to suspected_cl.builds if the try job for # this group has already completed. if need_new_try_job: _IsBuildFailureUniqueAcrossPlatforms( master_name, builder_name, build_number, try_job_type, failure_info['builds'][str(build_number)]['blame_list'], failure_info['failed_steps'], signals, heuristic_result) try_job_was_created, try_job_key = _ReviveOrCreateTryJobEntity( master_name, builder_name, build_number, force_try_job) need_new_try_job = need_new_try_job and try_job_was_created return need_new_try_job, try_job_key
def DownloadBuildData(master_name, builder_name, build_number): """Downloads build data and returns a WfBuild instance.""" build = WfBuild.Get(master_name, builder_name, build_number) if not build: build = WfBuild.Create(master_name, builder_name, build_number) if build.build_id: return build luci_project, luci_bucket = buildbot.GetLuciProjectAndBucketForMaster( master_name) bb_build = buildbucket_client.GetV2BuildByBuilderAndBuildNumber( luci_project, luci_bucket, builder_name, build_number) build.last_crawled_time = time_util.GetUTCNow() build.build_id = str(bb_build.id) build.put() return build
def NeedANewWaterfallTryJob(master_name, builder_name, build_number, force_try_job, build_completed=True): """Preliminary check if a new try job is needed. Don't need try job if build not completed yet, only runs for builds started within 24 hours, unless it's a forced rerun. """ if not build_completed: return False if not force_try_job: build = WfBuild.Get(master_name, builder_name, build_number) if _ShouldBailOutForOutdatedBuild(build): logging.error('Build time %s is more than 24 hours old. ' 'Try job will not be triggered.' % build.start_time) return False return True
def StoreDetectedCIFlakes(master_name, builder_name, build_number, flaky_tests): """Stores detected CL flakes to datastore. Args: master_name(str): Name of the master. builder_name(str): Name of the builder. build_number(int): Number of the build. flaky_tests(dict): A dict of flaky tests, in the format: { 'step1': ['test1', 'test2', ...], ... } """ build = WfBuild.Get(master_name, builder_name, build_number) if not build or not build.build_id: logging.error( 'Could not save CI flake on %s/%s/%d since the build or build_id' ' is missing.', master_name, builder_name, build_number) return luci_project, luci_bucket = build_util.GetBuilderInfoForLUCIBuild( build.build_id) if not luci_project or not luci_bucket: # pragma: no branch. logging.debug( 'Could not get luci_project or luci_bucket from' ' build %s/%s/%d.', master_name, builder_name, build_number) return row = { 'luci_project': luci_project, 'luci_bucket': luci_bucket, 'luci_builder': builder_name, 'legacy_master_name': master_name, 'legacy_build_number': build_number, 'build_id': int(build.build_id), 'test_start_msec': time_util.GetUTCNow(), # No affected gerrit cls for CI flakes, set related fields to None. 'gerrit_project': None, 'gerrit_cl_id': -1 } local_flakes = [] local_flake_occurrences = [] for step, step_flaky_tests in flaky_tests.iteritems(): row['step_ui_name'] = step for flaky_test in step_flaky_tests: row['test_name'] = flaky_test local_flakes.append(_CreateFlakeFromRow(row)) local_flake_occurrences.append( _CreateFlakeOccurrenceFromRow(row, FlakeType.CI_FAILED_STEP)) _StoreMultipleLocalEntities(local_flakes) new_occurrences = _StoreMultipleLocalEntities(local_flake_occurrences) _UpdateFlakeMetadata(new_occurrences) flake_type_desc = FLAKE_TYPE_DESCRIPTIONS.get(FlakeType.CI_FAILED_STEP, 'N/A') monitoring.OnFlakeDetectionDetectNewOccurrences( flake_type=flake_type_desc, num_occurrences=len(new_occurrences))