From f182c8cb455b5b23eac4e00dcd1e9217855f46e6 Mon Sep 17 00:00:00 2001 From: Adam Date: Thu, 7 May 2020 17:15:49 +0200 Subject: [PATCH 01/20] #764 Fix crash on parse some control chars --- test_runner/build.gradle.kts | 2 + test_runner/buildSrc/src/main/kotlin/Deps.kt | 4 ++ .../main/kotlin/ftl/reports/xml/JUnitXml.kt | 24 +++++------ .../xml/preprocesor/XmlPreprocessor.kt | 14 ++++++ .../kotlin/ftl/reports/xml/JUnitXmlTest.kt | 43 +++++++++++++++++-- 5 files changed, 70 insertions(+), 17 deletions(-) create mode 100644 test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/XmlPreprocessor.kt diff --git a/test_runner/build.gradle.kts b/test_runner/build.gradle.kts index 646ad2aaf4..c37db75413 100644 --- a/test_runner/build.gradle.kts +++ b/test_runner/build.gradle.kts @@ -213,6 +213,8 @@ dependencies { implementation(Libs.SYSTEM_RULES) testImplementation(Libs.TRUTH) testImplementation(Libs.MOCKK) + + implementation(Libs.COMMON_TEXT) } // Fix Exception in thread "main" java.lang.NoSuchMethodError: com.google.common.hash.Hashing.crc32c()Lcom/google/common/hash/HashFunction; diff --git a/test_runner/buildSrc/src/main/kotlin/Deps.kt b/test_runner/buildSrc/src/main/kotlin/Deps.kt index c445def81f..a0bb584313 100644 --- a/test_runner/buildSrc/src/main/kotlin/Deps.kt +++ b/test_runner/buildSrc/src/main/kotlin/Deps.kt @@ -74,6 +74,8 @@ object Versions { // https://github.com/mockk/mockk const val MOCKK = "1.9.3" + + const val COMMON_TEXT = "1.7" } object Libs { @@ -123,4 +125,6 @@ object Libs { const val TRUTH = "com.google.truth:truth:${Versions.TRUTH}" const val MOCKK = "io.mockk:mockk:${Versions.MOCKK}" //endregion + + const val COMMON_TEXT = "org.apache.commons:commons-text:${Versions.COMMON_TEXT}" } diff --git a/test_runner/src/main/kotlin/ftl/reports/xml/JUnitXml.kt b/test_runner/src/main/kotlin/ftl/reports/xml/JUnitXml.kt index cda3835a7f..bb19c5cb8b 100644 --- a/test_runner/src/main/kotlin/ftl/reports/xml/JUnitXml.kt +++ b/test_runner/src/main/kotlin/ftl/reports/xml/JUnitXml.kt @@ -6,10 +6,12 @@ import com.fasterxml.jackson.module.kotlin.KotlinModule import com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES import ftl.reports.xml.model.JUnitTestResult import ftl.reports.xml.model.JUnitTestSuite +import ftl.reports.xml.preprocesor.fixHtmlCodes import java.io.File import java.nio.file.Files import java.nio.file.Path + private val xmlModule = JacksonXmlModule().apply { setDefaultUseWrapper(false) } private val xmlMapper = XmlMapper(xmlModule) .registerModules(KotlinModule()) @@ -17,9 +19,10 @@ private val xmlMapper = XmlMapper(xmlModule) internal val xmlPrettyWriter = xmlMapper.writerWithDefaultPrettyPrinter() -private fun xmlBytes(path: Path): ByteArray { + +private fun xmlText(path: Path): String { if (!path.toFile().exists()) throw RuntimeException("$path doesn't exist!") - return Files.readAllBytes(path) + return Files.readString(path) } fun JUnitTestResult?.xmlToString(): String { @@ -28,30 +31,23 @@ fun JUnitTestResult?.xmlToString(): String { return prefix + xmlPrettyWriter.writeValueAsString(this) } -fun parseOneSuiteXml(bytes: ByteArray): JUnitTestResult { - return JUnitTestResult(mutableListOf(xmlMapper.readValue(bytes, JUnitTestSuite::class.java))) -} - fun parseOneSuiteXml(path: Path): JUnitTestResult { - return parseOneSuiteXml(xmlBytes(path)) + return parseOneSuiteXml(xmlText(path)) } fun parseOneSuiteXml(path: File): JUnitTestResult { - return parseOneSuiteXml(xmlBytes(path.toPath())) + return parseOneSuiteXml(xmlText(path.toPath())) } fun parseOneSuiteXml(data: String): JUnitTestResult { - return parseOneSuiteXml(data.toByteArray()) + return JUnitTestResult(mutableListOf(xmlMapper.readValue(fixHtmlCodes(data), JUnitTestSuite::class.java))) } // -- -fun parseAllSuitesXml(bytes: ByteArray): JUnitTestResult { - return xmlMapper.readValue(bytes, JUnitTestResult::class.java) -} fun parseAllSuitesXml(path: Path): JUnitTestResult { - return parseAllSuitesXml(xmlBytes(path)) + return parseAllSuitesXml(xmlText(path)) } fun parseAllSuitesXml(path: File): JUnitTestResult { @@ -59,5 +55,5 @@ fun parseAllSuitesXml(path: File): JUnitTestResult { } fun parseAllSuitesXml(data: String): JUnitTestResult { - return parseAllSuitesXml(data.toByteArray()) + return xmlMapper.readValue(fixHtmlCodes(data), JUnitTestResult::class.java) } diff --git a/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/XmlPreprocessor.kt b/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/XmlPreprocessor.kt new file mode 100644 index 0000000000..8dc28138a9 --- /dev/null +++ b/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/XmlPreprocessor.kt @@ -0,0 +1,14 @@ +package ftl.reports.xml.preprocesor + +import org.apache.commons.text.StringEscapeUtils + +fun fixHtmlCodes(data: String): String { + val isoHtmlCodesToReplace = listOf(0x00..0x1F).union(listOf(0x7F..0x9F)).flatten() + .map { StringEscapeUtils.escapeXml11(it.toChar().toString()) }.filter { it.startsWith("&#") } + + var fixedStr = data + for (isoControlCode in isoHtmlCodesToReplace) { + fixedStr = fixedStr.replace(isoControlCode, "") + } + return fixedStr +} \ No newline at end of file diff --git a/test_runner/src/test/kotlin/ftl/reports/xml/JUnitXmlTest.kt b/test_runner/src/test/kotlin/ftl/reports/xml/JUnitXmlTest.kt index 9481d3b698..0ffd4229e4 100644 --- a/test_runner/src/test/kotlin/ftl/reports/xml/JUnitXmlTest.kt +++ b/test_runner/src/test/kotlin/ftl/reports/xml/JUnitXmlTest.kt @@ -5,6 +5,7 @@ import ftl.test.util.TestHelper.normalizeLineEnding import java.nio.file.Paths import org.junit.Test + class JUnitXmlTest { companion object { @@ -73,7 +74,8 @@ junit.framework.Assert.fail(Assert.java:50) @Test fun `merge ios`() { - val merged = parseAllSuitesXml(iosPassXml).merge(parseAllSuitesXml(iosFailXml)).xmlToString().normalizeLineEnding() + val merged = + parseAllSuitesXml(iosPassXml).merge(parseAllSuitesXml(iosFailXml)).xmlToString().normalizeLineEnding() val expected = """ @@ -94,7 +96,8 @@ junit.framework.Assert.fail(Assert.java:50) @Test fun `Merge iOS large time`() { - val merged = parseAllSuitesXml(iosLargeNum).merge(parseAllSuitesXml(iosLargeNum)).xmlToString().normalizeLineEnding() + val merged = + parseAllSuitesXml(iosLargeNum).merge(parseAllSuitesXml(iosLargeNum)).xmlToString().normalizeLineEnding() val expected = """ @@ -423,7 +426,8 @@ junit.framework.Assert.fail(Assert.java:50) // * c() failed in newRun and passed in oldRun. timing info copied over from oldRun // * d() was skipped in newRun and successful in oldRun. d() is excluded from the merged result - val merged = parseAllSuitesXml(newRun).mergeTestTimes(parseAllSuitesXml(oldRun)).xmlToString().normalizeLineEnding() + val merged = + parseAllSuitesXml(newRun).mergeTestTimes(parseAllSuitesXml(oldRun)).xmlToString().normalizeLineEnding() val expected = """ @@ -437,4 +441,37 @@ junit.framework.Assert.fail(Assert.java:50) """.trimIndent() assertThat(merged).isEqualTo(expected) } + + + @Test + fun `parse ftl quirks`() { + val crashingAllSuitesMessage = """ + + + + + java.net.ConnectException: Failed to connect to ... at (Coroutine boundary.() + + + + + + """.trimIndent() + val crashingOneSuiteMessage = """ + + + + java.net.ConnectException: Failed to connect to ... at (Coroutine boundary.() + + + + + """.trimIndent() + + parseAllSuitesXml(crashingAllSuitesMessage) + parseOneSuiteXml(crashingOneSuiteMessage) + + } + } + From 6be0d1f2b45b722eebecc2b3a26ac37c2a262e06 Mon Sep 17 00:00:00 2001 From: Adam Date: Thu, 7 May 2020 17:52:53 +0200 Subject: [PATCH 02/20] #764 detekt issues fix detekt issues fix --- test_runner/src/main/kotlin/ftl/reports/xml/JUnitXml.kt | 4 +--- .../kotlin/ftl/reports/xml/preprocesor/XmlPreprocessor.kt | 2 +- test_runner/src/test/kotlin/ftl/reports/xml/JUnitXmlTest.kt | 6 ------ 3 files changed, 2 insertions(+), 10 deletions(-) diff --git a/test_runner/src/main/kotlin/ftl/reports/xml/JUnitXml.kt b/test_runner/src/main/kotlin/ftl/reports/xml/JUnitXml.kt index bb19c5cb8b..4e3338a3d1 100644 --- a/test_runner/src/main/kotlin/ftl/reports/xml/JUnitXml.kt +++ b/test_runner/src/main/kotlin/ftl/reports/xml/JUnitXml.kt @@ -11,15 +11,14 @@ import java.io.File import java.nio.file.Files import java.nio.file.Path - private val xmlModule = JacksonXmlModule().apply { setDefaultUseWrapper(false) } + private val xmlMapper = XmlMapper(xmlModule) .registerModules(KotlinModule()) .configure(FAIL_ON_UNKNOWN_PROPERTIES, false) internal val xmlPrettyWriter = xmlMapper.writerWithDefaultPrettyPrinter() - private fun xmlText(path: Path): String { if (!path.toFile().exists()) throw RuntimeException("$path doesn't exist!") return Files.readString(path) @@ -45,7 +44,6 @@ fun parseOneSuiteXml(data: String): JUnitTestResult { // -- - fun parseAllSuitesXml(path: Path): JUnitTestResult { return parseAllSuitesXml(xmlText(path)) } diff --git a/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/XmlPreprocessor.kt b/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/XmlPreprocessor.kt index 8dc28138a9..2c591b35a2 100644 --- a/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/XmlPreprocessor.kt +++ b/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/XmlPreprocessor.kt @@ -11,4 +11,4 @@ fun fixHtmlCodes(data: String): String { fixedStr = fixedStr.replace(isoControlCode, "") } return fixedStr -} \ No newline at end of file +} diff --git a/test_runner/src/test/kotlin/ftl/reports/xml/JUnitXmlTest.kt b/test_runner/src/test/kotlin/ftl/reports/xml/JUnitXmlTest.kt index 0ffd4229e4..10bbbb7270 100644 --- a/test_runner/src/test/kotlin/ftl/reports/xml/JUnitXmlTest.kt +++ b/test_runner/src/test/kotlin/ftl/reports/xml/JUnitXmlTest.kt @@ -5,7 +5,6 @@ import ftl.test.util.TestHelper.normalizeLineEnding import java.nio.file.Paths import org.junit.Test - class JUnitXmlTest { companion object { @@ -441,8 +440,6 @@ junit.framework.Assert.fail(Assert.java:50) """.trimIndent() assertThat(merged).isEqualTo(expected) } - - @Test fun `parse ftl quirks`() { val crashingAllSuitesMessage = """ @@ -470,8 +467,5 @@ junit.framework.Assert.fail(Assert.java:50) parseAllSuitesXml(crashingAllSuitesMessage) parseOneSuiteXml(crashingOneSuiteMessage) - } - } - From 10a179971e2890b34689dfd848c0ca90f57e7d3d Mon Sep 17 00:00:00 2001 From: Adam Date: Thu, 7 May 2020 19:08:55 +0200 Subject: [PATCH 03/20] Asserts in tests Add asserts in test and replace Files.readString to Files.readAllBytes for compability with java 1.8 --- .../main/kotlin/ftl/reports/xml/JUnitXml.kt | 2 +- .../kotlin/ftl/reports/xml/JUnitXmlTest.kt | 39 +++++++++++++++++-- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/test_runner/src/main/kotlin/ftl/reports/xml/JUnitXml.kt b/test_runner/src/main/kotlin/ftl/reports/xml/JUnitXml.kt index 4e3338a3d1..0211157adb 100644 --- a/test_runner/src/main/kotlin/ftl/reports/xml/JUnitXml.kt +++ b/test_runner/src/main/kotlin/ftl/reports/xml/JUnitXml.kt @@ -21,7 +21,7 @@ internal val xmlPrettyWriter = xmlMapper.writerWithDefaultPrettyPrinter() private fun xmlText(path: Path): String { if (!path.toFile().exists()) throw RuntimeException("$path doesn't exist!") - return Files.readString(path) + return String(Files.readAllBytes(path)) } fun JUnitTestResult?.xmlToString(): String { diff --git a/test_runner/src/test/kotlin/ftl/reports/xml/JUnitXmlTest.kt b/test_runner/src/test/kotlin/ftl/reports/xml/JUnitXmlTest.kt index 10bbbb7270..6fc3f97d5f 100644 --- a/test_runner/src/test/kotlin/ftl/reports/xml/JUnitXmlTest.kt +++ b/test_runner/src/test/kotlin/ftl/reports/xml/JUnitXmlTest.kt @@ -2,6 +2,7 @@ package ftl.reports.xml import com.google.common.truth.Truth.assertThat import ftl.test.util.TestHelper.normalizeLineEnding +import org.junit.Assert import java.nio.file.Paths import org.junit.Test @@ -440,8 +441,9 @@ junit.framework.Assert.fail(Assert.java:50) """.trimIndent() assertThat(merged).isEqualTo(expected) } + @Test - fun `parse ftl quirks`() { + fun `parse ftl quirks in all suites`() { val crashingAllSuitesMessage = """ @@ -454,6 +456,25 @@ junit.framework.Assert.fail(Assert.java:50) """.trimIndent() + + val expectedAllSuitesMessage = """ + + + + + java.net.ConnectException: Failed to connect to ... at (Coroutine boundary.() + + + + + + """.trimIndent() + val allSuitesXml = parseAllSuitesXml(crashingAllSuitesMessage).xmlToString().trimIndent() + Assert.assertEquals("All Suite Messages should be the same!", expectedAllSuitesMessage, allSuitesXml) + } + + @Test + fun `parse ftl quirks in on suite`() { val crashingOneSuiteMessage = """ @@ -465,7 +486,19 @@ junit.framework.Assert.fail(Assert.java:50) """.trimIndent() - parseAllSuitesXml(crashingAllSuitesMessage) - parseOneSuiteXml(crashingOneSuiteMessage) + val expectedOneSuiteMessage = """ + + + + + java.net.ConnectException: Failed to connect to ... at (Coroutine boundary.() + + + + + + """.trimIndent() + val oneSuiteXml = parseOneSuiteXml(crashingOneSuiteMessage).xmlToString().trimIndent() + Assert.assertEquals("One Suite Messages should be the same!", expectedOneSuiteMessage, oneSuiteXml) } } From 9387a48d4f9f00c46559de0f81994447794a1549 Mon Sep 17 00:00:00 2001 From: Adam Date: Thu, 7 May 2020 20:03:07 +0200 Subject: [PATCH 04/20] Add documentation of magicial numers --- .../ftl/reports/xml/preprocesor/UtfControlChars.kt | 13 +++++++++++++ .../ftl/reports/xml/preprocesor/XmlPreprocessor.kt | 7 +++++-- 2 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/UtfControlChars.kt diff --git a/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/UtfControlChars.kt b/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/UtfControlChars.kt new file mode 100644 index 0000000000..8d37889b4e --- /dev/null +++ b/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/UtfControlChars.kt @@ -0,0 +1,13 @@ +package ftl.reports.xml.preprocesor + +/** + * Numbers come from ascii table https://www.utf8-chartable.de. + * and represents control chars. We need to avoid characters in ranges CONTROL_TOP_START..CONTROL_TOP_END and + * CONTROL_BOTTOM_START..CONTROL_BOTTOM_END because chars from that range escaped to html causing parsing errors. + * */ +enum class UtfControlChars(val charValue: Int) { + CONTROL_TOP_START(0x00), + CONTROL_TOP_END(0x1F), + CONTROL_BOTTOM_START(0x7F), + CONTROL_BOTTOM_END(0x9F) +} diff --git a/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/XmlPreprocessor.kt b/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/XmlPreprocessor.kt index 2c591b35a2..b212b303b6 100644 --- a/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/XmlPreprocessor.kt +++ b/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/XmlPreprocessor.kt @@ -3,8 +3,11 @@ package ftl.reports.xml.preprocesor import org.apache.commons.text.StringEscapeUtils fun fixHtmlCodes(data: String): String { - val isoHtmlCodesToReplace = listOf(0x00..0x1F).union(listOf(0x7F..0x9F)).flatten() - .map { StringEscapeUtils.escapeXml11(it.toChar().toString()) }.filter { it.startsWith("&#") } + val isoHtmlCodesToReplace = + listOf(UtfControlChars.CONTROL_TOP_START.charValue..UtfControlChars.CONTROL_TOP_END.charValue).union( + listOf(UtfControlChars.CONTROL_BOTTOM_START.charValue..UtfControlChars.CONTROL_BOTTOM_END.charValue) + ).flatten() + .map { StringEscapeUtils.escapeXml11(it.toChar().toString()) }.filter { it.startsWith("&#") } var fixedStr = data for (isoControlCode in isoHtmlCodesToReplace) { From ee575ae651516cb178f3e1c1149e9954528efd96 Mon Sep 17 00:00:00 2001 From: Adam Date: Thu, 7 May 2020 20:48:42 +0200 Subject: [PATCH 05/20] set name of UtfControlChars enum to UtfControlCharRanges --- .../{UtfControlChars.kt => UtfControlCharRanges.kt} | 2 +- .../kotlin/ftl/reports/xml/preprocesor/XmlPreprocessor.kt | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) rename test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/{UtfControlChars.kt => UtfControlCharRanges.kt} (89%) diff --git a/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/UtfControlChars.kt b/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/UtfControlCharRanges.kt similarity index 89% rename from test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/UtfControlChars.kt rename to test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/UtfControlCharRanges.kt index 8d37889b4e..47948d1a68 100644 --- a/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/UtfControlChars.kt +++ b/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/UtfControlCharRanges.kt @@ -5,7 +5,7 @@ package ftl.reports.xml.preprocesor * and represents control chars. We need to avoid characters in ranges CONTROL_TOP_START..CONTROL_TOP_END and * CONTROL_BOTTOM_START..CONTROL_BOTTOM_END because chars from that range escaped to html causing parsing errors. * */ -enum class UtfControlChars(val charValue: Int) { +enum class UtfControlCharRanges(val charValue: Int) { CONTROL_TOP_START(0x00), CONTROL_TOP_END(0x1F), CONTROL_BOTTOM_START(0x7F), diff --git a/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/XmlPreprocessor.kt b/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/XmlPreprocessor.kt index b212b303b6..a039484874 100644 --- a/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/XmlPreprocessor.kt +++ b/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/XmlPreprocessor.kt @@ -4,8 +4,8 @@ import org.apache.commons.text.StringEscapeUtils fun fixHtmlCodes(data: String): String { val isoHtmlCodesToReplace = - listOf(UtfControlChars.CONTROL_TOP_START.charValue..UtfControlChars.CONTROL_TOP_END.charValue).union( - listOf(UtfControlChars.CONTROL_BOTTOM_START.charValue..UtfControlChars.CONTROL_BOTTOM_END.charValue) + listOf(UtfControlCharRanges.CONTROL_TOP_START.charValue..UtfControlCharRanges.CONTROL_TOP_END.charValue).union( + listOf(UtfControlCharRanges.CONTROL_BOTTOM_START.charValue..UtfControlCharRanges.CONTROL_BOTTOM_END.charValue) ).flatten() .map { StringEscapeUtils.escapeXml11(it.toChar().toString()) }.filter { it.startsWith("&#") } From b36c3b5cdbebc12998b5e37150fea616401f9cb1 Mon Sep 17 00:00:00 2001 From: Adam Date: Thu, 7 May 2020 17:15:49 +0200 Subject: [PATCH 06/20] #764 Fix crash on parse some control chars --- test_runner/build.gradle.kts | 2 + test_runner/buildSrc/src/main/kotlin/Deps.kt | 4 ++ .../main/kotlin/ftl/reports/xml/JUnitXml.kt | 28 +++++++----- .../xml/preprocesor/XmlPreprocessor.kt | 14 ++++++ .../kotlin/ftl/reports/xml/JUnitXmlTest.kt | 43 +++++++++++++++++-- 5 files changed, 77 insertions(+), 14 deletions(-) create mode 100644 test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/XmlPreprocessor.kt diff --git a/test_runner/build.gradle.kts b/test_runner/build.gradle.kts index 646ad2aaf4..c37db75413 100644 --- a/test_runner/build.gradle.kts +++ b/test_runner/build.gradle.kts @@ -213,6 +213,8 @@ dependencies { implementation(Libs.SYSTEM_RULES) testImplementation(Libs.TRUTH) testImplementation(Libs.MOCKK) + + implementation(Libs.COMMON_TEXT) } // Fix Exception in thread "main" java.lang.NoSuchMethodError: com.google.common.hash.Hashing.crc32c()Lcom/google/common/hash/HashFunction; diff --git a/test_runner/buildSrc/src/main/kotlin/Deps.kt b/test_runner/buildSrc/src/main/kotlin/Deps.kt index c445def81f..a0bb584313 100644 --- a/test_runner/buildSrc/src/main/kotlin/Deps.kt +++ b/test_runner/buildSrc/src/main/kotlin/Deps.kt @@ -74,6 +74,8 @@ object Versions { // https://github.com/mockk/mockk const val MOCKK = "1.9.3" + + const val COMMON_TEXT = "1.7" } object Libs { @@ -123,4 +125,6 @@ object Libs { const val TRUTH = "com.google.truth:truth:${Versions.TRUTH}" const val MOCKK = "io.mockk:mockk:${Versions.MOCKK}" //endregion + + const val COMMON_TEXT = "org.apache.commons:commons-text:${Versions.COMMON_TEXT}" } diff --git a/test_runner/src/main/kotlin/ftl/reports/xml/JUnitXml.kt b/test_runner/src/main/kotlin/ftl/reports/xml/JUnitXml.kt index b94676aa43..2289631f1e 100644 --- a/test_runner/src/main/kotlin/ftl/reports/xml/JUnitXml.kt +++ b/test_runner/src/main/kotlin/ftl/reports/xml/JUnitXml.kt @@ -6,16 +6,24 @@ import com.fasterxml.jackson.module.kotlin.KotlinModule import com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES import ftl.reports.xml.model.JUnitTestResult import ftl.reports.xml.model.JUnitTestSuite +import ftl.reports.xml.preprocesor.fixHtmlCodes import java.io.File +import java.nio.file.Files import java.nio.file.Path private val xmlModule = JacksonXmlModule().apply { setDefaultUseWrapper(false) } + private val xmlMapper = XmlMapper(xmlModule) .registerModules(KotlinModule()) .configure(FAIL_ON_UNKNOWN_PROPERTIES, false) internal val xmlPrettyWriter = xmlMapper.writerWithDefaultPrettyPrinter() +private fun xmlText(path: Path): String { + if (!path.toFile().exists()) throw RuntimeException("$path doesn't exist!") + return String(Files.readAllBytes(path)) +} + fun JUnitTestResult?.xmlToString(): String { if (this == null) return "" val prefix = "\n" @@ -23,29 +31,27 @@ fun JUnitTestResult?.xmlToString(): String { } fun parseOneSuiteXml(path: Path): JUnitTestResult { - return parseOneSuiteXml(path.toFile()) + return parseOneSuiteXml(xmlText(path)) } -fun parseOneSuiteXml(file: File): JUnitTestResult { - if (!file.exists()) throw RuntimeException("$file doesn't exist!") - return JUnitTestResult(mutableListOf(xmlMapper.readValue(file, JUnitTestSuite::class.java))) +fun parseOneSuiteXml(path: File): JUnitTestResult { + return parseOneSuiteXml(xmlText(path.toPath())) } fun parseOneSuiteXml(data: String): JUnitTestResult { - return JUnitTestResult(mutableListOf(xmlMapper.readValue(data, JUnitTestSuite::class.java))) + return JUnitTestResult(mutableListOf(xmlMapper.readValue(fixHtmlCodes(data), JUnitTestSuite::class.java))) } // -- fun parseAllSuitesXml(path: Path): JUnitTestResult { - return parseAllSuitesXml(path.toFile()) + return parseAllSuitesXml(xmlText(path)) } -fun parseAllSuitesXml(file: File): JUnitTestResult { - if (!file.exists()) throw RuntimeException("$file doesn't exist!") - return xmlMapper.readValue(file, JUnitTestResult::class.java) +fun parseAllSuitesXml(path: File): JUnitTestResult { + return parseAllSuitesXml(path.toPath()) } fun parseAllSuitesXml(data: String): JUnitTestResult { - return xmlMapper.readValue(data, JUnitTestResult::class.java) -} + return xmlMapper.readValue(fixHtmlCodes(data), JUnitTestResult::class.java) +} \ No newline at end of file diff --git a/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/XmlPreprocessor.kt b/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/XmlPreprocessor.kt new file mode 100644 index 0000000000..8dc28138a9 --- /dev/null +++ b/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/XmlPreprocessor.kt @@ -0,0 +1,14 @@ +package ftl.reports.xml.preprocesor + +import org.apache.commons.text.StringEscapeUtils + +fun fixHtmlCodes(data: String): String { + val isoHtmlCodesToReplace = listOf(0x00..0x1F).union(listOf(0x7F..0x9F)).flatten() + .map { StringEscapeUtils.escapeXml11(it.toChar().toString()) }.filter { it.startsWith("&#") } + + var fixedStr = data + for (isoControlCode in isoHtmlCodesToReplace) { + fixedStr = fixedStr.replace(isoControlCode, "") + } + return fixedStr +} \ No newline at end of file diff --git a/test_runner/src/test/kotlin/ftl/reports/xml/JUnitXmlTest.kt b/test_runner/src/test/kotlin/ftl/reports/xml/JUnitXmlTest.kt index 9481d3b698..0ffd4229e4 100644 --- a/test_runner/src/test/kotlin/ftl/reports/xml/JUnitXmlTest.kt +++ b/test_runner/src/test/kotlin/ftl/reports/xml/JUnitXmlTest.kt @@ -5,6 +5,7 @@ import ftl.test.util.TestHelper.normalizeLineEnding import java.nio.file.Paths import org.junit.Test + class JUnitXmlTest { companion object { @@ -73,7 +74,8 @@ junit.framework.Assert.fail(Assert.java:50) @Test fun `merge ios`() { - val merged = parseAllSuitesXml(iosPassXml).merge(parseAllSuitesXml(iosFailXml)).xmlToString().normalizeLineEnding() + val merged = + parseAllSuitesXml(iosPassXml).merge(parseAllSuitesXml(iosFailXml)).xmlToString().normalizeLineEnding() val expected = """ @@ -94,7 +96,8 @@ junit.framework.Assert.fail(Assert.java:50) @Test fun `Merge iOS large time`() { - val merged = parseAllSuitesXml(iosLargeNum).merge(parseAllSuitesXml(iosLargeNum)).xmlToString().normalizeLineEnding() + val merged = + parseAllSuitesXml(iosLargeNum).merge(parseAllSuitesXml(iosLargeNum)).xmlToString().normalizeLineEnding() val expected = """ @@ -423,7 +426,8 @@ junit.framework.Assert.fail(Assert.java:50) // * c() failed in newRun and passed in oldRun. timing info copied over from oldRun // * d() was skipped in newRun and successful in oldRun. d() is excluded from the merged result - val merged = parseAllSuitesXml(newRun).mergeTestTimes(parseAllSuitesXml(oldRun)).xmlToString().normalizeLineEnding() + val merged = + parseAllSuitesXml(newRun).mergeTestTimes(parseAllSuitesXml(oldRun)).xmlToString().normalizeLineEnding() val expected = """ @@ -437,4 +441,37 @@ junit.framework.Assert.fail(Assert.java:50) """.trimIndent() assertThat(merged).isEqualTo(expected) } + + + @Test + fun `parse ftl quirks`() { + val crashingAllSuitesMessage = """ + + + + + java.net.ConnectException: Failed to connect to ... at (Coroutine boundary.() + + + + + + """.trimIndent() + val crashingOneSuiteMessage = """ + + + + java.net.ConnectException: Failed to connect to ... at (Coroutine boundary.() + + + + + """.trimIndent() + + parseAllSuitesXml(crashingAllSuitesMessage) + parseOneSuiteXml(crashingOneSuiteMessage) + + } + } + From 9b025ac46ca994cf170665e8e36ba59c5f288a8a Mon Sep 17 00:00:00 2001 From: Adam Date: Thu, 7 May 2020 17:52:53 +0200 Subject: [PATCH 07/20] #764 detekt issues fix detekt issues fix --- .../kotlin/ftl/reports/xml/preprocesor/XmlPreprocessor.kt | 2 +- test_runner/src/test/kotlin/ftl/reports/xml/JUnitXmlTest.kt | 6 ------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/XmlPreprocessor.kt b/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/XmlPreprocessor.kt index 8dc28138a9..2c591b35a2 100644 --- a/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/XmlPreprocessor.kt +++ b/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/XmlPreprocessor.kt @@ -11,4 +11,4 @@ fun fixHtmlCodes(data: String): String { fixedStr = fixedStr.replace(isoControlCode, "") } return fixedStr -} \ No newline at end of file +} diff --git a/test_runner/src/test/kotlin/ftl/reports/xml/JUnitXmlTest.kt b/test_runner/src/test/kotlin/ftl/reports/xml/JUnitXmlTest.kt index 0ffd4229e4..10bbbb7270 100644 --- a/test_runner/src/test/kotlin/ftl/reports/xml/JUnitXmlTest.kt +++ b/test_runner/src/test/kotlin/ftl/reports/xml/JUnitXmlTest.kt @@ -5,7 +5,6 @@ import ftl.test.util.TestHelper.normalizeLineEnding import java.nio.file.Paths import org.junit.Test - class JUnitXmlTest { companion object { @@ -441,8 +440,6 @@ junit.framework.Assert.fail(Assert.java:50) """.trimIndent() assertThat(merged).isEqualTo(expected) } - - @Test fun `parse ftl quirks`() { val crashingAllSuitesMessage = """ @@ -470,8 +467,5 @@ junit.framework.Assert.fail(Assert.java:50) parseAllSuitesXml(crashingAllSuitesMessage) parseOneSuiteXml(crashingOneSuiteMessage) - } - } - From 77b574b078474da8cab3557522f8d0017aa85178 Mon Sep 17 00:00:00 2001 From: Adam Date: Thu, 7 May 2020 19:08:55 +0200 Subject: [PATCH 08/20] Asserts in tests Add asserts in test and replace Files.readString to Files.readAllBytes for compability with java 1.8 --- .../kotlin/ftl/reports/xml/JUnitXmlTest.kt | 39 +++++++++++++++++-- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/test_runner/src/test/kotlin/ftl/reports/xml/JUnitXmlTest.kt b/test_runner/src/test/kotlin/ftl/reports/xml/JUnitXmlTest.kt index 10bbbb7270..6fc3f97d5f 100644 --- a/test_runner/src/test/kotlin/ftl/reports/xml/JUnitXmlTest.kt +++ b/test_runner/src/test/kotlin/ftl/reports/xml/JUnitXmlTest.kt @@ -2,6 +2,7 @@ package ftl.reports.xml import com.google.common.truth.Truth.assertThat import ftl.test.util.TestHelper.normalizeLineEnding +import org.junit.Assert import java.nio.file.Paths import org.junit.Test @@ -440,8 +441,9 @@ junit.framework.Assert.fail(Assert.java:50) """.trimIndent() assertThat(merged).isEqualTo(expected) } + @Test - fun `parse ftl quirks`() { + fun `parse ftl quirks in all suites`() { val crashingAllSuitesMessage = """ @@ -454,6 +456,25 @@ junit.framework.Assert.fail(Assert.java:50) """.trimIndent() + + val expectedAllSuitesMessage = """ + + + + + java.net.ConnectException: Failed to connect to ... at (Coroutine boundary.() + + + + + + """.trimIndent() + val allSuitesXml = parseAllSuitesXml(crashingAllSuitesMessage).xmlToString().trimIndent() + Assert.assertEquals("All Suite Messages should be the same!", expectedAllSuitesMessage, allSuitesXml) + } + + @Test + fun `parse ftl quirks in on suite`() { val crashingOneSuiteMessage = """ @@ -465,7 +486,19 @@ junit.framework.Assert.fail(Assert.java:50) """.trimIndent() - parseAllSuitesXml(crashingAllSuitesMessage) - parseOneSuiteXml(crashingOneSuiteMessage) + val expectedOneSuiteMessage = """ + + + + + java.net.ConnectException: Failed to connect to ... at (Coroutine boundary.() + + + + + + """.trimIndent() + val oneSuiteXml = parseOneSuiteXml(crashingOneSuiteMessage).xmlToString().trimIndent() + Assert.assertEquals("One Suite Messages should be the same!", expectedOneSuiteMessage, oneSuiteXml) } } From 1ba4a77c2e1ba499c13579177b37f1252da51686 Mon Sep 17 00:00:00 2001 From: Adam Date: Thu, 7 May 2020 20:03:07 +0200 Subject: [PATCH 09/20] Add documentation of magicial numers --- .../ftl/reports/xml/preprocesor/UtfControlChars.kt | 13 +++++++++++++ .../ftl/reports/xml/preprocesor/XmlPreprocessor.kt | 7 +++++-- 2 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/UtfControlChars.kt diff --git a/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/UtfControlChars.kt b/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/UtfControlChars.kt new file mode 100644 index 0000000000..8d37889b4e --- /dev/null +++ b/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/UtfControlChars.kt @@ -0,0 +1,13 @@ +package ftl.reports.xml.preprocesor + +/** + * Numbers come from ascii table https://www.utf8-chartable.de. + * and represents control chars. We need to avoid characters in ranges CONTROL_TOP_START..CONTROL_TOP_END and + * CONTROL_BOTTOM_START..CONTROL_BOTTOM_END because chars from that range escaped to html causing parsing errors. + * */ +enum class UtfControlChars(val charValue: Int) { + CONTROL_TOP_START(0x00), + CONTROL_TOP_END(0x1F), + CONTROL_BOTTOM_START(0x7F), + CONTROL_BOTTOM_END(0x9F) +} diff --git a/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/XmlPreprocessor.kt b/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/XmlPreprocessor.kt index 2c591b35a2..b212b303b6 100644 --- a/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/XmlPreprocessor.kt +++ b/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/XmlPreprocessor.kt @@ -3,8 +3,11 @@ package ftl.reports.xml.preprocesor import org.apache.commons.text.StringEscapeUtils fun fixHtmlCodes(data: String): String { - val isoHtmlCodesToReplace = listOf(0x00..0x1F).union(listOf(0x7F..0x9F)).flatten() - .map { StringEscapeUtils.escapeXml11(it.toChar().toString()) }.filter { it.startsWith("&#") } + val isoHtmlCodesToReplace = + listOf(UtfControlChars.CONTROL_TOP_START.charValue..UtfControlChars.CONTROL_TOP_END.charValue).union( + listOf(UtfControlChars.CONTROL_BOTTOM_START.charValue..UtfControlChars.CONTROL_BOTTOM_END.charValue) + ).flatten() + .map { StringEscapeUtils.escapeXml11(it.toChar().toString()) }.filter { it.startsWith("&#") } var fixedStr = data for (isoControlCode in isoHtmlCodesToReplace) { From 795f9e296b77a3edf8461ab05f09329fd2ab7b6e Mon Sep 17 00:00:00 2001 From: Adam Date: Thu, 7 May 2020 20:48:42 +0200 Subject: [PATCH 10/20] set name of UtfControlChars enum to UtfControlCharRanges --- .../{UtfControlChars.kt => UtfControlCharRanges.kt} | 2 +- .../kotlin/ftl/reports/xml/preprocesor/XmlPreprocessor.kt | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) rename test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/{UtfControlChars.kt => UtfControlCharRanges.kt} (89%) diff --git a/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/UtfControlChars.kt b/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/UtfControlCharRanges.kt similarity index 89% rename from test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/UtfControlChars.kt rename to test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/UtfControlCharRanges.kt index 8d37889b4e..47948d1a68 100644 --- a/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/UtfControlChars.kt +++ b/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/UtfControlCharRanges.kt @@ -5,7 +5,7 @@ package ftl.reports.xml.preprocesor * and represents control chars. We need to avoid characters in ranges CONTROL_TOP_START..CONTROL_TOP_END and * CONTROL_BOTTOM_START..CONTROL_BOTTOM_END because chars from that range escaped to html causing parsing errors. * */ -enum class UtfControlChars(val charValue: Int) { +enum class UtfControlCharRanges(val charValue: Int) { CONTROL_TOP_START(0x00), CONTROL_TOP_END(0x1F), CONTROL_BOTTOM_START(0x7F), diff --git a/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/XmlPreprocessor.kt b/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/XmlPreprocessor.kt index b212b303b6..a039484874 100644 --- a/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/XmlPreprocessor.kt +++ b/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/XmlPreprocessor.kt @@ -4,8 +4,8 @@ import org.apache.commons.text.StringEscapeUtils fun fixHtmlCodes(data: String): String { val isoHtmlCodesToReplace = - listOf(UtfControlChars.CONTROL_TOP_START.charValue..UtfControlChars.CONTROL_TOP_END.charValue).union( - listOf(UtfControlChars.CONTROL_BOTTOM_START.charValue..UtfControlChars.CONTROL_BOTTOM_END.charValue) + listOf(UtfControlCharRanges.CONTROL_TOP_START.charValue..UtfControlCharRanges.CONTROL_TOP_END.charValue).union( + listOf(UtfControlCharRanges.CONTROL_BOTTOM_START.charValue..UtfControlCharRanges.CONTROL_BOTTOM_END.charValue) ).flatten() .map { StringEscapeUtils.escapeXml11(it.toChar().toString()) }.filter { it.startsWith("&#") } From 58074c3d77246403b8a1cd85e576666d82b2eec3 Mon Sep 17 00:00:00 2001 From: Adam Date: Thu, 7 May 2020 20:56:02 +0200 Subject: [PATCH 11/20] Detekt suggestions --- test_runner/src/main/kotlin/ftl/reports/xml/JUnitXml.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_runner/src/main/kotlin/ftl/reports/xml/JUnitXml.kt b/test_runner/src/main/kotlin/ftl/reports/xml/JUnitXml.kt index 2289631f1e..0211157adb 100644 --- a/test_runner/src/main/kotlin/ftl/reports/xml/JUnitXml.kt +++ b/test_runner/src/main/kotlin/ftl/reports/xml/JUnitXml.kt @@ -54,4 +54,4 @@ fun parseAllSuitesXml(path: File): JUnitTestResult { fun parseAllSuitesXml(data: String): JUnitTestResult { return xmlMapper.readValue(fixHtmlCodes(data), JUnitTestResult::class.java) -} \ No newline at end of file +} From 4a484aa916de09597d0745c06a934f2ba140b3e5 Mon Sep 17 00:00:00 2001 From: Adam Date: Thu, 7 May 2020 20:56:22 +0200 Subject: [PATCH 12/20] Create should_exists.txt --- test_runner/should_exists.txt | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 test_runner/should_exists.txt diff --git a/test_runner/should_exists.txt b/test_runner/should_exists.txt new file mode 100644 index 0000000000..e69de29bb2 From 2e9f92507464f95e1782355ec9a8c80b3db4c841 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20G=C3=B3ral?= <60390247+jan-gogo@users.noreply.github.com> Date: Thu, 7 May 2020 22:36:52 +0200 Subject: [PATCH 13/20] Fail fast when results-dir is incorrect (#772) * Fail fast when results-dir is incorrect --- release_notes.md | 1 + .../src/main/kotlin/ftl/args/AndroidArgs.kt | 2 +- .../ftl/run/platform/common/BeforeRunTests.kt | 4 ++-- .../test/kotlin/ftl/args/AndroidArgsTest.kt | 18 ++++++++++++++---- 4 files changed, 18 insertions(+), 7 deletions(-) diff --git a/release_notes.md b/release_notes.md index 85d9aa6eca..f21510da90 100644 --- a/release_notes.md +++ b/release_notes.md @@ -1,4 +1,5 @@ ## next (unreleased) +- [#772](https://github.com/Flank/flank/pull/772) Fail fast when results-dir is incorrect. ([jan-gogo](https://github.com/jan-gogo)) - [#757](https://github.com/Flank/flank/pull/767) Reduce memory usage by using Reader and Writer instead of ByteArrays. ([jan-gogo](https://github.com/jan-gogo)) - [#763](https://github.com/Flank/flank/pull/763) Use "localhost" as default for hostname to fix backward compatibility. ([jan-gogo](https://github.com/jan-gogo)) - [#757](https://github.com/Flank/flank/pull/757) Print version and revision before each command. ([jan-gogo](https://github.com/jan-gogo)) diff --git a/test_runner/src/main/kotlin/ftl/args/AndroidArgs.kt b/test_runner/src/main/kotlin/ftl/args/AndroidArgs.kt index dfb93ddb1a..27452176aa 100644 --- a/test_runner/src/main/kotlin/ftl/args/AndroidArgs.kt +++ b/test_runner/src/main/kotlin/ftl/args/AndroidArgs.kt @@ -45,7 +45,7 @@ class AndroidArgs( ) : IArgs { private val gcloud = gcloudYml.gcloud override val resultsBucket: String - override val resultsDir = cli?.resultsDir ?: gcloud.resultsDir + override val resultsDir = (cli?.resultsDir ?: gcloud.resultsDir)?.also { assertFileExists(it, "from results-dir") } override val recordVideo = cli?.recordVideo ?: cli?.noRecordVideo?.not() ?: gcloud.recordVideo override val testTimeout = cli?.timeout ?: gcloud.timeout override val async = cli?.async ?: gcloud.async diff --git a/test_runner/src/main/kotlin/ftl/run/platform/common/BeforeRunTests.kt b/test_runner/src/main/kotlin/ftl/run/platform/common/BeforeRunTests.kt index 2006f2e95c..ece234abb7 100644 --- a/test_runner/src/main/kotlin/ftl/run/platform/common/BeforeRunTests.kt +++ b/test_runner/src/main/kotlin/ftl/run/platform/common/BeforeRunTests.kt @@ -18,7 +18,7 @@ internal fun beforeRunTests(args: IArgs): Pair { // Avoid spamming the results/ dir with temporary files from running the test suite. if (FtlConstants.useMock) - deleteMockResultDirOnShotDown(args, runGcsPath) + deleteMockResultDirOnShutDown(args, runGcsPath) if (args.useLocalResultDir()) { // Only one result is stored when using --local-result-dir @@ -36,7 +36,7 @@ private fun assertMockUrl() { if (!GcToolResults.service.rootUrl.contains(FtlConstants.localhost)) throw RuntimeException("expected localhost in GcToolResults") } -private fun deleteMockResultDirOnShotDown(args: IArgs, runGcsPath: String) { +private fun deleteMockResultDirOnShutDown(args: IArgs, runGcsPath: String) { Runtime.getRuntime().addShutdownHook(Thread { File(args.localResultDir, runGcsPath).deleteRecursively() }) diff --git a/test_runner/src/test/kotlin/ftl/args/AndroidArgsTest.kt b/test_runner/src/test/kotlin/ftl/args/AndroidArgsTest.kt index d07981606d..34a73e6bcd 100644 --- a/test_runner/src/test/kotlin/ftl/args/AndroidArgsTest.kt +++ b/test_runner/src/test/kotlin/ftl/args/AndroidArgsTest.kt @@ -969,20 +969,30 @@ AndroidArgs assertThat(AndroidArgs.load(yaml, cli).testTargetsAlwaysRun).isEqualTo(arrayListOf("com.A", "com.B")) } + @Test(expected = FlankFatalError::class) + fun `cli resultsDir fail if not exist`() { + val yaml = """ + gcloud: + app: $appApk + test: $testApk + results-dir: not_exist + """ + AndroidArgs.load(yaml) + } @Test fun `cli resultsDir`() { val cli = AndroidRunCommand() - CommandLine(cli).parseArgs("--results-dir=b") + CommandLine(cli).parseArgs("--results-dir=build") val yaml = """ gcloud: app: $appApk test: $testApk - results-dir: a + results-dir: results """ - assertThat(AndroidArgs.load(yaml).resultsDir).isEqualTo("a") - assertThat(AndroidArgs.load(yaml, cli).resultsDir).isEqualTo("b") + assertThat(AndroidArgs.load(yaml).resultsDir).isEqualTo("results") + assertThat(AndroidArgs.load(yaml, cli).resultsDir).isEqualTo("build") } @Test From da1fa2af18512a25a8609feba03b880b056f9f5f Mon Sep 17 00:00:00 2001 From: Adam Date: Thu, 7 May 2020 17:15:49 +0200 Subject: [PATCH 14/20] #764 Fix crash on parse some control chars --- test_runner/src/main/kotlin/ftl/reports/xml/JUnitXml.kt | 3 +++ .../kotlin/ftl/reports/xml/preprocesor/XmlPreprocessor.kt | 2 +- .../src/test/kotlin/ftl/reports/xml/JUnitXmlTest.kt | 7 +++++++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/test_runner/src/main/kotlin/ftl/reports/xml/JUnitXml.kt b/test_runner/src/main/kotlin/ftl/reports/xml/JUnitXml.kt index 0211157adb..ada4441dff 100644 --- a/test_runner/src/main/kotlin/ftl/reports/xml/JUnitXml.kt +++ b/test_runner/src/main/kotlin/ftl/reports/xml/JUnitXml.kt @@ -11,6 +11,7 @@ import java.io.File import java.nio.file.Files import java.nio.file.Path + private val xmlModule = JacksonXmlModule().apply { setDefaultUseWrapper(false) } private val xmlMapper = XmlMapper(xmlModule) @@ -19,6 +20,7 @@ private val xmlMapper = XmlMapper(xmlModule) internal val xmlPrettyWriter = xmlMapper.writerWithDefaultPrettyPrinter() + private fun xmlText(path: Path): String { if (!path.toFile().exists()) throw RuntimeException("$path doesn't exist!") return String(Files.readAllBytes(path)) @@ -44,6 +46,7 @@ fun parseOneSuiteXml(data: String): JUnitTestResult { // -- + fun parseAllSuitesXml(path: Path): JUnitTestResult { return parseAllSuitesXml(xmlText(path)) } diff --git a/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/XmlPreprocessor.kt b/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/XmlPreprocessor.kt index a039484874..b9e012b710 100644 --- a/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/XmlPreprocessor.kt +++ b/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/XmlPreprocessor.kt @@ -8,10 +8,10 @@ fun fixHtmlCodes(data: String): String { listOf(UtfControlCharRanges.CONTROL_BOTTOM_START.charValue..UtfControlCharRanges.CONTROL_BOTTOM_END.charValue) ).flatten() .map { StringEscapeUtils.escapeXml11(it.toChar().toString()) }.filter { it.startsWith("&#") } - var fixedStr = data for (isoControlCode in isoHtmlCodesToReplace) { fixedStr = fixedStr.replace(isoControlCode, "") } return fixedStr } + diff --git a/test_runner/src/test/kotlin/ftl/reports/xml/JUnitXmlTest.kt b/test_runner/src/test/kotlin/ftl/reports/xml/JUnitXmlTest.kt index 6fc3f97d5f..263d373a10 100644 --- a/test_runner/src/test/kotlin/ftl/reports/xml/JUnitXmlTest.kt +++ b/test_runner/src/test/kotlin/ftl/reports/xml/JUnitXmlTest.kt @@ -6,6 +6,7 @@ import org.junit.Assert import java.nio.file.Paths import org.junit.Test + class JUnitXmlTest { companion object { @@ -442,8 +443,11 @@ junit.framework.Assert.fail(Assert.java:50) assertThat(merged).isEqualTo(expected) } + @Test fun `parse ftl quirks in all suites`() { + + val crashingAllSuitesMessage = """ @@ -457,6 +461,7 @@ junit.framework.Assert.fail(Assert.java:50) """.trimIndent() + val expectedAllSuitesMessage = """ @@ -486,6 +491,7 @@ junit.framework.Assert.fail(Assert.java:50) """.trimIndent() + val expectedOneSuiteMessage = """ @@ -502,3 +508,4 @@ junit.framework.Assert.fail(Assert.java:50) Assert.assertEquals("One Suite Messages should be the same!", expectedOneSuiteMessage, oneSuiteXml) } } + From dfd80fb672a8b11e2fa71d8e7789605944428f6b Mon Sep 17 00:00:00 2001 From: Adam Date: Thu, 7 May 2020 17:52:53 +0200 Subject: [PATCH 15/20] #764 detekt issues fix detekt issues fix --- test_runner/src/main/kotlin/ftl/reports/xml/JUnitXml.kt | 3 --- .../kotlin/ftl/reports/xml/preprocesor/XmlPreprocessor.kt | 1 - test_runner/src/test/kotlin/ftl/reports/xml/JUnitXmlTest.kt | 6 +----- 3 files changed, 1 insertion(+), 9 deletions(-) diff --git a/test_runner/src/main/kotlin/ftl/reports/xml/JUnitXml.kt b/test_runner/src/main/kotlin/ftl/reports/xml/JUnitXml.kt index ada4441dff..0211157adb 100644 --- a/test_runner/src/main/kotlin/ftl/reports/xml/JUnitXml.kt +++ b/test_runner/src/main/kotlin/ftl/reports/xml/JUnitXml.kt @@ -11,7 +11,6 @@ import java.io.File import java.nio.file.Files import java.nio.file.Path - private val xmlModule = JacksonXmlModule().apply { setDefaultUseWrapper(false) } private val xmlMapper = XmlMapper(xmlModule) @@ -20,7 +19,6 @@ private val xmlMapper = XmlMapper(xmlModule) internal val xmlPrettyWriter = xmlMapper.writerWithDefaultPrettyPrinter() - private fun xmlText(path: Path): String { if (!path.toFile().exists()) throw RuntimeException("$path doesn't exist!") return String(Files.readAllBytes(path)) @@ -46,7 +44,6 @@ fun parseOneSuiteXml(data: String): JUnitTestResult { // -- - fun parseAllSuitesXml(path: Path): JUnitTestResult { return parseAllSuitesXml(xmlText(path)) } diff --git a/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/XmlPreprocessor.kt b/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/XmlPreprocessor.kt index b9e012b710..bbb0dbfab4 100644 --- a/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/XmlPreprocessor.kt +++ b/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/XmlPreprocessor.kt @@ -14,4 +14,3 @@ fun fixHtmlCodes(data: String): String { } return fixedStr } - diff --git a/test_runner/src/test/kotlin/ftl/reports/xml/JUnitXmlTest.kt b/test_runner/src/test/kotlin/ftl/reports/xml/JUnitXmlTest.kt index 263d373a10..c173dd2450 100644 --- a/test_runner/src/test/kotlin/ftl/reports/xml/JUnitXmlTest.kt +++ b/test_runner/src/test/kotlin/ftl/reports/xml/JUnitXmlTest.kt @@ -6,7 +6,6 @@ import org.junit.Assert import java.nio.file.Paths import org.junit.Test - class JUnitXmlTest { companion object { @@ -442,8 +441,6 @@ junit.framework.Assert.fail(Assert.java:50) """.trimIndent() assertThat(merged).isEqualTo(expected) } - - @Test fun `parse ftl quirks in all suites`() { @@ -491,7 +488,6 @@ junit.framework.Assert.fail(Assert.java:50) """.trimIndent() - val expectedOneSuiteMessage = """ @@ -506,6 +502,6 @@ junit.framework.Assert.fail(Assert.java:50) """.trimIndent() val oneSuiteXml = parseOneSuiteXml(crashingOneSuiteMessage).xmlToString().trimIndent() Assert.assertEquals("One Suite Messages should be the same!", expectedOneSuiteMessage, oneSuiteXml) + } } - From 793b97e4eb0aa4012985e369f664f4196286a09c Mon Sep 17 00:00:00 2001 From: Adam Date: Thu, 7 May 2020 19:08:55 +0200 Subject: [PATCH 16/20] Asserts in tests Add asserts in test and replace Files.readString to Files.readAllBytes for compability with java 1.8 --- test_runner/src/test/kotlin/ftl/reports/xml/JUnitXmlTest.kt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test_runner/src/test/kotlin/ftl/reports/xml/JUnitXmlTest.kt b/test_runner/src/test/kotlin/ftl/reports/xml/JUnitXmlTest.kt index c173dd2450..b664bbe79a 100644 --- a/test_runner/src/test/kotlin/ftl/reports/xml/JUnitXmlTest.kt +++ b/test_runner/src/test/kotlin/ftl/reports/xml/JUnitXmlTest.kt @@ -441,10 +441,9 @@ junit.framework.Assert.fail(Assert.java:50) """.trimIndent() assertThat(merged).isEqualTo(expected) } + @Test fun `parse ftl quirks in all suites`() { - - val crashingAllSuitesMessage = """ @@ -458,7 +457,6 @@ junit.framework.Assert.fail(Assert.java:50) """.trimIndent() - val expectedAllSuitesMessage = """ From 6f8fc9eef8229d9ab814bb0390512e8a124d6232 Mon Sep 17 00:00:00 2001 From: Adam Date: Thu, 7 May 2020 20:03:07 +0200 Subject: [PATCH 17/20] Add documentation of magicial numers --- .../ftl/reports/xml/preprocesor/UtfControlChars.kt | 13 +++++++++++++ .../ftl/reports/xml/preprocesor/XmlPreprocessor.kt | 1 + 2 files changed, 14 insertions(+) create mode 100644 test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/UtfControlChars.kt diff --git a/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/UtfControlChars.kt b/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/UtfControlChars.kt new file mode 100644 index 0000000000..8d37889b4e --- /dev/null +++ b/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/UtfControlChars.kt @@ -0,0 +1,13 @@ +package ftl.reports.xml.preprocesor + +/** + * Numbers come from ascii table https://www.utf8-chartable.de. + * and represents control chars. We need to avoid characters in ranges CONTROL_TOP_START..CONTROL_TOP_END and + * CONTROL_BOTTOM_START..CONTROL_BOTTOM_END because chars from that range escaped to html causing parsing errors. + * */ +enum class UtfControlChars(val charValue: Int) { + CONTROL_TOP_START(0x00), + CONTROL_TOP_END(0x1F), + CONTROL_BOTTOM_START(0x7F), + CONTROL_BOTTOM_END(0x9F) +} diff --git a/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/XmlPreprocessor.kt b/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/XmlPreprocessor.kt index bbb0dbfab4..a039484874 100644 --- a/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/XmlPreprocessor.kt +++ b/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/XmlPreprocessor.kt @@ -8,6 +8,7 @@ fun fixHtmlCodes(data: String): String { listOf(UtfControlCharRanges.CONTROL_BOTTOM_START.charValue..UtfControlCharRanges.CONTROL_BOTTOM_END.charValue) ).flatten() .map { StringEscapeUtils.escapeXml11(it.toChar().toString()) }.filter { it.startsWith("&#") } + var fixedStr = data for (isoControlCode in isoHtmlCodesToReplace) { fixedStr = fixedStr.replace(isoControlCode, "") From 5350fc3b96c0f23b0ce80e3d5f812e9a5a4b20c1 Mon Sep 17 00:00:00 2001 From: Adam Date: Thu, 7 May 2020 20:48:42 +0200 Subject: [PATCH 18/20] set name of UtfControlChars enum to UtfControlCharRanges --- .../ftl/reports/xml/preprocesor/UtfControlChars.kt | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/UtfControlChars.kt diff --git a/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/UtfControlChars.kt b/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/UtfControlChars.kt deleted file mode 100644 index 8d37889b4e..0000000000 --- a/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/UtfControlChars.kt +++ /dev/null @@ -1,13 +0,0 @@ -package ftl.reports.xml.preprocesor - -/** - * Numbers come from ascii table https://www.utf8-chartable.de. - * and represents control chars. We need to avoid characters in ranges CONTROL_TOP_START..CONTROL_TOP_END and - * CONTROL_BOTTOM_START..CONTROL_BOTTOM_END because chars from that range escaped to html causing parsing errors. - * */ -enum class UtfControlChars(val charValue: Int) { - CONTROL_TOP_START(0x00), - CONTROL_TOP_END(0x1F), - CONTROL_BOTTOM_START(0x7F), - CONTROL_BOTTOM_END(0x9F) -} From df19d79a2ec5899d78de4b0d0565560213719f67 Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 8 May 2020 13:28:22 +0200 Subject: [PATCH 19/20] #764 Change XmlPreprocessor more functional and remove should_exists --- test_runner/buildSrc/src/main/kotlin/Deps.kt | 3 ++- test_runner/should_exists.txt | 0 .../xml/preprocesor/XmlPreprocessor.kt | 20 +++++++------------ .../kotlin/ftl/reports/xml/JUnitXmlTest.kt | 1 - 4 files changed, 9 insertions(+), 15 deletions(-) delete mode 100644 test_runner/should_exists.txt diff --git a/test_runner/buildSrc/src/main/kotlin/Deps.kt b/test_runner/buildSrc/src/main/kotlin/Deps.kt index a0bb584313..2f6cbc2020 100644 --- a/test_runner/buildSrc/src/main/kotlin/Deps.kt +++ b/test_runner/buildSrc/src/main/kotlin/Deps.kt @@ -75,7 +75,8 @@ object Versions { // https://github.com/mockk/mockk const val MOCKK = "1.9.3" - const val COMMON_TEXT = "1.7" + //https://commons.apache.org/proper/commons-text/ + const val COMMON_TEXT = "1.8" } object Libs { diff --git a/test_runner/should_exists.txt b/test_runner/should_exists.txt deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/XmlPreprocessor.kt b/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/XmlPreprocessor.kt index a039484874..288dba1e23 100644 --- a/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/XmlPreprocessor.kt +++ b/test_runner/src/main/kotlin/ftl/reports/xml/preprocesor/XmlPreprocessor.kt @@ -2,16 +2,10 @@ package ftl.reports.xml.preprocesor import org.apache.commons.text.StringEscapeUtils -fun fixHtmlCodes(data: String): String { - val isoHtmlCodesToReplace = - listOf(UtfControlCharRanges.CONTROL_TOP_START.charValue..UtfControlCharRanges.CONTROL_TOP_END.charValue).union( - listOf(UtfControlCharRanges.CONTROL_BOTTOM_START.charValue..UtfControlCharRanges.CONTROL_BOTTOM_END.charValue) - ).flatten() - .map { StringEscapeUtils.escapeXml11(it.toChar().toString()) }.filter { it.startsWith("&#") } - - var fixedStr = data - for (isoControlCode in isoHtmlCodesToReplace) { - fixedStr = fixedStr.replace(isoControlCode, "") - } - return fixedStr -} +fun fixHtmlCodes(data: String): String = listOf( + UtfControlCharRanges.CONTROL_TOP_START.charValue..UtfControlCharRanges.CONTROL_TOP_END.charValue, + UtfControlCharRanges.CONTROL_BOTTOM_START.charValue..UtfControlCharRanges.CONTROL_BOTTOM_END.charValue +).flatten() + .map { StringEscapeUtils.escapeXml11(it.toChar().toString()) } + .filter { it.startsWith("&#") } + .fold(data) { fixedStr: String, isoControlCode: String -> fixedStr.replace(isoControlCode, "") } diff --git a/test_runner/src/test/kotlin/ftl/reports/xml/JUnitXmlTest.kt b/test_runner/src/test/kotlin/ftl/reports/xml/JUnitXmlTest.kt index b664bbe79a..6fc3f97d5f 100644 --- a/test_runner/src/test/kotlin/ftl/reports/xml/JUnitXmlTest.kt +++ b/test_runner/src/test/kotlin/ftl/reports/xml/JUnitXmlTest.kt @@ -500,6 +500,5 @@ junit.framework.Assert.fail(Assert.java:50) """.trimIndent() val oneSuiteXml = parseOneSuiteXml(crashingOneSuiteMessage).xmlToString().trimIndent() Assert.assertEquals("One Suite Messages should be the same!", expectedOneSuiteMessage, oneSuiteXml) - } } From 6c604534ceb1b068376a09238fec1202f43e3156 Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 8 May 2020 13:53:09 +0200 Subject: [PATCH 20/20] Add info about issue to release notes --- release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/release_notes.md b/release_notes.md index f21510da90..ba6587ad77 100644 --- a/release_notes.md +++ b/release_notes.md @@ -1,4 +1,5 @@ ## next (unreleased) +- [#764](https://github.com/Flank/flank/pull/771) Fix crash on parse some control chars. ([adamfilipow92](https://github.com/adamfilipow92)) - [#772](https://github.com/Flank/flank/pull/772) Fail fast when results-dir is incorrect. ([jan-gogo](https://github.com/jan-gogo)) - [#757](https://github.com/Flank/flank/pull/767) Reduce memory usage by using Reader and Writer instead of ByteArrays. ([jan-gogo](https://github.com/jan-gogo)) - [#763](https://github.com/Flank/flank/pull/763) Use "localhost" as default for hostname to fix backward compatibility. ([jan-gogo](https://github.com/jan-gogo))