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']
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
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]
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
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
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
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
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
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
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