Exemplo n.º 1
0
    def testGetFirstFailuresInCurrentBuildWithoutGroupExistingGroupForSameBuild(
            self, *_):
        build_121_info = {
            'id': 8000000000121,
            'number': self.build_number - 2,
            'commit_id': 'git_sha_121'
        }
        first_failures_in_current_build = {
            'failures': {
                'compile': {
                    'output_targets':
                    [frozenset(['target1']),
                     frozenset(['target2'])],
                    'last_passed_build':
                    build_121_info,
                },
            },
            'last_passed_build': build_121_info
        }

        # Creates and saves entities of the existing group.
        detailed_compile_failures = {
            'compile': {
                'failures': {
                    frozenset(['target1']): {
                        'rule': 'CXX',
                        'first_failed_build': self.build_info,
                        'last_passed_build': build_121_info,
                    },
                    frozenset(['target2']): {
                        'rule': 'ACTION',
                        'first_failed_build': self.build_info,
                        'last_passed_build': build_121_info,
                    },
                },
                'first_failed_build': self.build_info,
                'last_passed_build': build_121_info,
            },
        }

        pre_compile_analysis.SaveCompileFailures(self.context, self.build,
                                                 detailed_compile_failures)

        expected_result = {
            'failures': {
                'compile': {
                    'output_targets':
                    [frozenset(['target1']),
                     frozenset(['target2'])],
                    'last_passed_build':
                    build_121_info,
                },
            },
            'last_passed_build': build_121_info
        }

        self.assertEqual(
            expected_result,
            pre_compile_analysis.GetFirstFailuresInCurrentBuildWithoutGroup(
                self.context, self.build, first_failures_in_current_build))
Exemplo n.º 2
0
    def testSaveCompileAnalysisWithGroup(self, *_):
        build_120_info = {
            'id': 8000000000120,
            'number': self.build_number - 3,
            'commit_id': 'git_sha_120'
        }

        detailed_compile_failures = {
            'compile': {
                'failures': {
                    frozenset(['target1', 'target2']): {
                        'rule': 'CXX',
                        'first_failed_build': self.build_info,
                        'last_passed_build': build_120_info,
                    },
                    frozenset(['target3']): {
                        'rule': 'ACTION',
                        'first_failed_build': self.build_info,
                        'last_passed_build': None,
                    },
                },
                'first_failed_build': self.build_info,
                'last_passed_build': build_120_info,
            },
        }

        pre_compile_analysis.SaveCompileFailures(self.context, self.build,
                                                 detailed_compile_failures)

        first_failures_in_current_build = {
            'failures': {
                'compile': {
                    'output_targets': [{'target1', 'target2'}],
                    'last_passed_build': build_120_info,
                },
            },
            'last_passed_build': build_120_info
        }
        pre_compile_analysis.SaveCompileAnalysis(
            self.context, self.build, first_failures_in_current_build, True)

        analysis = CompileFailureAnalysis.GetVersion(self.build_id)
        self.assertIsNotNone(analysis)
        self.assertEqual('git_sha_120', analysis.last_passed_commit.gitiles_id)
        self.assertEqual(66666, analysis.last_passed_commit.commit_position)
        self.assertEqual('chromium/findit/findit_variables',
                         analysis.rerun_builder_id)
        self.assertEqual(1, len(analysis.compile_failure_keys))
        self.assertItemsEqual(
            ['target1', 'target2'],
            analysis.compile_failure_keys[0].get().output_targets)

        group = CompileFailureGroup.get_by_id(self.build_id)
        self.assertIsNotNone(group)
        self.assertEqual('git_sha_120', analysis.last_passed_commit.gitiles_id)
        self.assertEqual(self.build_info['commit_id'],
                         analysis.first_failed_commit.gitiles_id)
Exemplo n.º 3
0
    def testSaveCompileFailuresOnlyStepLevelFailures(self, _):
        detailed_compile_failures = {
            'compile': {
                'failures': {},
                'first_failed_build': {
                    'id': 8000000000121,
                    'number': 121,
                    'commit_id': 'git_sha'
                },
                'last_passed_build': {
                    'id': 8000000000120,
                    'number': 120,
                    'commit_id': 'git_sha'
                },
            },
        }

        # Prepares data for first failed build.
        first_failed_build = self._MockBuild(8000000000121, 121, 'git_sha_121')
        first_failed_build_entity = luci_build.SaveFailedBuild(
            self.context, first_failed_build, StepTypeEnum.COMPILE)
        first_failure = CompileFailure.Create(first_failed_build_entity.key,
                                              'compile', None, 'CXX')
        first_failure.put()

        pre_compile_analysis.SaveCompileFailures(self.context, self.build,
                                                 detailed_compile_failures)

        build_entity = LuciFailedBuild.get_by_id(self.build_id)
        self.assertIsNotNone(build_entity)

        compile_failures = CompileFailure.query(
            ancestor=build_entity.key).fetch()
        self.assertEqual(1, len(compile_failures))
        self.assertEqual(8000000000121,
                         compile_failures[0].first_failed_build_id)
        self.assertEqual([], compile_failures[0].output_targets)
        self.assertEqual(first_failure.key,
                         compile_failures[0].merged_failure_key)
Exemplo n.º 4
0
    def testGetFirstFailuresInCurrentBuildWithoutGroup(self, *_):
        build_121_info = {
            'id': 8000000000121,
            'number': self.build_number - 2,
            'commit_id': 'git_sha_121'
        }
        first_failures_in_current_build = {
            'failures': {
                'compile': {
                    'output_targets':
                    [frozenset(['target1']),
                     frozenset(['target2'])],
                    'last_passed_build':
                    build_121_info,
                },
            },
            'last_passed_build': build_121_info
        }

        # Creates and saves entities of the existing group.
        detailed_compile_failures = {
            'compile': {
                'failures': {
                    frozenset(['target1']): {
                        'rule': 'CXX',
                        'first_failed_build': self.build_info,
                        'last_passed_build': build_121_info,
                    },
                    frozenset(['target2']): {
                        'rule': 'ACTION',
                        'first_failed_build': self.build_info,
                        'last_passed_build': build_121_info,
                    },
                },
                'first_failed_build': self.build_info,
                'last_passed_build': build_121_info,
            },
        }

        pre_compile_analysis.SaveCompileFailures(self.context, self.build,
                                                 detailed_compile_failures)

        # Prepares data for existing failure group.
        group_build = self._MockBuild(8000000000134,
                                      12134,
                                      'git_sha_134',
                                      builder_name='Mac')
        group_build_entity = luci_build.SaveFailedBuild(
            self.context, group_build, StepTypeEnum.COMPILE)
        group_failure1 = CompileFailure.Create(group_build_entity.key,
                                               'compile', ['target1'], 'CXX')
        group_failure1.put()
        group_failure2 = CompileFailure.Create(group_build_entity.key,
                                               'compile', ['target2'],
                                               'ACTION')
        group_failure2.put()

        self.assertEqual(
            {
                'failures': {},
                'last_passed_build': None
            },
            pre_compile_analysis.GetFirstFailuresInCurrentBuildWithoutGroup(
                self.context, self.build, first_failures_in_current_build))

        build = LuciFailedBuild.get_by_id(self.build_id)
        compile_failures = CompileFailure.query(ancestor=build.key).fetch()
        self.assertEqual(2, len(compile_failures))

        for failure in compile_failures:
            if failure.output_targets == ['target1']:
                self.assertEqual(group_failure1.key,
                                 failure.merged_failure_key)
            else:
                self.assertEqual(group_failure2.key,
                                 failure.merged_failure_key)
Exemplo n.º 5
0
    def testSaveCompileFailures(self, _):
        detailed_compile_failures = {
            'compile': {
                'failures': {
                    frozenset(['target1', 'target2']): {
                        'rule': 'CXX',
                        'first_failed_build': {
                            'id': 8000000000121,
                            'number': 121,
                            'commit_id': 'git_sha_121'
                        },
                        'last_passed_build': {
                            'id': 8000000000120,
                            'number': 120,
                            'commit_id': 'git_sha'
                        },
                    },
                },
                'first_failed_build': {
                    'id': 8000000000121,
                    'number': 121,
                    'commit_id': 'git_sha_121'
                },
                'last_passed_build': {
                    'id': 8000000000120,
                    'number': 120,
                    'commit_id': 'git_sha'
                },
            },
        }

        # Prepares data for existing failure group.
        group_build = self._MockBuild(8000003400121,
                                      12134,
                                      'git_sha_121',
                                      builder_name='Mac')
        group_build_entity = luci_build.SaveFailedBuild(
            self.context, group_build, StepTypeEnum.COMPILE)
        group_failure = CompileFailure.Create(group_build_entity.key,
                                              'compile',
                                              ['target1', 'target2'], 'CXX')
        group_failure.put()

        # Prepares data for first failed build.
        first_failed_build = self._MockBuild(8000000000121, 121, 'git_sha_121')
        first_failed_build_entity = luci_build.SaveFailedBuild(
            self.context, first_failed_build, StepTypeEnum.COMPILE)
        first_failure = CompileFailure.Create(first_failed_build_entity.key,
                                              'compile',
                                              ['target1', 'target2'], 'CXX')
        first_failure.merged_failure_key = group_failure.key
        first_failure.put()

        pre_compile_analysis.SaveCompileFailures(self.context, self.build,
                                                 detailed_compile_failures)

        build = LuciFailedBuild.get_by_id(self.build_id)
        self.assertIsNotNone(build)

        compile_failures = CompileFailure.query(ancestor=build.key).fetch()
        self.assertEqual(1, len(compile_failures))
        self.assertEqual(8000000000121,
                         compile_failures[0].first_failed_build_id)
        self.assertEqual(group_failure.key,
                         compile_failures[0].merged_failure_key)
Exemplo n.º 6
0
def AnalyzeCompileFailure(context, build, compile_steps):
  """Analyzes compile failure from a failed ci/postsubmit build.

  Args:
    context (findit_v2.services.context.Context): Scope of the analysis.
    build (buildbucket build.proto): ALL info about the build.
    compile_steps (list of buildbucket step.proto): The failed compile steps.

  Returns:
    (bool): Returns True if a new analysis starts, otherwise False.
  """
  luci_project = context.luci_project_name
  if luci_project == 'chromium':
    logging.warning('Findit does not support chromium project in v2.')
    return False

  project_api = projects.GetProjectAPI(luci_project)
  if not project_api:
    logging.debug('Unsupported project %s', luci_project)
    return False

  # Project config for if failures should be grouped to reduce duplicated
  # analyses.
  should_group_failures = projects.PROJECT_CFG.get(
      luci_project, {}).get('should_group_failures')

  detailed_compile_failures = project_api.GetCompileFailures(
      build, compile_steps)
  # Checks previous builds to look for first time failures for all the failures
  # in current failed build.
  pre_compile_analysis.UpdateCompileFailuresWithFirstFailureInfo(
      context, build, detailed_compile_failures)
  pre_compile_analysis.SaveCompileFailures(context, build,
                                           detailed_compile_failures)

  # Looks for the failures that started to fail in the current build.
  first_failures_in_current_build = (
      pre_compile_analysis.GetFirstFailuresInCurrentBuild(
          context, build, detailed_compile_failures))
  if not first_failures_in_current_build.get('failures'):
    logging.info(
        'No new analysis for build %d because all failures have '
        'happened in previous builds.', build.id)
    return False

  # Filters out the first failures with existing failure group.
  if should_group_failures:
    failures_without_existing_group = (
        pre_compile_analysis.GetFirstFailuresInCurrentBuildWithoutGroup(
            context, build, first_failures_in_current_build))
  else:
    failures_without_existing_group = first_failures_in_current_build

  if not failures_without_existing_group.get('failures'):
    logging.info(
        'All failures have matching failure groups in build %s,'
        ' no need to start a new analysis.', build.id)
    return False

  # Start a new analysis to analyze the first time failures.
  pre_compile_analysis.SaveCompileAnalysis(
      context, build, failures_without_existing_group, should_group_failures)
  compile_failure_rerun_analysis.RerunBasedAnalysis(context, build.id, build)
  return True