Пример #1
0
def test_phabricator_exception():
    """ Ensures that the PhabricatorClient converts JSON errors from Phabricator
    into proper exceptions with the error_code and error_message in tact.
    """
    phab = PhabricatorClient(api_key='api-key')
    with requests_mock.mock() as m:
        m.get(phab_url('differential.query'),
              status_code=200,
              json=CANNED_ERROR_1)
        with pytest.raises(PhabricatorAPIException) as e_info:
            phab.get_revision(id=CANNED_REVISION_1['result'][0]['id'])
        assert e_info.value.error_code == CANNED_ERROR_1['error_code']
        assert e_info.value.error_info == CANNED_ERROR_1['error_info']
Пример #2
0
def test_landing_revision_calls_transplant_service(db, client, phabfactory,
                                                   monkeypatch, s3):
    # Mock the phabricator response data
    phabfactory.revision()

    # Build the patch we expect to see
    phabclient = PhabricatorClient('someapi')
    revision = phabclient.get_revision('D1')
    diff_id = phabclient.get_diff(phid=revision['activeDiffPHID'])['id']
    gitdiff = phabclient.get_rawdiff(diff_id)
    author = phabclient.get_revision_author(revision)
    hgpatch = build_patch_for_revision(gitdiff, author, revision)
    patch_url = 's3://landoapi.test.bucket/L1_D1_1.patch'

    # The repo we expect to see
    repo_uri = phabclient.get_revision_repo(revision)['uri']

    tsclient = MagicMock(spec=TransplantClient)
    tsclient().land.return_value = 1
    monkeypatch.setattr('landoapi.models.landing.TransplantClient', tsclient)
    client.post('/landings?api_key=api-key',
                data=json.dumps({
                    'revision_id': 'D1',
                    'diff_id': int(diff_id)
                }),
                content_type='application/json')
    tsclient().land.assert_called_once_with(
        '*****@*****.**', patch_url, repo_uri,
        '{}/landings/1/update'.format(os.getenv('PINGBACK_HOST_URL')))
    body = s3.Object('landoapi.test.bucket',
                     'L1_D1_1.patch').get()['Body'].read().decode("utf-8")
    assert body == hgpatch
Пример #3
0
def test_get_revision_with_200_response():
    phab = PhabricatorClient(api_key='api-key')
    with requests_mock.mock() as m:
        m.get(phab_url('differential.query'),
              status_code=200,
              json=CANNED_REVISION_1)
        revision = phab.get_revision(id=CANNED_REVISION_1['result'][0]['id'])
        assert revision == CANNED_REVISION_1['result'][0]
Пример #4
0
def test_get_repo_for_revision(phabfactory):
    repo_response = phabfactory.repo()
    phabfactory.revision(id='D5')
    expected_repo = first_result_in_response(repo_response)

    phab = PhabricatorClient(api_key='api-key')
    revision = phab.get_revision(id='D5')
    repo = phab.get_revision_repo(revision)

    assert repo == expected_repo
Пример #5
0
def test_get_author_for_revision(phabfactory):
    user_response = phabfactory.user()
    phabfactory.revision(id='D5')
    expected_user = first_result_in_response(user_response)

    phab = PhabricatorClient(api_key='api-key')
    revision = phab.get_revision(id='D5')
    author = phab.get_revision_author(revision)

    assert author == expected_user
Пример #6
0
def test_build_patch(phabfactory, docker_env_vars):
    phabfactory.user(username='******', phid='PHID-USER-mpm')
    phabfactory.revision(id='D5', author_phid='PHID-USER-mpm')

    phab = PhabricatorClient(api_key='api-key')
    revision = phab.get_revision(id='D5')
    revision['summary'] = "Express great joy at existence of Mercurial"
    author = phab.get_revision_author(revision)

    patch = build_patch_for_revision(git_diff_from_revision, author, revision)

    assert patch == hg_patch
Пример #7
0
def test_patch_uploads_to_s3(db, phabfactory, s3):
    phabfactory.user()
    phabfactory.revision()
    phabfactory.rawdiff(1)

    phab = PhabricatorClient(None)
    revision = phab.get_revision(1)
    patch = Patch(1, revision, 1)
    expected_body = patch.build(phab)
    patch.upload(phab)

    assert patch.s3_url == 's3://landoapi.test.bucket/L1_D1_1.patch'
    body = s3.Object('landoapi.test.bucket', 'L1_D1_1.patch').get()['Body'].read().decode("utf-8")
    assert body == expected_body
Пример #8
0
def get(revision_id, api_key=None):
    """ Gets revision from Phabricator.

    Returns None or revision.
    """
    phab = PhabricatorClient(api_key)
    revision = phab.get_revision(id=revision_id)

    if not revision:
        # We could not find a matching revision.
        return problem(
            404,
            'Revision not found',
            'The requested revision does not exist',
            type='https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/404'
        )

    return _format_revision(phab, revision, include_parents=True), 200
Пример #9
0
    def create(cls, revision_id, diff_id, phabricator_api_key=None):
        """Land revision.

        A typical successful story:
            * Revision and Diff are loaded from Phabricator.
            * Patch is created and uploaded to S3 bucket.
            * Landing object is created (without request_id)
            * A request to land the patch is send to Transplant client.
            * Created landing object is updated with returned `request_id`,
              it is then saved and returned.

        Args:
            revision_id: The id of the revision to be landed
            diff_id: The id of the diff to be landed
            phabricator_api_key: API Key to identify in Phabricator

        Returns:
            A new Landing object

        Raises:
            RevisionNotFoundException: PhabricatorClient returned no revision
                for given revision_id
            LandingNotCreatedException: landing request in Transplant failed
        """
        phab = PhabricatorClient(phabricator_api_key)
        revision = phab.get_revision(id=revision_id)

        if not revision:
            raise RevisionNotFoundException(revision_id)

        repo = phab.get_revision_repo(revision)

        # Save landing to make sure we've got the callback URL.
        landing = cls(revision_id=revision_id, diff_id=diff_id)
        landing.save()

        patch = Patch(landing.id, revision, diff_id)
        patch.upload(phab)

        # Define the pingback URL with the port.
        callback = '{host_url}/landings/{id}/update'.format(
            host_url=current_app.config['PINGBACK_HOST_URL'], id=landing.id)

        trans = TransplantClient()
        # The LDAP username used here has to be the username of the patch
        # pusher (the person who pushed the 'Land it!' button).
        # FIXME: change [email protected] to the real data retrieved
        #        from Auth0 userinfo
        request_id = trans.land('*****@*****.**', patch.s3_url,
                                repo['uri'], callback)
        if not request_id:
            raise LandingNotCreatedException

        landing.request_id = request_id
        landing.status = TRANSPLANT_JOB_STARTED
        landing.save()

        logger.info(
            {
                'revision_id': revision_id,
                'landing_id': landing.id,
                'msg': 'landing created for revision'
            }, 'landing.success')

        return landing
Пример #10
0
def test_get_revision_with_200_response(phabfactory):
    revision_response = phabfactory.revision(id='D1234')
    expected_revision = first_result_in_response(revision_response)
    phab = PhabricatorClient(api_key='api-key')
    revision = phab.get_revision(id=1234)
    assert revision == expected_revision