def testDistanceBetweenTouchedFileAndFrameInfos(self):
    """Tests ``DistanceBetweenTouchedFileAndFrameInfos`` method."""
    feature = min_distance.MinDistanceFeature(self._get_repository, _MAXIMUM)
    frame1 = StackFrame(0, 'src/', 'func', 'a.cc', 'src/a.cc', [7],
                        repo_url='https://repo_url')
    frame2 = StackFrame(0, 'src/', 'func', 'a.cc', 'src/a.cc', [17],
                        repo_url='https://repo_url')
    touched_file = FileChangeInfo(ChangeType.MODIFY, 'file', 'file')

    blame = Blame('rev', 'src/')
    blame.AddRegions([Region(0, 10, 'rev', 'a1', 'e1', 't1'),
                      Region(11, 20, 'dummy_rev', 'a2', 'e2', 't2')])

    url_to_blame = {'rev/file': blame}

    def _MockGetBlame(path, revision):
      revision_path = '%s/%s' % (revision, path)
      return url_to_blame.get(revision_path)

    with mock.patch('libs.gitiles.gitiles_repository.GitilesRepository.'
                    'GetBlame') as mock_get_blame:
      mock_get_blame.side_effect = _MockGetBlame

      distance_info = feature.DistanceBetweenTouchedFileAndFrameInfos(
          'rev', touched_file, [FrameInfo(frame1, 0), FrameInfo(frame2, 0)],
           Dependency('src/', 'https://repo', 'rev'))
      self.assertEqual(distance_info, min_distance.Distance(0, frame1))

      distance_info = feature.DistanceBetweenTouchedFileAndFrameInfos(
          'wrong_rev', touched_file, [FrameInfo(frame1, 0),
                                      FrameInfo(frame2, 0)],
           Dependency('src/', 'https://repo', 'wrong_rev'))
      self.assertIsNone(distance_info)
    def __call__(self, output, path, revision):  # pylint:disable=W
        if not output:
            return None

        blame = Blame(revision, path)
        commit_info = defaultdict(dict)
        region_info = None
        for line in output.splitlines():
            # Sample: ec3ed6... 2 1 7.
            match = REGION_START_COUNT_PATTERN.match(line)
            if match:
                if region_info:
                    blame.AddRegion(
                        Region(
                            region_info.start, region_info.count,
                            region_info.revision,
                            commit_info[region_info.revision]['author_name'],
                            commit_info[region_info.revision]['author_email'],
                            commit_info[region_info.revision]['author_time']))

                region_info = RegionInfo(start=int(match.group(2)),
                                         count=int(match.group(3)),
                                         revision=match.group(1))

            elif region_info:
                # Sample: author [email protected].
                if AUTHOR_NAME_PATTERN.match(line):
                    commit_info[region_info.revision]['author_name'] = (
                        AUTHOR_NAME_PATTERN.match(line).group(1))
                # Sample: author-mail <[email protected]@2eff-a529-9590-31e7-b00076f81>.
                elif AUTHOR_MAIL_PATTERN.match(line):
                    commit_info[region_info.revision]['author_email'] = (
                        commit_util.NormalizeEmail(
                            AUTHOR_MAIL_PATTERN.match(line).group(1).replace(
                                '<', '').replace('>', '')))
                # Sample: author-time 1311863160.
                elif AUTHOR_TIME_PATTERN.match(line):
                    commit_info[region_info.revision]['author_time'] = (
                        AUTHOR_TIME_PATTERN.match(line).group(1))
                # Sample: author-tz +0800.
                elif AUTHOR_TIMEZONE_PATTERN.match(line):
                    time_zone = time_util.TimeZoneInfo(
                        AUTHOR_TIMEZONE_PATTERN.match(line).group(1))
                    commit_info[region_info.revision]['author_time'] = (
                        time_zone.LocalToUTC(
                            datetime.fromtimestamp(
                                int(commit_info[region_info.revision]
                                    ['author_time']))))

        if region_info:
            blame.AddRegion(
                Region(region_info.start, region_info.count,
                       region_info.revision,
                       commit_info[region_info.revision]['author_name'],
                       commit_info[region_info.revision]['author_email'],
                       commit_info[region_info.revision]['author_time']))

        return blame if blame else None
Exemple #3
0
 def testBlameToDict(self):
     blame = Blame('def', 'a/c.cc')
     blame.AddRegions([self.REGION1, self.REGION2])
     blame_json = blame.ToDict()
     self.assertEqual(3, len(blame_json))
     self.assertEqual('def', blame_json['revision'])
     self.assertEqual('a/c.cc', blame_json['path'])
     self.assertEqual(self.REGION1_EXPECTED_JSON, blame_json['regions'][0])
     self.assertEqual(self.REGION2_EXPECTED_JSON, blame_json['regions'][1])
Exemple #4
0
  def testGetSuspectedRevisions(self):
    region_1 = Region(1, 5, 'r1', 'a', '*****@*****.**', '2017-08-11 19:38:42')
    region_2 = Region(6, 10, 'r2', 'b', '*****@*****.**', '2017-08-12 19:38:42')
    blame = Blame('r2', 'a.cc')
    blame.AddRegion(region_1)
    blame.AddRegion(region_2)
    revision_range = ['r2', 'r3']
    expected_suspected_revisions = ['r2']

    self.assertEqual(
        expected_suspected_revisions,
        heuristic_analysis.GetSuspectedRevisions(blame, revision_range))
    self.assertEqual([], heuristic_analysis.GetSuspectedRevisions([], ['r1']))
    self.assertEqual([], heuristic_analysis.GetSuspectedRevisions(
        blame, ['r4']))
    self.assertEqual([], heuristic_analysis.GetSuspectedRevisions(None, None))
    def GetBlame(self, path, revision):
        """Returns blame of the file at ``path`` of the given revision."""
        url = '%s/+blame/%s/%s' % (self.repo_url, revision, path)

        data = self._SendRequestForJsonResponse(url)
        if not data:
            return None

        blame = Blame(revision, path)
        for region in data['regions']:
            author_time = self._GetDateTimeFromString(region['author']['time'],
                                                      '%Y-%m-%d %H:%M:%S')

            blame.AddRegion(
                Region(region['start'], region['count'], region['commit'],
                       region['author']['name'],
                       commit_util.NormalizeEmail(region['author']['email']),
                       author_time))

        return blame
Exemple #6
0
    def testGitBlameParser(self):
        output = textwrap.dedent("""
        revision_hash 18 18 3
        author [email protected]
        author-mail <[email protected]@2bbb7eff-a529-9590-31e7-b0007b416f81>
        author-time 1363032816
        author-tz +0000
        committer [email protected]
        committer-mail <[email protected]@2bbb7eff-a529-9590-31e7-b0007b416f81>
        committer-time 1363032816
        committer-tz +0000
        summary add (mac) test for ttcindex in SkFontStream
        previous fe7533eebe777cc66c7f8fa7a03f00572755c5b4 src/core/SkFont.h
        filename src/core/SkFont.h
                     *  blabla line 1
        revision_hash 19 19
                     *  blabla line 2
        revision_hash 20 20
                     *  blabla line 3

        revision_hash 29 29 2
                     *  blabla line 4
        """)

        expected_blame = Blame('src/core/SkFont.h', 'rev')
        mock_email = '*****@*****.**'
        author_time = datetime(2013, 03, 11, 17, 13, 36)
        expected_blame.AddRegions([
            Region(18, 3, 'revision_hash', mock_email, mock_email,
                   author_time),
            Region(29, 2, 'revision_hash', mock_email, mock_email, author_time)
        ])

        blame_result = self.blame_parser(output, 'src/core/SkFont.h', 'rev')
        self.assertTrue(blame_result.revision, expected_blame.revision)
        self.assertTrue(blame_result.path, expected_blame.path)
        for region, expected_region in zip(blame_result, expected_blame):
            self.assertTrue(region.ToDict(), expected_region.ToDict())
Exemple #7
0
    def testAddRegions(self):
        blame1 = Blame('def', 'a/c.cc')
        blame1.AddRegions([self.REGION1, self.REGION2])

        blame2 = Blame('def', 'a/c.cc')
        blame2.AddRegion(self.REGION1)
        blame2.AddRegion(self.REGION2)

        self.assertEqual(blame1, blame2)
Exemple #8
0
  def testIdentifySuspectedRangesFailedToGetRevisions(self, _, mock_blame,
                                                      mock_test_location):
    mock_blame.return_value = [Blame('r1000', 'a/b.cc')]
    mock_test_location.return_value = TestLocation(file='a/b.cc', line=1)

    analysis = MasterFlakeAnalysis.Create('m', 'b', 123, 's', 't')
    analysis.data_points = [
        DataPoint.Create(commit_position=1000, git_hash='r1000', pass_rate=0.5),
        DataPoint.Create(commit_position=997, git_hash='r997', pass_rate=1.0)
    ]

    analysis.Save()

    self.assertEqual([],
                     heuristic_analysis.IdentifySuspectedRevisions(analysis))
Exemple #9
0
    def _MockGetBlame(self, path, revision):
        blame = Blame(revision, path)

        blame.AddRegions([
            Region(1, 2, '7', u'*****@*****.**', u'*****@*****.**',
                   datetime(2015, 06, 07, 04, 35, 32)),
            Region(3, 3, '5', u'*****@*****.**', u'*****@*****.**',
                   datetime(2015, 06, 05, 04, 35, 32)),
            Region(7, 1, '8', u'*****@*****.**', u'*****@*****.**',
                   datetime(2015, 06, 8, 04, 35, 32)),
            Region(8, 1, '7', u'*****@*****.**', u'*****@*****.**',
                   datetime(2015, 06, 07, 21, 35, 32)),
            Region(9, 10, '12', u'*****@*****.**', u'*****@*****.**',
                   datetime(2015, 06, 12, 04, 35, 32))
        ])
        return blame
    def _MockGetBlame(self, path, revision):
        if revision == '10' or revision == '11' or path == 'f_not_exist.cc':
            return None
        blame = Blame(revision, path)

        blame.AddRegions([
            Region(1, 2, '7', u'*****@*****.**', u'*****@*****.**',
                   datetime(2015, 06, 07, 04, 35, 32)),
            Region(3, 3, '5', u'*****@*****.**', u'*****@*****.**',
                   datetime(2015, 06, 05, 04, 35, 32)),
            Region(7, 1, '8', u'*****@*****.**', u'*****@*****.**',
                   datetime(2015, 06, 8, 04, 35, 32)),
            Region(8, 1, '7', u'*****@*****.**', u'*****@*****.**',
                   datetime(2015, 06, 07, 21, 35, 32)),
            Region(9, 10, '12', u'*****@*****.**', u'*****@*****.**',
                   datetime(2015, 06, 12, 04, 35, 32))
        ])
        return blame
Exemple #11
0
    def testDistanceBetweenTouchedFileAndFrameInfos(self):
        """Tests ``DistanceBetweenTouchedFileAndFrameInfos`` method."""
        feature = min_distance.MinDistanceFeature(self._get_repository,
                                                  _MAXIMUM)
        frame1 = StackFrame(0,
                            'src/',
                            'func',
                            'a.cc',
                            'src/a.cc', [7],
                            repo_url='https://repo_url')
        frame2 = StackFrame(0,
                            'src/',
                            'func',
                            'a.cc',
                            'src/a.cc', [17],
                            repo_url='https://repo_url')
        profiler_frame = ProfilerStackFrame(0,
                                            -0.1,
                                            -5.3,
                                            True,
                                            function_start_line=13)
        profiler_frame_without_line_number = ProfilerStackFrame(
            0, -0.1, -5.3, True, function_start_line=None)
        touched_file = FileChangeInfo(ChangeType.MODIFY, 'file', 'file')

        blame = Blame('rev', 'src/')
        blame.AddRegions([
            Region(0, 10, 'rev', 'a1', 'e1', 't1'),
            Region(11, 20, 'dummy_rev', 'a2', 'e2', 't2')
        ])

        url_to_blame = {'rev/file': blame}

        def _MockGetBlame(path, revision):
            revision_path = '%s/%s' % (revision, path)
            return url_to_blame.get(revision_path)

        with mock.patch('libs.gitiles.gitiles_repository.GitilesRepository.'
                        'GetBlame') as mock_get_blame:
            mock_get_blame.side_effect = _MockGetBlame

            distance_info = feature.DistanceBetweenTouchedFileAndFrameInfos(
                'rev', touched_file,
                [FrameInfo(frame1, 0),
                 FrameInfo(frame2, 0)],
                Dependency('src/', 'https://repo', 'rev'))
            self.assertEqual(distance_info, min_distance.Distance(0, frame1))

            distance_info = feature.DistanceBetweenTouchedFileAndFrameInfos(
                'wrong_rev', touched_file,
                [FrameInfo(frame1, 0),
                 FrameInfo(frame2, 0)],
                Dependency('src/', 'https://repo', 'wrong_rev'))
            self.assertIsNone(distance_info)

            # Test with a ProfilerStackFrame
            distance_info = feature.DistanceBetweenTouchedFileAndFrameInfos(
                'rev', touched_file, [
                    FrameInfo(profiler_frame, 0),
                    FrameInfo(profiler_frame_without_line_number, 0)
                ], Dependency('src/', 'https://repo', 'rev'))
            self.assertEqual(distance_info,
                             min_distance.Distance(4, profiler_frame))

            # Test that the distance remains at ``inf`` if the ProfilerStackFrames
            # passed in do not have line numbers.
            distance_info = feature.DistanceBetweenTouchedFileAndFrameInfos(
                'rev', touched_file,
                [FrameInfo(profiler_frame_without_line_number, 0)],
                Dependency('src/', 'https://repo', 'rev'))
            self.assertEqual(distance_info,
                             min_distance.Distance(float('inf'), None))