Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Fix crash on parse some control chars
  • Loading branch information
adamfilipow92 committed May 7, 2020
1 parent 39282ec commit f182c8c
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 17 deletions.
2 changes: 2 additions & 0 deletions test_runner/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 4 additions & 0 deletions test_runner/buildSrc/src/main/kotlin/Deps.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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}"
}
24 changes: 10 additions & 14 deletions test_runner/src/main/kotlin/ftl/reports/xml/JUnitXml.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,23 @@ 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 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 {
Expand All @@ -28,36 +31,29 @@ 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 {
return parseAllSuitesXml(path.toPath())
}

fun parseAllSuitesXml(data: String): JUnitTestResult {
return parseAllSuitesXml(data.toByteArray())
return xmlMapper.readValue(fixHtmlCodes(data), JUnitTestResult::class.java)
}
Original file line number Diff line number Diff line change
@@ -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
}
43 changes: 40 additions & 3 deletions test_runner/src/test/kotlin/ftl/reports/xml/JUnitXmlTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import ftl.test.util.TestHelper.normalizeLineEnding
import java.nio.file.Paths
import org.junit.Test


class JUnitXmlTest {

companion object {
Expand Down Expand Up @@ -73,7 +74,8 @@ junit.framework.Assert.fail(Assert.java:50)</failure>

@Test
fun `merge ios`() {
val merged = parseAllSuitesXml(iosPassXml).merge(parseAllSuitesXml(iosFailXml)).xmlToString().normalizeLineEnding()
val merged =
parseAllSuitesXml(iosPassXml).merge(parseAllSuitesXml(iosFailXml)).xmlToString().normalizeLineEnding()
val expected = """
<?xml version='1.0' encoding='UTF-8' ?>
<testsuites>
Expand All @@ -94,7 +96,8 @@ junit.framework.Assert.fail(Assert.java:50)</failure>

@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 = """
<?xml version='1.0' encoding='UTF-8' ?>
Expand Down Expand Up @@ -423,7 +426,8 @@ junit.framework.Assert.fail(Assert.java:50)</failure>
// * 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 = """
<?xml version='1.0' encoding='UTF-8' ?>
<testsuites>
Expand All @@ -437,4 +441,37 @@ junit.framework.Assert.fail(Assert.java:50)</failure>
""".trimIndent()
assertThat(merged).isEqualTo(expected)
}


@Test
fun `parse ftl quirks`() {
val crashingAllSuitesMessage = """
<?xml version='1.0' encoding='UTF-8' ?>
<testsuites>
<testsuite name="EarlGreyExampleSwiftTests" tests="3" failures="0" errors="0" skipped="0" time="10.0" hostname="localhost">
<testcase name="a()" classname="a" time="1.0">
<failure> java.net.ConnectException: Failed to connect to ... at &#8;&#8;&#8;(Coroutine boundary.&#8;(&#8;)</failure>
</testcase>
<testcase name="b()" classname="b" time="2.0"/>
<testcase name="c()" classname="c" time="7.0"/>
</testsuite>
</testsuites>
""".trimIndent()
val crashingOneSuiteMessage = """
<?xml version='1.0' encoding='UTF-8' ?>
<testsuite name="EarlGreyExampleSwiftTests" tests="3" failures="0" errors="0" skipped="0" time="10.0" hostname="localhost">
<testcase name="a()" classname="a" time="1.0">
<failure> java.net.ConnectException: Failed to connect to ... at &#8;&#8;&#8;(Coroutine boundary.&#8;(&#8;)</failure>
</testcase>
<testcase name="b()" classname="b" time="2.0"/>
<testcase name="c()" classname="c" time="7.0"/>
</testsuite>
""".trimIndent()

parseAllSuitesXml(crashingAllSuitesMessage)
parseOneSuiteXml(crashingOneSuiteMessage)

}

}

0 comments on commit f182c8c

Please sign in to comment.