@@ -13,7 +13,6 @@ import java.util.zip.ZipInputStream
13
13
import scala .collection .mutable
14
14
import scala .jdk .CollectionConverters .IteratorHasAsScala
15
15
import java .io .PrintStream
16
- import java .util .concurrent .atomic .LongAdder
17
16
import java .util .concurrent .atomic .AtomicBoolean
18
17
19
18
@ internal object TestRunnerUtils {
@@ -138,18 +137,21 @@ import java.util.concurrent.atomic.AtomicBoolean
138
137
tasks : Seq [Task ],
139
138
testReporter : TestReporter ,
140
139
events : ConcurrentLinkedQueue [Event ],
141
- systemOut : PrintStream ,
142
- claimStatsFileOpt : Option [os.Path ]
143
- ): Unit = {
144
- val testEventSummary = new TestEventSummary (claimStatsFileOpt)
140
+ systemOut : PrintStream
141
+ ): Boolean = {
142
+ val taskStatus = new AtomicBoolean (true )
145
143
val taskQueue = tasks.to(mutable.Queue )
146
144
while (taskQueue.nonEmpty) {
147
145
val next = taskQueue.dequeue().execute(
148
146
new EventHandler {
149
147
def handle (event : Event ) = {
150
148
testReporter.logStart(event)
151
149
events.add(event)
152
- testEventSummary.record(event)
150
+ event.status match {
151
+ case Status .Error => taskStatus.set(false )
152
+ case Status .Failure => taskStatus.set(false )
153
+ case _ => taskStatus.compareAndSet(true , true ) // consider success as a default
154
+ }
153
155
testReporter.logFinish(event)
154
156
}
155
157
},
@@ -165,8 +167,7 @@ import java.util.concurrent.atomic.AtomicBoolean
165
167
166
168
taskQueue.enqueueAll(next)
167
169
}
168
- testEventSummary.summary()
169
- ()
170
+ taskStatus.get()
170
171
}
171
172
172
173
def parseRunTaskResults (events : Iterator [Event ]): Iterator [TestResult ] = {
@@ -217,7 +218,7 @@ import java.util.concurrent.atomic.AtomicBoolean
217
218
// isn't affected by a test framework's stream redirects
218
219
val systemOut = System .out
219
220
val events = new ConcurrentLinkedQueue [Event ]()
220
- executeTasks(tasks, testReporter, events, systemOut, None )
221
+ executeTasks(tasks, testReporter, events, systemOut)
221
222
handleRunnerDone(runner, events)
222
223
}
223
224
@@ -254,7 +255,9 @@ import java.util.concurrent.atomic.AtomicBoolean
254
255
val globSelectorCache = testClasses.view
255
256
.map { case (cls, fingerprint) => cls.getName.stripSuffix(" $" ) -> (cls, fingerprint) }
256
257
.toMap
257
-
258
+ var successCounter = 0L
259
+ var failureCounter = 0L
260
+
258
261
def runClaimedTestClass (testClassName : String ) = {
259
262
260
263
System .err.println(s " Running Test Class $testClassName" )
@@ -266,7 +269,9 @@ import java.util.concurrent.atomic.AtomicBoolean
266
269
}
267
270
268
271
val tasks = runner.tasks(taskDefs.toArray)
269
- executeTasks(tasks, testReporter, events, systemOut, Some (claimFolder / os.up / s " ${claimFolder.last}.stats " ))
272
+ val taskStatus = executeTasks(tasks, testReporter, events, systemOut)
273
+ if taskStatus then successCounter += 1 else failureCounter += 1
274
+ os.write.over(claimFolder / os.up / s " ${claimFolder.last}.stats " , upickle.default.write((successCounter, failureCounter)))
270
275
}
271
276
272
277
startingTestClass.foreach { testClass =>
@@ -277,6 +282,7 @@ import java.util.concurrent.atomic.AtomicBoolean
277
282
for (file <- os.list(testClassQueueFolder)) {
278
283
for (claimedTestClass <- claimFile(file, claimFolder)) runClaimedTestClass(claimedTestClass)
279
284
}
285
+
280
286
handleRunnerDone(runner, events)
281
287
}
282
288
@@ -287,8 +293,8 @@ import java.util.concurrent.atomic.AtomicBoolean
287
293
) {
288
294
// append only log, used to communicate with parent about what test is being claimed
289
295
// so that the parent can log the claimed test's name to its logger
290
- val queueLog = claimFolder / os.up / s " ${claimFolder.last}.log "
291
- os.write.append(queueLog , s " ${file.last}\n " )
296
+ val claimLog = claimFolder / os.up / s " ${claimFolder.last}.log "
297
+ os.write.append(claimLog , s " ${file.last}\n " )
292
298
file.last
293
299
}
294
300
}
@@ -356,24 +362,4 @@ import java.util.concurrent.atomic.AtomicBoolean
356
362
filters.exists(f => f(name))
357
363
}
358
364
}
359
-
360
- @ internal private [TestRunnerUtils ] final class TestEventSummary (outputFileOpt : Option [os.Path ]) extends AtomicBoolean (true ) {
361
- def record (event : Event ): Unit = {
362
- event.status() match {
363
- case Status .Error => set(false )
364
- case Status .Failure => set(false )
365
- case _ => val _ = compareAndSet(true , true ) // consider success as a default
366
- }
367
- }
368
-
369
- def summary (): Boolean = {
370
- val isSuccess = get()
371
- outputFileOpt.foreach { outputFile =>
372
- val (success, failure) = upickle.default.read[(Long , Long )](os.read.stream(outputFile))
373
- val (newSuccess, newFailure) = if (isSuccess) (success + 1 , failure) else (success, failure + 1 )
374
- os.write.over(outputFile, upickle.default.write((newSuccess, newFailure)))
375
- }
376
- isSuccess
377
- }
378
- }
379
365
}
0 commit comments