mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2026-11-03 04:40:31 -06:00
Stared some RPC-related error cleanup; started work on ipa_server.rcp.xmlrpc plugin
This commit is contained in:
1 parent
237c16f0fd
commit
2d458a1233
5 files changed
+134
-5
No files matched your search
@@ -22,11 +22,16 @@ Dispatcher for RPC server.
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
from ipalib import Backend
|
from ipalib import Backend
|
||||||
|
from ipalib.errors import CommandError
|
||||||
from ipalib.rpc import xmlrpc_wrap, xmlrpc_unwrap
|
from ipalib.rpc import xmlrpc_wrap, xmlrpc_unwrap
|
||||||
|
|
||||||
|
|
||||||
class XMLServer(Backend):
|
class xmlrpc(Backend):
|
||||||
|
|
||||||
def dispatch(self, method, params):
|
def dispatch(self, method, params):
|
||||||
self.info('Received call to %r', method)
|
assert type(method) is str
|
||||||
|
assert type(params) is tuple
|
||||||
|
self.info('Received RPC call to %r', method)
|
||||||
|
if method not in self.Command:
|
||||||
|
raise CommandError(name=method)
|
||||||
params = xml_unwrap(params)
|
params = xml_unwrap(params)
|
||||||
@@ -113,9 +113,33 @@ class IPAError(StandardError):
|
|||||||
class InvocationError(IPAError):
|
class InvocationError(IPAError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class UnknownCommandError(InvocationError):
|
class UnknownCommandError(InvocationError):
|
||||||
format = 'unknown command "%s"'
|
format = 'unknown command "%s"'
|
||||||
|
|
||||||
|
def _(text):
|
||||||
|
return text
|
||||||
|
|
||||||
|
|
||||||
|
class HandledError(StandardError):
|
||||||
|
"""
|
||||||
|
Base class for errors that can be raised across a remote procecdure call.
|
||||||
|
"""
|
||||||
|
def __init__(self, message=None, **kw):
|
||||||
|
self.kw = kw
|
||||||
|
if message is None:
|
||||||
|
message = self.format % kw
|
||||||
|
StandardError.__init__(self, message)
|
||||||
|
|
||||||
|
|
||||||
|
class CommandError(HandledError):
|
||||||
|
format = _('Unknown command %(name)r')
|
||||||
|
|
||||||
|
|
||||||
|
class RemoteCommandError(HandledError):
|
||||||
|
format = 'Server at %(uri)r has no command %(command)r'
|
||||||
|
|
||||||
|
|
||||||
class UnknownHelpError(InvocationError):
|
class UnknownHelpError(InvocationError):
|
||||||
format = 'no command nor topic "%s"'
|
format = 'no command nor topic "%s"'
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
# Authors:
|
||||||
|
# Jason Gerard DeRose <jderose@redhat.com>
|
||||||
|
#
|
||||||
|
# Copyright (C) 2008 Red Hat
|
||||||
|
# see file 'COPYING' for use and warranty information
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License as
|
||||||
|
# published by the Free Software Foundation; version 2 only
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
|
"""
|
||||||
|
Test the `ipa_server.rpc` module.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from tests.util import create_test_api, raises, PluginTester
|
||||||
|
from ipalib import errors, Command
|
||||||
|
from ipa_server import rpc
|
||||||
|
|
||||||
|
|
||||||
|
class test_xmlrpc(PluginTester):
|
||||||
|
"""
|
||||||
|
Test the `ipa_server.rpc.xmlrpc` plugin.
|
||||||
|
"""
|
||||||
|
|
||||||
|
_plugin = rpc.xmlrpc
|
||||||
|
|
||||||
|
def test_dispatch(self):
|
||||||
|
"""
|
||||||
|
Test the `ipa_server.rpc.xmlrpc.dispatch` method.
|
||||||
|
"""
|
||||||
|
(o, api, home) = self.instance('Backend')
|
||||||
|
e = raises(errors.CommandError, o.dispatch, 'example', tuple())
|
||||||
|
assert str(e) == "Unknown command 'example'"
|
||||||
|
assert e.kw['name'] == 'example'
|
||||||
@@ -32,10 +32,10 @@ BINARY_BYTES = ''.join(struct.pack('B', d) for d in xrange(256))
|
|||||||
assert '\x00' in BINARY_BYTES and '\xff' in BINARY_BYTES
|
assert '\x00' in BINARY_BYTES and '\xff' in BINARY_BYTES
|
||||||
assert type(BINARY_BYTES) is str and len(BINARY_BYTES) == 256
|
assert type(BINARY_BYTES) is str and len(BINARY_BYTES) == 256
|
||||||
|
|
||||||
# A UTF-8 encoded str
|
# A UTF-8 encoded str:
|
||||||
UTF8_BYTES = '\xd0\x9f\xd0\xb0\xd0\xb2\xd0\xb5\xd0\xbb'
|
UTF8_BYTES = '\xd0\x9f\xd0\xb0\xd0\xb2\xd0\xb5\xd0\xbb'
|
||||||
|
|
||||||
# The same UTF-8 data decoded (a unicode instance)
|
# The same UTF-8 data decoded (a unicode instance):
|
||||||
UNICODE_CHARS = u'\u041f\u0430\u0432\u0435\u043b'
|
UNICODE_CHARS = u'\u041f\u0430\u0432\u0435\u043b'
|
||||||
assert UTF8_BYTES.decode('UTF-8') == UNICODE_CHARS
|
assert UTF8_BYTES.decode('UTF-8') == UNICODE_CHARS
|
||||||
assert UNICODE_CHARS.encode('UTF-8') == UTF8_BYTES
|
assert UNICODE_CHARS.encode('UTF-8') == UTF8_BYTES
|
||||||
@@ -60,7 +60,7 @@ def test_round_trip():
|
|||||||
Test `ipalib.rpc.xmlrpc_wrap` and `ipalib.rpc.xmlrpc_unwrap`.
|
Test `ipalib.rpc.xmlrpc_wrap` and `ipalib.rpc.xmlrpc_unwrap`.
|
||||||
|
|
||||||
This tests the two functions together with ``xmlrpclib.dumps()`` and
|
This tests the two functions together with ``xmlrpclib.dumps()`` and
|
||||||
``xmlrpclib.loads()`` in a full encode/dumps/loads/decode round trip.
|
``xmlrpclib.loads()`` in a full wrap/dumps/loads/unwrap round trip.
|
||||||
"""
|
"""
|
||||||
# We first test that our assumptions about xmlrpclib module in the Python
|
# We first test that our assumptions about xmlrpclib module in the Python
|
||||||
# standard library are correct:
|
# standard library are correct:
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ from os import path
|
|||||||
import tempfile
|
import tempfile
|
||||||
import shutil
|
import shutil
|
||||||
import ipalib
|
import ipalib
|
||||||
|
from ipalib.plugable import Plugin
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -198,6 +199,11 @@ class ClassChecker(object):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def check_TypeError(value, type_, name, callback, *args, **kw):
|
def check_TypeError(value, type_, name, callback, *args, **kw):
|
||||||
"""
|
"""
|
||||||
Tests a standard TypeError raised with `errors.raise_TypeError`.
|
Tests a standard TypeError raised with `errors.raise_TypeError`.
|
||||||
@@ -224,3 +230,54 @@ def get_api(**kw):
|
|||||||
for (key, value) in kw.iteritems():
|
for (key, value) in kw.iteritems():
|
||||||
api.env[key] = value
|
api.env[key] = value
|
||||||
return (api, home)
|
return (api, home)
|
||||||
|
|
||||||
|
|
||||||
|
def create_test_api(**kw):
|
||||||
|
"""
|
||||||
|
Returns (api, home) tuple.
|
||||||
|
|
||||||
|
This function returns a tuple containing an `ipalib.plugable.API`
|
||||||
|
instance and a `TempHome` instance.
|
||||||
|
"""
|
||||||
|
home = TempHome()
|
||||||
|
api = ipalib.create_api(mode='unit_test')
|
||||||
|
api.env.in_tree = True
|
||||||
|
for (key, value) in kw.iteritems():
|
||||||
|
api.env[key] = value
|
||||||
|
return (api, home)
|
||||||
|
|
||||||
|
|
||||||
|
class PluginTester(object):
|
||||||
|
__plugin = None
|
||||||
|
|
||||||
|
def __get_plugin(self):
|
||||||
|
if self.__plugin is None:
|
||||||
|
self.__plugin = self._plugin
|
||||||
|
assert issubclass(self.__plugin, Plugin)
|
||||||
|
return self.__plugin
|
||||||
|
plugin = property(__get_plugin)
|
||||||
|
|
||||||
|
def register(self, *plugins, **kw):
|
||||||
|
"""
|
||||||
|
Create a testing api and register ``self.plugin``.
|
||||||
|
|
||||||
|
This method returns an (api, home) tuple.
|
||||||
|
|
||||||
|
:param plugins: Additional \*plugins to register.
|
||||||
|
:param kw: Additional \**kw args to pass to `create_test_api`.
|
||||||
|
"""
|
||||||
|
(api, home) = create_test_api(**kw)
|
||||||
|
api.register(self.plugin)
|
||||||
|
for p in plugins:
|
||||||
|
api.register(p)
|
||||||
|
return (api, home)
|
||||||
|
|
||||||
|
def finalize(self, *plugins, **kw):
|
||||||
|
(api, home) = self.register(*plugins, **kw)
|
||||||
|
api.finalize()
|
||||||
|
return (api, home)
|
||||||
|
|
||||||
|
def instance(self, namespace, *plugins, **kw):
|
||||||
|
(api, home) = self.finalize(*plugins, **kw)
|
||||||
|
o = api[namespace][self.plugin.__name__]
|
||||||
|
return (o, api, home)
|
||||||
Reference in new issue
Block a user