@@ -129,44 +129,42 @@ tasks.withType<Test>().configureEach {
129129 //
130130 // However, all intermediate attempts are reported as failures in TestOptimization, which is misleading.
131131 //
132- // Ideally , we would expose a final_status field:
132+ // To tackle this , we'll expose a final_status field:
133133 // - "skip" for intermediate retries
134- // - "fail"/"pass" for the final attempt
135- //
136- // Unfortunately, the test framework provides very limited control over this, and no built-in solution was found.
137- //
138- // As a workaround, this post-processor removes those synthetic test cases. Given that these errors are arguably
139- // not actionable for test owners (TBD), this is considered an acceptable trade-off.
134+ // - nothing on last attempt, using the defaulting made by Test Optimization
140135 //
141136 // Charles de Beauchesne, March 2025
142137
143- val reportsLocation = reports.junitXml.outputLocation
144- val removeInitErrors = tasks.register(" ${name} RemoveInitializationErrors" ) {
145- doLast {
146- val dir = reportsLocation.get().asFile
147- if (! dir.exists()) return @doLast
148- dir.walkTopDown()
149- .filter { it.isFile && it.extension == " xml" }
150- .forEach { xmlFile ->
151- try {
152- removeInitializationErrors(xmlFile)
153- } catch (e: Exception ) {
154- logger.warn(" Failed to remove initializationError testcases from {}: {}" , xmlFile.name, e.message)
155- }
138+ doLast(" post-process-junit-xml-report" ) {
139+ val dir = reports.junitXml.outputLocation.get().asFile
140+ if (! dir.exists()) return @doLast
141+ dir.walkTopDown()
142+ .filter { it.isFile && it.extension == " xml" }
143+ .forEach { xmlFile ->
144+ try {
145+ tagInitializationErrors(xmlFile)
146+ } catch (e: Exception ) {
147+ logger.warn(" Failed to remove initializationError testcases from {}: {}" , xmlFile.name, e.message)
156148 }
157- }
149+ }
158150 }
159- finalizedBy(removeInitErrors)
160151}
161152
162- fun removeInitializationErrors (xmlFile : File ) {
153+ fun tagInitializationErrors (xmlFile : File ) {
163154 val doc = DocumentBuilderFactory .newInstance().newDocumentBuilder().parse(xmlFile)
164155 val testcases = doc.getElementsByTagName(" testcase" )
165- val toRemove = (0 until testcases.length)
156+ val initErrorCases = (0 until testcases.length)
166157 .map { testcases.item(it) as Element }
167158 .filter { it.getAttribute(" name" ) == " initializationError" }
168- if (toRemove.isEmpty()) return
169- toRemove.forEach { it.parentNode.removeChild(it) }
159+ if (initErrorCases.size <= 1 ) return
160+ initErrorCases.dropLast(1 ).forEach { testcase ->
161+ val properties = doc.createElement(" properties" )
162+ val property = doc.createElement(" property" )
163+ property.setAttribute(" name" , " dd_tags[test.final_status]" )
164+ property.setAttribute(" value" , " skip" )
165+ properties.appendChild(property)
166+ testcase.appendChild(properties)
167+ }
170168 val transformer = TransformerFactory .newInstance().newTransformer()
171169 transformer.setOutputProperty(OutputKeys .ENCODING , " UTF-8" )
172170 transformer.transform(DOMSource (doc), StreamResult (xmlFile))
0 commit comments