mirror of https://gitee.com/openkylin/qemu.git
QEMUMachine: add events_wait method
Instead of event_wait which looks for a single event, add an events_wait which can look for any number of events simultaneously. However, it will still only return one at a time, whichever happens first. Signed-off-by: John Snow <jsnow@redhat.com> Message-id: 20190523170643.20794-4-jsnow@redhat.com Reviewed-by: Max Reitz <mreitz@redhat.com> Signed-off-by: Max Reitz <mreitz@redhat.com>
This commit is contained in:
parent
8b6f5f8b9f
commit
f6f4b3f045
|
@ -402,42 +402,71 @@ def get_qmp_events(self, wait=False):
|
||||||
self._qmp.clear_events()
|
self._qmp.clear_events()
|
||||||
return events
|
return events
|
||||||
|
|
||||||
def event_wait(self, name, timeout=60.0, match=None):
|
@staticmethod
|
||||||
"""
|
|
||||||
Wait for specified timeout on named event in QMP; optionally filter
|
|
||||||
results by match.
|
|
||||||
|
|
||||||
The 'match' is checked to be a recursive subset of the 'event'; skips
|
|
||||||
branch processing on match's value None
|
|
||||||
{"foo": {"bar": 1}} matches {"foo": None}
|
|
||||||
{"foo": {"bar": 1}} does not matches {"foo": {"baz": None}}
|
|
||||||
"""
|
|
||||||
def event_match(event, match=None):
|
def event_match(event, match=None):
|
||||||
|
"""
|
||||||
|
Check if an event matches optional match criteria.
|
||||||
|
|
||||||
|
The match criteria takes the form of a matching subdict. The event is
|
||||||
|
checked to be a superset of the subdict, recursively, with matching
|
||||||
|
values whenever those values are not None.
|
||||||
|
|
||||||
|
Examples, with the subdict queries on the left:
|
||||||
|
- None matches any object.
|
||||||
|
- {"foo": None} matches {"foo": {"bar": 1}}
|
||||||
|
- {"foo": {"baz": None}} does not match {"foo": {"bar": 1}}
|
||||||
|
- {"foo": {"baz": 2}} matches {"foo": {"bar": 1, "baz": 2}}
|
||||||
|
"""
|
||||||
if match is None:
|
if match is None:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
for key in match:
|
for key in match:
|
||||||
if key in event:
|
if key in event:
|
||||||
if isinstance(event[key], dict):
|
if isinstance(event[key], dict):
|
||||||
if not event_match(event[key], match[key]):
|
if not QEMUMachine.event_match(event[key], match[key]):
|
||||||
return False
|
return False
|
||||||
elif event[key] != match[key]:
|
elif event[key] != match[key]:
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def event_wait(self, name, timeout=60.0, match=None):
|
||||||
|
"""
|
||||||
|
event_wait waits for and returns a named event from QMP with a timeout.
|
||||||
|
|
||||||
|
name: The event to wait for.
|
||||||
|
timeout: QEMUMonitorProtocol.pull_event timeout parameter.
|
||||||
|
match: Optional match criteria. See event_match for details.
|
||||||
|
"""
|
||||||
|
return self.events_wait([(name, match)], timeout)
|
||||||
|
|
||||||
|
def events_wait(self, events, timeout=60.0):
|
||||||
|
"""
|
||||||
|
events_wait waits for and returns a named event from QMP with a timeout.
|
||||||
|
|
||||||
|
events: a sequence of (name, match_criteria) tuples.
|
||||||
|
The match criteria are optional and may be None.
|
||||||
|
See event_match for details.
|
||||||
|
timeout: QEMUMonitorProtocol.pull_event timeout parameter.
|
||||||
|
"""
|
||||||
|
def _match(event):
|
||||||
|
for name, match in events:
|
||||||
|
if (event['event'] == name and
|
||||||
|
self.event_match(event, match)):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
# Search cached events
|
# Search cached events
|
||||||
for event in self._events:
|
for event in self._events:
|
||||||
if (event['event'] == name) and event_match(event, match):
|
if _match(event):
|
||||||
self._events.remove(event)
|
self._events.remove(event)
|
||||||
return event
|
return event
|
||||||
|
|
||||||
# Poll for new events
|
# Poll for new events
|
||||||
while True:
|
while True:
|
||||||
event = self._qmp.pull_event(wait=timeout)
|
event = self._qmp.pull_event(wait=timeout)
|
||||||
if (event['event'] == name) and event_match(event, match):
|
if _match(event):
|
||||||
return event
|
return event
|
||||||
self._events.append(event)
|
self._events.append(event)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue