@@ -51,6 +51,16 @@ trait ParallelTesting { self =>
51
51
def outDir : JFile
52
52
def flags : Array [String ]
53
53
54
+
55
+ def title : String = self match {
56
+ case self : JointCompilationSource =>
57
+ if (self.files.length > 1 ) name
58
+ else self.files.head.getPath
59
+
60
+ case self : SeparateCompilationSource =>
61
+ self.dir.getPath
62
+ }
63
+
54
64
/** Adds the flags specified in `newFlags0` if they do not already exist */
55
65
def withFlags (newFlags0 : String * ) = {
56
66
val newFlags = newFlags0.toArray
@@ -69,7 +79,11 @@ trait ParallelTesting { self =>
69
79
val maxLen = 80
70
80
var lineLen = 0
71
81
72
- sb.append(s " \n\n Test compiled with $errors error(s) and $warnings warning(s), the test can be reproduced by running: " )
82
+ sb.append(
83
+ s """ |
84
+ |Test ' $title' compiled with $errors error(s) and $warnings warning(s),
85
+ |the test can be reproduced by running: """ .stripMargin
86
+ )
73
87
sb.append(" \n\n ./bin/dotc " )
74
88
flags.foreach { arg =>
75
89
if (lineLen > maxLen) {
@@ -160,6 +174,8 @@ trait ParallelTesting { self =>
160
174
* according to the implementing class "neg", "run" or "pos".
161
175
*/
162
176
private abstract class Test (testSources : List [TestSource ], times : Int , threadLimit : Option [Int ], suppressAllOutput : Boolean ) {
177
+ protected final val realStdout = System .out
178
+ protected final val realStderr = System .err
163
179
164
180
/** Actual compilation run logic, the test behaviour is defined here */
165
181
protected def compilationRunnable (testSource : TestSource ): Runnable
@@ -178,10 +194,10 @@ trait ParallelTesting { self =>
178
194
val sourceCount = filteredSources.length
179
195
180
196
private [this ] var _errorCount = 0
181
- def errorCount : Int = synchronized { _errorCount }
197
+ def errorCount : Int = _errorCount
182
198
183
199
private [this ] var _testSourcesCompiled = 0
184
- private def testSourcesCompiled : Int = synchronized { _testSourcesCompiled }
200
+ private def testSourcesCompiled : Int = _testSourcesCompiled
185
201
186
202
/** Complete the current compilation with the amount of errors encountered */
187
203
protected final def registerCompilation (errors : Int ) = synchronized {
@@ -214,7 +230,7 @@ trait ParallelTesting { self =>
214
230
215
231
/** Prints to `System.err` if we're not suppressing all output */
216
232
protected def echo (msg : String ): Unit =
217
- if (! suppressAllOutput) System .err .println(msg)
233
+ if (! suppressAllOutput) realStderr .println(msg)
218
234
219
235
/** A single `Runnable` that prints a progress bar for the curent `Test` */
220
236
private def createProgressMonitor : Runnable = new Runnable {
@@ -224,17 +240,19 @@ trait ParallelTesting { self =>
224
240
while (tCompiled < sourceCount) {
225
241
val timestamp = (System .currentTimeMillis - start) / 1000
226
242
val progress = (tCompiled.toDouble / sourceCount * 40 ).toInt
227
- print(
243
+
244
+ realStdout.print(
228
245
" [" + (" =" * (math.max(progress - 1 , 0 ))) +
229
246
(if (progress > 0 ) " >" else " " ) +
230
247
(" " * (39 - progress)) +
231
248
s " ] compiling ( $tCompiled/ $sourceCount, ${timestamp}s) \r "
232
249
)
250
+
233
251
Thread .sleep(100 )
234
252
tCompiled = testSourcesCompiled
235
253
}
236
254
// println, otherwise no newline and cursor at start of line
237
- println(
255
+ realStdout. println(
238
256
s " [=======================================] compiled ( $sourceCount/ $sourceCount, " +
239
257
s " ${(System .currentTimeMillis - start) / 1000 }s) "
240
258
)
@@ -245,7 +263,10 @@ trait ParallelTesting { self =>
245
263
* if it did, the test should automatically fail.
246
264
*/
247
265
protected def tryCompile (testSource : TestSource )(op : => Unit ): Unit =
248
- try op catch {
266
+ try {
267
+ if (! isInteractive) realStdout.println(s " Testing ${testSource.title}" )
268
+ op
269
+ } catch {
249
270
case NonFatal (e) => {
250
271
// if an exception is thrown during compilation, the complete test
251
272
// run should fail
@@ -295,8 +316,10 @@ trait ParallelTesting { self =>
295
316
Runtime .getRuntime.exec(fullArgs).waitFor() == 0
296
317
} else true
297
318
298
- val reporter = TestReporter .parallelReporter(this , logLevel =
299
- if (suppressErrors || suppressAllOutput) ERROR + 1 else ERROR )
319
+ val reporter =
320
+ TestReporter .reporter(realStdout, logLevel =
321
+ if (suppressErrors || suppressAllOutput) ERROR + 1 else ERROR )
322
+
300
323
val driver =
301
324
if (times == 1 ) new Driver { def newCompiler (implicit ctx : Context ) = new Compiler }
302
325
else new Driver {
@@ -339,8 +362,12 @@ trait ParallelTesting { self =>
339
362
}
340
363
341
364
pool.shutdown()
342
- if (! pool.awaitTermination(10 , TimeUnit .MINUTES ))
365
+ if (! pool.awaitTermination(20 , TimeUnit .MINUTES )) {
366
+ pool.shutdownNow()
367
+ System .setOut(realStdout)
368
+ System .setErr(realStderr)
343
369
throw new TimeoutException (" Compiling targets timed out" )
370
+ }
344
371
345
372
if (didFail) {
346
373
reportFailed()
@@ -403,16 +430,14 @@ trait ParallelTesting { self =>
403
430
import java .net .{ URL , URLClassLoader }
404
431
405
432
val printStream = new ByteArrayOutputStream
406
- val oldOut = System .out
407
- val oldErr = System .err
408
433
409
434
try {
410
435
// Do classloading magic and running here:
411
436
val ucl = new URLClassLoader (Array (dir.toURI.toURL))
412
437
val cls = ucl.loadClass(" Test" )
413
438
val meth = cls.getMethod(" main" , classOf [Array [String ]])
414
439
415
- self. synchronized {
440
+ synchronized {
416
441
try {
417
442
val ps = new PrintStream (printStream)
418
443
System .setOut(ps)
@@ -422,9 +447,13 @@ trait ParallelTesting { self =>
422
447
meth.invoke(null , Array (" jvm" )) // partest passes at least "jvm" as an arg
423
448
}
424
449
}
425
- } finally {
426
- System .setOut(oldOut)
427
- System .setErr(oldErr)
450
+ System .setOut(realStdout)
451
+ System .setErr(realStderr)
452
+ } catch {
453
+ case t : Throwable =>
454
+ System .setOut(realStdout)
455
+ System .setErr(realStderr)
456
+ throw t
428
457
}
429
458
}
430
459
}
@@ -447,6 +476,7 @@ trait ParallelTesting { self =>
447
476
private def verifyOutput (checkFile : JFile , dir : JFile , testSource : TestSource , warnings : Int ) = {
448
477
val outputLines = runMain(dir, testSource)
449
478
val checkLines = Source .fromFile(checkFile).getLines.toArray
479
+ val sourceTitle = testSource.title
450
480
451
481
def linesMatch =
452
482
outputLines
@@ -456,9 +486,13 @@ trait ParallelTesting { self =>
456
486
if (outputLines.length != checkLines.length || ! linesMatch) {
457
487
// Print diff to files and summary:
458
488
val diff = outputLines.zip(checkLines).map { case (act, exp) =>
459
- DiffUtil .mkColoredCodeDiff (exp, act, true )
489
+ DiffUtil .mkColoredLineDiff (exp, act)
460
490
}.mkString(" \n " )
461
- val msg = s " \n Output from run test ' $checkFile' did not match expected, output: \n $diff\n "
491
+
492
+ val msg =
493
+ s """ |Output from ' $sourceTitle' did not match check file.
494
+ |Diff ('e' is expected, 'a' is actual):
495
+ | """ .stripMargin + diff + " \n "
462
496
echo(msg)
463
497
addFailureInstruction(msg)
464
498
@@ -920,9 +954,8 @@ trait ParallelTesting { self =>
920
954
private def compilationTargets (sourceDir : JFile ): (List [JFile ], List [JFile ]) =
921
955
sourceDir.listFiles.foldLeft((List .empty[JFile ], List .empty[JFile ])) { case ((dirs, files), f) =>
922
956
if (f.isDirectory) (f :: dirs, files)
923
- else if (f.getName.endsWith(" .check" )) (dirs, files)
924
- else if (f.getName.endsWith(" .flags" )) (dirs, files)
925
- else (dirs, f :: files)
957
+ else if (isSourceFile(f)) (dirs, f :: files)
958
+ else (dirs, files)
926
959
}
927
960
928
961
/** Gets the name of the calling method via reflection.
0 commit comments