예제 #1
0
    def testAnalyzeBuildFailurePipelineAbortedWithoutAnalysis(self):
        master_name = 'm'
        builder_name = 'b'
        build_number = 124

        root_pipeline = AnalyzeBuildFailurePipeline(master_name, builder_name,
                                                    build_number)
        root_pipeline._LogUnexpectedAborting(True)

        analysis = WfAnalysis.Get(master_name, builder_name, build_number)
        self.assertIsNone(analysis)
  def testAnalyzeBuildFailurePipelineAbortedWithoutAnalysis(self):
    master_name = 'm'
    builder_name = 'b'
    build_number = 124

    root_pipeline = AnalyzeBuildFailurePipeline(master_name,
                                                builder_name,
                                                build_number)
    root_pipeline._LogUnexpectedAborting(True)

    analysis = WfAnalysis.Get(master_name, builder_name, build_number)
    self.assertIsNone(analysis)
예제 #3
0
    def testBuildFailurePipelineFlow(self):
        master_name = 'm'
        builder_name = 'b'
        build_number = 124

        self._Setup(master_name, builder_name, build_number)

        self.MockPipeline(
            analyze_build_failure_pipeline.DetectFirstFailurePipeline,
            'failure_info',
            expected_args=[master_name, builder_name, build_number],
            expected_kwargs={})
        self.MockPipeline(analyze_build_failure_pipeline.PullChangelogPipeline,
                          'change_logs',
                          expected_args=['failure_info'],
                          expected_kwargs={})
        self.MockPipeline(
            analyze_build_failure_pipeline.ExtractDEPSInfoPipeline,
            'deps_info',
            expected_args=['failure_info', 'change_logs'],
            expected_kwargs={})
        self.MockPipeline(analyze_build_failure_pipeline.ExtractSignalPipeline,
                          'signals',
                          expected_args=['failure_info'],
                          expected_kwargs={})
        self.MockPipeline(
            analyze_build_failure_pipeline.IdentifyCulpritPipeline,
            'heuristic_result',
            expected_args=[
                'failure_info', 'change_logs', 'deps_info', 'signals', False
            ],
            expected_kwargs={})
        self.MockPipeline(
            analyze_build_failure_pipeline.TriggerSwarmingTasksPipeline,
            None,
            expected_args=[
                master_name, builder_name, build_number, 'failure_info', False
            ],
            expected_kwargs={})
        self.MockPipeline(
            analyze_build_failure_pipeline.StartTryJobOnDemandPipeline,
            'try_job_result',
            expected_args=[
                master_name, builder_name, build_number, 'failure_info',
                'signals', 'heuristic_result', False, False
            ],
            expected_kwargs={})

        root_pipeline = AnalyzeBuildFailurePipeline(master_name, builder_name,
                                                    build_number, False, False)
        root_pipeline.start(queue_name=constants.DEFAULT_QUEUE)
        self.execute_queued_tasks()
예제 #4
0
    def testBuildFailurePipelineStartWithNoneResultStatus(self):
        master_name = 'm'
        builder_name = 'b'
        build_number = 124

        self._Setup(master_name, builder_name, build_number)

        root_pipeline = AnalyzeBuildFailurePipeline(master_name, builder_name,
                                                    build_number, False, False)
        root_pipeline._ResetAnalysis(master_name, builder_name, build_number)
        analysis = WfAnalysis.Get(master_name, builder_name, build_number)
        self.assertIsNotNone(analysis)
        self.assertEqual(analysis_status.RUNNING, analysis.status)
        self.assertIsNone(analysis.result_status)
예제 #5
0
    def testAnalyzeBuildFailurePipelineNotAborted(self):
        master_name = 'm'
        builder_name = 'b'
        build_number = 124

        self._Setup(master_name, builder_name, build_number)

        root_pipeline = AnalyzeBuildFailurePipeline(master_name, builder_name,
                                                    build_number)
        root_pipeline._LogUnexpectedAborting(False)

        analysis = WfAnalysis.Get(master_name, builder_name, build_number)
        self.assertIsNotNone(analysis)
        self.assertNotEqual(wf_analysis_status.ERROR, analysis.status)
  def testAnalyzeBuildFailurePipelineNotAborted(self):
    master_name = 'm'
    builder_name = 'b'
    build_number = 124

    self._Setup(master_name, builder_name, build_number)

    root_pipeline = AnalyzeBuildFailurePipeline(master_name,
                                                builder_name,
                                                build_number)
    root_pipeline._LogUnexpectedAborting(False)

    analysis = WfAnalysis.Get(master_name, builder_name, build_number)
    self.assertIsNotNone(analysis)
    self.assertNotEqual(wf_analysis_status.ERROR, analysis.status)
  def testBuildFailurePipelineStartWithNoneResultStatus(self):
    master_name = 'm'
    builder_name = 'b'
    build_number = 124

    self._Setup(master_name, builder_name, build_number)

    root_pipeline = AnalyzeBuildFailurePipeline(master_name,
                                                builder_name,
                                                build_number)
    root_pipeline._ResetAnalysis(master_name, builder_name, build_number)
    analysis = WfAnalysis.Get(master_name, builder_name, build_number)
    self.assertIsNotNone(analysis)
    self.assertEqual(wf_analysis_status.ANALYZING, analysis.status)
    self.assertIsNone(analysis.result_status)
예제 #8
0
    def testAnalyzeBuildFailurePipelineNotAbortedIfWithoutError(self):
        master_name = 'm'
        builder_name = 'b'
        build_number = 124

        self._Setup(master_name,
                    builder_name,
                    build_number,
                    status=analysis_status.COMPLETED)

        root_pipeline = AnalyzeBuildFailurePipeline(master_name, builder_name,
                                                    build_number, False, False)
        root_pipeline._LogUnexpectedAborting(True)

        analysis = WfAnalysis.Get(master_name, builder_name, build_number)
        self.assertIsNotNone(analysis)
        self.assertNotEqual(analysis_status.ERROR, analysis.status)
예제 #9
0
    def testBuildFailurePipeline(self):
        master_name = 'm'
        builder_name = 'b'
        build_number = 124

        self._Setup(master_name, builder_name, build_number)

        root_pipeline = AnalyzeBuildFailurePipeline(master_name, builder_name,
                                                    build_number)
        root_pipeline.start(queue_name='default')
        self.execute_queued_tasks()

        expected_analysis_result = {
            'failures': [{
                'step_name':
                'a',
                'first_failure':
                124,
                'last_pass':
                123,
                'suspected_cls': [{
                    'build_number':
                    124,
                    'repo_name':
                    'chromium',
                    'revision':
                    'some_git_hash',
                    'commit_position':
                    8888,
                    'url': ('https://chromium.googlesource.com/chromium'
                            '/src.git/+/some_git_hash'),
                    'score':
                    2,
                    'hints': {
                        'modified x.cc (and it was in log)': 2,
                    },
                }],
            }]
        }

        analysis = WfAnalysis.Get(master_name, builder_name, build_number)
        self.assertIsNotNone(analysis)
        self.assertEqual(wf_analysis_status.ANALYZED, analysis.status)
        self.assertEqual(expected_analysis_result, analysis.result)
        self.assertIsNotNone(analysis.result_status)
  def testBuildFailurePipeline(self):
    master_name = 'm'
    builder_name = 'b'
    build_number = 124

    self._Setup(master_name, builder_name, build_number)

    root_pipeline = AnalyzeBuildFailurePipeline(master_name,
                                                builder_name,
                                                build_number,
                                                False)
    root_pipeline.start(queue_name=constants.DEFAULT_QUEUE)
    self.execute_queued_tasks()

    expected_analysis_result = {
        'failures': [
            {
                'step_name': 'a',
                'supported': True,
                'first_failure': 124,
                'last_pass': 123,
                'suspected_cls': [
                    {
                        'build_number': 124,
                        'repo_name': 'chromium',
                        'revision': 'some_git_hash',
                        'commit_position': 8888,
                        'url': ('https://chromium.googlesource.com/chromium'
                                '/src.git/+/some_git_hash'),
                        'score': 2,
                        'hints': {
                            'modified x.cc (and it was in log)': 2,
                        },
                    }
                ],
            }
        ]
    }

    analysis = WfAnalysis.Get(master_name, builder_name, build_number)
    self.assertIsNotNone(analysis)
    self.assertEqual(analysis_status.COMPLETED, analysis.status)
    self.assertEqual(expected_analysis_result, analysis.result)
    self.assertIsNotNone(analysis.result_status)
def ScheduleAnalysisIfNeeded(master_name,
                             builder_name,
                             build_number,
                             failed_steps=None,
                             build_completed=False,
                             force=False,
                             queue_name=constants.DEFAULT_QUEUE):
    """Schedules an analysis if needed and returns the build analysis.

  When the build failure was already analyzed and a new analysis is scheduled,
  the returned WfAnalysis will still have the result of last completed analysis.

  Args:
    master_name (str): The master name of the failed build.
    builder_name (str): The builder name of the failed build.
    build_number (int): The build number of the failed build.
    failed_steps (list): The names of all failed steps reported for the build.
    build_completed (bool): Indicate whether the build is completed.
    force (bool): If True, a fresh new analysis will be triggered even when an
        old one was completed already; otherwise bail out.
    queue_name (str): The task queue to be used for pipeline tasks.

  Returns:
    A WfAnalysis instance.
  """
    if NeedANewAnalysis(master_name, builder_name, build_number, failed_steps,
                        build_completed, force):
        pipeline_job = AnalyzeBuildFailurePipeline(master_name, builder_name,
                                                   build_number,
                                                   build_completed, force)
        # Explicitly run analysis in the backend module "waterfall-backend".
        # Note: Just setting the target in queue.yaml does NOT work for pipeline
        # when deployed to App Engine, but it does work in dev-server locally.
        # A possible reason is that pipeline will pick a default target if none is
        # specified explicitly, and the default target is used rather than the one
        # in the queue.yaml file, but this contradicts the documentation in
        # https://cloud.google.com/appengine/docs/python/taskqueue/tasks#Task.
        pipeline_job.target = appengine_util.GetTargetNameForModule(
            constants.WATERFALL_BACKEND)
        pipeline_job.start(queue_name=queue_name)

        logging.info('An analysis was scheduled for build %s, %s, %s: %s',
                     master_name, builder_name, build_number,
                     pipeline_job.pipeline_status_path())
    else:
        logging.info('An analysis is not needed for build %s, %s, %s',
                     master_name, builder_name, build_number)

    return WfAnalysis.Get(master_name, builder_name, build_number)