Changeset View
Changeset View
Standalone View
Standalone View
swh/core/api/tests/test_rpc_client_server.py
# Copyright (C) 2018-2019 The Software Heritage developers | # Copyright (C) 2018-2019 The Software Heritage developers | ||||
# See the AUTHORS file at the top-level directory of this distribution | # See the AUTHORS file at the top-level directory of this distribution | ||||
# License: GNU General Public License version 3, or any later version | # License: GNU General Public License version 3, or any later version | ||||
# See top-level LICENSE file for more information | # See top-level LICENSE file for more information | ||||
import pytest | import pytest | ||||
from swh.core.api import remote_api_endpoint, RPCServerApp, RPCClient | from swh.core.api import remote_api_endpoint, RPCServerApp, RPCClient | ||||
from swh.core.api import error_handler, encode_data_server, RemoteException | from swh.core.api import error_handler, encode_data_server, RemoteException | ||||
# this class is used on the server part | # this class is used on the server part | ||||
class RPCTest: | class RPCTest: | ||||
@remote_api_endpoint('endpoint_url') | @remote_api_endpoint("endpoint_url") | ||||
def endpoint(self, test_data, db=None, cur=None): | def endpoint(self, test_data, db=None, cur=None): | ||||
assert test_data == 'spam' | assert test_data == "spam" | ||||
return 'egg' | return "egg" | ||||
@remote_api_endpoint('path/to/endpoint') | @remote_api_endpoint("path/to/endpoint") | ||||
def something(self, data, db=None, cur=None): | def something(self, data, db=None, cur=None): | ||||
return data | return data | ||||
@remote_api_endpoint('raises_typeerror') | @remote_api_endpoint("raises_typeerror") | ||||
def raise_typeerror(self): | def raise_typeerror(self): | ||||
raise TypeError('Did I pass through?') | raise TypeError("Did I pass through?") | ||||
# this class is used on the client part. We cannot inherit from RPCTest | # this class is used on the client part. We cannot inherit from RPCTest | ||||
# because the automagic metaclass based code that generates the RPCClient | # because the automagic metaclass based code that generates the RPCClient | ||||
# proxy class from this does not handle inheritance properly. | # proxy class from this does not handle inheritance properly. | ||||
# We do add an endpoint on the client side that has no implementation | # We do add an endpoint on the client side that has no implementation | ||||
# server-side to test this very situation (in should generate a 404) | # server-side to test this very situation (in should generate a 404) | ||||
class RPCTest2: | class RPCTest2: | ||||
@remote_api_endpoint('endpoint_url') | @remote_api_endpoint("endpoint_url") | ||||
def endpoint(self, test_data, db=None, cur=None): | def endpoint(self, test_data, db=None, cur=None): | ||||
assert test_data == 'spam' | assert test_data == "spam" | ||||
return 'egg' | return "egg" | ||||
@remote_api_endpoint('path/to/endpoint') | @remote_api_endpoint("path/to/endpoint") | ||||
def something(self, data, db=None, cur=None): | def something(self, data, db=None, cur=None): | ||||
return data | return data | ||||
@remote_api_endpoint('not_on_server') | @remote_api_endpoint("not_on_server") | ||||
def not_on_server(self, db=None, cur=None): | def not_on_server(self, db=None, cur=None): | ||||
return 'ok' | return "ok" | ||||
@remote_api_endpoint('raises_typeerror') | @remote_api_endpoint("raises_typeerror") | ||||
def raise_typeerror(self): | def raise_typeerror(self): | ||||
return 'data' | return "data" | ||||
class RPCTestClient(RPCClient): | class RPCTestClient(RPCClient): | ||||
backend_class = RPCTest2 | backend_class = RPCTest2 | ||||
@pytest.fixture | @pytest.fixture | ||||
def app(): | def app(): | ||||
# This fixture is used by the 'swh_rpc_adapter' fixture | # This fixture is used by the 'swh_rpc_adapter' fixture | ||||
# which is defined in swh/core/pytest_plugin.py | # which is defined in swh/core/pytest_plugin.py | ||||
application = RPCServerApp('testapp', backend_class=RPCTest) | application = RPCServerApp("testapp", backend_class=RPCTest) | ||||
@application.errorhandler(Exception) | @application.errorhandler(Exception) | ||||
def my_error_handler(exception): | def my_error_handler(exception): | ||||
return error_handler(exception, encode_data_server) | return error_handler(exception, encode_data_server) | ||||
return application | return application | ||||
@pytest.fixture | @pytest.fixture | ||||
def swh_rpc_client_class(): | def swh_rpc_client_class(): | ||||
# This fixture is used by the 'swh_rpc_client' fixture | # This fixture is used by the 'swh_rpc_client' fixture | ||||
# which is defined in swh/core/pytest_plugin.py | # which is defined in swh/core/pytest_plugin.py | ||||
return RPCTestClient | return RPCTestClient | ||||
def test_api_client_endpoint_missing(swh_rpc_client): | def test_api_client_endpoint_missing(swh_rpc_client): | ||||
with pytest.raises(AttributeError): | with pytest.raises(AttributeError): | ||||
swh_rpc_client.missing(data='whatever') | swh_rpc_client.missing(data="whatever") | ||||
def test_api_server_endpoint_missing(swh_rpc_client): | def test_api_server_endpoint_missing(swh_rpc_client): | ||||
# A 'missing' endpoint (server-side) should raise an exception | # A 'missing' endpoint (server-side) should raise an exception | ||||
# due to a 404, since at the end, we do a GET/POST an inexistent URL | # due to a 404, since at the end, we do a GET/POST an inexistent URL | ||||
with pytest.raises(Exception, match='404 not found'): | with pytest.raises(Exception, match="404 not found"): | ||||
swh_rpc_client.not_on_server() | swh_rpc_client.not_on_server() | ||||
def test_api_endpoint_kwargs(swh_rpc_client): | def test_api_endpoint_kwargs(swh_rpc_client): | ||||
res = swh_rpc_client.something(data='whatever') | res = swh_rpc_client.something(data="whatever") | ||||
assert res == 'whatever' | assert res == "whatever" | ||||
res = swh_rpc_client.endpoint(test_data='spam') | res = swh_rpc_client.endpoint(test_data="spam") | ||||
assert res == 'egg' | assert res == "egg" | ||||
def test_api_endpoint_args(swh_rpc_client): | def test_api_endpoint_args(swh_rpc_client): | ||||
res = swh_rpc_client.something('whatever') | res = swh_rpc_client.something("whatever") | ||||
assert res == 'whatever' | assert res == "whatever" | ||||
res = swh_rpc_client.endpoint('spam') | res = swh_rpc_client.endpoint("spam") | ||||
assert res == 'egg' | assert res == "egg" | ||||
def test_api_typeerror(swh_rpc_client): | def test_api_typeerror(swh_rpc_client): | ||||
with pytest.raises(RemoteException) as exc_info: | with pytest.raises(RemoteException) as exc_info: | ||||
swh_rpc_client.raise_typeerror() | swh_rpc_client.raise_typeerror() | ||||
assert exc_info.value.args[0]['type'] == 'TypeError' | assert exc_info.value.args[0]["type"] == "TypeError" | ||||
assert exc_info.value.args[0]['args'] == ['Did I pass through?'] | assert exc_info.value.args[0]["args"] == ["Did I pass through?"] | ||||
assert str(exc_info.value) \ | assert ( | ||||
str(exc_info.value) | |||||
== "<RemoteException 500 TypeError: ['Did I pass through?']>" | == "<RemoteException 500 TypeError: ['Did I pass through?']>" | ||||
) |