@@ -6,7 +6,7 @@ package scala.tools.partest
6
6
package nest
7
7
8
8
import java .io .{Console => _ , _ }
9
- import java .util .concurrent .Executors
9
+ import java .util .concurrent .{ Executors , ExecutionException }
10
10
import java .util .concurrent .TimeUnit .NANOSECONDS
11
11
import scala .collection .mutable .ListBuffer
12
12
import scala .concurrent .duration .Duration
@@ -63,11 +63,11 @@ class Runner(val testFile: File, val suiteRunner: SuiteRunner, val nestUI: NestU
63
63
// except for a . per passing test to show progress.
64
64
def isEnumeratedTest = false
65
65
66
- private var _lastState : TestState = null
67
- private val _transcript = new TestTranscript
66
+ private [ this ] var _lastState : TestState = null
67
+ private [ this ] val _transcript = new TestTranscript
68
68
69
69
def lastState = if (_lastState == null ) Uninitialized (testFile) else _lastState
70
- def setLastState (s : TestState ) = _lastState = s
70
+ def lastState_= (s : TestState ) = _lastState = s
71
71
def transcript : List [String ] = _transcript.fail ++ logFile.fileLines
72
72
def pushTranscript (msg : String ) = _transcript add msg
73
73
@@ -141,7 +141,7 @@ class Runner(val testFile: File, val suiteRunner: SuiteRunner, val nestUI: NestU
141
141
*/
142
142
def nextTestAction [T ](body : => T )(failFn : PartialFunction [T , TestState ]): T = {
143
143
val result = body
144
- setLastState( if ( failFn isDefinedAt result) failFn(result) else genPass() )
144
+ lastState = failFn.applyOrElse( result, ( _ : T ) => genPass())
145
145
result
146
146
}
147
147
def nextTestActionExpectTrue (reason : String , body : => Boolean ): Boolean = (
@@ -204,15 +204,14 @@ class Runner(val testFile: File, val suiteRunner: SuiteRunner, val nestUI: NestU
204
204
protected def runCommand (args : Seq [String ], outFile : File ): Boolean = {
205
205
// (Process(args) #> outFile !) == 0 or (Process(args) ! pl) == 0
206
206
val pl = ProcessLogger (outFile)
207
- val nonzero = 17 // rounding down from 17.3
208
207
def run : Int = {
209
208
val p = Process (args) run pl
210
209
try p.exitValue
211
210
catch {
212
- case _ : InterruptedException =>
211
+ case ie : InterruptedException =>
213
212
nestUI.verbose(s " Interrupted waiting for command to finish ( ${args mkString " " }) " )
214
213
p.destroy
215
- nonzero
214
+ throw ie
216
215
case t : Throwable =>
217
216
nestUI.verbose(s " Exception waiting for command to finish: $t ( ${args mkString " " }) " )
218
217
p.destroy
@@ -399,9 +398,6 @@ class Runner(val testFile: File, val suiteRunner: SuiteRunner, val nestUI: NestU
399
398
else diff
400
399
_transcript append bestDiff
401
400
genFail(" output differs" )
402
- // TestState.fail("output differs", "output differs",
403
- // genFail("output differs")
404
- // TestState.Fail("output differs", bestDiff)
405
401
case None => genPass() // redundant default case
406
402
} getOrElse true
407
403
}
@@ -636,7 +632,7 @@ class Runner(val testFile: File, val suiteRunner: SuiteRunner, val nestUI: NestU
636
632
// and just looking at the diff, so I made them all do that
637
633
// because this is long enough.
638
634
if (! Output .withRedirected(logWriter)(try loop() finally resReader.close()))
639
- setLastState( genPass() )
635
+ lastState = genPass()
640
636
641
637
(diffIsOk, LogContext (logFile, swr, wr))
642
638
}
@@ -645,16 +641,22 @@ class Runner(val testFile: File, val suiteRunner: SuiteRunner, val nestUI: NestU
645
641
// javac runner, for one, would merely append to an existing log file, so just delete it before we start
646
642
logFile.delete()
647
643
648
- if (kind == " neg" || (kind endsWith " -neg" )) runNegTest()
649
- else kind match {
650
- case " pos" => runTestCommon(true )
651
- case " ant" => runAntTest()
652
- case " res" => runResidentTest()
653
- case " scalap" => runScalapTest()
654
- case " script" => runScriptTest()
655
- case _ => runTestCommon(execTest(outDir, logFile) && diffIsOk)
656
- }
644
+ def runWhatever () =
645
+ if (kind == " neg" || (kind endsWith " -neg" )) runNegTest()
646
+ else kind match {
647
+ case " pos" => runTestCommon(true )
648
+ case " ant" => runAntTest()
649
+ case " res" => runResidentTest()
650
+ case " scalap" => runScalapTest()
651
+ case " script" => runScriptTest()
652
+ case _ => runTestCommon(execTest(outDir, logFile) && diffIsOk)
653
+ }
657
654
655
+ try runWhatever()
656
+ catch {
657
+ case _ : InterruptedException => lastState = genTimeout()
658
+ case t : Throwable => lastState = genCrash(t)
659
+ }
658
660
lastState
659
661
}
660
662
@@ -731,7 +733,7 @@ class SuiteRunner(
731
733
val javaOpts : String = PartestDefaults .javaOpts,
732
734
val scalacOpts : String = PartestDefaults .scalacOpts) {
733
735
734
- import PartestDefaults .{ numThreads , waitTime }
736
+ import PartestDefaults .{numThreads , waitTime }
735
737
736
738
setUncaughtHandler
737
739
@@ -770,47 +772,47 @@ class SuiteRunner(
770
772
if (failed && ! runner.logFile.canRead)
771
773
runner.genPass()
772
774
else {
773
- val (state, _) =
774
- try timed(runner.run())
775
- catch {
776
- case t : Throwable => throw new RuntimeException (s " Error running $testFile" , t)
777
- }
775
+ val (state, time) = timed(runner.run())
776
+ nestUI.verbose(s " $testFile completed in $time" )
778
777
nestUI.reportTest(state, runner)
779
778
runner.cleanup()
780
779
state
781
780
}
782
781
onFinishTest(testFile, state)
783
782
}
784
783
785
- def runTestsForFiles (kindFiles : Array [File ]): Array [TestState ] = {
784
+ def runTestsForFiles (kindFiles : Array [File ]): Either [( Exception , Array [TestState ]), Array [ TestState ] ] = {
786
785
nestUI.resetTestNumber(kindFiles.size)
787
786
788
787
val pool = Executors .newFixedThreadPool(numThreads)
789
788
val futures = kindFiles.map(f => pool.submit(callable(runTest(f.getAbsoluteFile))))
790
789
791
790
pool.shutdown()
792
- Try (pool.awaitTermination(waitTime) {
793
- throw TimeoutException (waitTime)
794
- }) match {
795
- case Success (_) => futures map (_.get)
796
- case Failure (e) =>
791
+ Try (pool.awaitTermination(waitTime)(throw TimeoutException (waitTime))) match {
792
+ case Success (_) => Right (futures.map(_.get))
793
+ case Failure (e : Exception ) =>
797
794
e match {
798
795
case TimeoutException (_) =>
799
- nestUI.warning (" Thread pool timeout elapsed before all tests were complete!" )
796
+ nestUI.echoWarning (" Thread pool timeout elapsed before all tests were complete!" )
800
797
case ie : InterruptedException =>
801
- nestUI.warning (" Thread pool was interrupted" )
798
+ nestUI.echoWarning (" Thread pool was interrupted" )
802
799
ie.printStackTrace()
803
800
}
804
- pool.shutdownNow() // little point in continuing
805
- // try to get as many completions as possible, in case someone cares
806
- val results = for (f <- futures) yield {
801
+ pool.shutdownNow()
802
+ val states = (kindFiles, futures).zipped.map {(testFile, future) =>
807
803
try {
808
- Some (f.get(0 , NANOSECONDS ))
804
+ if (future.isDone) future.get(0 , NANOSECONDS ) else {
805
+ val s = Uninitialized (testFile)
806
+ onFinishTest(testFile, s) // reported as pending
807
+ s
808
+ }
809
809
} catch {
810
- case _ : Throwable => None
810
+ case e : ExecutionException => new Runner (testFile, this , nestUI).genCrash(e.getCause)
811
+ case _ : Throwable => new Runner (testFile, this , nestUI).genTimeout()
811
812
}
812
813
}
813
- results.flatten
814
+ Left ((e, states))
815
+ case Failure (t) => throw t
814
816
}
815
817
}
816
818
0 commit comments