Taking a short break.
[SquirrelJME.git] / nanocoat / ctest-to-junit.py
blob3fb26cba578441bd8d27e0abfc77beef8287b538
1 # ---------------------------------------------------------------------------
2 # SquirrelJME
3 # Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
4 # ---------------------------------------------------------------------------
5 # SquirrelJME is under the GNU General Public License v3, or later.
6 # For more information see license.txt.
7 # ---------------------------------------------------------------------------
8 # DESCRIPTION: Converts CTest Result XML Output into Ant/Gradle JUnit's XML
10 import sys
11 import os
12 import xml.etree.ElementTree as Xml
13 import datetime
15 # Convert banner
16 print("Converting CTest from stdin...")
18 # Globals
19 squirreljmeGlobalTestTime = None
21 # Resultant Variables for runs
22 testName = None
23 squirreljmeTestResult = None
24 squirreljmeNumSkipped = None
25 squirreljmeNumFailed = None
26 squirreljmeExecTime = None
27 squirreljmeWantValue = None
28 squirreljmeStdErr = None
30 # Parse the XML Tree
31 for event, tree in Xml.iterparse(sys.stdin, events=("start", "end")):
32 tag = tree.tag
33 text = tree.text
34 attrib = tree.attrib
36 # Debugging
37 # print('DEBUG: %s %s `%s` %s' % (event, tag, text, attrib))
39 # Start of a new tag
40 if event == "start":
41 # Test time (UNIX Time -> 2021-03-05T18:23:27.788)
42 if tag == "StartTestTime":
43 squirreljmeGlobalTestTime = datetime.datetime \
44 .utcfromtimestamp(int(text)).strftime("%Y-%m-%dT%H:%M:%S")
46 # Defining new test
47 elif tag == "Test" and "Status" in attrib:
48 # Failed test?
49 status = attrib["Status"]
50 if status == "failed":
51 squirreljmeNumSkipped = 0
52 squirreljmeNumFailed = 1
54 # Skipped test
55 elif status == "notrun":
56 squirreljmeNumSkipped = 1
57 squirreljmeNumFailed = 0
59 # Passed test
60 elif status == "passed":
61 squirreljmeNumSkipped = 0
62 squirreljmeNumFailed = 0
64 # Name of test
65 elif tag == "Name":
66 testName = text
68 # Time test took to execute (CTest ?? -> JUnit ms)
69 elif (tag == "NamedMeasurement" and "name" in attrib and
70 attrib["name"] == "Execution Time"):
71 squirreljmeWantValue = "execTime"
73 # Test output
74 elif tag == "Measurement" and len(attrib) == 0:
75 squirreljmeWantValue = "stdErr"
77 # Reading a value
78 elif tag == "Value":
79 # Execution time?
80 if "execTime" == squirreljmeWantValue:
81 squirreljmeExecTime = max(float(1), float(text) * 1000)
83 # Standard error?
84 elif "stdErr" == squirreljmeWantValue:
85 squirreljmeStdErr = text
87 # Always clear out what we want, so it is not used
88 squirreljmeWantValue = None
90 # End of a test tag, dump the XML, or end of entire file
91 elif event == "end" and tag == 'Test' and "Status" in attrib:
92 # Make sure the name is always invalid, if missed try again
93 if testName is None:
94 testName = "InvalidTestName"
96 # Force values to be set?
97 if squirreljmeExecTime is None:
98 squirreljmeExecTime = 0
100 # Create build directory if missing
101 if not os.path.isdir("build"):
102 os.mkdir("build")
103 if not os.path.isdir("build/junit"):
104 os.mkdir("build/junit")
106 # Open output file
107 with open("build/junit/TEST-" + testName + ".xml", "wt") as file:
108 # XML Header
109 file.write('<?xml version="1.0" encoding="UTF-8"?>')
110 file.write('\n')
112 # Test Suite Information
113 file.write('<testsuite name="%s" tests="1" skipped="%d" '
114 'failures="%d" errors="%d" timestamp="%s" '
115 'hostname="CTest" time="%g">' %
116 (testName, squirreljmeNumSkipped,
117 squirreljmeNumFailed, squirreljmeNumFailed,
118 squirreljmeGlobalTestTime, squirreljmeExecTime))
119 file.write('\n')
121 # Test Case (mostly the same)
122 file.write('<testcase name="%s" '
123 'classname="%s" time="%g">' %
124 (testName, testName,
125 squirreljmeExecTime))
126 file.write('\n')
128 # Failure, needed for cases
129 if squirreljmeNumFailed > 0:
130 file.write('<failure type="%s"><![CDATA[%s]]></failure>' %
131 (testName, squirreljmeStdErr))
132 file.write('\n')
134 # Standard output
135 file.write('<system-out><![CDATA[]]></system-out>')
136 file.write('\n')
138 # Standard error
139 file.write(
140 '<system-err><![CDATA[%s]]></system-err>' % squirreljmeStdErr)
141 file.write('\n')
143 # End tags
144 file.write('</testcase>')
145 file.write('</testsuite>')
146 file.write('\n')
148 # Reset all test state
149 testName = None
150 squirreljmeTestResult = None
151 squirreljmeNumSkipped = None
152 squirreljmeNumFailed = None
153 squirreljmeExecTime = None
154 squirreljmeWantValue = None
155 squirreljmeStdErr = None