summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ipalib/rpc.py36
-rw-r--r--ipaserver/rpc.py6
-rw-r--r--tests/test_ipalib/test_rpc.py108
3 files changed, 116 insertions, 34 deletions
diff --git a/ipalib/rpc.py b/ipalib/rpc.py
index c4662f84c..df31669d3 100644
--- a/ipalib/rpc.py
+++ b/ipalib/rpc.py
@@ -22,10 +22,10 @@ Core RPC functionality.
"""
from types import NoneType
-from xmlrpclib import Binary
+from xmlrpclib import Binary, Fault, dumps, loads
-def xmlrpc_wrap(value):
+def xml_wrap(value):
"""
Wrap all ``str`` in ``xmlrpclib.Binary``.
@@ -42,13 +42,13 @@ def xmlrpc_wrap(value):
converted to UTF-8 encoded ``str`` instances (although as mentioned,
not by this function).
- Also see `xmlrpc_unwrap`.
+ Also see `xml_unwrap`.
"""
if type(value) in (list, tuple):
- return tuple(xmlrpc_wrap(v) for v in value)
+ return tuple(xml_wrap(v) for v in value)
if type(value) is dict:
return dict(
- (k, xmlrpc_wrap(v)) for (k, v) in value.iteritems()
+ (k, xml_wrap(v)) for (k, v) in value.iteritems()
)
if type(value) is str:
return Binary(value)
@@ -56,7 +56,7 @@ def xmlrpc_wrap(value):
return value
-def xmlrpc_unwrap(value, encoding='UTF-8'):
+def xml_unwrap(value, encoding='UTF-8'):
"""
Unwrap all ``xmlrpc.Binary``, decode all ``str`` into ``unicode``.
@@ -69,13 +69,13 @@ def xmlrpc_unwrap(value, encoding='UTF-8'):
* All ``str`` instances are treated as UTF-8 encoded character data.
They are decoded and the resulting ``unicode`` instance is returned.
- Also see `xmlrpc_wrap`.
+ Also see `xml_wrap`.
"""
if type(value) in (list, tuple):
- return tuple(xmlrpc_unwrap(v, encoding) for v in value)
+ return tuple(xml_unwrap(v, encoding) for v in value)
if type(value) is dict:
return dict(
- (k, xmlrpc_unwrap(v, encoding)) for (k, v) in value.iteritems()
+ (k, xml_unwrap(v, encoding)) for (k, v) in value.iteritems()
)
if type(value) is str:
return value.decode(encoding)
@@ -84,3 +84,21 @@ def xmlrpc_unwrap(value, encoding='UTF-8'):
return value.data
assert type(value) in (unicode, int, float, bool, NoneType)
return value
+
+
+def xml_dumps(params, methodname=None, methodresponse=False, encoding='UTF-8'):
+ if type(params) is tuple:
+ params = xml_wrap(params)
+ else:
+ assert isinstance(params, Fault)
+ return dumps(params,
+ methodname=methodname,
+ methodresponse=methodresponse,
+ encoding=encoding,
+ allow_none=True,
+ )
+
+
+def xml_loads(data):
+ (params, method) = loads(data)
+ return (xml_unwrap(params), method)
diff --git a/ipaserver/rpc.py b/ipaserver/rpc.py
index 34de915cb..c2cb0bd59 100644
--- a/ipaserver/rpc.py
+++ b/ipaserver/rpc.py
@@ -24,7 +24,7 @@ Execute an RPC request.
from xmlrpclib import dumps, loads, Fault
from ipalib import Backend
from ipalib.errors import HandledError, CommandError
-from ipalib.rpc import xmlrpc_wrap, xmlrpc_unwrap
+from ipalib.rpc import xml_wrap, xml_unwrap
def params_2_args_options(params):
@@ -44,9 +44,9 @@ class xmlrpc(Backend):
self.info('Received RPC call to %r', method)
if method not in self.Command:
raise CommandError(name=method)
- (args, options) = params_2_args_options(xmlrpc_unwrap(params))
+ (args, options) = params_2_args_options(xml_unwrap(params))
result = self.Command[method](*args, **options)
- return (xmlrpc_wrap(result),)
+ return (xml_wrap(result),)
def execute(self, data, ccache=None, client_ip=None, locale=None):
try:
diff --git a/tests/test_ipalib/test_rpc.py b/tests/test_ipalib/test_rpc.py
index 614db6074..eba35261b 100644
--- a/tests/test_ipalib/test_rpc.py
+++ b/tests/test_ipalib/test_rpc.py
@@ -21,64 +21,68 @@
Test the `ipalib.rpc` module.
"""
-from xmlrpclib import Binary, dumps, loads
-from tests.util import raises
+from xmlrpclib import Binary, Fault, dumps, loads
+from tests.util import raises, assert_equal
from tests.data import binary_bytes, utf8_bytes, unicode_str
from ipalib import rpc
def dump_n_load(value):
(param, method) = loads(
- dumps((value,))
+ dumps((value,), allow_none=True)
)
return param[0]
def round_trip(value):
- return rpc.xmlrpc_unwrap(
- dump_n_load(rpc.xmlrpc_wrap(value))
+ return rpc.xml_unwrap(
+ dump_n_load(rpc.xml_wrap(value))
)
def test_round_trip():
"""
- Test `ipalib.rpc.xmlrpc_wrap` and `ipalib.rpc.xmlrpc_unwrap`.
+ Test `ipalib.rpc.xml_wrap` and `ipalib.rpc.xml_unwrap`.
This tests the two functions together with ``xmlrpclib.dumps()`` and
``xmlrpclib.loads()`` in a full wrap/dumps/loads/unwrap round trip.
"""
# We first test that our assumptions about xmlrpclib module in the Python
# standard library are correct:
- assert dump_n_load(utf8_bytes) == unicode_str
- assert dump_n_load(unicode_str) == unicode_str
- assert dump_n_load(Binary(binary_bytes)).data == binary_bytes
+ assert_equal(dump_n_load(utf8_bytes), unicode_str)
+ assert_equal(dump_n_load(unicode_str), unicode_str)
+ assert_equal(dump_n_load(Binary(binary_bytes)).data, binary_bytes)
assert isinstance(dump_n_load(Binary(binary_bytes)), Binary)
assert type(dump_n_load('hello')) is str
assert type(dump_n_load(u'hello')) is str
+ assert_equal(dump_n_load(''), '')
+ assert_equal(dump_n_load(u''), '')
+ assert dump_n_load(None) is None
# Now we test our wrap and unwrap methods in combination with dumps, loads:
# All str should come back str (because they get wrapped in
# xmlrpclib.Binary(). All unicode should come back unicode because str
- # explicity get decoded by rpc.xmlrpc_unwrap() if they weren't already
+ # explicity get decoded by rpc.xml_unwrap() if they weren't already
# decoded by xmlrpclib.loads().
- assert round_trip(utf8_bytes) == utf8_bytes
- assert round_trip(unicode_str) == unicode_str
- assert round_trip(binary_bytes) == binary_bytes
+ assert_equal(round_trip(utf8_bytes), utf8_bytes)
+ assert_equal(round_trip(unicode_str), unicode_str)
+ assert_equal(round_trip(binary_bytes), binary_bytes)
assert type(round_trip('hello')) is str
assert type(round_trip(u'hello')) is unicode
- assert round_trip('') == ''
- assert round_trip(u'') == u''
- compound = [utf8_bytes, unicode_str, binary_bytes,
+ assert_equal(round_trip(''), '')
+ assert_equal(round_trip(u''), u'')
+ assert round_trip(None) is None
+ compound = [utf8_bytes, None, binary_bytes, (None, unicode_str),
dict(utf8=utf8_bytes, chars=unicode_str, data=binary_bytes)
]
assert round_trip(compound) == tuple(compound)
-def test_xmlrpc_wrap():
+def test_xml_wrap():
"""
- Test the `ipalib.rpc.xmlrpc_wrap` function.
+ Test the `ipalib.rpc.xml_wrap` function.
"""
- f = rpc.xmlrpc_wrap
+ f = rpc.xml_wrap
assert f([]) == tuple()
assert f({}) == dict()
b = f('hello')
@@ -90,11 +94,11 @@ def test_xmlrpc_wrap():
value = f([dict(one=False, two=u'hello'), None, 'hello'])
-def test_xmlrpc_unwrap():
+def test_xml_unwrap():
"""
- Test the `ipalib.rpc.xmlrpc_unwrap` function.
+ Test the `ipalib.rpc.xml_unwrap` function.
"""
- f = rpc.xmlrpc_unwrap
+ f = rpc.xml_unwrap
assert f([]) == tuple()
assert f({}) == dict()
value = f(Binary(utf8_bytes))
@@ -106,3 +110,63 @@ def test_xmlrpc_unwrap():
assert value == (True, 'hello', dict(one=1, two=unicode_str, three=None))
assert type(value[1]) is str
assert type(value[2]['two']) is unicode
+
+
+def test_xml_dumps():
+ """
+ Test the `ipalib.rpc.xml_dumps` function.
+ """
+ f = rpc.xml_dumps
+ params = (binary_bytes, utf8_bytes, unicode_str, None)
+
+ # Test serializing an RPC request:
+ data = f(params, 'the_method')
+ (p, m) = loads(data)
+ assert_equal(m, u'the_method')
+ assert type(p) is tuple
+ assert rpc.xml_unwrap(p) == params
+
+ # Test serializing an RPC response:
+ data = f((params,), methodresponse=True)
+ (tup, m) = loads(data)
+ assert m is None
+ assert len(tup) == 1
+ assert type(tup) is tuple
+ assert rpc.xml_unwrap(tup[0]) == params
+
+ # Test serializing an RPC response containing a Fault:
+ fault = Fault(69, unicode_str)
+ data = f(fault, methodresponse=True)
+ e = raises(Fault, loads, data)
+ assert e.faultCode == 69
+ assert_equal(e.faultString, unicode_str)
+
+
+def test_xml_loads():
+ """
+ Test the `ipalib.rpc.xml_loads` function.
+ """
+ f = rpc.xml_loads
+ params = (binary_bytes, utf8_bytes, unicode_str, None)
+ wrapped = rpc.xml_wrap(params)
+
+ # Test un-serializing an RPC request:
+ data = dumps(wrapped, 'the_method', allow_none=True)
+ (p, m) = f(data)
+ assert_equal(m, u'the_method')
+ assert_equal(p, params)
+
+ # Test un-serializing an RPC response:
+ data = dumps((wrapped,), methodresponse=True, allow_none=True)
+ (tup, m) = f(data)
+ assert m is None
+ assert len(tup) == 1
+ assert type(tup) is tuple
+ assert_equal(tup[0], params)
+
+ # Test un-serializing an RPC response containing a Fault:
+ fault = Fault(69, unicode_str)
+ data = dumps(fault, methodresponse=True, allow_none=True)
+ e = raises(Fault, f, data)
+ assert e.faultCode == 69
+ assert_equal(e.faultString, unicode_str)