From 1e07abaf01ff5af6e6d4edab68546b9824905fbe Mon Sep 17 00:00:00 2001 From: Evgenii Matsiuk Date: Mon, 11 Dec 2023 17:58:24 +0300 Subject: [PATCH 1/3] fix(android_parsing): remote parse without overridden testrun listener if a user forgot to add the correspondent dependency in the project --- .../android/adam/AmInstrumentTestParser.kt | 26 +++++++++++++++---- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/vendor/vendor-android/src/main/kotlin/com/malinskiy/marathon/android/adam/AmInstrumentTestParser.kt b/vendor/vendor-android/src/main/kotlin/com/malinskiy/marathon/android/adam/AmInstrumentTestParser.kt index d60ded19a..79f71307f 100644 --- a/vendor/vendor-android/src/main/kotlin/com/malinskiy/marathon/android/adam/AmInstrumentTestParser.kt +++ b/vendor/vendor-android/src/main/kotlin/com/malinskiy/marathon/android/adam/AmInstrumentTestParser.kt @@ -32,6 +32,8 @@ import kotlinx.coroutines.CancellationException import kotlinx.coroutines.NonCancellable.isActive import kotlinx.coroutines.withTimeoutOrNull +private const val LISTENER_ARGUMENT = "listener" + class AmInstrumentTestParser( private val configuration: Configuration, private val testBundleIdentifier: AndroidTestBundleIdentifier, @@ -42,15 +44,22 @@ class AmInstrumentTestParser( override suspend fun extract(device: Device): List { val testBundles = vendorConfiguration.testBundlesCompat() + var blockListenerArgumentOverride = false return withRetry(3, 0) { try { val device = device as? AdamAndroidDevice ?: throw ConfigurationException("Unexpected device type for remote test parsing") - return@withRetry parseTests(device, configuration, vendorConfiguration, testBundles) + return@withRetry parseTests(device, configuration, vendorConfiguration, testBundles, blockListenerArgumentOverride) } catch (e: CancellationException) { throw e - } catch (e: Exception) { - logger.debug(e) { "Remote parsing failed. Retrying" } + } catch (e: PossibleListenerIssueException) { + logger.warn { "The previous parse operation failed. The most possible reason is " + + "a developer missed this step https://docs.marathonlabs.io/android/configure#test-parser. " + + "The next attempt will be done without overridden testrun listener." } + blockListenerArgumentOverride = true throw e + } catch (throwable: Throwable) { + logger.debug(throwable) { "Remote parsing failed. Retrying" } + throw throwable } } } @@ -59,7 +68,8 @@ class AmInstrumentTestParser( device: AdamAndroidDevice, configuration: Configuration, vendorConfiguration: VendorConfiguration.AndroidConfiguration, - testBundles: List + testBundles: List, + blockListenerArgumentOverride: Boolean, ): List { return testBundles.flatMap { bundle -> val androidTestBundle = @@ -68,7 +78,10 @@ class AmInstrumentTestParser( val testParserConfiguration = vendorConfiguration.testParserConfiguration val overrides: Map = when { - testParserConfiguration is TestParserConfiguration.RemoteTestParserConfiguration -> testParserConfiguration.instrumentationArgs + testParserConfiguration is TestParserConfiguration.RemoteTestParserConfiguration -> { + if (blockListenerArgumentOverride) testParserConfiguration.instrumentationArgs.filterKeys { it != LISTENER_ARGUMENT } + else testParserConfiguration.instrumentationArgs + } else -> emptyMap() } @@ -125,9 +138,12 @@ class AmInstrumentTestParser( "Bundle ${bundle.id} did not report any test annotations. If you need test annotations retrieval, remote test parser requires additional setup " + "see https://docs.marathonlabs.io/android/configure#test-parser" } + if (overrides.containsKey(LISTENER_ARGUMENT)) throw PossibleListenerIssueException() } tests } } } + +private class PossibleListenerIssueException : RuntimeException() From 352a49d9ca3ce7c9cb5cb8bde223a2710d38bdf0 Mon Sep 17 00:00:00 2001 From: Evgenii Matsiuk Date: Tue, 12 Dec 2023 07:15:17 +0300 Subject: [PATCH 2/3] fix(android_parsing): change overrides only when test run fails --- .../marathon/android/adam/AmInstrumentTestParser.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/vendor/vendor-android/src/main/kotlin/com/malinskiy/marathon/android/adam/AmInstrumentTestParser.kt b/vendor/vendor-android/src/main/kotlin/com/malinskiy/marathon/android/adam/AmInstrumentTestParser.kt index 79f71307f..e626b00f3 100644 --- a/vendor/vendor-android/src/main/kotlin/com/malinskiy/marathon/android/adam/AmInstrumentTestParser.kt +++ b/vendor/vendor-android/src/main/kotlin/com/malinskiy/marathon/android/adam/AmInstrumentTestParser.kt @@ -125,7 +125,9 @@ class AmInstrumentTestParser( testBundleIdentifier.put(test, androidTestBundle) } - is TestRunFailed -> Unit + is TestRunFailed -> { + if (overrides.containsKey(LISTENER_ARGUMENT)) throw PossibleListenerIssueException() + } is TestRunStopped -> Unit is TestRunEnded -> Unit } @@ -138,7 +140,6 @@ class AmInstrumentTestParser( "Bundle ${bundle.id} did not report any test annotations. If you need test annotations retrieval, remote test parser requires additional setup " + "see https://docs.marathonlabs.io/android/configure#test-parser" } - if (overrides.containsKey(LISTENER_ARGUMENT)) throw PossibleListenerIssueException() } tests From 22a646ae31a02dff59e4bdbefb5b32b912e44392 Mon Sep 17 00:00:00 2001 From: Evgenii Matsiuk Date: Tue, 12 Dec 2023 12:14:09 +0300 Subject: [PATCH 3/3] fix(android_parsing): check overrides value too (annotation producer) --- .../marathon/android/adam/AmInstrumentTestParser.kt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/vendor/vendor-android/src/main/kotlin/com/malinskiy/marathon/android/adam/AmInstrumentTestParser.kt b/vendor/vendor-android/src/main/kotlin/com/malinskiy/marathon/android/adam/AmInstrumentTestParser.kt index e626b00f3..c7c608627 100644 --- a/vendor/vendor-android/src/main/kotlin/com/malinskiy/marathon/android/adam/AmInstrumentTestParser.kt +++ b/vendor/vendor-android/src/main/kotlin/com/malinskiy/marathon/android/adam/AmInstrumentTestParser.kt @@ -33,6 +33,7 @@ import kotlinx.coroutines.NonCancellable.isActive import kotlinx.coroutines.withTimeoutOrNull private const val LISTENER_ARGUMENT = "listener" +private const val TEST_ANNOTATION_PRODUCER = "com.malinskiy.adam.junit4.android.listener.TestAnnotationProducer" class AmInstrumentTestParser( private val configuration: Configuration, @@ -79,7 +80,8 @@ class AmInstrumentTestParser( val testParserConfiguration = vendorConfiguration.testParserConfiguration val overrides: Map = when { testParserConfiguration is TestParserConfiguration.RemoteTestParserConfiguration -> { - if (blockListenerArgumentOverride) testParserConfiguration.instrumentationArgs.filterKeys { it != LISTENER_ARGUMENT } + if (blockListenerArgumentOverride) testParserConfiguration.instrumentationArgs + .filterNot { it.key == LISTENER_ARGUMENT && it.value == TEST_ANNOTATION_PRODUCER } else testParserConfiguration.instrumentationArgs } else -> emptyMap() @@ -126,7 +128,8 @@ class AmInstrumentTestParser( } is TestRunFailed -> { - if (overrides.containsKey(LISTENER_ARGUMENT)) throw PossibleListenerIssueException() + if (overrides.containsKey(LISTENER_ARGUMENT) && overrides[LISTENER_ARGUMENT] == TEST_ANNOTATION_PRODUCER) + throw PossibleListenerIssueException() } is TestRunStopped -> Unit is TestRunEnded -> Unit