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':
|
||||
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)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user