Пример #1
0
    def test_invalid_compare(self):
        with self.assertRaises(ValueError):
            Commit(revision=1).__cmp__(Commit(identifier=2))

        with self.assertRaises(ValueError):
            Commit(revision=1,
                   timestamp=100).__cmp__(Commit(identifier=2, timestamp=100))
Пример #2
0
 def test_branch_point(self):
     self.assertEqual('0', str(Commit(identifier=0)))
     self.assertEqual('0@branch-a',
                      str(Commit(identifier=0, branch='branch-a')))
     self.assertEqual(
         '1234.0@branch-a',
         str(Commit(branch_point=1234, identifier=0, branch='branch-a')))
Пример #3
0
    def test_siblings(self, client, **kwargs):
        self.register_all_commits(client)

        response = client.get(
            self.URL + '/api/commits/siblings?repository_id=webkit&id=6')
        self.assertEqual(200, response.status_code)
        commits = {
            key: [Commit.from_json(element).hash for element in values]
            for key, values in response.json().items()
        }
        self.assertEqual(
            commits,
            dict(safari=[
                'd8bce26fa65c6fc8f39c17927abb77f69fab82fc',
                'bae5d1e90999d4f916a8a15810ccfa43f37a2fd6',
                '1abe25b443e985f93b90d830e4a7e3731336af4d',
                'fff83bb2d9171b4d9196e977eb0508fd57e7a08d',
                '9b8311f25a77ba14923d9d5a6532103f54abefcb',
            ]),
        )

        response = client.get(
            self.URL +
            '/api/commits/siblings?repository_id=safari&id=d8bce26fa65c')
        self.assertEqual(200, response.status_code)
        commits = {
            key: [Commit.from_json(element).revision for element in values]
            for key, values in response.json().items()
        }
        self.assertEqual(commits, dict(webkit=[6]))
Пример #4
0
    def test_from_json(self):
        self.assertEqual(
            Commit.from_json(
                dict(
                    repository_id='webkit',
                    id=1234,
                    timestamp=1000,
                )),
            Commit(
                repository_id='webkit',
                revision=1234,
                timestamp=1000,
            ),
        )

        self.assertEqual(
            Commit.from_json(
                dict(
                    repository_id='webkit',
                    id='c3bd784f8b88bd03f64467ddd3304ed8be28acbe',
                    timestamp=2000,
                )),
            Commit(
                repository_id='webkit',
                hash='c3bd784f8b88bd03f64467ddd3304ed8be28acbe',
                timestamp=2000,
            ),
        )
Пример #5
0
 def test_commits(self):
     with mocks.local.Svn(self.path), OutputCapture():
         svn = local.Svn(self.path)
         self.assertEqual(Commit.Encoder().default([
             svn.commit(revision='r6'),
             svn.commit(revision='r4'),
             svn.commit(revision='r2'),
             svn.commit(revision='r1'),
         ]), Commit.Encoder().default(list(svn.commits(begin=dict(revision='r1'), end=dict(revision='r6')))))
Пример #6
0
 def test_commits_branch(self):
     with mocks.remote.Svn(), OutputCapture():
         svn = remote.Svn(self.remote)
         self.assertEqual(Commit.Encoder().default([
             svn.commit(revision='r7'),
             svn.commit(revision='r3'),
             svn.commit(revision='r2'),
             svn.commit(revision='r1'),
         ]), Commit.Encoder().default(list(svn.commits(begin=dict(argument='r1'), end=dict(argument='r7')))))
Пример #7
0
    def test_branch_commits(self):
        with OutputCapture() as captured, mocks.local.Git(
                self.path) as mock, mocks.local.Svn(), MockTime:
            contirbutors = Contributor.Mapping()
            contirbutors.create('Jonathan Bedard', '*****@*****.**')

            local.Git(self.path).checkout('branch-a')
            mock.commits['branch-a'].append(
                Commit(
                    hash='f93138e3bf1d5ecca25fc0844b7a2a78b8e00aae',
                    branch='branch-a',
                    author=Contributor('*****@*****.**',
                                       emails=['*****@*****.**']),
                    branch_point=mock.commits['branch-a'][-1].branch_point,
                    identifier=mock.commits['branch-a'][-1].identifier + 1,
                    timestamp=1601668000,
                    message='New commit 1\n',
                ))
            mock.commits['branch-a'].append(
                Commit(
                    hash='0148c0df0faf248aa133d6d5ad911d7cb1b56a5b',
                    branch='branch-a',
                    author=Contributor('*****@*****.**',
                                       emails=['*****@*****.**']),
                    branch_point=mock.commits['branch-a'][-1].branch_point,
                    identifier=mock.commits['branch-a'][-1].identifier + 1,
                    timestamp=1601669000,
                    message='New commit 2\n',
                ))

            self.assertEqual(
                0,
                program.main(
                    args=('canonicalize', ),
                    path=self.path,
                    contributors=contirbutors,
                ))

            commit_a = local.Git(self.path).commit(branch='branch-a~1')
            self.assertEqual(commit_a.author,
                             contirbutors['*****@*****.**'])
            self.assertEqual(commit_a.message,
                             'New commit 1\nIdentifier: 2.3@branch-a')

            commit_b = local.Git(self.path).commit(branch='branch-a')
            self.assertEqual(commit_b.author,
                             contirbutors['*****@*****.**'])
            self.assertEqual(commit_b.message,
                             'New commit 2\nIdentifier: 2.4@branch-a')

        self.assertEqual(
            captured.stdout.getvalue(),
            'Rewrite f93138e3bf1d5ecca25fc0844b7a2a78b8e00aae (1/2) (--- seconds passed, remaining --- predicted)\n'
            'Rewrite 0148c0df0faf248aa133d6d5ad911d7cb1b56a5b (2/2) (--- seconds passed, remaining --- predicted)\n'
            '2 commits successfully canonicalized!\n',
        )
Пример #8
0
 def test_commits(self):
     self.maxDiff = None
     with mocks.remote.Svn():
         svn = remote.Svn(self.remote)
         self.assertEqual(Commit.Encoder().default([
             svn.commit(revision='r6'),
             svn.commit(revision='r4'),
             svn.commit(revision='r2'),
             svn.commit(revision='r1'),
         ]), Commit.Encoder().default(list(svn.commits(begin=dict(revision='r1'), end=dict(revision='r6')))))
Пример #9
0
    def test_contributor(self):
        contributor = Contributor.from_scm_log(
            'Author: Jonathan Bedard <*****@*****.**>')

        commit = Commit(revision=1, identifier=1, author=contributor)
        self.assertEqual(commit.author, contributor)

        commit = Commit(revision=1,
                        identifier=1,
                        author=Contributor.Encoder().default(contributor))
        self.assertEqual(commit.author, contributor)
Пример #10
0
    def test_parse_hash(self):
        self.assertEqual(
            '1a2e41e3f7cdf51b1e1d02880cfb65eab9327ef2',
            Commit._parse_hash('1a2e41e3f7cdf51b1e1d02880cfb65eab9327ef2'))
        self.assertEqual(
            'c3bd784f8b88bd03f64467ddd3304ed8be28acbe',
            Commit._parse_hash('C3BD784F8B88BD03F64467DDD3304ED8BE28ACBE'))

        self.assertEqual(None, Commit._parse_hash('invalid hash'))
        self.assertEqual(
            None,
            Commit._parse_hash('c3bd784f8b88bd03f64467ddd3304ed8be28acbe1'))
Пример #11
0
    def test_next(self, client, **kwargs):
        self.register_all_commits(client)
        response = client.get(self.URL + '/api/commits/next?id=bae5d1e90999')
        self.assertEqual(200, response.status_code)
        self.assertEqual(1, len(response.json()))
        self.assertEqual('d8bce26fa65c6fc8f39c17927abb77f69fab82fc',
                         Commit.from_json(response.json()[0]).hash)

        response = client.get(self.URL + '/api/commits/next?id=4')
        self.assertEqual(200, response.status_code)
        self.assertEqual(1, len(response.json()))
        self.assertEqual(6, Commit.from_json(response.json()[0]).revision)
Пример #12
0
    def test_find_uuid(self, client, **kwargs):
        self.register_all_commits(client)
        response = client.get(self.URL + '/api/commits?uuid=160166800001')
        self.assertEqual(200, response.status_code)
        self.assertEqual(1, len(response.json()))
        self.assertEqual(
            Commit.from_json(response.json()[0]).hash,
            'd8bce26fa65c6fc8f39c17927abb77f69fab82fc')

        response = client.get(self.URL + '/api/commits?uuid=160163990000')
        self.assertEqual(200, response.status_code)
        self.assertEqual(1, len(response.json()))
        self.assertEqual(Commit.from_json(response.json()[0]).revision, 6)
Пример #13
0
 def test_find_range_id(self, client, **kwargs):
     self.register_all_commits(client)
     response = client.get(self.URL +
                           '/api/commits?after_id=6&before_id=fff83bb2d917')
     self.assertEqual(200, response.status_code)
     self.assertEqual([
         Commit.from_json(element).revision
         or Commit.from_json(element).hash for element in response.json()
     ], [
         6,
         '9b8311f25a77ba14923d9d5a6532103f54abefcb',
         'fff83bb2d9171b4d9196e977eb0508fd57e7a08d',
     ])
Пример #14
0
    def test_repr(self):
        self.assertEqual(str(Commit(identifier=123, branch='main')),
                         '123@main')
        self.assertEqual(
            str(Commit(branch_point=1234, identifier=1, branch='eng/1234')),
            '1234.1@eng/1234')
        self.assertEqual(str(Commit(identifier=123)), '123')

        self.assertEqual(str(Commit(revision=123)), 'r123')

        self.assertEqual(
            str(Commit(hash='c3bd784f8b88bd03f64467ddd3304ed8be28acbe')),
            'c3bd784f8b88')
Пример #15
0
    def test_previous(self, client, **kwargs):
        self.register_all_commits(client)
        response = client.get(self.URL +
                              '/api/commits/previous?id=d8bce26fa65c')
        self.assertEqual(200, response.status_code)
        self.assertEqual(1, len(response.json()))
        self.assertEqual('bae5d1e90999d4f916a8a15810ccfa43f37a2fd6',
                         Commit.from_json(response.json()[0]).hash)

        response = client.get(self.URL + '/api/commits/previous?id=6')
        self.assertEqual(200, response.status_code)
        self.assertEqual(1, len(response.json()))
        self.assertEqual(4, Commit.from_json(response.json()[0]).revision)
Пример #16
0
 def test_commits_branch(self):
     with mocks.remote.GitHub():
         git = remote.GitHub(self.remote)
         self.assertEqual(
             Commit.Encoder().default([
                 git.commit(hash='621652ad'),
                 git.commit(hash='a30ce849'),
                 git.commit(hash='fff83bb2'),
                 git.commit(hash='9b8311f2'),
             ]),
             Commit.Encoder().default(
                 list(
                     git.commits(begin=dict(argument='9b8311f2'),
                                 end=dict(argument='621652ad')))))
Пример #17
0
 def test_commits(self):
     with mocks.remote.GitHub():
         git = remote.GitHub(self.remote)
         self.assertEqual(
             Commit.Encoder().default([
                 git.commit(hash='bae5d1e9'),
                 git.commit(hash='1abe25b4'),
                 git.commit(hash='fff83bb2'),
                 git.commit(hash='9b8311f2'),
             ]),
             Commit.Encoder().default(
                 list(
                     git.commits(begin=dict(hash='9b8311f2'),
                                 end=dict(hash='bae5d1e9')))))
Пример #18
0
    def test_parse_revision(self):
        self.assertEqual(266896, Commit._parse_revision('r266896'))
        self.assertEqual(266896, Commit._parse_revision('R266896'))
        self.assertEqual(266896, Commit._parse_revision('266896'))
        self.assertEqual(266896, Commit._parse_revision(266896))

        self.assertEqual(None, Commit._parse_revision('c3bd784f8b88bd03'))
        self.assertEqual(None, Commit._parse_revision('0'))
        self.assertEqual(None, Commit._parse_revision('-1'))
        self.assertEqual(None, Commit._parse_revision('3.141592'))
        self.assertEqual(None, Commit._parse_revision(3.141592))
Пример #19
0
    def test_find_timestamp(self, client, **kwargs):
        self.register_all_commits(client)
        response = client.get(self.URL + '/api/commits?timestamp=1601668000')
        self.assertEqual(200, response.status_code)
        self.assertEqual(2, len(response.json()))
        self.assertEqual(
            [Commit.from_json(element).hash for element in response.json()], [
                'bae5d1e90999d4f916a8a15810ccfa43f37a2fd6',
                'd8bce26fa65c6fc8f39c17927abb77f69fab82fc',
            ])

        response = client.get(self.URL + '/api/commits?timestamp=1601639900')
        self.assertEqual(200, response.status_code)
        self.assertEqual(1, len(response.json()))
        self.assertEqual(Commit.from_json(response.json()[0]).revision, 6)
Пример #20
0
    def test_json_decode(self):
        contributor = Contributor.from_scm_log(
            'Author: Jonathan Bedard <*****@*****.**>')

        commit_a = Commit(revision=1,
                          hash='c3bd784f8b88bd03f64467ddd3304ed8be28acbe',
                          identifier='1@main',
                          timestamp=1000,
                          author=Contributor.Encoder().default(contributor),
                          message='Message')

        dictionary = json.loads(json.dumps(commit_a, cls=Commit.Encoder))
        commit_b = Commit(**dictionary)

        self.assertEqual(commit_a, commit_b)
Пример #21
0
    def checkout(self, argument):
        if not isinstance(argument, six.string_types):
            raise ValueError(
                "Expected 'argument' to be a string, not '{}'".format(
                    type(argument)))

        self._branch = None

        if log.level > logging.WARNING:
            log_arg = ['-q']
        elif log.level < logging.WARNING:
            log_arg = ['--progress']
        else:
            log_arg = []

        parsed_commit = Commit.parse(argument, do_assert=False)
        if parsed_commit:
            commit = self.commit(
                hash=parsed_commit.hash,
                revision=parsed_commit.revision,
                identifier=parsed_commit.identifier,
                branch=parsed_commit.branch,
            )
            return None if run(
                [self.executable(), 'checkout'] + [commit.hash] + log_arg,
                cwd=self.root_path,
            ).returncode else commit

        return None if run(
            [self.executable(), 'checkout'] + [argument] + log_arg,
            cwd=self.root_path,
        ).returncode else self.commit()
Пример #22
0
    def __init__(
        self,
        remote='github.example.com/WebKit/webkit',
        datafile=None,
        default_branch='main',
        git_svn=False,
    ):
        if not scmremote.GitHub.is_webserver('https://{}'.format(remote)):
            raise ValueError(
                '"{}" is not a valid GitHub remote'.format(remote))

        self.default_branch = default_branch
        self.remote = remote
        hostname = self.remote.split('/')[0]
        self.api_remote = 'api.{hostname}/repos/{repo}'.format(
            hostname=hostname,
            repo='/'.join(self.remote.split('/')[1:]),
        )

        super(GitHub, self).__init__(hostname, 'api.{}'.format(hostname))

        with open(datafile
                  or os.path.join(os.path.dirname(os.path.dirname(__file__)),
                                  'git-repo.json')) as file:
            self.commits = json.load(file)
        for key, commits in self.commits.items():
            self.commits[key] = [Commit(**kwargs) for kwargs in commits]
            if not git_svn:
                for commit in self.commits[key]:
                    commit.revision = None

        self.head = self.commits[self.default_branch][-1]
        self.tags = {}
        self._environment = None
Пример #23
0
    def find(self, argument, include_log=True, include_identifier=True):
        if not isinstance(argument, six.string_types):
            raise ValueError("Expected 'argument' to be a string, not '{}'".format(type(argument)))

        if argument in self.DEFAULT_BRANCHES:
            argument = self.default_branch

        parsed_commit = Commit.parse(argument, do_assert=False)
        if parsed_commit:
            if parsed_commit.branch in self.DEFAULT_BRANCHES:
                parsed_commit.branch = self.default_branch

            return self.commit(
                hash=parsed_commit.hash,
                revision=parsed_commit.revision,
                identifier=parsed_commit.identifier,
                branch=parsed_commit.branch,
                include_log=include_log,
                include_identifier=include_identifier,
            )

        commit_data = self.request('commits/{}'.format(argument))
        if not commit_data:
            raise ValueError("'{}' is not an argument recognized by git".format(argument))
        return self.commit(hash=commit_data['sha'], include_log=include_log, include_identifier=include_identifier)
Пример #24
0
    def test_json_encode(self):
        contributor = Contributor.from_scm_log(
            'Author: Jonathan Bedard <*****@*****.**>')

        self.assertDictEqual(
            dict(
                revision=1,
                hash='c3bd784f8b88bd03f64467ddd3304ed8be28acbe',
                branch='main',
                identifier='1@main',
                timestamp=1000,
                order=0,
                author=dict(
                    name='Jonathan Bedard',
                    emails=['*****@*****.**'],
                ),
                message='Message',
            ),
            json.loads(
                json.dumps(Commit(
                    revision=1,
                    hash='c3bd784f8b88bd03f64467ddd3304ed8be28acbe',
                    identifier='1@main',
                    timestamp=1000,
                    author=contributor,
                    message='Message',
                ),
                           cls=Commit.Encoder)))
Пример #25
0
 def _do_job_for_key(self, key, attempts=1):
     job_complete = False
     try:
         raw_data = self.redis.get(f'data_for_{key}')
         if raw_data:
             data = json.loads(raw_data)
             self.synchronously_process_test_results(
                 configuration=Configuration.from_json(
                     data['configuration']),
                 commits=[
                     Commit.from_json(commit_json)
                     for commit_json in data['commits']
                 ],
                 suite=data['suite'],
                 timestamp=data['timestamp'],
                 test_results=data['test_results'],
             )
         job_complete = True
     finally:
         if job_complete or attempts >= self.MAX_ATTEMPTS:
             self.redis.delete(key)
             self.redis.delete(f'data_for_{key}')
         else:
             self.redis.set(
                 key,
                 json.dumps(dict(started_processing=0, attempts=attempts)),
                 ex=self.PROCESS_TIMEOUT,
             )
     return job_complete
Пример #26
0
    def webkit(cls):
        svn = mocks.remote.Svn(remote='svn.webkit.org/repository/webkit')
        github = mocks.remote.GitHub(remote='github.com/WebKit/WebKit',
                                     git_svn=True)
        github.commits = {}

        for branch, commits in svn.commits.items():
            if 'tag' in branch:
                continue
            if branch == 'trunk':
                branch = 'main'
            github.commits[branch] = []

            for commit in commits:
                github.commits[branch].append(
                    Commit(
                        repository_id=commit.repository_id,
                        branch=branch,
                        author=commit.author,
                        message=commit.message,
                        timestamp=commit.timestamp,
                        order=commit.order,
                        identifier=commit.identifier,
                        branch_point=commit.branch_point,
                        revision=commit.revision,
                        hash=commit.hash,
                    ))

        with svn, github:
            yield github
Пример #27
0
    def info(self, branch=None, revision=None, tag=None):
        if tag and branch:
            raise ValueError('Cannot specify both branch and tag')
        if tag and revision:
            raise ValueError('Cannot specify both branch and tag')

        revision = Commit._parse_revision(revision)
        if branch and branch != self.default_branch and '/' not in branch:
            branch = 'branches/{}'.format(branch)
        additional_args = [
            '^/{}'.format(branch)
        ] if branch and branch != self.default_branch else []
        additional_args += ['^/tags/{}'.format(tag)] if tag else []
        additional_args += ['-r', str(revision)] if revision else []

        info_result = run([self.executable(), 'info'] + additional_args,
                          cwd=self.root_path,
                          capture_output=True,
                          encoding='utf-8')
        if info_result.returncode:
            return {}

        result = {}
        for line in info_result.stdout.splitlines():
            split = line.split(': ')
            result[split[0]] = ': '.join(split[1:])
        return result
Пример #28
0
    def __init__(
        self,
        remote='bitbucket.example.com/projects/WEBKIT/repos/webkit',
        datafile=None,
        default_branch='main',
        git_svn=False,
    ):
        if not scmremote.BitBucket.is_webserver('https://{}'.format(remote)):
            raise ValueError(
                '"{}" is not a valid BitBucket remote'.format(remote))

        self.default_branch = default_branch
        self.remote = remote
        self.project = '/'.join(remote.split('/')[1:])

        super(BitBucket, self).__init__(self.remote.split('/')[0])

        with open(datafile
                  or os.path.join(os.path.dirname(os.path.dirname(__file__)),
                                  'git-repo.json')) as file:
            self.commits = json.load(file)
        for key, commits in self.commits.items():
            self.commits[key] = [Commit(**kwargs) for kwargs in commits]
            if not git_svn:
                for commit in self.commits[key]:
                    commit.revision = None

        self.head = self.commits[self.default_branch][-1]
        self.tags = {}
Пример #29
0
    def find(self, argument, include_log=True):
        if not isinstance(argument, six.string_types):
            raise ValueError(
                "Expected 'argument' to be a string, not '{}'".format(
                    type(argument)))

        parsed_commit = Commit.parse(argument, do_assert=False)
        if parsed_commit:
            return self.commit(
                hash=parsed_commit.hash,
                revision=parsed_commit.revision,
                identifier=parsed_commit.identifier,
                branch=parsed_commit.branch,
                include_log=include_log,
            )

        output = run(
            [self.executable(), 'rev-parse', argument],
            cwd=self.root_path,
            capture_output=True,
            encoding='utf-8',
        )
        if output.returncode:
            raise ValueError(
                "'{}' is not an argument recognized by git".format(argument))
        return self.commit(hash=output.stdout.rstrip(),
                           include_log=include_log)
Пример #30
0
    def commits(self, begin=None, end=None, include_log=True, include_identifier=True):
        begin, end = self._commit_range(begin=begin, end=end, include_identifier=include_identifier)

        previous = end
        cached = [previous]
        while previous:
            response = self.request('commits', paginate=False, params=dict(sha=previous.hash))
            if not response:
                break
            for commit_data in response:
                branch_point = previous.branch_point
                identifier = previous.identifier
                if commit_data['sha'] == previous.hash:
                    cached = cached[:-1]
                else:
                    identifier -= 1

                if not identifier:
                    identifier = branch_point
                    branch_point = None

                matches = self.GIT_SVN_REVISION.findall(commit_data['commit']['message'])
                revision = int(matches[-1].split('@')[0]) if matches else None

                email_match = self.EMAIL_RE.match(commit_data['commit']['author']['email'])
                timestamp = int(calendar.timegm(datetime.strptime(
                    commit_data['commit']['committer']['date'], '%Y-%m-%dT%H:%M:%SZ',
                ).timetuple()))

                previous = Commit(
                    repository_id=self.id,
                    hash=commit_data['sha'],
                    revision=revision,
                    branch=end.branch if identifier and branch_point else self.default_branch,
                    identifier=identifier if include_identifier else None,
                    branch_point=branch_point if include_identifier else None,
                    timestamp=timestamp,
                    author=self.contributors.create(
                        commit_data['commit']['author']['name'],
                        email_match.group('email') if email_match else None,
                    ), order=0,
                    message=commit_data['commit']['message'] if include_log else None,
                )
                if not cached or cached[0].timestamp != previous.timestamp:
                    for c in cached:
                        yield c
                    cached = [previous]
                else:
                    for c in cached:
                        c.order += 1
                    cached.append(previous)

                if previous.hash == begin.hash or previous.timestamp < begin.timestamp:
                    previous = None
                    break

        for c in cached:
            c.order += begin.order
            yield c