From cd455291055473d1c5e61aaffe91cb62f0f988e2 Mon Sep 17 00:00:00 2001 From: Sebastian Mitterle Date: Wed, 22 Feb 2023 04:50:41 -0500 Subject: [PATCH] libvirt: add helper function to find matches in Libvirt XML XML attributes are unordered. Therefore, the existing function `check_dumpxml` can't be used if attribute order changes. Add new function that leverages the existing xmltreefile property to match xpath expressions instead. Signed-off-by: Sebastian Mitterle --- spell.ignore | 2 ++ virttest/utils_test/libvirt.py | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/spell.ignore b/spell.ignore index 948f8534df..b1f74f8f1b 100644 --- a/spell.ignore +++ b/spell.ignore @@ -38,6 +38,7 @@ cpu efi env environ +etree cgroup ip rtype @@ -187,6 +188,7 @@ num polkit pos xpath +xpaths cpus fsfreeze OVS diff --git a/virttest/utils_test/libvirt.py b/virttest/utils_test/libvirt.py index ee2e00e38c..091d9660e8 100644 --- a/virttest/utils_test/libvirt.py +++ b/virttest/utils_test/libvirt.py @@ -3954,6 +3954,39 @@ def check_domuuid_compliant_with_rfc4122(dom_uuid_value): return dom_uuid_segments[2].startswith('4') and dom_uuid_segments[3][0] in '89ab' +def check_xpaths(xml, xpaths, text=None): + """ + Check if the xml has elements that match all xpaths and optionally + contain a given text. + + :param xml: Libvirt XML instance + :param xpaths: list of xpath expressions as supported by etree.ElementTree + :param text: string to match the text node of matching elements + per default this is not checked if not given + :return: None + :raises: TestFail if no element matches all xpaths + and optionally the given text node + """ + test_failure = exceptions.TestFail("XML did not match all xpaths or text." + " XPaths: %s" + " Text: %s" + " XML: %s" % (xpaths, text, xml)) + + matches = set(xml.xmltreefile.findall(xpaths[0])) + + if not matches: + raise test_failure + + for xpath in xpaths[0:]: + matches &= set(xml.xmltreefile.findall(xpath)) + + if not matches: + raise test_failure + + if text is not None and not [x for x in matches if x.text == text]: + raise test_failure + + def check_dumpxml(vm, content, err_ignore=False): """ Check the specified content in the VM dumpxml