From ea631fcdb4572c73c27102b58fbb89414afb07b5 Mon Sep 17 00:00:00 2001 From: Patrick Honkonen Date: Wed, 29 Oct 2025 00:31:02 -0400 Subject: [PATCH] Add 4 test shard tasks for parallel CI execution - testShard1Vault: ui.vault.* (1,476 tests) - testShard2Platform: ui.platform/tools/credentials/autofill (1,270 tests) - testShard3Auth: data.auth/autofill (738 tests) - testShard4Data: data.vault/platform/tools/util + integration (1,663 tests) Each shard balanced within 25% variance. Part of Tier 2 optimization. --- app/build.gradle.kts | 81 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 78 insertions(+), 3 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 39df639fe6..a79a7d60cb 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -302,14 +302,89 @@ tasks { useJUnitPlatform() maxHeapSize = "2g" maxParallelForks = Runtime.getRuntime().availableProcessors() - jvmArgs = jvmArgs.orEmpty() + "-XX:+UseParallelGC" + - // Explicitly setting the user Country and Language because tests assume en-US - "-Duser.country=US" + + jvmArgs = jvmArgs.orEmpty() + "-XX:+UseParallelGC" + + // Explicitly setting the user Country and Language because tests assume en-US + "-Duser.country=US" + "-Duser.language=en" } } afterEvaluate { + // Test sharding for parallel CI execution (Tier 2 optimization) + val testTask = tasks.named("testStandardDebugUnitTest").get() + + tasks.register("testShard1Vault") { + description = "Run Shard 1: Vault UI tests (1,476 tests)" + group = "verification" + testClassesDirs = testTask.testClassesDirs + classpath = testTask.classpath + useJUnitPlatform() + maxHeapSize = "2g" + maxParallelForks = Runtime.getRuntime().availableProcessors() + jvmArgs = jvmArgs.orEmpty() + "-XX:+UseParallelGC" + filter { + includeTestsMatching("com.x8bit.bitwarden.ui.vault.*") + } + } + + tasks.register("testShard2Platform") { + description = "Run Shard 2: Platform, Tools, Credentials UI tests (1,270 tests)" + group = "verification" + testClassesDirs = testTask.testClassesDirs + classpath = testTask.classpath + useJUnitPlatform() + maxHeapSize = "2g" + maxParallelForks = Runtime.getRuntime().availableProcessors() + jvmArgs = jvmArgs.orEmpty() + "-XX:+UseParallelGC" + filter { + includeTestsMatching("com.x8bit.bitwarden.ui.platform.*") + includeTestsMatching("com.x8bit.bitwarden.ui.tools.*") + includeTestsMatching("com.x8bit.bitwarden.ui.credentials.*") + includeTestsMatching("com.x8bit.bitwarden.ui.autofill.*") + } + } + + tasks.register("testShard3Auth") { + description = "Run Shard 3: Auth & Autofill data layer tests (738 tests)" + group = "verification" + testClassesDirs = testTask.testClassesDirs + classpath = testTask.classpath + useJUnitPlatform() + maxHeapSize = "2g" + maxParallelForks = Runtime.getRuntime().availableProcessors() + jvmArgs = jvmArgs.orEmpty() + "-XX:+UseParallelGC" + filter { + includeTestsMatching("com.x8bit.bitwarden.data.auth.*") + includeTestsMatching("com.x8bit.bitwarden.data.autofill.*") + } + } + + tasks.register("testShard4Data") { + description = "Run Shard 4: Data layer + Integration tests (1,663 tests)" + group = "verification" + testClassesDirs = testTask.testClassesDirs + classpath = testTask.classpath + useJUnitPlatform() + maxHeapSize = "2g" + maxParallelForks = Runtime.getRuntime().availableProcessors() + jvmArgs = jvmArgs.orEmpty() + "-XX:+UseParallelGC" + filter { + includeTestsMatching("com.x8bit.bitwarden.data.vault.*") + includeTestsMatching("com.x8bit.bitwarden.data.platform.*") + includeTestsMatching("com.x8bit.bitwarden.data.tools.*") + includeTestsMatching("com.x8bit.bitwarden.data.credentials.*") + includeTestsMatching("com.x8bit.bitwarden.data.util.*") + includeTestsMatching("com.x8bit.bitwarden.MainViewModelTest") + includeTestsMatching("com.x8bit.bitwarden.*CallbackViewModelTest") + } + } + + tasks.register("testAllShards") { + description = "Run all test shards (for local verification)" + group = "verification" + dependsOn("testShard1Vault", "testShard2Platform", "testShard3Auth", "testShard4Data") + } + // Disable Fdroid-specific tasks that we want to exclude val fdroidTasksToDisable = tasks.withType() + tasks.withType() +