diff --git a/release_notes.md b/release_notes.md index 539f93bb3a..30f3eba13c 100644 --- a/release_notes.md +++ b/release_notes.md @@ -12,6 +12,7 @@ - [#781](https://github.com/Flank/flank/pull/781) Remove local exists check on cloud results-dir. Fixes crash when results-dir is set by the user. ([adamfilipow92](https://github.com/adamfilipow92)) - [#656](https://github.com/Flank/flank/issues/656) Improve error message reporting. ([adamfilipow92](https://github.com/adamfilipow92)) - [#783](https://github.com/Flank/flank/pull/783) Use legacy results for iOS by default. ([pawelpasterz](https://github.com/pawelpasterz)) +- [#794](https://github.com/Flank/flank/pull/794) Enhance `--dump-shards` to dump shards from all test apks ([bootstraponline](https://github.com/bootstraponline), [jan-gogo](https://github.com/jan-gogo)) ## v20.05.1 diff --git a/test_runner/src/main/kotlin/ftl/args/AndroidTestShard.kt b/test_runner/src/main/kotlin/ftl/args/AndroidTestShard.kt deleted file mode 100644 index 0c08a96605..0000000000 --- a/test_runner/src/main/kotlin/ftl/args/AndroidTestShard.kt +++ /dev/null @@ -1,51 +0,0 @@ -package ftl.args - -import com.linkedin.dex.parser.DexParser -import com.linkedin.dex.parser.TestMethod -import ftl.config.FtlConstants -import ftl.filter.TestFilter -import ftl.filter.TestFilters -import ftl.gc.GcStorage -import ftl.util.FlankTestMethod -import java.io.File - -object AndroidTestShard { - - // computed properties not specified in yaml - fun getTestShardChunks(args: AndroidArgs, testApk: String): ShardChunks { - // Download test APK if necessary so it can be used to validate test methods - val testLocalApk = if (testApk.startsWith(FtlConstants.GCS_PREFIX)) - GcStorage.download(testApk) else - testApk - - val filteredTests = getTestMethods(args, testLocalApk) - - if (filteredTests.isEmpty()) println("${FtlConstants.indent}No tests for ${testLocalApk.apkFileName}") - - return if (args.numUniformShards == null) - ArgsHelper.calculateShards(filteredTests, args) else - listOf(filteredTests.map(FlankTestMethod::testName)) - } - - private fun getTestMethods(args: AndroidArgs, testLocalApk: String): List<FlankTestMethod> { - val allTestMethods = DexParser.findTestMethods(testLocalApk) - if (allTestMethods.isEmpty()) { - // Avoid unnecessary computation if we already know there aren't tests. - return emptyList() - } - val testFilter = TestFilters.fromTestTargets(args.testTargets) - return allTestMethods filterWith testFilter - } - - private infix fun List<TestMethod>.filterWith(filter: TestFilter) = asSequence() - .distinct() - .filter(filter.shouldRun) - .map { FlankTestMethod("class ${it.testName}", it.isIgnored) } - .toList() -} - -private val TestMethod.isIgnored: Boolean - get() = annotations.map { it.name }.contains("org.junit.Ignore") - -private inline val String.apkFileName: String - get() = File(this).name diff --git a/test_runner/src/main/kotlin/ftl/args/ArgsHelper.kt b/test_runner/src/main/kotlin/ftl/args/ArgsHelper.kt index 7ef73ea3e8..4db5eead49 100644 --- a/test_runner/src/main/kotlin/ftl/args/ArgsHelper.kt +++ b/test_runner/src/main/kotlin/ftl/args/ArgsHelper.kt @@ -224,7 +224,11 @@ object ArgsHelper { return ArgsFileVisitor("glob:$filePath").walk(searchDir) } - fun calculateShards(filteredTests: List<FlankTestMethod>, args: IArgs): ShardChunks { + fun calculateShards( + filteredTests: List<FlankTestMethod>, + args: IArgs, + forcedShardCount: Int? = null + ): ShardChunks { if (filteredTests.isEmpty()) { // Avoid unnecessary computing if we already know there aren't tests to run. return listOf(emptyList()) @@ -234,7 +238,7 @@ object ArgsHelper { listOf(filteredTests.map { it.testName }.toMutableList()) } else { val oldTestResult = GcStorage.downloadJunitXml(args) ?: JUnitTestResult(mutableListOf()) - val shardCount = Shard.shardCountByTime(filteredTests, oldTestResult, args) + val shardCount = forcedShardCount ?: Shard.shardCountByTime(filteredTests, oldTestResult, args) Shard.createShardsByShardCount(filteredTests, oldTestResult, args, shardCount).stringShards() } diff --git a/test_runner/src/main/kotlin/ftl/args/yml/errors/ConfigurationErrorParser.kt b/test_runner/src/main/kotlin/ftl/args/yml/errors/ConfigurationErrorParser.kt index 1f037a1f9a..ff8eac3c61 100644 --- a/test_runner/src/main/kotlin/ftl/args/yml/errors/ConfigurationErrorParser.kt +++ b/test_runner/src/main/kotlin/ftl/args/yml/errors/ConfigurationErrorParser.kt @@ -5,7 +5,7 @@ internal object ConfigurationErrorParser { //region regex patterns private val propertyNameRegex = "(?<=property\\s)[a-z]*".toRegex() private val referenceChainRegex = "(?<=chain:\\s).*(?=[)])".toRegex() - private val referenceChainCleanUpRegex = "(?<=[\\[])\"?[\\w]*\"?(?=])".toRegex() + private val referenceChainCleanUpRegex = "(?<=[\\[])\"?(\\w|-)*\"?(?=])".toRegex() private val lineAndColumnRegex = "((?<=line:\\s)\\d*), column:\\s(\\d*)".toRegex() //endregion diff --git a/test_runner/src/main/kotlin/ftl/cli/firebase/test/android/AndroidRunCommand.kt b/test_runner/src/main/kotlin/ftl/cli/firebase/test/android/AndroidRunCommand.kt index 05b3001d7e..3cc9e619ad 100644 --- a/test_runner/src/main/kotlin/ftl/cli/firebase/test/android/AndroidRunCommand.kt +++ b/test_runner/src/main/kotlin/ftl/cli/firebase/test/android/AndroidRunCommand.kt @@ -1,8 +1,6 @@ package ftl.cli.firebase.test.android import ftl.args.AndroidArgs -import ftl.args.AndroidTestShard -import ftl.args.ShardChunks import ftl.args.yml.AppTestPair import ftl.cli.firebase.test.CommonRunCommand import ftl.config.Device @@ -12,12 +10,12 @@ import ftl.config.FtlConstants.defaultAndroidVersion import ftl.config.FtlConstants.defaultLocale import ftl.config.FtlConstants.defaultOrientation import ftl.mock.MockServer -import ftl.run.common.prettyPrint +import ftl.run.ANDROID_SHARD_FILE +import ftl.run.dumpShards import ftl.run.newTestRun import kotlinx.coroutines.runBlocking import picocli.CommandLine.Command import picocli.CommandLine.Option -import java.nio.file.Files import java.nio.file.Paths @Command( @@ -45,25 +43,18 @@ class AndroidRunCommand : CommonRunCommand(), Runnable { val config = AndroidArgs.load(Paths.get(configPath), cli = this) if (dumpShards) { - val testShardChunks: ShardChunks = AndroidTestShard.getTestShardChunks(config, config.testApk!!) - val testShardChunksJson: String = prettyPrint.toJson(testShardChunks) - - Files.write(Paths.get(shardFile), testShardChunksJson.toByteArray()) - println("Saved shards to $shardFile") - } else { - runBlocking { - newTestRun(config) - } + dumpShards(config) + } else runBlocking { + newTestRun(config) } } - companion object { - private const val shardFile = "android_shards.json" - } - // Flank debug - @Option(names = ["--dump-shards"], description = ["Dumps the shards to $shardFile for debugging"]) + @Option( + names = ["--dump-shards"], + description = ["Measures test shards from given test apks and writes them into $ANDROID_SHARD_FILE file instead of executing."] + ) var dumpShards: Boolean = false // Flank specific diff --git a/test_runner/src/main/kotlin/ftl/cli/firebase/test/ios/IosRunCommand.kt b/test_runner/src/main/kotlin/ftl/cli/firebase/test/ios/IosRunCommand.kt index 29c40dbb91..52e362ca29 100644 --- a/test_runner/src/main/kotlin/ftl/cli/firebase/test/ios/IosRunCommand.kt +++ b/test_runner/src/main/kotlin/ftl/cli/firebase/test/ios/IosRunCommand.kt @@ -7,12 +7,12 @@ import ftl.config.FtlConstants import ftl.config.FtlConstants.defaultIosModel import ftl.config.FtlConstants.defaultIosVersion import ftl.mock.MockServer -import ftl.run.common.prettyPrint +import ftl.run.IOS_SHARD_FILE +import ftl.run.dumpShards import ftl.run.newTestRun import kotlinx.coroutines.runBlocking import picocli.CommandLine.Command import picocli.CommandLine.Option -import java.nio.file.Files import java.nio.file.Paths @Command( @@ -39,23 +39,18 @@ class IosRunCommand : CommonRunCommand(), Runnable { val config = IosArgs.load(Paths.get(configPath), cli = this) if (dumpShards) { - val testShardChunksJson: String = prettyPrint.toJson(config.testShardChunks) - Files.write(Paths.get(shardFile), testShardChunksJson.toByteArray()) - println("Saved shards to $shardFile") - } else { - runBlocking { - newTestRun(config) - } + dumpShards(config) + } else runBlocking { + newTestRun(config) } } - companion object { - private const val shardFile = "ios_shards.json" - } - // Flank debug - @Option(names = ["--dump-shards"], description = ["Dumps the shards to $shardFile for debugging"]) + @Option( + names = ["--dump-shards"], + description = ["Measures test shards from given test apks and writes them into $IOS_SHARD_FILE file instead of executing."] + ) var dumpShards: Boolean = false // Flank specific diff --git a/test_runner/src/main/kotlin/ftl/run/DumpShards.kt b/test_runner/src/main/kotlin/ftl/run/DumpShards.kt new file mode 100644 index 0000000000..06a62c5593 --- /dev/null +++ b/test_runner/src/main/kotlin/ftl/run/DumpShards.kt @@ -0,0 +1,45 @@ +package ftl.run + +import ftl.args.AndroidArgs +import ftl.args.IosArgs +import ftl.run.common.prettyPrint +import ftl.run.model.AndroidMatrixTestShards +import ftl.run.platform.android.getAndroidMatrixShards +import ftl.util.FlankFatalError +import java.nio.file.Files +import java.nio.file.Paths + +fun dumpShards(args: AndroidArgs) { + if (!args.isInstrumentationTest) throw FlankFatalError( + "Cannot dump shards for non instrumentation test, ensure test apk has been set." + ) + val shards: AndroidMatrixTestShards = getAndroidMatrixShards(args) + saveShardChunks( + shardFilePath = ANDROID_SHARD_FILE, + shards = shards, + size = shards.size + ) +} + +fun dumpShards(args: IosArgs) { + saveShardChunks( + shardFilePath = IOS_SHARD_FILE, + shards = args.testShardChunks, + size = args.testShardChunks.size + ) +} + +private fun saveShardChunks( + shardFilePath: String, + shards: Any, + size: Int +) { + Files.write( + Paths.get(shardFilePath), + prettyPrint.toJson(shards).toByteArray() + ) + println("Saved $size shards to $shardFilePath") +} + +const val ANDROID_SHARD_FILE = "android_shards.json" +const val IOS_SHARD_FILE = "ios_shards.json" diff --git a/test_runner/src/main/kotlin/ftl/run/model/AndroidMatrixTestShards.kt b/test_runner/src/main/kotlin/ftl/run/model/AndroidMatrixTestShards.kt new file mode 100644 index 0000000000..e69edf4605 --- /dev/null +++ b/test_runner/src/main/kotlin/ftl/run/model/AndroidMatrixTestShards.kt @@ -0,0 +1,3 @@ +package ftl.run.model + +typealias AndroidMatrixTestShards = Map<String, AndroidTestShards> diff --git a/test_runner/src/main/kotlin/ftl/run/model/AndroidTestShards.kt b/test_runner/src/main/kotlin/ftl/run/model/AndroidTestShards.kt new file mode 100644 index 0000000000..2dc0ff1d21 --- /dev/null +++ b/test_runner/src/main/kotlin/ftl/run/model/AndroidTestShards.kt @@ -0,0 +1,7 @@ +package ftl.run.model + +data class AndroidTestShards( + val app: String, + val test: String, + val shards: Map<String, List<String>> = emptyMap() +) diff --git a/test_runner/src/main/kotlin/ftl/run/model/InstrumentationTestApk.kt b/test_runner/src/main/kotlin/ftl/run/model/InstrumentationTestApk.kt new file mode 100644 index 0000000000..13966d94a8 --- /dev/null +++ b/test_runner/src/main/kotlin/ftl/run/model/InstrumentationTestApk.kt @@ -0,0 +1,8 @@ +package ftl.run.model + +import ftl.util.FileReference + +data class InstrumentationTestApk( + val app: FileReference = FileReference(), + val test: FileReference = FileReference() +) diff --git a/test_runner/src/main/kotlin/ftl/run/platform/RunAndroidTests.kt b/test_runner/src/main/kotlin/ftl/run/platform/RunAndroidTests.kt index 4af82e4302..f9dabd7cce 100644 --- a/test_runner/src/main/kotlin/ftl/run/platform/RunAndroidTests.kt +++ b/test_runner/src/main/kotlin/ftl/run/platform/RunAndroidTests.kt @@ -3,8 +3,8 @@ package ftl.run.platform import com.google.api.services.testing.Testing import com.google.api.services.testing.model.TestMatrix import ftl.args.AndroidArgs -import ftl.args.AndroidTestShard import ftl.args.ShardChunks +import ftl.run.platform.android.getAndroidShardChunks import ftl.args.yml.ResolvedApks import ftl.gc.GcAndroidDevice import ftl.gc.GcAndroidTestMatrix @@ -40,7 +40,7 @@ internal suspend fun runAndroidTests(args: AndroidArgs): TestResult = coroutineS args.resolveApks().forEachIndexed { index: Int, apks: ResolvedApks -> val testShards = apks.test?.let { test -> - AndroidTestShard.getTestShardChunks(args, test) + getAndroidShardChunks(args, test) } // We can't return if testShards is null since it can be a robo test. testShards?.let { diff --git a/test_runner/src/main/kotlin/ftl/run/platform/android/GetAndroidMatrixShards.kt b/test_runner/src/main/kotlin/ftl/run/platform/android/GetAndroidMatrixShards.kt new file mode 100644 index 0000000000..e0898287ee --- /dev/null +++ b/test_runner/src/main/kotlin/ftl/run/platform/android/GetAndroidMatrixShards.kt @@ -0,0 +1,44 @@ +package ftl.run.platform.android + +import ftl.args.AndroidArgs +import ftl.args.ShardChunks +import ftl.run.model.AndroidMatrixTestShards +import ftl.run.model.AndroidTestShards +import ftl.run.model.InstrumentationTestApk +import ftl.util.asFileReference + +fun getAndroidMatrixShards( + args: AndroidArgs +): AndroidMatrixTestShards = + getInstrumentationShardChunks( + args = args, + testApks = args.createInstrumentationTestApks() + ).asMatrixTestShards() + +private fun AndroidArgs.createInstrumentationTestApks(): List<InstrumentationTestApk> = + listOfNotNull( + testApk?.let { testApk -> + InstrumentationTestApk( + app = appApk.asFileReference(), + test = testApk.asFileReference() + ) + } + ) + additionalAppTestApks.map { + InstrumentationTestApk( + app = (it.app ?: appApk).asFileReference(), + test = it.test.asFileReference() + ) + } + +private fun Map<InstrumentationTestApk, ShardChunks>.asMatrixTestShards(): AndroidMatrixTestShards = + map { (testApks, shards: List<List<String>>) -> + AndroidTestShards( + app = testApks.app.local, + test = testApks.test.local, + shards = shards.mapIndexed { index, testCases -> + "shard-$index" to testCases + }.toMap() + ) + }.mapIndexed { index, androidTestShards -> + "matrix-$index" to androidTestShards + }.toMap() diff --git a/test_runner/src/main/kotlin/ftl/run/platform/android/GetAndroidShardChunks.kt b/test_runner/src/main/kotlin/ftl/run/platform/android/GetAndroidShardChunks.kt new file mode 100644 index 0000000000..709c1f51fb --- /dev/null +++ b/test_runner/src/main/kotlin/ftl/run/platform/android/GetAndroidShardChunks.kt @@ -0,0 +1,15 @@ +package ftl.run.platform.android + +import ftl.args.AndroidArgs +import ftl.args.ShardChunks +import ftl.run.model.InstrumentationTestApk +import ftl.util.asFileReference + +fun getAndroidShardChunks( + args: AndroidArgs, + testApk: String +): ShardChunks = + getInstrumentationShardChunks( + args = args, + testApks = listOf(InstrumentationTestApk(test = testApk.asFileReference())) + ).flatMap { (_, shardChunks) -> shardChunks } diff --git a/test_runner/src/main/kotlin/ftl/run/platform/android/GetInstrumentationShardChunks.kt b/test_runner/src/main/kotlin/ftl/run/platform/android/GetInstrumentationShardChunks.kt new file mode 100644 index 0000000000..a15a8ea113 --- /dev/null +++ b/test_runner/src/main/kotlin/ftl/run/platform/android/GetInstrumentationShardChunks.kt @@ -0,0 +1,55 @@ +package ftl.run.platform.android + +import com.linkedin.dex.parser.DexParser +import ftl.args.AndroidArgs +import ftl.args.ArgsHelper +import ftl.args.ShardChunks +import ftl.config.FtlConstants +import ftl.filter.TestFilter +import ftl.filter.TestFilters +import ftl.run.model.InstrumentationTestApk +import ftl.util.FlankTestMethod +import ftl.util.downloadIfNeeded +import java.io.File + +fun getInstrumentationShardChunks( + args: AndroidArgs, + testApks: List<InstrumentationTestApk> +): Map<InstrumentationTestApk, ShardChunks> = + getFlankTestMethods( + testApks = testApks.download(), + testFilter = TestFilters.fromTestTargets(args.testTargets) + ).mapValues { (_, testMethods: List<FlankTestMethod>) -> + if (testMethods.isNotEmpty()) { + ArgsHelper.calculateShards(testMethods, args, args.numUniformShards) + } else { + printNoTests(testApks) + emptyList() + } + } + +private fun getFlankTestMethods( + testApks: List<InstrumentationTestApk>, + testFilter: TestFilter +): Map<InstrumentationTestApk, List<FlankTestMethod>> = + testApks.associateWith { testApk -> + DexParser.findTestMethods(testApk.test.local).asSequence().distinct().filter(testFilter.shouldRun).map { testMethod -> + FlankTestMethod( + testName = "class ${testMethod.testName}", + ignored = testMethod.annotations.any { it.name == "org.junit.Ignore" } + ) + }.toList() + } + +private fun List<InstrumentationTestApk>.download(): List<InstrumentationTestApk> = + map { reference -> + reference.copy( + app = reference.app.downloadIfNeeded(), + test = reference.test.downloadIfNeeded() + ) + } + +private fun printNoTests(testApks: List<InstrumentationTestApk>) { + val testApkNames = testApks.joinToString(", ") { pathname -> File(pathname.test.local).name } + println("${FtlConstants.indent}No tests for $testApkNames") +} diff --git a/test_runner/src/main/kotlin/ftl/util/FileReference.kt b/test_runner/src/main/kotlin/ftl/util/FileReference.kt new file mode 100644 index 0000000000..d66a97a9d9 --- /dev/null +++ b/test_runner/src/main/kotlin/ftl/util/FileReference.kt @@ -0,0 +1,20 @@ +package ftl.util + +import ftl.config.FtlConstants +import ftl.gc.GcStorage + +data class FileReference( + val local: String = "", + val gcs: String = "" +) + +fun String.asFileReference(): FileReference = + if (startsWith(FtlConstants.GCS_PREFIX)) + FileReference(gcs = this) else + FileReference(local = this) + +fun FileReference.downloadIfNeeded() = when { + local.isNotBlank() -> this + gcs.isNotBlank() -> copy(local = GcStorage.download(gcs)) + else -> this +} diff --git a/test_runner/src/test/kotlin/ftl/args/AndroidArgsFileTest.kt b/test_runner/src/test/kotlin/ftl/args/AndroidArgsFileTest.kt index 56d826dc46..113bf12b49 100644 --- a/test_runner/src/test/kotlin/ftl/args/AndroidArgsFileTest.kt +++ b/test_runner/src/test/kotlin/ftl/args/AndroidArgsFileTest.kt @@ -1,13 +1,17 @@ package ftl.args import ftl.args.yml.AndroidFlankYml +import ftl.args.yml.AndroidFlankYmlParams import ftl.args.yml.AndroidGcloudYml import ftl.args.yml.AndroidGcloudYmlParams +import ftl.args.yml.AppTestPair import ftl.args.yml.FlankYml import ftl.args.yml.FlankYmlParams import ftl.args.yml.GcloudYml import ftl.args.yml.GcloudYmlParams import ftl.config.Device +import ftl.run.platform.android.getAndroidMatrixShards +import ftl.run.platform.android.getAndroidShardChunks import ftl.run.status.OutputStyle import ftl.test.util.FlankTestRunner import ftl.test.util.TestHelper.absolutePath @@ -108,21 +112,57 @@ class AndroidArgsFileTest { ) } + @Test + fun `calculateShards additionalAppTestApks`() { + val test1 = "src/test/kotlin/ftl/fixtures/tmp/apk/app-debug-androidTest_1.apk" + val test155 = "src/test/kotlin/ftl/fixtures/tmp/apk/app-debug-androidTest_155.apk" + val config = AndroidArgs( + GcloudYml(GcloudYmlParams()), + AndroidGcloudYml( + AndroidGcloudYmlParams( + app = appApkLocal, + test = getString(test1) + ) + ), + FlankYml( + FlankYmlParams( + maxTestShards = 3 + ) + ), + AndroidFlankYml( + AndroidFlankYmlParams( + additionalAppTestApks = listOf( + AppTestPair( + app = appApkLocal, + test = getString(test155) + ) + ) + ) + ), + "" + ) + with(getAndroidMatrixShards(config)) { + assertEquals(1, get("matrix-0")!!.shards["shard-0"]!!.size) + assertEquals(51, get("matrix-1")!!.shards["shard-0"]!!.size) + assertEquals(52, get("matrix-1")!!.shards["shard-1"]!!.size) + assertEquals(52, get("matrix-1")!!.shards["shard-2"]!!.size) + } + } + @Test fun `calculateShards 0`() { val config = configWithTestMethods(0) - val testShardChunks = AndroidTestShard.getTestShardChunks(config, config.testApk!!) + val testShardChunks = getAndroidShardChunks(config, config.testApk!!) with(config) { assert(maxTestShards, 1) - assert(testShardChunks.size, 1) - assert(testShardChunks.first().size, 0) + assert(testShardChunks.size, 0) } } @Test fun `calculateShards 1`() { val config = configWithTestMethods(1) - val testShardChunks = AndroidTestShard.getTestShardChunks(config, config.testApk!!) + val testShardChunks = getAndroidShardChunks(config, config.testApk!!) with(config) { assert(maxTestShards, 1) assert(testShardChunks.size, 1) @@ -133,7 +173,7 @@ class AndroidArgsFileTest { @Test fun `calculateShards 155`() { val config = configWithTestMethods(155) - val testShardChunks = AndroidTestShard.getTestShardChunks(config, config.testApk!!) + val testShardChunks = getAndroidShardChunks(config, config.testApk!!) with(config) { assert(maxTestShards, 1) assert(testShardChunks.size, 1) @@ -144,7 +184,7 @@ class AndroidArgsFileTest { @Test fun `calculateShards 155 40`() { val config = configWithTestMethods(155, maxTestShards = 40) - val testShardChunks = AndroidTestShard.getTestShardChunks(config, config.testApk!!) + val testShardChunks = getAndroidShardChunks(config, config.testApk!!) with(config) { assert(maxTestShards, 40) assert(testShardChunks.size, 40) diff --git a/test_runner/src/test/kotlin/ftl/args/AndroidArgsTest.kt b/test_runner/src/test/kotlin/ftl/args/AndroidArgsTest.kt index b495de22cb..23e9841166 100644 --- a/test_runner/src/test/kotlin/ftl/args/AndroidArgsTest.kt +++ b/test_runner/src/test/kotlin/ftl/args/AndroidArgsTest.kt @@ -8,6 +8,7 @@ import ftl.config.FlankRoboDirective import ftl.config.FtlConstants.defaultAndroidModel import ftl.config.FtlConstants.defaultAndroidVersion import ftl.run.platform.runAndroidTests +import ftl.run.platform.android.getAndroidShardChunks import ftl.run.status.OutputStyle import ftl.test.util.FlankTestRunner import ftl.test.util.TestHelper.absolutePath @@ -16,7 +17,7 @@ import ftl.test.util.TestHelper.getPath import ftl.util.FlankCommonException import ftl.util.FlankFatalError import io.mockk.every -import io.mockk.mockkObject +import io.mockk.mockkStatic import io.mockk.unmockkAll import kotlinx.coroutines.runBlocking import org.junit.After @@ -447,7 +448,7 @@ AndroidArgs """ ) - val testShardChunks = AndroidTestShard.getTestShardChunks(androidArgs, androidArgs.testApk!!) + val testShardChunks = getAndroidShardChunks(androidArgs, androidArgs.testApk!!) with(androidArgs) { assert(maxTestShards, -1) assert(testShardChunks.size, 2) @@ -481,8 +482,8 @@ AndroidArgs disable-sharding: true """ val androidArgs = AndroidArgs.load(yaml) - val testShardChunks = AndroidTestShard.getTestShardChunks(androidArgs, androidArgs.testApk!!) - assertThat(testShardChunks).hasSize(1) + val testShardChunks = getAndroidShardChunks(androidArgs, androidArgs.testApk!!) + assertThat(testShardChunks).hasSize(0) } @Test @@ -493,8 +494,8 @@ AndroidArgs test: $invalidApk """ val androidArgs = AndroidArgs.load(yaml) - val testShardChunks = AndroidTestShard.getTestShardChunks(androidArgs, androidArgs.testApk!!) - assertThat(testShardChunks).hasSize(1) + val testShardChunks = getAndroidShardChunks(androidArgs, androidArgs.testApk!!) + assertThat(testShardChunks).hasSize(0) } @Test @@ -1274,8 +1275,8 @@ AndroidArgs test: $testApk """.trimIndent() - mockkObject(AndroidTestShard) - every { AndroidTestShard.getTestShardChunks(any(), any()) } returns listOf() + mockkStatic("ftl.run.platform.android.GetAndroidShardChunksKt") + every { getAndroidShardChunks(any(), any()) } returns listOf() val parsedYml = AndroidArgs.load(yaml) runBlocking { runAndroidTests(parsedYml) }