I am working now around library for creating testing infrastructure for dbus objects via python-dbus-next
library and i have a stuck around assertes for dbus property, which can changed via signal.
Typical example of property update its simple sync callback on needed signal:
...interface initialisation....
def _prop_change(prop: dict):
print(f'Property changed dict')
interface.on_property_changed(_prop_change)
In my case i want have watched
property with expected value with until
expression like next signature:
iface = await IFaceClient(bus_name, path, interface)
await iface.call_method('bla')
await iface.wait_property('bla_property').equal(30)
For this implementation i try use subscribe/unsubscribe callback handler with awaitable object from sync callbakc to asserter by Event object, but i see that my assert equal
dont see that value been changed and try compare with initial value (None):
# handler on interface
def wait_property(self, prop_name):
event = asyncio.Event()
value = None
def property_changed(prop):
nonlocal value
nonlocal event
value = prop.get(prop_name)
self._iface.on_property_changed(property_changed)
return Comparer(event, value)
Comparer object
class Comparer:
timeout = 10
def __init__(self, event, value):
self.event = event
self.value = value
def until(self, t):
self.timeout = t
return self
async def _eq(self, expected):
f = asyncio.get_event_loop().create_future()
try:
await self.event.wait()
assert self.value == expected
f.set_result(self.value)
except AssertionError:
self.event.clear()
return await f
async def equal(self, value):
try:
return await asyncio.wait_for(self._eq(value), timeout=self.timeout)
except asyncio.TimeoutError:
raise AssertionError(f'Values isn`t equal: {self.value} != {value}')
In live loog i see that method_eq
only once be called and check, but its get first value (none)
I am also try use property value
in call back but loking that corotine method doesnt see that value was changed and i get similar value (None).
I think about using Future object like container for value from call back, but it cant be implemented, cause working only once and not possible coverage case, when you wait assert property from transitiend state: property.equal(30) -> but property can start from 10, then 20, then 30 So, the question is - what i am doing wrong?