def testFindSuspectedChangesOnHWTestFailuresBlameEverything(self):
        """Test FindSuspectedChanges on HWTestFailures and blame everything."""
        changes = self._GetMockChanges()
        f_1 = failure_message_helper.GetTestFailureMessage(failure_id=1)
        build_failure = self.ConstructBuildFailureMessage(
            failure_messages=[f_1])
        mock_find = self.PatchObject(hwtest_results.HWTestResultManager,
                                     'FindHWTestFailureSuspects',
                                     return_value=({changes[2]}, True))
        build_root = mock.Mock()
        failed_hwtests = mock.Mock()

        suspects = build_failure.FindSuspectedChanges(changes, build_root,
                                                      failed_hwtests, True)
        expected = triage_lib.SuspectChanges({
            changes[0]:
            constants.SUSPECT_REASON_UNKNOWN,
            changes[1]:
            constants.SUSPECT_REASON_UNKNOWN,
            changes[2]:
            constants.SUSPECT_REASON_TEST_FAIL,
            changes[3]:
            constants.SUSPECT_REASON_UNKNOWN
        })
        self.assertEqual(suspects, expected)
        mock_find.assert_called_once_with(changes, build_root, failed_hwtests)
        mock_find.reset_mock()

        suspects = build_failure.FindSuspectedChanges(changes, build_root,
                                                      failed_hwtests, False)
        expected = triage_lib.SuspectChanges(
            {changes[2]: constants.SUSPECT_REASON_TEST_FAIL})
        self.assertEqual(suspects, expected)
        mock_find.assert_called_once_with(changes, build_root, failed_hwtests)
    def testFindSuspectedChangesOnPackageBuildFailuresBlameEverything(self):
        """Test FindSuspectedChanges on PackageBuildFailures and BlameEverything."""
        changes = self._GetMockChanges()
        f_1 = failure_message_helper.GetPackageBuildFailureMessage(
            failure_id=1)
        build_failure = self.ConstructBuildFailureMessage(
            failure_messages=[f_1])
        mock_find = self.PatchObject(build_failure_message.BuildFailureMessage,
                                     'FindPackageBuildFailureSuspects',
                                     return_value=({changes[2]}, True))
        suspects = build_failure.FindSuspectedChanges(changes, mock.Mock(),
                                                      mock.Mock(), True)
        expected = triage_lib.SuspectChanges({
            changes[0]:
            constants.SUSPECT_REASON_UNKNOWN,
            changes[1]:
            constants.SUSPECT_REASON_UNKNOWN,
            changes[2]:
            constants.SUSPECT_REASON_BUILD_FAIL,
            changes[3]:
            constants.SUSPECT_REASON_UNKNOWN
        })

        self.assertEqual(suspects, expected)
        mock_find.assert_called_once_with(changes, f_1)
        mock_find.reset_mock()

        suspects = build_failure.FindSuspectedChanges(changes, mock.Mock(),
                                                      mock.Mock(), False)
        expected = triage_lib.SuspectChanges(
            {changes[2]: constants.SUSPECT_REASON_BUILD_FAIL})
        self.assertEqual(suspects, expected)
        mock_find.assert_called_once_with(changes, f_1)
    def testFindSuspectedChangesOnUnknownFailures(self):
        """Test FindSuspectedChanges on unknown failures."""
        changes = self._GetMockChanges()
        f_1 = failure_message_helper.GetStageFailureMessage(failure_id=1)
        build_failure = self.ConstructBuildFailureMessage(
            failure_messages=[f_1])
        mock_find_build_failure = self.PatchObject(
            build_failure_message.BuildFailureMessage,
            'FindPackageBuildFailureSuspects',
            return_value=({changes[2]}, True))
        mock_find_hwtest_failure = self.PatchObject(
            hwtest_results.HWTestResultManager,
            'FindHWTestFailureSuspects',
            return_value=({changes[2]}, False))
        build_root = mock.Mock()
        failed_hwtests = mock.Mock()

        suspects = build_failure.FindSuspectedChanges(changes, build_root,
                                                      failed_hwtests, True)
        expected = triage_lib.SuspectChanges({
            changes[0]:
            constants.SUSPECT_REASON_UNKNOWN,
            changes[1]:
            constants.SUSPECT_REASON_UNKNOWN,
            changes[2]:
            constants.SUSPECT_REASON_UNKNOWN,
            changes[3]:
            constants.SUSPECT_REASON_UNKNOWN
        })
        self.assertEqual(suspects, expected)
        mock_find_build_failure.assert_not_called()
        mock_find_hwtest_failure.assert_not_called()

        suspects = build_failure.FindSuspectedChanges(changes, build_root,
                                                      failed_hwtests, False)
        expected = triage_lib.SuspectChanges()
        self.assertEqual(suspects, expected)
        mock_find_build_failure.assert_not_called()
        mock_find_hwtest_failure.assert_not_called()
Beispiel #4
0
    def _AssertMessage(self,
                       change,
                       suspects,
                       messages,
                       sanity=True,
                       infra_fail=False,
                       lab_fail=False,
                       no_stat=None,
                       xretry=False,
                       pre_cq_trybot=False,
                       cl_status_url=None):
        """Call the CreateValidationFailureMessage method.

    Args:
      change: The change we are commenting on.
      suspects: List of suspected changes.
      messages: List of messages should appear in the failure message.
      sanity: Bool indicating sanity of build, default: True.
      infra_fail: True if build failed due to infrastructure issues.
      lab_fail: True if build failed due to lab infrastructure issues.
      no_stat: List of builders that did not start.
      xretry: Whether we expect the change to be retried.
      pre_cq_trybot: Whether the builder is a Pre-CQ trybot.
      cl_status_url: URL of the CL status viewer for the change.
    """
        suspects = triage_lib.SuspectChanges(
            {x: constants.SUSPECT_REASON_UNKNOWN
             for x in suspects})
        msg = cl_messages.CreateValidationFailureMessage(
            pre_cq_trybot,
            change,
            suspects, [],
            sanity=sanity,
            infra_fail=infra_fail,
            lab_fail=lab_fail,
            no_stat=no_stat,
            retry=xretry,
            cl_status_url=cl_status_url)
        for x in messages:
            self.assertTrue(x in msg)
        self.assertEqual(xretry, 'retry your change automatically' in msg)
        return msg
Beispiel #5
0
    def testFindSuspectsForFailuresWithMessages(self):
        """Test FindSuspectsForFailures with not None messages."""
        build_root = mock.Mock()
        failed_hwtests = mock.Mock()
        messages = []
        for _ in range(0, 3):
            m = mock.Mock()
            m.FindSuspectedChanges.return_value = triage_lib.SuspectChanges(
                {self.changes[0]: constants.SUSPECT_REASON_UNKNOWN})
            messages.append(m)

        suspects = triage_lib.CalculateSuspects.FindSuspectsForFailures(
            self.changes, messages, build_root, failed_hwtests, False)
        self.assertItemsEqual(suspects.keys(), self.changes[0:1])

        suspects = triage_lib.CalculateSuspects.FindSuspectsForFailures(
            self.changes, messages, build_root, failed_hwtests, True)
        self.assertItemsEqual(suspects.keys(), self.changes[0:1])

        for index in range(0, 3):
            messages[index].FindSuspectedChanges.called_once_with(
                self.changes, build_root, failed_hwtests, True)
            messages[index].FindSuspectedChanges.called_once_with(
                self.changes, build_root, failed_hwtests, False)
Beispiel #6
0
 def _CreateSuspectChanges(self, suspect_dict=None):
     return triage_lib.SuspectChanges(suspect_dict)
Beispiel #7
0
  def FindSuspectedChanges(self, changes, build_root, failed_hwtests, sanity):
    """Find and return suspected changes.

    Suspected changes are CLs that probably caused failures and will be
    rejected. This method analyzes every failure message and returns a set of
    changes as suspects.
    1) if a failure message is a PackageBuildFailure, get suspects for the build
    failure. If there're failed packages without assigned suspects, blame all
    changes when sanity is True.
    2) if a failure message is a TEST failure, get suspects for the HWTest
    failure. If there're failed HWTests without assigned suspects, blame all
    changes when sanity is True.
    3) If a failure message is neither PackagebuildFailure nor HWTestFailure,
    we can't explain the failure and so blame all changes when sanity is True.

    It is certainly possible to trick this algorithm: If one developer submits
    a change to libchromeos that breaks the power_manager, and another developer
    submits a change to the power_manager at the same time, only the
    power_manager change will be kicked out. That said, in that situation, the
    libchromeos change will likely be kicked out on the next run when the next
    run fails power_manager but dosen't include any changes from power_manager.

    Args:
      changes: A list of cros_patch.GerritPatch instances.
      build_root: The path to the build root.
      failed_hwtests: A list of name of failed hwtests got from CIDB (see the
        return type of HWTestResultManager.GetFailedHWTestsFromCIDB), or None.
      sanity: The sanity checker builder passed and the tree was open when
        the build started and ended.

    Returns:
      An instance of triage_lib.SuspectChanges.
    """
    suspect_changes = triage_lib.SuspectChanges()
    blame_everything = False
    for failure in self.failure_messages:
      if (failure.exception_type in
          failure_message_lib.PACKAGE_BUILD_FAILURE_TYPES):
        # Find suspects for PackageBuildFailure
        build_suspects, no_assignee_packages = (
            self.FindPackageBuildFailureSuspects(changes, failure))
        suspect_changes.update(
            {x: constants.SUSPECT_REASON_BUILD_FAIL for x in build_suspects})
        blame_everything = blame_everything or no_assignee_packages
      elif failure.exception_category == constants.EXCEPTION_CATEGORY_TEST:
        # Find suspects for HWTestFailure
        hwtest_suspects, no_assignee_hwtests = (
            hwtest_results.HWTestResultManager.FindHWTestFailureSuspects(
                changes, build_root, failed_hwtests))
        suspect_changes.update(
            {x: constants.SUSPECT_REASON_TEST_FAIL for x in hwtest_suspects})
        blame_everything = blame_everything or no_assignee_hwtests
      else:
        # Unknown failures, blame everything
        blame_everything = True

    # Only do broad-brush blaming if the tree is sane.
    if sanity:
      if blame_everything or len(suspect_changes) == 0:
        suspect_changes.update(
            {x: constants.SUSPECT_REASON_UNKNOWN for x in changes})
      else:
        # Never treat changes to overlays as innocent.
        overlay_changes = [x for x in changes if '/overlays/' in x.project]
        suspect_changes.update(
            {x: constants.SUSPECT_REASON_OVERLAY_CHANGE
             for x in overlay_changes})

    return suspect_changes