diff --git a/test_runner/src/main/kotlin/ftl/adapter/google/JUnitTestResultAdapter.kt b/test_runner/src/main/kotlin/ftl/adapter/google/JUnitTestResultAdapter.kt index 99af0f121e..4400caabae 100644 --- a/test_runner/src/main/kotlin/ftl/adapter/google/JUnitTestResultAdapter.kt +++ b/test_runner/src/main/kotlin/ftl/adapter/google/JUnitTestResultAdapter.kt @@ -38,5 +38,8 @@ private fun JUnitTestCase.toApiModel() = JUnitTest.Case( time = time, failures = failures, errors = errors, - skipped = skipped -) + skipped = skipped, + flaky = flaky +).also { + it.webLink = webLink +} diff --git a/test_runner/src/main/kotlin/ftl/api/JUnitTestResult.kt b/test_runner/src/main/kotlin/ftl/api/JUnitTestResult.kt index b31d0df8d4..f61e02f19b 100644 --- a/test_runner/src/main/kotlin/ftl/api/JUnitTestResult.kt +++ b/test_runner/src/main/kotlin/ftl/api/JUnitTestResult.kt @@ -102,15 +102,15 @@ object JUnitTest { val errors: List? = null, @JsonInclude(JsonInclude.Include.CUSTOM, valueFilter = FilterNotNull::class) - val skipped: String? = "absent" // used by FilterNotNull to filter out absent `skipped` values + val skipped: String? = "absent", // used by FilterNotNull to filter out absent `skipped` values + + @JacksonXmlProperty(isAttribute = true) + val flaky: Boolean? = null // use null instead of false ) { // Consider to move all properties to constructor if will doesn't conflict with parser @JsonInclude(JsonInclude.Include.NON_NULL) var webLink: String? = null - - @JacksonXmlProperty(isAttribute = true) - var flaky: Boolean? = null // use null instead of false } @Suppress("UnusedPrivateClass") diff --git a/test_runner/src/main/kotlin/ftl/reports/util/ReportManager.kt b/test_runner/src/main/kotlin/ftl/reports/util/ReportManager.kt index ecd415a7c1..47dfd78910 100644 --- a/test_runner/src/main/kotlin/ftl/reports/util/ReportManager.kt +++ b/test_runner/src/main/kotlin/ftl/reports/util/ReportManager.kt @@ -42,46 +42,6 @@ import kotlin.math.roundToInt object ReportManager { - private fun Pair.toApiIdentity(): JUnitTest.Result.ApiIdentity { - val (args, matrices) = this - return JUnitTest.Result.ApiIdentity( - projectId = args.project, - matrixIds = matrices.map.values.map { it.matrixId } - ) - } - - @VisibleForTesting - internal fun processXmlFromFile( - matrices: MatrixMap, - args: IArgs, - parsingFunction: (File) -> JUnitTest.Result - ): JUnitTest.Result? = findXmlFiles(matrices, args) - .map { xmlFile -> parsingFunction(xmlFile).updateWebLink(getWebLink(matrices, xmlFile)) } - .reduceOrNull { acc, result -> result.merge(acc) } - - private fun getWebLink(matrices: MatrixMap, xmlFile: File): String = - xmlFile.getMatrixPath(matrices.runPath) - ?.findMatrixPath(matrices) - ?: "".also { logLn("WARNING: Matrix path not found in JSON.") } - - private fun findXmlFiles( - matrices: MatrixMap, - args: IArgs - ) = File(resolveLocalRunPath(matrices, args)) - .walk() - .filter { it.name.matches(Artifacts.testResultRgx) } - .fold(listOf()) { xmlFiles, file -> xmlFiles + file } - - private fun JUnitTest.Result.updateWebLink( - webLink: String - ) = apply { - testsuites?.forEach { testSuite -> - testSuite.testcases?.forEach { testCase -> - testCase.webLink = webLink - } - } - } - /** Returns true if there were no test failures */ fun generate( matrices: MatrixMap, @@ -120,6 +80,55 @@ object ReportManager { uploadMatricesId(args, matrices) } + private fun Pair.toApiIdentity(): JUnitTest.Result.ApiIdentity { + val (args, matrices) = this + return JUnitTest.Result.ApiIdentity( + projectId = args.project, + matrixIds = matrices.map.values.map { it.matrixId } + ) + } + + @VisibleForTesting + internal fun processXmlFromFile( + matrices: MatrixMap, + args: IArgs, + parsingFunction: (File) -> JUnitTest.Result + ): JUnitTest.Result? = findXmlFiles(matrices, args) + .map { xmlFile -> parsingFunction(xmlFile).updateWebLink(getWebLink(matrices, xmlFile)) } + .reduceOrNull { acc, result -> result.merge(acc) } + + private fun findXmlFiles( + matrices: MatrixMap, + args: IArgs + ) = File(resolveLocalRunPath(matrices, args)) + .walk() + .filter { it.name.matches(Artifacts.testResultRgx) } + .fold(listOf()) { xmlFiles, file -> xmlFiles + file } + + private fun getWebLink(matrices: MatrixMap, xmlFile: File): String = + xmlFile.getMatrixPath(matrices.runPath) + ?.findMatrixPath(matrices) + ?: "".also { logLn("WARNING: Matrix path not found in JSON.") } + + private fun String.findMatrixPath(matrices: MatrixMap) = matrices.map.values + .firstOrNull { savedMatrix -> savedMatrix.gcsPath.endsWithTextWithOptionalSlashAtTheEnd(this) } + ?.webLink + ?: "".also { logLn("WARNING: Matrix path not found in JSON. $this") } + + @VisibleForTesting + internal fun String.endsWithTextWithOptionalSlashAtTheEnd(text: String) = + "($text)/*$".toRegex().containsMatchIn(this) + + private fun JUnitTest.Result.updateWebLink( + webLink: String + ) = apply { + testsuites?.forEach { testSuite -> + testSuite.testcases?.forEach { testCase -> + testCase.webLink = webLink + } + } + } + private fun parseTestSuite(matrices: MatrixMap, args: IArgs): JUnitTest.Result? = when { // ios supports only legacy parsing args is IosArgs -> processXmlFromFile(matrices, args, parseJUnitTestResultFromFile) @@ -273,13 +282,4 @@ object ReportManager { RemoteStorage.Data(file, Files.readAllBytes(Paths.get(file))) ) } - - private fun String.findMatrixPath(matrices: MatrixMap) = matrices.map.values - .firstOrNull { savedMatrix -> savedMatrix.gcsPath.endsWithTextWithOptionalSlashAtTheEnd(this) } - ?.webLink - ?: "".also { logLn("WARNING: Matrix path not found in JSON. $this") } - - @VisibleForTesting - internal fun String.endsWithTextWithOptionalSlashAtTheEnd(text: String) = - "($text)/*$".toRegex().containsMatchIn(this) } diff --git a/test_runner/src/test/kotlin/ftl/reports/utils/JUnitDedupeTest.kt b/test_runner/src/test/kotlin/ftl/reports/utils/JUnitDedupeTest.kt index b1afb59d55..0dcd04f63d 100644 --- a/test_runner/src/test/kotlin/ftl/reports/utils/JUnitDedupeTest.kt +++ b/test_runner/src/test/kotlin/ftl/reports/utils/JUnitDedupeTest.kt @@ -52,9 +52,14 @@ class JUnitDedupeTest { junit.framework.AssertionFailedError + matrices/7494574344413871385 + + + matrices/7494574344413871385 + + + matrices/7494574344413871385 - - @@ -65,8 +70,6 @@ class JUnitDedupeTest { ).toApiModel() JUnitDedupe.modify(suites) - val x = suites.toXmlString().normalizeLineEnding() - val y = expectedXml - assertThat(x).isEqualTo(y) + assertThat(suites.toXmlString().normalizeLineEnding()).isEqualTo(expectedXml) } }