@@ -175,52 +175,66 @@ private final class TestModuleUtil(
175
175
private def runTestDefault (
176
176
filteredClassLists : Seq [Seq [String ]]
177
177
)(implicit ctx : mill.api.Ctx ) = {
178
- TestModuleUtil .withTestProgressTickerThread(filteredClassLists.map(_.size).sum)(body = workerResultSet => {
179
- filteredClassLists match {
180
- // When no tests at all are discovered, run at least one test JVM
181
- // process to go through the test framework setup/teardown logic
182
- case Nil => callTestRunnerSubprocess(Task .dest, Left (Nil ), workerResultSet)
183
- case Seq (singleTestClassList) =>
184
- callTestRunnerSubprocess(Task .dest, Left (singleTestClassList), workerResultSet)
185
- case multipleTestClassLists =>
186
- val maxLength = multipleTestClassLists.length.toString.length
187
- val futures = multipleTestClassLists.zipWithIndex.map { case (testClassList, i) =>
188
- val groupPromptMessage = testClassList match {
189
- case Seq (single) => single
190
- case multiple =>
191
- TestModuleUtil .collapseTestClassNames(
192
- multiple
193
- ).mkString(" , " ) + s " , ${multiple.length} suites "
194
- }
178
+ TestModuleUtil .withTestProgressTickerThread(filteredClassLists.map(_.size).sum)(body =
179
+ workerResultSet => {
180
+ filteredClassLists match {
181
+ // When no tests at all are discovered, run at least one test JVM
182
+ // process to go through the test framework setup/teardown logic
183
+ case Nil => callTestRunnerSubprocess(Task .dest, Left (Nil ), workerResultSet)
184
+ case Seq (singleTestClassList) =>
185
+ callTestRunnerSubprocess(Task .dest, Left (singleTestClassList), workerResultSet)
186
+ case multipleTestClassLists =>
187
+ val maxLength = multipleTestClassLists.length.toString.length
188
+ val futures = multipleTestClassLists.zipWithIndex.map { case (testClassList, i) =>
189
+ val groupPromptMessage = testClassList match {
190
+ case Seq (single) => single
191
+ case multiple =>
192
+ TestModuleUtil .collapseTestClassNames(
193
+ multiple
194
+ ).mkString(" , " ) + s " , ${multiple.length} suites "
195
+ }
195
196
196
- val paddedIndex = mill.util.Util .leftPad(i.toString, maxLength, '0' )
197
- val folderName = testClassList match {
198
- case Seq (single) => single
199
- case multiple =>
200
- s " group- $paddedIndex- ${multiple.head}"
201
- }
197
+ val paddedIndex = mill.util.Util .leftPad(i.toString, maxLength, '0' )
198
+ val folderName = testClassList match {
199
+ case Seq (single) => single
200
+ case multiple =>
201
+ s " group- $paddedIndex- ${multiple.head}"
202
+ }
202
203
203
- // set priority = -1 to always prioritize test subprocesses over normal Mill
204
- // tasks. This minimizes the number of blocked tasks since Mill tasks can be
205
- // blocked on test subprocesses, but not vice versa, so better to schedule
206
- // the test subprocesses first
207
- Task .fork.async(Task .dest / folderName, paddedIndex, groupPromptMessage, priority = - 1 ) {
208
- logger =>
209
- (folderName, callTestRunnerSubprocess(Task .dest / folderName, Left (testClassList), workerResultSet))
204
+ // set priority = -1 to always prioritize test subprocesses over normal Mill
205
+ // tasks. This minimizes the number of blocked tasks since Mill tasks can be
206
+ // blocked on test subprocesses, but not vice versa, so better to schedule
207
+ // the test subprocesses first
208
+ Task .fork.async(
209
+ Task .dest / folderName,
210
+ paddedIndex,
211
+ groupPromptMessage,
212
+ priority = - 1
213
+ ) {
214
+ logger =>
215
+ (
216
+ folderName,
217
+ callTestRunnerSubprocess(
218
+ Task .dest / folderName,
219
+ Left (testClassList),
220
+ workerResultSet
221
+ )
222
+ )
223
+ }
210
224
}
211
- }
212
225
213
- val outputs = Task .fork.awaitAll(futures)
226
+ val outputs = Task .fork.awaitAll(futures)
214
227
215
- val (lefts, rights) = outputs.partitionMap {
216
- case (name, Left (v)) => Left (name + " " + v)
217
- case (name, Right ((msg, results))) => Right ((name + " " + msg, results))
218
- }
228
+ val (lefts, rights) = outputs.partitionMap {
229
+ case (name, Left (v)) => Left (name + " " + v)
230
+ case (name, Right ((msg, results))) => Right ((name + " " + msg, results))
231
+ }
219
232
220
- if (lefts.nonEmpty) Left (lefts.mkString(" \n " ))
221
- else Right ((rights.map(_._1).mkString(" \n " ), rights.flatMap(_._2)))
233
+ if (lefts.nonEmpty) Left (lefts.mkString(" \n " ))
234
+ else Right ((rights.map(_._1).mkString(" \n " ), rights.flatMap(_._2)))
235
+ }
222
236
}
223
- } )
237
+ )
224
238
}
225
239
226
240
private def runTestQueueScheduler (
@@ -427,8 +441,8 @@ private final class TestModuleUtil(
427
441
private [scalalib] object TestModuleUtil {
428
442
429
443
private def withTestProgressTickerThread [T ](totalClassCount : Long )(
430
- tickerThreadBlock : () => Unit = () => (),
431
- body : java.util.concurrent.ConcurrentMap [os.Path , Unit ] => T
444
+ tickerThreadBlock : () => Unit = () => (),
445
+ body : java.util.concurrent.ConcurrentMap [os.Path , Unit ] => T
432
446
)(implicit ctx : mill.api.Ctx ): T = {
433
447
val workerResultSet = new java.util.concurrent.ConcurrentHashMap [os.Path , Unit ]()
434
448
val executor = Executors .newScheduledThreadPool(1 )
@@ -437,14 +451,18 @@ private[scalalib] object TestModuleUtil {
437
451
executor.scheduleWithFixedDelay(
438
452
() => {
439
453
tickerThreadBlock()
440
- var totalSuccess = 0L
454
+ var totalSuccess = 0L
441
455
var totalFailure = 0L
442
456
workerResultSet.forEach { (resultLog, _) =>
443
457
val (success, failure) = upickle.default.read[(Long , Long )](os.read.stream(resultLog))
444
458
totalSuccess += success
445
459
totalFailure += failure
446
460
}
447
- ctx.log.ticker(s " ${totalSuccess + totalFailure}/ ${totalClassCount} completed ${ if (totalFailure > 0 ) { s " , ${totalFailure} failures. " } else { " ." } }" )
461
+ ctx.log.ticker(
462
+ s " ${totalSuccess + totalFailure}/ ${totalClassCount} completed ${if (totalFailure > 0 ) {
463
+ s " , ${totalFailure} failures. "
464
+ } else { " ." }}"
465
+ )
448
466
},
449
467
0 ,
450
468
20 ,
0 commit comments