From 53197950a4ca1260e435484d633a97614e48ea7c Mon Sep 17 00:00:00 2001 From: Christopher Perry Date: Thu, 19 Apr 2018 00:36:03 -0700 Subject: [PATCH] Fix Logcat Parsing (#133) * Fix Logcat Parsing --- .../kotlin/com/gojuno/composer/TestRun.kt | 25 ++++--- .../com/gojuno/composer/LogLineParserSpec.kt | 69 +++++++++++++++++++ 2 files changed, 85 insertions(+), 9 deletions(-) create mode 100644 composer/src/test/kotlin/com/gojuno/composer/LogLineParserSpec.kt diff --git a/composer/src/main/kotlin/com/gojuno/composer/TestRun.kt b/composer/src/main/kotlin/com/gojuno/composer/TestRun.kt index ce88529..4a845cd 100644 --- a/composer/src/main/kotlin/com/gojuno/composer/TestRun.kt +++ b/composer/src/main/kotlin/com/gojuno/composer/TestRun.kt @@ -181,6 +181,20 @@ private fun pullTestFiles(adbDevice: AdbDevice, test: InstrumentationTest, outpu ) } +internal fun String.parseTestClassAndName(): Pair? { + val index = indexOf("TestRunner") + if (index < 0) return null + + val tokens = substring(index, length).split(':') + if (tokens.size != 3) return null + + val startedOrFinished = tokens[1].trimStart() + if (startedOrFinished == "started" || startedOrFinished == "finished") { + return tokens[2].substringAfter("(").removeSuffix(")") to tokens[2].substringBefore("(").trim() + } + return null +} + private fun saveLogcat(adbDevice: AdbDevice, logsDir: File): Observable> = Observable .just(logsDir to logcatFileForDevice(logsDir)) .flatMap { (logsDir, fullLogcatFile) -> adbDevice.redirectLogcatToFile(fullLogcatFile).toObservable().map { logsDir to fullLogcatFile } } @@ -194,17 +208,10 @@ private fun saveLogcat(adbDevice: AdbDevice, logsDir: File): Observable "${previous.logcat}\n$newline" } - fun String.parseTestClassAndName(prefix: String): Pair? = this.substringAfter(prefix, missingDelimiterValue = "").let { - when (it) { - "" -> null - else -> it.substringAfter("(").removeSuffix(")") to it.substringBefore("(") - } - } - // Implicitly expecting to see logs from `android.support.test.internal.runner.listener.LogRunListener`. // Was not able to find more reliable solution to capture logcat per test. - val startedTest: Pair? = newline.parseTestClassAndName("TestRunner: started: ") - val finishedTest: Pair? = newline.parseTestClassAndName("TestRunner: finished: ") + val startedTest: Pair? = newline.parseTestClassAndName() + val finishedTest: Pair? = newline.parseTestClassAndName() result( logcat = logcat, diff --git a/composer/src/test/kotlin/com/gojuno/composer/LogLineParserSpec.kt b/composer/src/test/kotlin/com/gojuno/composer/LogLineParserSpec.kt new file mode 100644 index 0000000..575142e --- /dev/null +++ b/composer/src/test/kotlin/com/gojuno/composer/LogLineParserSpec.kt @@ -0,0 +1,69 @@ +package com.gojuno.composer + +import org.assertj.core.api.Assertions.assertThat +import org.jetbrains.spek.api.Spek +import org.jetbrains.spek.api.dsl.context +import org.jetbrains.spek.api.dsl.it + +class LogLineParserSpec : Spek({ + + context("parse TestRunner log line with long prefix") { + + context("parse started log") { + val args by memoized { + "04-06 00:25:49.747 28632 28650 I TestRunner: started: someTestMethod(com.example.SampleClass)".parseTestClassAndName() + } + + it("extracts test class and method") { + assertThat(args).isEqualTo("com.example.SampleClass" to "someTestMethod") + } + } + + context("parse finished log") { + val args by memoized { + "04-06 00:25:49.747 28632 28650 I TestRunner: finished: someTestMethod(com.example.SampleClass)".parseTestClassAndName() + } + + it("extracts test class and method") { + assertThat(args).isEqualTo("com.example.SampleClass" to "someTestMethod") + } + } + } + + context("parse TestRunner log line with short prefix") { + + context("parse started log") { + + val args by memoized { + "I/TestRunner( 123): started: someTestMethod(com.example.SampleClass)".parseTestClassAndName() + } + + it("extracts test class and method") { + assertThat(args).isEqualTo("com.example.SampleClass" to "someTestMethod") + } + } + + context("parse finished log") { + + val args by memoized { + "I/TestRunner( 123): finished: someTestMethod(com.example.SampleClass)".parseTestClassAndName() + } + + it("extracts test class and method") { + assertThat(args).isEqualTo("com.example.SampleClass" to "someTestMethod") + } + } + } + + context("parse non TestRunner started/finished logs") { + + it("does not parse empty log") { + assertThat("".parseTestClassAndName()).isNull() + } + + it("does not parse TestRunner logs without started/finished") { + assertThat("I/TestRunner( 123):".parseTestClassAndName()).isNull() + assertThat("04-06 00:25:49.747 28632 28650 I TestRunner:".parseTestClassAndName()).isNull() + } + } +}) \ No newline at end of file