Skip to content

Commit 9ad6e39

Browse files
tokoubartekpacia
andauthored
Introduce --shard-split and --shard-all (#1955)
Also deprecate `--shards --------- Co-authored-by: Bartek Pacia <[email protected]>
1 parent 022840f commit 9ad6e39

File tree

1 file changed

+36
-8
lines changed

1 file changed

+36
-8
lines changed

maestro-cli/src/main/java/maestro/cli/command/TestCommand.kt

+36-8
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,22 @@ class TestCommand : Callable<Int> {
8383

8484
@Option(
8585
names = ["-s", "--shards"],
86-
description = ["Number of parallel shards to distribute tests across"]
86+
description = ["Number of parallel shards to distribute tests across"],
8787
)
88-
private var shards: Int = 1
88+
@Deprecated("Use --shard-split or --shard-all instead")
89+
private var legacyShardCount: Int? = null
90+
91+
@Option(
92+
names = ["--shard-split"],
93+
description = ["Splits the tests across N connected devices"],
94+
)
95+
private var shardSplit: Int? = null
96+
97+
@Option(
98+
names = ["--shard-all"],
99+
description = ["Replicates all the tests across N connected devices"],
100+
)
101+
private var shardAll: Int? = null
89102

90103
@Option(names = ["-c", "--continuous"])
91104
private var continuous: Boolean = false
@@ -152,6 +165,14 @@ class TestCommand : Callable<Int> {
152165
}
153166

154167
override fun call(): Int {
168+
if (shardSplit != null && shardAll != null) {
169+
throw CliError("Options --shard-split and --shard-all are mutually exclusive.")
170+
}
171+
172+
if (legacyShardCount != null) {
173+
PrintUtils.warn("--shards option is deprecated and will be removed in the next Maestro version. Use --shard-split or --shard-all instead.")
174+
shardSplit = legacyShardCount
175+
}
155176
val executionPlan = try {
156177
WorkspaceExecutionPlanner.plan(
157178
flowFile.toPath().toAbsolutePath(),
@@ -177,7 +198,6 @@ class TestCommand : Callable<Int> {
177198
}
178199

179200
private fun handleSessions(debugOutputPath: Path, plan: ExecutionPlan): Int = runBlocking(Dispatchers.IO) {
180-
val sharded = shards > 1
181201

182202
runCatching {
183203
val deviceIds = (if (isWebFlow())
@@ -193,10 +213,18 @@ class TestCommand : Callable<Int> {
193213
initialActiveDevices.addAll(DeviceService.listConnectedDevices().map {
194214
it.instanceId
195215
}.toMutableSet())
216+
217+
val shards = shardSplit ?: shardAll ?: 1
218+
219+
val availableDevices = if (deviceIds.isNotEmpty()) deviceIds.size else initialActiveDevices.size
196220
val effectiveShards = shards.coerceAtMost(plan.flowsToRun.size)
197-
val chunkPlans = plan.flowsToRun
221+
val sharded = effectiveShards > 1
222+
223+
val chunkPlans =
224+
if (shardAll != null) (0 until effectiveShards).map { plan.copy() }
225+
else plan.flowsToRun
198226
.withIndex()
199-
.groupBy { it.index % shards }
227+
.groupBy { it.index % effectiveShards }
200228
.map { (shardIndex, files) ->
201229
ExecutionPlan(
202230
files.map { it.value },
@@ -208,12 +236,12 @@ class TestCommand : Callable<Int> {
208236
}
209237

210238
// Collect device configurations for missing shards, if any
211-
val missing = effectiveShards - if (deviceIds.isNotEmpty()) deviceIds.size else initialActiveDevices.size
212-
val allDeviceConfigs = (0 until missing).map { shardIndex ->
239+
val missing = effectiveShards - availableDevices
240+
val allDeviceConfigs = if (shardAll == null) (0 until missing).map { shardIndex ->
213241
PrintUtils.message("------------------ Shard ${shardIndex + 1} ------------------")
214242
// Collect device configurations here, one per shard
215243
PickDeviceView.requestDeviceOptions()
216-
}.toMutableList()
244+
}.toMutableList() else mutableListOf()
217245

218246
val barrier = CountDownLatch(effectiveShards)
219247

0 commit comments

Comments
 (0)