diff --git a/corellium/shard/README.md b/corellium/shard/README.md index 7b96b66170..e96891b6fa 100644 --- a/corellium/shard/README.md +++ b/corellium/shard/README.md @@ -1,100 +1,11 @@ -# Sharding +# Shards data structures -Depending on the provided test cases duration, the sharding algorithm will: - -* Split the test cases from one test apk to run on many devices. -* Group the test cases from many test apks to run on a single device. -* A mix both of the above options. +This module is specifying only a data structures for sharding. ## Diagram -![sharding_class_diagram](http://www.plantuml.com/plantuml/proxy?cache=no&fmt=svg&src=https://raw.githubusercontent.com/Flank/flank/master/docs/corellium/sharding-class.puml) - -## Example - -### Input - -```yaml -bundle: - - app: app1 - tests: - - test: app1-test1 - cases: - - "class app1.test1.TestClass#test1" // 1s - - app: app2 - tests: - - test: app2-test1 - cases: - - "class app2.test1.TestClass#test2" // 2s - - "class app2.test1.TestClass#test3" // 3s - - test: app2-test2 - cases: - - "class app2.test2.TestClass#test7" // 7s - - "class app2.test2.TestClass#test8" // 8s - - "class app2.test2.TestClass#test9" // 9s -``` - -### Output - -#### Max shards 3 - -```yaml -shards: - - shard1: - - app: app1 - tests: - - test: app1-test1 - cases: - - "class app1.test1.TestClass#test1" // 1s - - app: app2 - tests: - - test: app2-test2 - cases: - - "class app2.test2.TestClass#test9" // 9s - - shard2: - - app: app2 - test: app2-test1 - cases: - - "class app1.test2.TestClass#test2" // 2s - - app: app2 - test: app2-test2 - cases: - - "class app2.test2.TestClass#test8" // 8s - - shard3: - - app: app2 - test: app2-test1 - cases: - - "class app2.test1.TestClass#test3" // 3s - - app: app2 - test: app2-test2 - cases: - - "class app2.test2.TestClass#test7" // 7s -``` +![sharding_class_diagram](http://www.plantuml.com/plantuml/proxy?cache=no&fmt=svg&src=https://raw.githubusercontent.com/Flank/flank/master/docs/corellium/shard-structures.puml) -#### Max shards 2 +## Nested modules -```yaml -shards: - - shard1: - - app: app1 - tests: - - test: app1-test1 - cases: - - "class app1.test1.TestClass#test1" // 1sz - - app: app2 - tests: - - test: app2-test1 - cases: - - "class app2.test1.TestClass#test2" // 2s - - "class app2.test2.TestClass#test3" // 3s - - test: app2-test2 - cases: - - "class app2.test2.TestClass#test9" // 9s - - shard2: - - app: app2 - tests: - - test: app2-test2 - cases: - - "class app2.test2.TestClass#test7" // 7s - - "class app2.test2.TestClass#test8" // 8s -``` +* [:shard:calculate](./calculate) diff --git a/corellium/shard/build.gradle.kts b/corellium/shard/build.gradle.kts index 461177c967..1417115155 100644 --- a/corellium/shard/build.gradle.kts +++ b/corellium/shard/build.gradle.kts @@ -2,7 +2,6 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { kotlin(Plugins.Kotlin.PLUGIN_JVM) - kotlin(Plugins.Kotlin.PLUGIN_SERIALIZATION) version Versions.KOTLIN } repositories { @@ -14,7 +13,6 @@ repositories { tasks.withType { kotlinOptions.jvmTarget = "1.8" } dependencies { - implementation(Dependencies.KOTLIN_SERIALIZATION) implementation(Dependencies.KOTLIN_COROUTINES_CORE) testImplementation(Dependencies.JUNIT) diff --git a/corellium/shard/calculate/README.md b/corellium/shard/calculate/README.md new file mode 100644 index 0000000000..247e635cbe --- /dev/null +++ b/corellium/shard/calculate/README.md @@ -0,0 +1,96 @@ +# Shards calculation + +Depending on the provided test cases duration, the sharding algorithm will: + +* Split the test cases from one test apk to run on many devices. +* Group the test cases from many test apks to run on a single device. +* A mix both of the above options. + +## Example + +### Input + +```yaml +bundle: + - app: app1 + tests: + - test: app1-test1 + cases: + - "class app1.test1.TestClass#test1" // 1s + - app: app2 + tests: + - test: app2-test1 + cases: + - "class app2.test1.TestClass#test2" // 2s + - "class app2.test1.TestClass#test3" // 3s + - test: app2-test2 + cases: + - "class app2.test2.TestClass#test7" // 7s + - "class app2.test2.TestClass#test8" // 8s + - "class app2.test2.TestClass#test9" // 9s +``` + +### Output + +#### Max shards 3 + +```yaml +shards: + - shard1: + - app: app1 + tests: + - test: app1-test1 + cases: + - "class app1.test1.TestClass#test1" // 1s + - app: app2 + tests: + - test: app2-test2 + cases: + - "class app2.test2.TestClass#test9" // 9s + - shard2: + - app: app2 + test: app2-test1 + cases: + - "class app1.test2.TestClass#test2" // 2s + - app: app2 + test: app2-test2 + cases: + - "class app2.test2.TestClass#test8" // 8s + - shard3: + - app: app2 + test: app2-test1 + cases: + - "class app2.test1.TestClass#test3" // 3s + - app: app2 + test: app2-test2 + cases: + - "class app2.test2.TestClass#test7" // 7s +``` + +#### Max shards 2 + +```yaml +shards: + - shard1: + - app: app1 + tests: + - test: app1-test1 + cases: + - "class app1.test1.TestClass#test1" // 1sz + - app: app2 + tests: + - test: app2-test1 + cases: + - "class app2.test1.TestClass#test2" // 2s + - "class app2.test2.TestClass#test3" // 3s + - test: app2-test2 + cases: + - "class app2.test2.TestClass#test9" // 9s + - shard2: + - app: app2 + tests: + - test: app2-test2 + cases: + - "class app2.test2.TestClass#test7" // 7s + - "class app2.test2.TestClass#test8" // 8s +``` diff --git a/corellium/shard/calculate/build.gradle.kts b/corellium/shard/calculate/build.gradle.kts new file mode 100644 index 0000000000..4c8db5f498 --- /dev/null +++ b/corellium/shard/calculate/build.gradle.kts @@ -0,0 +1,20 @@ +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +plugins { + kotlin(Plugins.Kotlin.PLUGIN_JVM) +} + +repositories { + jcenter() + mavenCentral() + maven(url = "https://kotlin.bintray.com/kotlinx") +} + +tasks.withType { kotlinOptions.jvmTarget = "1.8" } + +dependencies { + implementation(Dependencies.KOTLIN_COROUTINES_CORE) + api(project(":corellium:shard")) + + testImplementation(Dependencies.JUNIT) +} diff --git a/corellium/shard/calculate/src/main/kotlin/flank/corellium/shard/CalculateShards.kt b/corellium/shard/calculate/src/main/kotlin/flank/corellium/shard/CalculateShards.kt new file mode 100644 index 0000000000..cf019d12a9 --- /dev/null +++ b/corellium/shard/calculate/src/main/kotlin/flank/corellium/shard/CalculateShards.kt @@ -0,0 +1,13 @@ +package flank.corellium.shard + +/** + * Distribute the test cases into the [List] of shards where each shard have similar duration. + * @receiver The bunch of test cases grouped by test and app. + * @return [List] of shards where each shard may contains many apps and test cases. + */ +fun Apps.calculateShards( + maxCount: Int +): Shards = this + .mapToInternalChunks() + .groupByDuration(maxCount) + .mapToShards() diff --git a/corellium/shard/src/main/kotlin/flank/corellium/shard/Internal.kt b/corellium/shard/calculate/src/main/kotlin/flank/corellium/shard/Internal.kt similarity index 100% rename from corellium/shard/src/main/kotlin/flank/corellium/shard/Internal.kt rename to corellium/shard/calculate/src/main/kotlin/flank/corellium/shard/Internal.kt diff --git a/corellium/shard/src/test/kotlin/flank/corellium/shard/ShardKtTest.kt b/corellium/shard/calculate/src/test/kotlin/flank/corellium/shard/CalculateShardsTest.kt similarity index 98% rename from corellium/shard/src/test/kotlin/flank/corellium/shard/ShardKtTest.kt rename to corellium/shard/calculate/src/test/kotlin/flank/corellium/shard/CalculateShardsTest.kt index 01dd51904e..265567a5cd 100644 --- a/corellium/shard/src/test/kotlin/flank/corellium/shard/ShardKtTest.kt +++ b/corellium/shard/calculate/src/test/kotlin/flank/corellium/shard/CalculateShardsTest.kt @@ -55,7 +55,7 @@ val apps = listOf( ) ) -class ShardKtTest { +class CalculateShardsTest { @JTest fun test2() { diff --git a/corellium/shard/src/main/kotlin/flank/corellium/shard/Shard.kt b/corellium/shard/src/main/kotlin/flank/corellium/shard/Shard.kt index 01031c2c8b..f4fd0fb012 100644 --- a/corellium/shard/src/main/kotlin/flank/corellium/shard/Shard.kt +++ b/corellium/shard/src/main/kotlin/flank/corellium/shard/Shard.kt @@ -1,17 +1,5 @@ package flank.corellium.shard -/** - * Distribute the test cases into the [List] of shards where each shard have similar duration. - * @receiver The bunch of test cases grouped by test and app. - * @return [List] of shards where each shard may contains many apps and test cases. - */ -fun List.calculateShards( - maxCount: Int -): List> = this - .mapToInternalChunks() - .groupByDuration(maxCount) - .mapToShards() - /** * Namespace for sharding input and output structures. */ @@ -49,3 +37,18 @@ object Shard { private const val DEFAULT_DURATION = 120L } + +/** + * Collection of apps, tests, and test cases that can be identified as test-shard for running on a single device instance. + */ +typealias InstanceShard = List + +/** + * List of shards. Each shard for another device instance. + */ +typealias Shards = List + +/** + * Collection of apps, tests, and test cases that can be used to calculate [Shards] + */ +typealias Apps = List diff --git a/docs/corellium/sharding-class.puml b/docs/corellium/shard-structures.puml similarity index 55% rename from docs/corellium/sharding-class.puml rename to docs/corellium/shard-structures.puml index 4c69bb62b0..ec8078d9f2 100644 --- a/docs/corellium/sharding-class.puml +++ b/docs/corellium/shard-structures.puml @@ -1,14 +1,16 @@ @startuml 'https://plantuml.com/component-diagram -object calculateShards +abstract Apps { +List +} -abstract Input { -one: App +abstract Shards { +List } -abstract Output { -many: List +abstract Shard { +List } class App { @@ -26,11 +28,9 @@ name: String duration: Long } -calculateShards ..> Input : receive -calculateShards ..> Output : return - -Input "1" o-- "1" App -Output "1" o-- "*" App +Apps "1" o-- "*" App +Shards "1" o-- "*" Shard +Shard "1" o-- "*" App App "1" o-- "*" Test Test "1" o-- "*" Case diff --git a/settings.gradle.kts b/settings.gradle.kts index 0fa5038cf0..ee503ee6e0 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -16,6 +16,7 @@ include( ":corellium:log", ":corellium:api", ":corellium:shard", + ":corellium:shard:calculate", ":corellium:adapter", )