event_match: always match on None value

Before, event_match didn't always recurse if the event value was not a
dictionary, and would instead check for equality immediately.

By delaying equality checking to post-recursion, we can allow leaf
values like "5" to match "None" and take advantage of the generic
None-returns-True clause.

This makes the matching a little more obviously consistent at the
expense of being able to check for explicit None values, which is
probably not that important given what this function is used for.

Signed-off-by: John Snow <jsnow@redhat.com>
Message-id: 20190528183857.26167-1-jsnow@redhat.com
Signed-off-by: Max Reitz <mreitz@redhat.com>
This commit is contained in:
John Snow 2019-05-28 14:38:57 -04:00 committed by Max Reitz
parent ba7704f222
commit 9e8dfad045

View file

@ -409,27 +409,31 @@ class QEMUMachine(object):
The match criteria takes the form of a matching subdict. The event is The match criteria takes the form of a matching subdict. The event is
checked to be a superset of the subdict, recursively, with matching checked to be a superset of the subdict, recursively, with matching
values whenever those values are not None. values whenever the subdict values are not None.
This has a limitation that you cannot explicitly check for None values.
Examples, with the subdict queries on the left: Examples, with the subdict queries on the left:
- None matches any object. - None matches any object.
- {"foo": None} matches {"foo": {"bar": 1}} - {"foo": None} matches {"foo": {"bar": 1}}
- {"foo": {"baz": None}} does not match {"foo": {"bar": 1}} - {"foo": None} matches {"foo": 5}
- {"foo": {"baz": 2}} matches {"foo": {"bar": 1, "baz": 2}} - {"foo": {"abc": None}} does not match {"foo": {"bar": 1}}
- {"foo": {"rab": 2}} matches {"foo": {"bar": 1, "rab": 2}}
""" """
if match is None: if match is None:
return True return True
for key in match: try:
if key in event: for key in match:
if isinstance(event[key], dict): if key in event:
if not QEMUMachine.event_match(event[key], match[key]): if not QEMUMachine.event_match(event[key], match[key]):
return False return False
elif event[key] != match[key]: else:
return False return False
else: return True
return False except TypeError:
return True # either match or event wasn't iterable (not a dict)
return match == event
def event_wait(self, name, timeout=60.0, match=None): def event_wait(self, name, timeout=60.0, match=None):
""" """