Esempio n. 1
0
    def test_register_with_full_commit(self, client, **kwargs):
        git_commit = Commit(
            repository_id='safari',
            branch='main',
            id='8eba280e32daaf5fddbbb65aea37932ea9ad85df',
            timestamp=1601650100,
            order=0,
            committer='*****@*****.**',
            message='custom commit',
        )
        self.assertEqual(
            200,
            client.post(self.URL + '/api/commits',
                        data=Commit.Encoder().default(git_commit)).status_code)
        response = client.get(self.URL + '/api/commits?repository_id=safari')
        self.assertEqual(200, response.status_code)
        self.assertEqual(Commit.from_json(response.json()[0]), git_commit)

        svn_commit = Commit(
            repository_id='webkit',
            branch='trunk',
            id='1234',
            timestamp=1601650100,
            order=0,
            committer='*****@*****.**',
            message='custom commit',
        )
        self.assertEqual(
            200,
            client.post(self.URL + '/api/commits',
                        data=Commit.Encoder().default(svn_commit)).status_code)
        response = client.get(self.URL + '/api/commits?repository_id=webkit')
        self.assertEqual(200, response.status_code)
        self.assertEqual(Commit.from_json(response.json()[0]), svn_commit)
Esempio n. 2
0
    def test_encoding(self):
        commits_to_test = [
            Commit(
                repository_id='safari',
                branch='master',
                id='e64810a40c3fecb728871e12ca31482ca715b383',
                timestamp=1537550685,
            ),
            Commit(
                repository_id='safari',
                branch='master',
                id='7be4084258a452e8fe22f36287c5b321e9c8249b',
                timestamp=1537550685,
                order=1,
                committer='*****@*****.**',
                message='Changelog',
            ),
            Commit(
                repository_id='webkit',
                branch='master',
                id=236522,
                timestamp=1537826614,
            ),
        ]
        for commit in commits_to_test:
            converted_commit = Commit.from_json(commit.to_json())

            self.assertEqual(commit, converted_commit)
            self.assertEqual(commit.repository_id,
                             converted_commit.repository_id)
            self.assertEqual(commit.id, converted_commit.id)
            self.assertEqual(commit.timestamp, converted_commit.timestamp)
            self.assertEqual(commit.order, converted_commit.order)
            self.assertEqual(commit.committer, converted_commit.committer)
            self.assertEqual(commit.message, converted_commit.message)
Esempio n. 3
0
def _find_comparison(commit_context, repository_id, branch, id, uuid, timestamp, priority=min):
    if bool(id) + bool(uuid) + bool(timestamp) > 1:
        abort(400, description='Can only search by one of [commit id, commit uuid, timestamp] in a single request')

    try:
        if uuid:
            # We don't need real commit to search by uuid and CommitContexts have trouble diffrentiating between uuids and timestamps.
            uuid = priority([int(element) for element in uuid])
            return Commit('?', '?', '?', uuid // Commit.TIMESTAMP_TO_UUID_MULTIPLIER, uuid % Commit.TIMESTAMP_TO_UUID_MULTIPLIER)
        if timestamp:
            return priority([round(float(element)) for element in timestamp])
    except ValueError:
        abort(400, description='Timestamp and uuid must be integers')

    if not repository_id and not id:
        return None
    if not repository_id:
        repository_id = commit_context.repositories.keys()
    for repository in repository_id:
        if repository not in commit_context.repositories.keys():
            abort(404, description=f"\'{repository}\' is not a registered repository")

    result = []
    for repository in repository_id:
        for b in branch:
            if id:
                for elm in id:
                    result += commit_context.find_commits_by_id(repository, b, elm)
            else:
                result += commit_context.find_commits_in_range(repository, b, limit=1)

    if not result:
        abort(404, description='No commits found matching the specified criteria')
    return priority(result)
Esempio n. 4
0
    def commit_for_id(self, id, branch=DEFAULT_BRANCH):
        with self.session():
            try:
                commit_data = self.get(
                    branch=branch, revision=id
                )['D:multistatus']['D:response']['D:propstat'][0]['D:prop']
                if commit_data['lp1:version-name'] != str(id):
                    raise SCMException(
                        f'Revision {id} does not exist on branch {branch}')

                # Of the form '2018-09-24T22:03:34.436217Z'
                timestamp = datetime.datetime.strptime(
                    commit_data['lp1:creationdate'], '%Y-%m-%dT%H:%M:%S.%fZ')

                return Commit(
                    repository_id=self.key,
                    id=str(id),
                    branch=branch,
                    timestamp=timestamp,
                    order=0,
                    committer=commit_data['lp1:creator-displayname'],
                )
            except ExpatError:
                raise SCMException(f'Failed to connect to {self.url}')
            except KeyError:
                raise SCMException(
                    f'Revision {id} does not exist on branch {branch}')
Esempio n. 5
0
 def test_invalid(self):
     with self.assertRaises(ValueError):
         Commit(
             repository_id='safari',
             branch='master',
             id='7be4084258a452e8fe22f36287c5b321e9c8249b',
             timestamp=None,
         )
Esempio n. 6
0
 def to_commit(self):
     return Commit(
         repository_id=self.repository_id, branch=self.branch,
         id=self.commit_id,
         timestamp=self.uuid // Commit.TIMESTAMP_TO_UUID_MULTIPLIER,
         order=self.uuid % Commit.TIMESTAMP_TO_UUID_MULTIPLIER,
         committer=self.committer, message=self.message,
     )
Esempio n. 7
0
 def test_udid(self):
     self.assertEqual(
         Commit(
             repository_id='safari',
             branch='master',
             id='7be4084258a452e8fe22f36287c5b321e9c8249b',
             timestamp=1537550685,
             order=1,
         ).uuid, 153755068501)
Esempio n. 8
0
 def commit_for_id(self, id):
     commit = self.remote.commit(revision=id, include_identifier=False)
     return Commit(
         repository_id=self.key,
         id=commit.revision,
         branch=commit.branch,
         timestamp=commit.timestamp,
         order=commit.order,
         committer=commit.author.email,
         message=commit.message,
     )
Esempio n. 9
0
    def test_compare(self):
        commit1 = Commit(
            repository_id='safari',
            branch='master',
            id='e64810a40c3fecb728871e12ca31482ca715b383',
            timestamp=1537550685,
        )
        commit2 = Commit(
            repository_id='safari',
            branch='master',
            id='7be4084258a452e8fe22f36287c5b321e9c8249b',
            timestamp=1537550685,
            order=1,
        )
        commit3 = Commit(
            repository_id='safari',
            branch='master',
            id='bb6bda5f44dd24d0b54539b8ff6e8c17f519249a',
            timestamp=1537810281,
        )
        commit4 = Commit(
            repository_id='webkit',
            branch='master',
            id=236522,
            timestamp=1537826614,
        )

        self.assertTrue(commit2 > commit1)
        self.assertTrue(commit2 >= commit1)
        self.assertTrue(commit1 >= commit1)
        self.assertTrue(commit1 < commit2)
        self.assertTrue(commit1 <= commit2)
        self.assertTrue(commit1 <= commit1)
        self.assertTrue(commit1 == commit1)

        self.assertTrue(commit2 < commit3)
        self.assertTrue(commit3 > commit2)
        self.assertEqual(commit1.timestamp, commit2.timestamp)

        self.assertTrue(commit4 > commit3)
        self.assertNotEqual(commit3.repository_id, commit4.repository_id)
Esempio n. 10
0
    def commit_for_id(self, id, branch=Repository.DEFAULT_BRANCH):
        try:
            with self.session():
                commit_data = self.get(f'commits/{id}')
                if not commit_data:
                    raise SCMException(
                        f'Commit {id} does not exist on branch {branch}')
                timestamp = int(commit_data['committerTimestamp']
                                ) // self.COMMIT_TIMESTAMP_CONVERSION

                branch_filter = urllib.parse.quote(f'refs/heads/{branch}')
                commits_between_commit_and_branch_head = self.get(
                    f"commits?since={commit_data['id']}&until={branch_filter}&limit=1",
                    cache=False)
                if commits_between_commit_and_branch_head[
                        'isLastPage'] and commits_between_commit_and_branch_head[
                            'size'] == 0:
                    # We may have missed the case the commit in question is the HEAD of the branch
                    commits_at_branch_head = self.get(
                        f'commits?until={branch_filter}&limit=20', cache=False)
                    if all([
                            commit['id'] != commit_data['id']
                            for commit in commits_at_branch_head['values']
                    ]):
                        raise SCMException(f'{id} exists, but not on {branch}')

                # Ordering commits by timestamp in git is a bit problematic because multiple commits can share a timestamp.
                # Generally, if your parent shares your timestamp, your order needs to be incremented.
                order = 0
                loop_data = commit_data
                while len(loop_data['parents']) == 1 and int(
                        loop_data['parents'][0]['committerTimestamp']
                ) // self.COMMIT_TIMESTAMP_CONVERSION == timestamp:
                    order += 1
                    loop_data = self.get(
                        f"commits/{loop_data['parents'][0]['id']}")

                return Commit(
                    repository_id=self.key,
                    id=commit_data['id'],
                    branch=branch,
                    timestamp=timestamp,
                    order=order,
                    committer=commit_data['committer']['emailAddress'],
                    message=commit_data['message'],
                )
        except ValueError:
            raise SCMException(f'Failed to connect to {self.url}')
Esempio n. 11
0
 def test_basic_svn(self, redis=StrictRedis):
     svn_repo = MockSVNRepository(url='svn.webkit.org/repository/webkit/',
                                  name='webkit',
                                  redis=redis())
     svn_repo.add_commit(
         Commit(
             repository_id=svn_repo.name,
             branch='trunk',
             id=236544,
             timestamp=1538052408,
             order=0,
             committer='*****@*****.**',
             message='Change 1 description.',
         ))
     commit = svn_repo.commit_for_id(236544, branch='trunk')
     self.assertEqual(commit.uuid, 153805240800)
     self.assertIsNone(commit.message, None)
Esempio n. 12
0
    def safari(redis=None):
        result = MockStashRepository('https://fake-stash-instance.apple.com/projects/BROWSER/repos/safari', name='safari', redis=redis)
        result.add_commit(Commit(
            repository_id=result.name, branch='master', id='bb6bda5f44dd24d0b54539b8ff6e8c17f519249a',
            timestamp=1537810281, order=0,
            committer='*****@*****.**',
            message='Change 1 description.',
        ))
        result.add_commit(Commit(
            repository_id=result.name, branch='master', id='336610a84fdcf14ddcf1db65075af95480516fda',
            timestamp=1537809818, order=0,
            committer='*****@*****.**',
            message='Change 2 description.',
        ))
        result.add_commit(Commit(
            repository_id=result.name, branch='master', id='336610a40c3fecb728871e12ca31482ca715b383',
            timestamp=1537566386, order=0,
            committer='*****@*****.**',
            message='<rdar://problem/99999999> Change 3 description.',
        ))
        result.add_commit(Commit(
            repository_id=result.name, branch='master', id='e64810a40c3fecb728871e12ca31482ca715b383',
            timestamp=1537550685, order=0,
            committer='*****@*****.**',
            message=u'Change 4 \u2014 (Part 1) description.',
        ))
        result.add_commit(Commit(
            repository_id=result.name, branch='master', id='7be4084258a452e8fe22f36287c5b321e9c8249b',
            timestamp=1537550685, order=1,
            committer='*****@*****.**',
            message=u'Change 4 \u2014 (Part 2) description.\nReviewed by person.',
        ))

        result.add_commit(Commit(
            repository_id=result.name, branch='safari-606-branch', id='79256c32a855ac8612112279008334d90e901c55',
            timestamp=1537897367, order=0,
            committer='*****@*****.**',
            message='Change 5 description.',
        ))
        result.add_commit(Commit(
            repository_id=result.name, branch='safari-606-branch', id='d85222d9407fdbbf47406509400a9cecb73ac6de',
            timestamp=1537563383, order=0,
            committer='*****@*****.**',
            message='Change 6 description.',
        ))
        return result
Esempio n. 13
0
    def webkit(redis=None):
        result = MockWebKitRepository(redis=redis)
        result.add_commit(Commit(
            repository_id=result.name, branch='trunk', id=236544,
            timestamp=1538052408, order=0,
            committer='*****@*****.**',
            message='Change 1 description.',
        ))
        result.add_commit(Commit(
            repository_id=result.name, branch='trunk', id=236543,
            timestamp=1538050458, order=0,
            committer='*****@*****.**',
            message='Change 2 description.',
        ))
        result.add_commit(Commit(
            repository_id=result.name, branch='trunk', id=236542,
            timestamp=1538049108, order=0,
            committer='*****@*****.**',
            message='Change 3 description.',
        ))
        result.add_commit(Commit(
            repository_id=result.name, branch='trunk', id=236541,
            timestamp=1538041792, order=0,
            committer='*****@*****.**',
            message='Change 4 (Part 2) description.',
        ))
        result.add_commit(Commit(
            repository_id=result.name, branch='trunk', id=236540,
            timestamp=1538029479, order=0,
            committer='*****@*****.**',
            message='Change 4 (Part 1) description.',
        ))

        result.add_commit(Commit(
            repository_id=result.name, branch='safari-606-branch', id=236335,
            timestamp=1538029480, order=0,
            committer='*****@*****.**',
            message='Integration 1.',
        ))
        result.add_commit(Commit(
            repository_id=result.name, branch='safari-606-branch', id=236334,
            timestamp=1538029479, order=0,
            committer='*****@*****.**',
            message='Integration 2.',
        ))
        return result
Esempio n. 14
0
    def register(self, commit=None, fast=True):
        is_endpoint = not bool(commit)
        if is_endpoint:
            AssertRequest.is_type(['POST'])
            AssertRequest.no_query()

        if is_endpoint:
            try:
                commit = request.form or json.loads(request.get_data())
                if 'api_key' in commit:
                    del commit['api_key']
            except ValueError:
                abort(400, description='Expected uploaded data to be json')

        try:
            candidate = ScmCommit.from_json(commit)

            # Commit needs to be sufficiently defined
            if candidate.repository_id and candidate.branch and candidate.timestamp and (
                    candidate.revision or candidate.hash):
                self.commit_context.register_commit(candidate)
                if is_endpoint:
                    return jsonify({'status': 'ok'})
                return candidate
        except ValueError:
            pass

        required_args = ['repository_id']
        for arg in required_args:
            if arg not in commit:
                abort(400, description=f"'{arg}' required to define commit")

        has_ref = False
        one_of_args = ['id', 'ref', 'hash', 'revision', 'identifier']
        for arg in one_of_args:
            if arg in commit:
                if has_ref:
                    abort(400,
                          description='Multiple commit references specified')
                has_ref = True
        if not has_ref:
            abort(400, description='No commit reference specified')

        for arg in commit.keys():
            if arg in required_args or arg in one_of_args:
                continue
            if arg in ['branch', 'timestamp', 'order', 'committer', 'message']:
                abort(
                    400,
                    description=
                    'Not enough arguments provided to define a commit, but too many to search for a commit'
                )
            abort(400,
                  description=f"'{arg}' is not valid for defining commits")

        try:
            commit = self.commit_context.register_partial_commit(
                repository_id=commit.get('repository_id'),
                ref=commit.get('id') or commit.get('ref'),
                hash=commit.get('hash'),
                revision=commit.get('revision'),
                identifier=commit.get('identifier'),
                fast=fast,
            )
        except (RuntimeError, ScmBase.Exception) as error:
            abort(404, description=str(error))

        if is_endpoint:
            return jsonify({'status': 'ok'})
        return Commit(
            repository_id=commit.repository_id,
            id=commit.revision or commit.hash,
            branch=commit.branch,
            timestamp=commit.timestamp,
            order=commit.order,
            committer=commit.author.email if commit.author else None,
            message=commit.message,
        )
Esempio n. 15
0
    def test_invalid(self):
        with self.assertRaises(ValueError) as error:
            Commit(
                repository_id='safari',
                branch='master',
                id='7be4084258a452e8fe22f36287c5b321e9c8249b',
                timestamp=None,
            )
        self.assertEqual(str(error.exception),
                         'timestamp is not defined for commit')

        with self.assertRaises(ValueError) as error:
            Commit(
                repository_id='invalid-repo',
                branch='master',
                id='7be4084258a452e8fe22f36287c5b321e9c8249b',
                timestamp=1537550685,
            )
        self.assertEqual(str(error.exception),
                         "'invalid-repo' is an invalid repository id")

        with self.assertRaises(ValueError) as error:
            Commit(
                repository_id='i' * 129,
                branch='master',
                id='7be4084258a452e8fe22f36287c5b321e9c8249b',
                timestamp=1537550685,
            )
        self.assertEqual(str(error.exception),
                         f"'{'i' * 129}' is an invalid repository id")

        with self.assertRaises(ValueError) as error:
            Commit(
                repository_id='safari',
                branch='<html>invalid-branch</html>',
                id='7be4084258a452e8fe22f36287c5b321e9c8249b',
                timestamp=1537550685,
            )
        self.assertEqual(
            str(error.exception),
            "'<html>invalid-branch</html>' is an invalid branch name")

        with self.assertRaises(ValueError) as error:
            Commit(
                repository_id='safari',
                branch='i' * 129,
                id='7be4084258a452e8fe22f36287c5b321e9c8249b',
                timestamp=1537550685,
            )
        self.assertEqual(str(error.exception),
                         f"'{'i' * 129}' is an invalid branch name")

        with self.assertRaises(ValueError) as error:
            Commit(
                repository_id='safari',
                branch='master',
                id='<html>1234</html>',
                timestamp=1537550685,
            )
        self.assertEqual(str(error.exception),
                         "'<html>1234</html>' is an invalid commit id")

        with self.assertRaises(ValueError) as error:
            Commit(
                repository_id='safari',
                branch='master',
                id='0' * 41,
                timestamp=1537550685,
            )
        self.assertEqual(str(error.exception),
                         f"'{'0' * 41}' is an invalid commit id")