Exemplo n.º 1
0
 def install_404_responses(self):
     """Install catch-all 404 response handlers for API queries."""
     query_urls = ['differential.query', 'phid.query', 'user.query']
     for query_url in query_urls:
         self.mock.get(phab_url(query_url),
                       status_code=404,
                       json=CANNED_EMPTY_RESULT)
Exemplo n.º 2
0
def test_check_connection_success():
    phab = PhabricatorClient(api_key='api-key')
    success_json = CANNED_EMPTY_RESULT.copy()
    with requests_mock.mock() as m:
        m.get(phab_url('conduit.ping'), status_code=200, json=success_json)
        phab.check_connection()
        assert m.called
Exemplo n.º 3
0
 def phid(self, response_data):
     """Add a phid.query matcher for the given Phabricator response object.
     """
     phid = phid_for_response(response_data)
     self.mock.get(phab_url('phid.query'),
                   status_code=200,
                   additional_matcher=form_matcher('phids[]', phid),
                   json=response_data)
Exemplo n.º 4
0
 def rawdiff(self, diffID='12345'):
     """Return raw diff text for a Revision Diff."""
     rawdiff = deepcopy(CANNED_REVISION_1_RAW_DIFF)
     self.mock.get(phab_url('differential.getrawdiff'),
                   status_code=200,
                   json=rawdiff,
                   additional_matcher=form_matcher('diffID', diffID))
     return rawdiff
Exemplo n.º 5
0
def test_heartbeat_returns_200_if_phabricator_api_is_up(client):
    json_response = CANNED_EMPTY_RESULT.copy()
    with requests_mock.mock() as m:
        m.get(phab_url('conduit.ping'), status_code=200, json=json_response)

        response = client.get('/__heartbeat__')

        assert m.called
        assert response.status_code == 200
Exemplo n.º 6
0
def test_raise_exception_if_ping_encounters_connection_error(get_phab_client):
    phab = get_phab_client(api_key="api-key")
    with requests_mock.mock() as m:
        # Test with the generic ConnectionError, which is a superclass for
        # other connection error types.
        m.get(phab_url("conduit.ping"), exc=requests.ConnectionError)

        with pytest.raises(PhabricatorAPIException):
            phab.call_conduit("conduit.ping")
        assert m.called
Exemplo n.º 7
0
def test_get_current_user_with_200_response():
    phab = PhabricatorClient(api_key='api-key')
    with requests_mock.mock() as m:
        m.get(
            phab_url('user.whoami'),
            status_code=200,
            json=CANNED_USER_WHOAMI_1
        )
        user = phab.get_current_user()
        assert user == CANNED_USER_WHOAMI_1['result']
Exemplo n.º 8
0
def test_raise_exception_if_api_ping_times_out():
    phab = PhabricatorClient(api_key='api-key')
    with requests_mock.mock() as m:
        # Test with the generic Timeout exception, which all other timeout
        # exceptions derive from.
        m.get(phab_url('conduit.ping'), exc=requests.Timeout)

        with pytest.raises(PhabricatorAPIException):
            phab.check_connection()
        assert m.called
Exemplo n.º 9
0
def test_raise_exception_if_api_ping_times_out(get_phab_client):
    phab = get_phab_client(api_key="api-key")
    with requests_mock.mock() as m:
        # Test with the generic Timeout exception, which all other timeout
        # exceptions derive from.
        m.get(phab_url("conduit.ping"), exc=requests.Timeout)

        with pytest.raises(PhabricatorAPIException):
            phab.call_conduit("conduit.ping")
        assert m.called
Exemplo n.º 10
0
    def rawdiff(self, diff_id='1', patch=None):
        """Return raw diff text for a Revision Diff."""
        rawdiff = deepcopy(CANNED_RAW_DIFF_1)
        if patch is not None:
            rawdiff['result'] = patch

        self.mock.get(phab_url('differential.getrawdiff'),
                      status_code=200,
                      json=rawdiff,
                      additional_matcher=form_matcher('diffID', str(diff_id)))
        return rawdiff
Exemplo n.º 11
0
def test_get_repo_returns_with_200_response(phabfactory):
    phab = PhabricatorClient(api_key='api-key')
    with requests_mock.mock() as m:
        m.get(
            phab_url('phid.query'),
            status_code=200,
            json=CANNED_REPO_MOZCENTRAL
        )
        canned_response_repo = \
            list(CANNED_REPO_MOZCENTRAL['result'].values())[0]
        repo = phab.get_repo(phid=canned_response_repo['phid'])
        assert repo == canned_response_repo
Exemplo n.º 12
0
def test_heartbeat_returns_http_502_if_phabricator_ping_returns_error(client):
    error_json = {
        "result": None,
        "error_code": "ERR-CONDUIT-CORE",
        "error_info": "BOOM"
    }

    with requests_mock.mock() as m:
        m.get(phab_url('conduit.ping'), status_code=500, json=error_json)

        response = client.get('/__heartbeat__')

        assert m.called
        assert response.status_code == 502
Exemplo n.º 13
0
def test_heartbeat_returns_200_if_phabricator_api_is_up(client):
    with requests_mock.mock() as m:
        m.get(phab_url('conduit.ping'),
              status_code=200,
              json={
                  "result": [],
                  "error_code": None,
                  "error_info": None,
              })

        response = client.get('/__heartbeat__')

        assert m.called
        assert response.status_code == 200
Exemplo n.º 14
0
def test_ping_success(get_phab_client):
    phab = get_phab_client(api_key="api-key")
    with requests_mock.mock() as m:
        m.get(
            phab_url("conduit.ping"),
            status_code=200,
            json={
                "result": [],
                "error_code": None,
                "error_info": None
            },
        )
        phab.call_conduit("conduit.ping")
        assert m.called
Exemplo n.º 15
0
    def revision(self, **kwargs):
        """Return a Phabricator Revision."""
        result_json = deepcopy(CANNED_REVISION_1)
        revision = first_result_in_response(result_json)

        if 'id' in kwargs:
            # Convert 'D000' form to just '000'.
            str_id = kwargs['id']
            num_id = str_id[1:]
            revision['id'] = num_id
            revision['phid'] = "PHID-DREV-%s" % num_id

        if 'depends_on' in kwargs:
            parent_revision_response_data = kwargs['depends_on']
            if parent_revision_response_data:
                # This Revisions depends on another Revision.
                new_value = [phid_for_response(parent_revision_response_data)]
            else:
                # The user passed in None or an empty list, saying "this
                # revision has no parent revisions."
                new_value = []
            revision['auxiliary']['phabricator:depends-on'] = new_value

        # Revisions have at least one Diff.
        diff = self.diff()
        diffID = extract_rawdiff_id_from_uri(
            first_result_in_response(diff)['uri'])
        rawdiff = self.rawdiff(diffID=str(diffID))
        revision['activeDiffPHID'] = phid_for_response(diff)

        # Revisions may have a Repo.
        repo = self.repo()
        revision['repositoryPHID'] = phid_for_response(repo)

        def match_revision(request):
            # Revisions can be looked up by PHID or ID.
            found_phid = form_matcher('phids[]', revision['phid'])(request)
            found_id = form_matcher('ids[]', revision['id'])(request)
            return found_phid or found_id

        self.mock.get(phab_url('differential.query'),
                      status_code=200,
                      json=result_json,
                      additional_matcher=match_revision)

        # Revisions can also be looked up by phid.query.
        self.phid(result_json)

        return result_json
Exemplo n.º 16
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']
Exemplo n.º 17
0
    def user(self, username=None, phid=None):
        """Return a Phabricator User."""
        response = deepcopy(CANNED_USER_1)
        user = first_result_in_response(response)
        if username:
            user['userName'] = username
            user['realName'] = "{} Name".format(username)
            user['uri'] = 'http://phabricator.test/p/{}'.format(username)
        if phid:
            user['phid'] = phid

        self.mock.get(phab_url('user.query'),
                      status_code=200,
                      additional_matcher=form_matcher('phids[]', user['phid']),
                      json=response)
        return response
Exemplo n.º 18
0
def test_raise_exception_if_api_returns_error_json_response(get_phab_client):
    phab = get_phab_client(api_key="api-key")
    error_json = {
        "result": None,
        "error_code": "ERR-CONDUIT-CORE",
        "error_info": "BOOM",
    }

    with requests_mock.mock() as m:
        # Test with the generic Timeout exception, which all other timeout
        # exceptions derive from.
        m.get(phab_url("conduit.ping"), status_code=500, json=error_json)

        with pytest.raises(PhabricatorAPIException):
            phab.call_conduit("conduit.ping")
        assert m.called
Exemplo n.º 19
0
def test_phabricator_exception(get_phab_client):
    """ Ensures that the PhabricatorClient converts JSON errors from Phabricator
    into proper exceptions with the error_code and error_message in tact.
    """
    phab = get_phab_client(api_key="api-key")
    error = {
        "result": None,
        "error_code": "ERR-CONDUIT-CORE",
        "error_info": "The value for parameter 'blah' is not valid JSON.",
    }

    with requests_mock.mock() as m:
        m.get(phab_url("differential.query"), status_code=200, json=error)
        with pytest.raises(PhabricatorAPIException) as e_info:
            phab.call_conduit("differential.query", ids=["1"])[0]
        assert e_info.value.error_code == error["error_code"]
        assert e_info.value.error_info == error["error_info"]
Exemplo n.º 20
0
    def diff(self, **kwargs):
        """Create a Phabricator Diff along with stub API endpoints.

        Use the kwargs to customize the diff being created. If they are not
        provided, a default template will be used instead.

        kwargs:
            id: The integer diff id to be used. The diff's phid will be
                based on this.
            patch: The patch file to be used when generating the diff's
                rawdiff. All diffs must have a corresponding rawdiff.

        Returns:
            The full JSON response dict for the generated Diff.
        """
        diff = deepcopy(CANNED_DIFF_1)
        if 'id' in kwargs:
            diff_id = kwargs['id']
        else:
            diff_id = first_result_in_response(diff)['id']
        diff = self._replace_key(diff, 'id', diff_id)

        # Create the mock PHID endpoint.
        diff_phid = 'PHID-DIFF-{diff_id}'.format(diff_id=diff_id)
        diff_phid_resp = self._replace_key(CANNED_DIFF_PHID_QUERY_RESULT_1,
                                           'phid', diff_phid)
        diff_phid_resp['uri'] = "{url}/differential/diff/{diff_id}/".format(
            url=os.getenv('PHABRICATOR_URL'), diff_id=diff_id)
        diff_phid_resp['name'] = "Diff {diff_id}".format(diff_id=diff_id)
        diff_phid_resp['full_name'] = diff_phid_resp['name']
        self.phid(diff_phid_resp)

        # Create the mock raw diff endpoint.
        if 'patch' in kwargs:
            self.rawdiff(diff_id=diff_id, patch=kwargs['patch'])
        else:
            self.rawdiff(diff_id=diff_id)

        # Create the mock diff endpoint.
        self.mock.get(phab_url('differential.querydiffs'),
                      status_code=200,
                      json=diff,
                      additional_matcher=form_matcher('ids[]', str(diff_id)))

        return diff
Exemplo n.º 21
0
def test_heartbeat_returns_http_502_if_phabricator_ping_returns_error(
        client, request_mocker, redis_cache, s3, jwks, treestatusdouble):
    error_json = {
        "result": None,
        "error_code": "ERR-CONDUIT-CORE",
        "error_info": "BOOM",
    }

    request_mocker.get(trans_url(""),
                       status_code=200,
                       text="Welcome to Autoland")
    request_mocker.get(phab_url("conduit.ping"),
                       status_code=500,
                       json=error_json)
    response = client.get("/__heartbeat__")

    assert request_mocker.called
    assert response.status_code == 502
Exemplo n.º 22
0
 def user(self):
     """Return a Phabricator User."""
     user = deepcopy(CANNED_USER_1)
     self.mock.get(phab_url('user.query'), status_code=200, json=user)
     return user
Exemplo n.º 23
0
    def revision(self, **kwargs):
        """Create a Phabricator Revision along with stub API endpoints.

        Use the kwargs to customize the revision being created. If they are not
        provided, a default template will be used instead.

        kwargs:
            id: String ID to give the generated revision. E.g. 'D2233'.
            author_phid: PHID of the author user to use, instead of making a
                default user.
            template: A template revision to base this on from.
            depends_on: Response data for a Revision this revision should depend
                on.
            active_diff: Response data for a Diff that should be this
                Revision's "active diff" (usually this Revision's most recently
                uploaded patch). If you manually set an active diff, it must
                have been made with this factory.

        Returns:
            The full JSON response dict for the generated Revision.
        """
        if 'template' in kwargs:
            result_json = deepcopy(kwargs['template'])
        else:
            result_json = deepcopy(CANNED_REVISION_1)
        revision = first_result_in_response(result_json)

        if 'id' in kwargs:
            # Convert 'D000' form to just '000'.
            str_id = kwargs['id']
            num_id = str_id[1:]
            revision['id'] = num_id
            revision['phid'] = "PHID-DREV-%s" % num_id

        if 'author_phid' in kwargs:
            revision['authorPHID'] = kwargs['author_phid']
        else:
            self.user()

        if 'depends_on' in kwargs:
            parent_revision_response_data = kwargs['depends_on']
            if parent_revision_response_data:
                # This Revisions depends on another Revision.
                new_value = [phid_for_response(parent_revision_response_data)]
            else:
                # The user passed in None or an empty list, saying "this
                # revision has no parent revisions."
                new_value = []
            revision['auxiliary']['phabricator:depends-on'] = new_value

        # Create default reviewer for the Revision
        self.user(username='******', phid='PHID-USER-review_bot')
        revision['reviewers'] = {
            'PHID-USER-review_bot': 'PHID-USER-review_bot'
        }

        # Revisions have at least one Diff.
        if 'active_diff' in kwargs:
            diff = kwargs['active_diff']
        else:
            diff = self.diff()

        revision['activeDiffPHID'] = 'PHID-DIFF-{}'.format(
            first_result_in_response(diff)['id'])

        # Revisions may have a Repo.
        repo = self.repo()
        revision['repositoryPHID'] = phid_for_response(repo)

        def match_revision(request):
            # Revisions can be looked up by PHID or ID.
            found_phid = form_matcher('phids[]', revision['phid'])(request)
            found_id = form_matcher('ids[]', revision['id'])(request)
            return found_phid or found_id

        self.mock.get(phab_url('differential.query'),
                      status_code=200,
                      json=result_json,
                      additional_matcher=match_revision)
        return result_json