Пример #1
0
  def testMinDistanceChangedFiles(self):
    """Tests ``ChangedFile`` method."""
    report = self._GetDummyReport(
        deps={'src/': Dependency('src/', 'https://repo', '6')},
        dep_rolls={'src/': DependencyRoll('src/', 'https://repo', '0', '4')})

    distance = 42
    crashed = CrashedFile(_MOCK_FRAME)
    matches = {
        crashed:
        CrashMatch(crashed,
                   [FileChangeInfo(ChangeType.MODIFY, 'file', 'file')],
                   [FrameInfo(_MOCK_FRAME, 0)])
    }
    frame = StackFrame(0, 'src/', 'func', 'f.cc', 'f.cc', [7], 'https://repo')
    with mock.patch('analysis.linear.changelist_features.min_distance.'
                    'MinDistanceFeature.'
                    'DistanceBetweenTouchedFileAndFrameInfos') as mock_distance:
      mock_distance.return_value = min_distance.Distance(distance, frame)
      self.assertEqual(
          min_distance.MinDistanceFeature(
              self._get_repository, _MAXIMUM)(report)(
              self._GetMockSuspect(), matches).changed_files,
              [ChangedFile(name='file',
                           blame_url=('%s/+blame/%s/f.cc#%d' %
                                      (frame.repo_url,
                                       report.crashed_version,
                                       frame.crashed_line_numbers[0])),
                           reasons=['Distance between touched lines and crashed'
                                    ' lines is %d, in frame #%d' % (
                                        distance, frame.index)])])
Пример #2
0
  def testAggregateChangedFilesAggregates(self):
    """Test that ``AggregateChangedFiles`` does aggregate reasons per file.

    In the main/inner loop of ``AggregateChangedFiles``: if multiple
    features all blame the same file change, we try to aggregate those
    reasons so that we only report the file once (with all reasons). None
    of the other tests here actually check the case where the same file
    is blamed multiple times, so we check that here.

    In particular, we provide the same ``FeatureValue`` twice, and
    hence the same ``ChangedFile`` twice; so we should get back a single
    ``ChangedFile`` but with the ``reasons`` fields concatenated.
    """
    self.assertListEqual(self.feature.changed_files,
                         [ChangedFile(name='a.cc',
                                      blame_url=None,
                                      reasons=['file_reason0']),
                          ChangedFile(name='b.cc',
                                      blame_url=None,
                                      reasons=['file_reason0',
                                               'file_reason1'])])
    self.assertEqual(self.feature.changed_files,
                     self.feature._changed_files)
Пример #3
0
    def ChangedFiles(suspect, touched_file_to_distance, crashed_version):
        """Get all the changed files causing this feature to blame this result.

    Arg:
      suspect (Suspect): the suspect being blamed.
      touched_file_to_distance (dict): Dict mapping file name to
        ``Distance``s.
      crashed_version (str): Crashed version.

    Returns:
      List of ``ChangedFile`` objects sorted by frame index. For example:

        [ChangedFile(
            file = 'render_frame_impl.cc',
            blame_url = 'https://chr.com/../render_frame_impl.cc#1586',
            reasons = ['Minimum distance (LOC) 1, frame #5']
        )]
    """
        frame_index_to_changed_files = {}

        for touched_file, distance in (touched_file_to_distance.iteritems()):
            file_name = touched_file.new_path.split('/')[-1]
            if distance.frame is None:  # pragma: no cover
                logging.warning('Missing the min_distance_frame for file %s' %
                                file_name)
                continue

            frame_index_to_changed_files[distance.frame.index] = ChangedFile(
                name=file_name,
                blame_url=distance.frame.BlameUrl(crashed_version),
                reasons=[
                    'Distance between touched lines and crashed lines is %d,'
                    ' in frame #%d' % (distance.distance, distance.frame.index)
                ])

        if not frame_index_to_changed_files:  # pragma: no cover
            logging.warning('Found no changed files for suspect: %s',
                            str(suspect))
            return []

        # Sort changed file by frame index.
        _, changed_files = zip(*sorted(
            frame_index_to_changed_files.iteritems(), key=lambda x: x[0]))

        return list(changed_files)
Пример #4
0
 def __call__(self, x):
   return lambda y: FeatureValue(self.name, y == ((x % 2) == 1), 'reason1',
                                 [ChangedFile(name='b.cc',
                                              blame_url=None,
                                              reasons=['file_reason1'])])