summaryrefslogtreecommitdiffstats
path: root/ipatests/test_ipalib/test_rpc.py
diff options
context:
space:
mode:
authorPetr Viktorin <pviktori@redhat.com>2013-05-21 13:40:27 +0200
committerMartin Kosek <mkosek@redhat.com>2013-06-17 19:22:50 +0200
commitc60142efda817f030a7495cd6fe4a19953e55afa (patch)
tree31a840ceddd4381311bbc879f9851bb71a8e2ffa /ipatests/test_ipalib/test_rpc.py
parent6d66e826c1c248dffc80056b20c1e4b74b04d46f (diff)
downloadfreeipa-c60142efda817f030a7495cd6fe4a19953e55afa.tar.gz
freeipa-c60142efda817f030a7495cd6fe4a19953e55afa.tar.xz
freeipa-c60142efda817f030a7495cd6fe4a19953e55afa.zip
Make an ipa-tests package
Rename the 'tests' directory to 'ipa-tests', and create an ipa-tests RPM containing the test suite Part of the work for: https://fedorahosted.org/freeipa/ticket/3654
Diffstat (limited to 'ipatests/test_ipalib/test_rpc.py')
-rw-r--r--ipatests/test_ipalib/test_rpc.py244
1 files changed, 244 insertions, 0 deletions
diff --git a/ipatests/test_ipalib/test_rpc.py b/ipatests/test_ipalib/test_rpc.py
new file mode 100644
index 000000000..56b8184cf
--- /dev/null
+++ b/ipatests/test_ipalib/test_rpc.py
@@ -0,0 +1,244 @@
+# 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, either version 3 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+
+"""
+Test the `ipalib.rpc` module.
+"""
+
+import threading
+from xmlrpclib import Binary, Fault, dumps, loads, ServerProxy
+from ipatests.util import raises, assert_equal, PluginTester, DummyClass
+from ipatests.data import binary_bytes, utf8_bytes, unicode_str
+from ipalib.frontend import Command
+from ipalib.request import context, Connection
+from ipalib import rpc, errors
+
+
+std_compound = (binary_bytes, utf8_bytes, unicode_str)
+
+
+def dump_n_load(value):
+ (param, method) = loads(
+ dumps((value,), allow_none=True)
+ )
+ return param[0]
+
+
+def round_trip(value):
+ return rpc.xml_unwrap(
+ dump_n_load(rpc.xml_wrap(value))
+ )
+
+
+def test_round_trip():
+ """
+ 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_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.xml_unwrap() if they weren't already
+ # decoded by xmlrpclib.loads().
+ 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_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_xml_wrap():
+ """
+ Test the `ipalib.rpc.xml_wrap` function.
+ """
+ f = rpc.xml_wrap
+ assert f([]) == tuple()
+ assert f({}) == dict()
+ b = f('hello')
+ assert isinstance(b, Binary)
+ assert b.data == 'hello'
+ u = f(u'hello')
+ assert type(u) is unicode
+ assert u == u'hello'
+ value = f([dict(one=False, two=u'hello'), None, 'hello'])
+
+
+def test_xml_unwrap():
+ """
+ Test the `ipalib.rpc.xml_unwrap` function.
+ """
+ f = rpc.xml_unwrap
+ assert f([]) == tuple()
+ assert f({}) == dict()
+ value = f(Binary(utf8_bytes))
+ assert type(value) is str
+ assert value == utf8_bytes
+ assert f(utf8_bytes) == unicode_str
+ assert f(unicode_str) == unicode_str
+ value = f([True, Binary('hello'), dict(one=1, two=utf8_bytes, three=None)])
+ 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:
+ for error in (unicode_str, u'hello'):
+ fault = Fault(69, error)
+ data = dumps(fault, methodresponse=True, allow_none=True, encoding='UTF-8')
+ e = raises(Fault, f, data)
+ assert e.faultCode == 69
+ assert_equal(e.faultString, error)
+ assert type(e.faultString) is unicode
+
+
+class test_xmlclient(PluginTester):
+ """
+ Test the `ipalib.rpc.xmlclient` plugin.
+ """
+ _plugin = rpc.xmlclient
+
+ def test_forward(self):
+ """
+ Test the `ipalib.rpc.xmlclient.forward` method.
+ """
+ class user_add(Command):
+ pass
+
+ # Test that ValueError is raised when forwarding a command that is not
+ # in api.Command:
+ (o, api, home) = self.instance('Backend', in_server=False)
+ e = raises(ValueError, o.forward, 'user_add')
+ assert str(e) == '%s.forward(): %r not in api.Command' % (
+ 'xmlclient', 'user_add'
+ )
+
+ (o, api, home) = self.instance('Backend', user_add, in_server=False)
+ args = (binary_bytes, utf8_bytes, unicode_str)
+ kw = dict(one=binary_bytes, two=utf8_bytes, three=unicode_str)
+ params = [args, kw]
+ result = (unicode_str, binary_bytes, utf8_bytes)
+ conn = DummyClass(
+ (
+ 'user_add',
+ rpc.xml_wrap(params),
+ {},
+ rpc.xml_wrap(result),
+ ),
+ (
+ 'user_add',
+ rpc.xml_wrap(params),
+ {},
+ Fault(3007, u"'four' is required"), # RequirementError
+ ),
+ (
+ 'user_add',
+ rpc.xml_wrap(params),
+ {},
+ Fault(700, u'no such error'), # There is no error 700
+ ),
+
+ )
+ context.xmlclient = Connection(conn, lambda: None)
+
+ # Test with a successful return value:
+ assert o.forward('user_add', *args, **kw) == result
+
+ # Test with an errno the client knows:
+ e = raises(errors.RequirementError, o.forward, 'user_add', *args, **kw)
+ assert_equal(e.args[0], u"'four' is required")
+
+ # Test with an errno the client doesn't know
+ e = raises(errors.UnknownError, o.forward, 'user_add', *args, **kw)
+ assert_equal(e.code, 700)
+ assert_equal(e.error, u'no such error')
+
+ assert context.xmlclient.conn._calledall() is True