summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTony Asleson <tasleson@redhat.com>2016-08-29 12:34:19 -0500
committerTony Asleson <tasleson@redhat.com>2016-08-29 15:26:56 -0500
commit313c40ed09d4eedba208a50c783d8d20e32de92e (patch)
tree2957814ff33877ff38f4b80030bfbfea97f2afb6
parent9241dbdf57c997bcb8467b823cae6aee7faab03b (diff)
downloadlvm2-313c40ed09d4eedba208a50c783d8d20e32de92e.tar.gz
dbus/testlib.py: Improve type checking
Leverage the introspection data to ensure that the service is returning what is says it will be returning for methods and properties.
-rw-r--r--test/dbus/testlib.py108
1 files changed, 93 insertions, 15 deletions
diff --git a/test/dbus/testlib.py b/test/dbus/testlib.py
index 550b0bf67..712b13a2f 100644
--- a/test/dbus/testlib.py
+++ b/test/dbus/testlib.py
@@ -63,7 +63,7 @@ class DbusIntrospection(object):
if arg_dir == 'in':
n = arg.attrib['name']
else:
- n = None
+ n = 'RETURN_VALUE'
arg_type = arg.attrib['type']
@@ -86,20 +86,73 @@ class DbusIntrospection(object):
# print('Interfaces...')
# for k, v in list(interfaces.items()):
- # print('Interface %s' % k)
- # if v['methods']:
- # for m, args in list(v['methods'].items()):
- # print(' method: %s' % m)
- # for a, aa in args.items():
- # print(' method arg: %s' % (a))
- # if v['properties']:
- # for p, d in list(v['properties'].items()):
- # print(' Property: %s' % (p))
+ # print('Interface %s' % k)
+ # if v['methods']:
+ # for m, args in list(v['methods'].items()):
+ # print(' method: %s' % m)
+ # for a, aa in args.items():
+ # print(' method arg: %s type %s' %
+ # (a, aa['a_type']))
+ # if v['properties']:
+ # for p, d in list(v['properties'].items()):
+ # print(' Property: %s type= %s' % (p, d['p_type']))
# print('End interfaces')
return interfaces
+def btsr(value):
+ t = type(value)
+ if t == dbus.Boolean:
+ return 'b'
+ elif t == dbus.ObjectPath:
+ return 'o'
+ elif t == dbus.String:
+ return 's'
+ elif t == dbus.Byte:
+ return 'y'
+ elif t == dbus.Int16:
+ return 'n'
+ elif t == dbus.Int32:
+ return 'i'
+ elif t == dbus.Int64:
+ return 'x'
+ elif t == dbus.UInt16:
+ return 'q'
+ elif t == dbus.UInt32:
+ return 'u'
+ elif t == dbus.UInt64:
+ return 't'
+ elif t == dbus.Double:
+ return 'd'
+ elif t == dbus.Struct:
+ rc = '('
+ for vt in value:
+ rc += btsr(vt)
+ rc += ')'
+ return rc
+ elif t == dbus.Array:
+ rc = "a"
+ for i in value:
+ rc += btsr(i)
+ break
+ return rc
+ else:
+ raise RuntimeError("Unhandled type %s" % str(t))
+
+
+def verify_type(value, dbus_str_rep):
+ actual_str_rep = btsr(value)
+
+ if dbus_str_rep != actual_str_rep:
+ # print("%s ~= %s" % (dbus_str_rep, actual_str_rep))
+ # Unless we have a full filled out type we won't match exactly
+ if not dbus_str_rep.startswith(actual_str_rep):
+ raise RuntimeError("Incorrect type, expected= %s actual "
+ "= %s object= %s" %
+ (dbus_str_rep, actual_str_rep,
+ str(type(value))))
+
class RemoteObject(object):
def _set_props(self, props=None):
# print 'Fetching properties'
@@ -119,12 +172,16 @@ class RemoteObject(object):
raise dbe
if props:
for kl, vl in list(props.items()):
+ # Verify type is correct!
+ verify_type(vl,
+ self.introspect[self.interface]['properties'][kl]['p_type'])
setattr(self, kl, vl)
- def __init__(self, specified_bus, object_path, interface, properties=None):
+ def __init__(self, specified_bus, object_path, interface, introspect, properties=None):
self.object_path = object_path
self.interface = interface
self.bus = specified_bus
+ self.introspect = introspect
self.dbus_method = dbus.Interface(specified_bus.get_object(
BUSNAME, self.object_path), self.interface)
@@ -138,7 +195,18 @@ class RemoteObject(object):
return functools.partial(self, item)
def _wrapper(self, _method_name, *args, **kwargs):
- return getattr(self.dbus_method, _method_name)(*args, **kwargs)
+ result = getattr(self.dbus_method, _method_name)(*args, **kwargs)
+ #print("DEBUG: %s.%s result %s" %
+ # (self.interface, _method_name, str(type(result))))
+
+ if 'RETURN_VALUE' in \
+ self.introspect[self.interface]['methods'][_method_name]:
+ r_type = self.introspect[self.interface]['methods'] \
+ [_method_name]['RETURN_VALUE']['a_type']
+
+ verify_type(result, r_type)
+
+ return result
def update(self):
self._set_props()
@@ -152,16 +220,26 @@ class ClientProxy(object):
def __init__(self, specified_bus, object_path, interface=None, props=None):
i = dbus.Interface(specified_bus.get_object(
BUSNAME, object_path), 'org.freedesktop.DBus.Introspectable')
- self.intro_spect = DbusIntrospection.introspect(i.Introspect())
+
+ introspection_xml = i.Introspect()
+
+ # import xml.dom.minidom
+ #
+ # xml = xml.dom.minidom.parseString(introspection_xml)
+ # print(xml.toprettyxml())
+
+ self.intro_spect = DbusIntrospection.introspect(introspection_xml)
for k in self.intro_spect.keys():
sn = ClientProxy._intf_short_name(k)
# print('Client proxy has interface: %s %s' % (k, sn))
if interface and interface == k and props is not None:
- ro = RemoteObject(specified_bus, object_path, k, props)
+ ro = RemoteObject(specified_bus, object_path, k,
+ self.intro_spect, props)
else:
- ro = RemoteObject(specified_bus, object_path, k)
+ ro = RemoteObject(specified_bus, object_path, k,
+ self.intro_spect)
setattr(self, sn, ro)