Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 1 | """Simple xunit results file creator utility.""" |
| 2 | # Copyright (c) 2020-2022, ARM Limited. |
| 3 | # SPDX-License-Identifier: Apache-2.0 |
Eric Kunze | e5e2676 | 2020-10-13 16:11:07 -0700 | [diff] [blame] | 4 | import xml.etree.ElementTree as ET |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 5 | from xml.dom import minidom |
Eric Kunze | e5e2676 | 2020-10-13 16:11:07 -0700 | [diff] [blame] | 6 | |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 7 | |
| 8 | class xunit_results: |
| 9 | """Xunit results writer.""" |
| 10 | |
| 11 | def __init__(self): |
| 12 | """Initialize results.""" |
| 13 | self.name = "testsuites" |
Eric Kunze | e5e2676 | 2020-10-13 16:11:07 -0700 | [diff] [blame] | 14 | self.suites = [] |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 15 | |
Eric Kunze | e5e2676 | 2020-10-13 16:11:07 -0700 | [diff] [blame] | 16 | def create_suite(self, name): |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 17 | """Create xunit suite for results.""" |
Eric Kunze | e5e2676 | 2020-10-13 16:11:07 -0700 | [diff] [blame] | 18 | s = xunit_suite(name) |
| 19 | self.suites.append(s) |
| 20 | return s |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 21 | |
Eric Kunze | e5e2676 | 2020-10-13 16:11:07 -0700 | [diff] [blame] | 22 | def write_results(self, filename): |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 23 | """Write the results to the appropriate suites.""" |
Eric Kunze | e5e2676 | 2020-10-13 16:11:07 -0700 | [diff] [blame] | 24 | suites = ET.Element(self.name) |
| 25 | tree = ET.ElementTree(suites) |
| 26 | for s in self.suites: |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 27 | testsuite = ET.SubElement( |
| 28 | suites, "testsuite", {"name": s.name, "errors": "0"} |
| 29 | ) |
Eric Kunze | e5e2676 | 2020-10-13 16:11:07 -0700 | [diff] [blame] | 30 | tests = 0 |
| 31 | failures = 0 |
| 32 | skip = 0 |
| 33 | for t in s.tests: |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 34 | test = ET.SubElement( |
| 35 | testsuite, |
| 36 | "testcase", |
| 37 | {"name": t.name, "classname": t.classname, "time": t.time}, |
| 38 | ) |
Eric Kunze | e5e2676 | 2020-10-13 16:11:07 -0700 | [diff] [blame] | 39 | tests += 1 |
| 40 | if t.skip: |
| 41 | skip += 1 |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 42 | ET.SubElement(test, "skipped", {"type": "Skipped test"}) |
Eric Kunze | e5e2676 | 2020-10-13 16:11:07 -0700 | [diff] [blame] | 43 | if t.fail: |
| 44 | failures += 1 |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 45 | fail = ET.SubElement(test, "failure", {"type": "Test failed"}) |
Eric Kunze | e5e2676 | 2020-10-13 16:11:07 -0700 | [diff] [blame] | 46 | fail.text = t.fail |
| 47 | if t.sysout: |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 48 | sysout = ET.SubElement(test, "system-out") |
Eric Kunze | e5e2676 | 2020-10-13 16:11:07 -0700 | [diff] [blame] | 49 | sysout.text = t.sysout |
| 50 | if t.syserr: |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 51 | syserr = ET.SubElement(test, "system-err") |
Eric Kunze | e5e2676 | 2020-10-13 16:11:07 -0700 | [diff] [blame] | 52 | syserr.text = t.syserr |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 53 | testsuite.attrib["tests"] = str(tests) |
| 54 | testsuite.attrib["failures"] = str(failures) |
| 55 | testsuite.attrib["skip"] = str(skip) |
| 56 | xmlstr = minidom.parseString(ET.tostring(tree.getroot())).toprettyxml( |
| 57 | indent=" " |
| 58 | ) |
| 59 | with open(filename, "w") as f: |
| 60 | f.write(xmlstr) |
Eric Kunze | e5e2676 | 2020-10-13 16:11:07 -0700 | [diff] [blame] | 61 | |
| 62 | |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 63 | class xunit_suite: |
| 64 | """Xunit suite for test results.""" |
| 65 | |
Eric Kunze | e5e2676 | 2020-10-13 16:11:07 -0700 | [diff] [blame] | 66 | def __init__(self, name): |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 67 | """Initialize suite.""" |
Eric Kunze | e5e2676 | 2020-10-13 16:11:07 -0700 | [diff] [blame] | 68 | self.name = name |
| 69 | self.tests = [] |
| 70 | |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 71 | |
| 72 | # classname should be of the form suite.class/subclass/subclass2/... |
| 73 | # You can have an unlimited number of subclasses in this manner |
| 74 | |
| 75 | |
| 76 | class xunit_test: |
| 77 | """Xunit test result.""" |
| 78 | |
Eric Kunze | e5e2676 | 2020-10-13 16:11:07 -0700 | [diff] [blame] | 79 | def __init__(self, name, classname=None): |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 80 | """Initialize test.""" |
Eric Kunze | e5e2676 | 2020-10-13 16:11:07 -0700 | [diff] [blame] | 81 | self.name = name |
| 82 | if classname: |
| 83 | self.classname = classname |
| 84 | else: |
| 85 | self.classname = name |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 86 | self.time = "0.000" |
Eric Kunze | e5e2676 | 2020-10-13 16:11:07 -0700 | [diff] [blame] | 87 | self.fail = None |
| 88 | self.skip = False |
| 89 | self.sysout = None |
| 90 | self.syserr = None |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 91 | |
Eric Kunze | e5e2676 | 2020-10-13 16:11:07 -0700 | [diff] [blame] | 92 | def failed(self, text): |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 93 | """Set test failed information.""" |
Eric Kunze | e5e2676 | 2020-10-13 16:11:07 -0700 | [diff] [blame] | 94 | self.fail = text |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 95 | |
Eric Kunze | e5e2676 | 2020-10-13 16:11:07 -0700 | [diff] [blame] | 96 | def skipped(self): |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 97 | """Set test as skipped.""" |
Eric Kunze | e5e2676 | 2020-10-13 16:11:07 -0700 | [diff] [blame] | 98 | self.skip = True |
| 99 | |
| 100 | |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 101 | if __name__ == "__main__": |
| 102 | # Simple test |
Eric Kunze | e5e2676 | 2020-10-13 16:11:07 -0700 | [diff] [blame] | 103 | r = xunit_results() |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 104 | s = r.create_suite("selftest") |
| 105 | for i in range(0, 10): |
| 106 | t = xunit_test("atest" + str(i), "selftest") |
Eric Kunze | e5e2676 | 2020-10-13 16:11:07 -0700 | [diff] [blame] | 107 | if i == 3: |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 108 | t.failed("Unknown failure foo") |
Eric Kunze | e5e2676 | 2020-10-13 16:11:07 -0700 | [diff] [blame] | 109 | if i == 7: |
| 110 | t.skipped() |
| 111 | s.tests.append(t) |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 112 | r.write_results("foo.xml") |