From 38a224dc7e27cac7a1b959c1a8abcbbe827ffdd9 Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Tue, 23 Jun 2020 11:56:57 -0700 Subject: [PATCH] Fix non-determinism in tests. The stdlib's xml apparently cares about ordering but also doesn't preserve it. There are a number of different recommendations of other ways to do this, but they all depend on packages we don't have available (lxml or xml.dom.ext, in particular). Test: pytest Bug: None Change-Id: I07108d8977c302404e7c90ca75a4bf7a1144750f --- .../test_ndk_api_coverage_parser.py | 32 ++++++++++++++++--- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/cc/ndk_api_coverage_parser/test_ndk_api_coverage_parser.py b/cc/ndk_api_coverage_parser/test_ndk_api_coverage_parser.py index f1c925ca9..3ec14c10a 100644 --- a/cc/ndk_api_coverage_parser/test_ndk_api_coverage_parser.py +++ b/cc/ndk_api_coverage_parser/test_ndk_api_coverage_parser.py @@ -19,7 +19,7 @@ import io import textwrap import unittest -from xml.etree.ElementTree import tostring +from xml.etree.ElementTree import fromstring from symbolfile import FUTURE_API_LEVEL, SymbolFileParser import ndk_api_coverage_parser as nparser @@ -27,6 +27,30 @@ import ndk_api_coverage_parser as nparser # pylint: disable=missing-docstring +# https://stackoverflow.com/a/24349916/632035 +def etree_equal(elem1, elem2): + """Returns true if the two XML elements are equal. + + xml.etree.ElementTree's comparison operator cares about the ordering of + elements and attributes, but they are stored in an unordered dict so the + ordering is not deterministic. + + lxml is apparently API compatible with xml and does use an OrderedDict, but + we don't have it in the tree. + """ + if elem1.tag != elem2.tag: + return False + if elem1.text != elem2.text: + return False + if elem1.tail != elem2.tail: + return False + if elem1.attrib != elem2.attrib: + return False + if len(elem1) != len(elem2): + return False + return all(etree_equal(c1, c2) for c1, c2 in zip(elem1, elem2)) + + class ApiCoverageSymbolFileParserTest(unittest.TestCase): def test_parse(self): input_file = io.StringIO(textwrap.dedent(u"""\ @@ -52,9 +76,9 @@ class ApiCoverageSymbolFileParserTest(unittest.TestCase): """)) parser = SymbolFileParser(input_file, {}, "", FUTURE_API_LEVEL, True, True) generator = nparser.XmlGenerator(io.StringIO()) - result = tostring(generator.convertToXml(parser.parse())).decode() - expected = '' - self.assertEqual(expected, result) + result = generator.convertToXml(parser.parse()) + expected = fromstring('') + self.assertTrue(etree_equal(expected, result)) def main():