1 # ---------------------------------------------------------------------------
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
12 import xml
.etree
.ElementTree
as Xml
16 print("Converting CTest from stdin...")
19 squirreljmeGlobalTestTime
= None
21 # Resultant Variables for runs
23 squirreljmeTestResult
= None
24 squirreljmeNumSkipped
= None
25 squirreljmeNumFailed
= None
26 squirreljmeExecTime
= None
27 squirreljmeWantValue
= None
28 squirreljmeStdErr
= None
31 for event
, tree
in Xml
.iterparse(sys
.stdin
, events
=("start", "end")):
37 # print('DEBUG: %s %s `%s` %s' % (event, tag, text, attrib))
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")
47 elif tag
== "Test" and "Status" in attrib
:
49 status
= attrib
["Status"]
50 if status
== "failed":
51 squirreljmeNumSkipped
= 0
52 squirreljmeNumFailed
= 1
55 elif status
== "notrun":
56 squirreljmeNumSkipped
= 1
57 squirreljmeNumFailed
= 0
60 elif status
== "passed":
61 squirreljmeNumSkipped
= 0
62 squirreljmeNumFailed
= 0
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"
74 elif tag
== "Measurement" and len(attrib
) == 0:
75 squirreljmeWantValue
= "stdErr"
80 if "execTime" == squirreljmeWantValue
:
81 squirreljmeExecTime
= max(float(1), float(text
) * 1000)
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
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"):
103 if not os
.path
.isdir("build/junit"):
104 os
.mkdir("build/junit")
107 with
open("build/junit/TEST-" + testName
+ ".xml", "wt") as file:
109 file.write('<?xml version="1.0" encoding="UTF-8"?>')
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
))
121 # Test Case (mostly the same)
122 file.write('<testcase name="%s" '
123 'classname="%s" time="%g">' %
125 squirreljmeExecTime
))
128 # Failure, needed for cases
129 if squirreljmeNumFailed
> 0:
130 file.write('<failure type="%s"><![CDATA[%s]]></failure>' %
131 (testName
, squirreljmeStdErr
))
135 file.write('<system-out><![CDATA[]]></system-out>')
140 '<system-err><![CDATA[%s]]></system-err>' % squirreljmeStdErr
)
144 file.write('</testcase>')
145 file.write('</testsuite>')
148 # Reset all test state
150 squirreljmeTestResult
= None
151 squirreljmeNumSkipped
= None
152 squirreljmeNumFailed
= None
153 squirreljmeExecTime
= None
154 squirreljmeWantValue
= None
155 squirreljmeStdErr
= None