mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
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.
This commit is contained in:
parent
9241dbdf57
commit
313c40ed09
@ -63,7 +63,7 @@ class DbusIntrospection(object):
|
|||||||
if arg_dir == 'in':
|
if arg_dir == 'in':
|
||||||
n = arg.attrib['name']
|
n = arg.attrib['name']
|
||||||
else:
|
else:
|
||||||
n = None
|
n = 'RETURN_VALUE'
|
||||||
|
|
||||||
arg_type = arg.attrib['type']
|
arg_type = arg.attrib['type']
|
||||||
|
|
||||||
@ -86,20 +86,73 @@ class DbusIntrospection(object):
|
|||||||
|
|
||||||
# print('Interfaces...')
|
# print('Interfaces...')
|
||||||
# for k, v in list(interfaces.items()):
|
# for k, v in list(interfaces.items()):
|
||||||
# print('Interface %s' % k)
|
# print('Interface %s' % k)
|
||||||
# if v['methods']:
|
# if v['methods']:
|
||||||
# for m, args in list(v['methods'].items()):
|
# for m, args in list(v['methods'].items()):
|
||||||
# print(' method: %s' % m)
|
# print(' method: %s' % m)
|
||||||
# for a, aa in args.items():
|
# for a, aa in args.items():
|
||||||
# print(' method arg: %s' % (a))
|
# print(' method arg: %s type %s' %
|
||||||
# if v['properties']:
|
# (a, aa['a_type']))
|
||||||
# for p, d in list(v['properties'].items()):
|
# if v['properties']:
|
||||||
# print(' Property: %s' % (p))
|
# for p, d in list(v['properties'].items()):
|
||||||
|
# print(' Property: %s type= %s' % (p, d['p_type']))
|
||||||
# print('End interfaces')
|
# print('End interfaces')
|
||||||
|
|
||||||
return 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):
|
class RemoteObject(object):
|
||||||
def _set_props(self, props=None):
|
def _set_props(self, props=None):
|
||||||
# print 'Fetching properties'
|
# print 'Fetching properties'
|
||||||
@ -119,12 +172,16 @@ class RemoteObject(object):
|
|||||||
raise dbe
|
raise dbe
|
||||||
if props:
|
if props:
|
||||||
for kl, vl in list(props.items()):
|
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)
|
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.object_path = object_path
|
||||||
self.interface = interface
|
self.interface = interface
|
||||||
self.bus = specified_bus
|
self.bus = specified_bus
|
||||||
|
self.introspect = introspect
|
||||||
|
|
||||||
self.dbus_method = dbus.Interface(specified_bus.get_object(
|
self.dbus_method = dbus.Interface(specified_bus.get_object(
|
||||||
BUSNAME, self.object_path), self.interface)
|
BUSNAME, self.object_path), self.interface)
|
||||||
@ -138,7 +195,18 @@ class RemoteObject(object):
|
|||||||
return functools.partial(self, item)
|
return functools.partial(self, item)
|
||||||
|
|
||||||
def _wrapper(self, _method_name, *args, **kwargs):
|
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):
|
def update(self):
|
||||||
self._set_props()
|
self._set_props()
|
||||||
@ -152,16 +220,26 @@ class ClientProxy(object):
|
|||||||
def __init__(self, specified_bus, object_path, interface=None, props=None):
|
def __init__(self, specified_bus, object_path, interface=None, props=None):
|
||||||
i = dbus.Interface(specified_bus.get_object(
|
i = dbus.Interface(specified_bus.get_object(
|
||||||
BUSNAME, object_path), 'org.freedesktop.DBus.Introspectable')
|
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():
|
for k in self.intro_spect.keys():
|
||||||
sn = ClientProxy._intf_short_name(k)
|
sn = ClientProxy._intf_short_name(k)
|
||||||
# print('Client proxy has interface: %s %s' % (k, sn))
|
# print('Client proxy has interface: %s %s' % (k, sn))
|
||||||
|
|
||||||
if interface and interface == k and props is not None:
|
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:
|
else:
|
||||||
ro = RemoteObject(specified_bus, object_path, k)
|
ro = RemoteObject(specified_bus, object_path, k,
|
||||||
|
self.intro_spect)
|
||||||
|
|
||||||
setattr(self, sn, ro)
|
setattr(self, sn, ro)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user