@@ -6,22 +6,21 @@ import java.io.{ File => JFile }
6
6
import java .text .SimpleDateFormat
7
7
import java .util .HashMap
8
8
import java .nio .file .StandardCopyOption .REPLACE_EXISTING
9
- import java .nio .file .{ Files , Path , Paths , NoSuchFileException }
10
- import java .util .concurrent .{ Executors => JExecutors , TimeUnit , TimeoutException }
9
+ import java .nio .file .{ Files , NoSuchFileException , Path , Paths }
10
+ import java .util .concurrent .{ TimeUnit , TimeoutException , Executors => JExecutors }
11
11
12
12
import scala .io .Source
13
13
import scala .util .control .NonFatal
14
14
import scala .util .Try
15
15
import scala .collection .mutable
16
16
import scala .util .matching .Regex
17
17
import scala .util .Random
18
-
19
18
import dotc .core .Contexts ._
20
- import dotc .reporting .{ Reporter , TestReporter }
19
+ import dotc .reporting .{ Reporter , StoredTestReporter , TestReporter }
21
20
import dotc .reporting .diagnostic .MessageContainer
22
21
import dotc .interfaces .Diagnostic .ERROR
23
22
import dotc .util .DiffUtil
24
- import dotc .{ Driver , Compiler }
23
+ import dotc .{ Compiler , Driver }
25
24
26
25
/** A parallel testing suite whose goal is to integrate nicely with JUnit
27
26
*
@@ -47,7 +46,7 @@ trait ParallelTesting extends RunnerOrchestration { self =>
47
46
/** A test source whose files or directory of files is to be compiled
48
47
* in a specific way defined by the `Test`
49
48
*/
50
- private sealed trait TestSource { self =>
49
+ sealed trait TestSource { self =>
51
50
def name : String
52
51
def outDir : JFile
53
52
def flags : TestFlags
@@ -128,7 +127,7 @@ trait ParallelTesting extends RunnerOrchestration { self =>
128
127
/** A group of files that may all be compiled together, with the same flags
129
128
* and output directory
130
129
*/
131
- private final case class JointCompilationSource (
130
+ final case class JointCompilationSource (
132
131
name : String ,
133
132
files : Array [JFile ],
134
133
flags : TestFlags ,
@@ -142,7 +141,7 @@ trait ParallelTesting extends RunnerOrchestration { self =>
142
141
/** A test source whose files will be compiled separately according to their
143
142
* suffix `_X`
144
143
*/
145
- private final case class SeparateCompilationSource (
144
+ final case class SeparateCompilationSource (
146
145
name : String ,
147
146
dir : JFile ,
148
147
flags : TestFlags ,
@@ -175,7 +174,7 @@ trait ParallelTesting extends RunnerOrchestration { self =>
175
174
/** Each `Test` takes the `testSources` and performs the compilation and assertions
176
175
* according to the implementing class "neg", "run" or "pos".
177
176
*/
178
- private abstract class Test (testSources : List [TestSource ], times : Int , threadLimit : Option [Int ], suppressAllOutput : Boolean )(implicit val summaryReport : SummaryReporting ) { test =>
177
+ private abstract class Test (testSources : List [TestSource ], times : Int , threadLimit : Option [Int ], suppressAllOutput : Boolean , checkCompileOutput : Boolean = false )(implicit val summaryReport : SummaryReporting ) { test =>
179
178
180
179
import summaryReport ._
181
180
@@ -360,9 +359,12 @@ trait ParallelTesting extends RunnerOrchestration { self =>
360
359
else None
361
360
} else None
362
361
362
+ val logLevel = if (suppressErrors || suppressAllOutput) ERROR + 1 else ERROR
363
363
val reporter =
364
- TestReporter .reporter(realStdout, logLevel =
365
- if (suppressErrors || suppressAllOutput) ERROR + 1 else ERROR )
364
+ if (checkCompileOutput)
365
+ TestReporter .storedReporter(realStdout, logLevel = logLevel)
366
+ else
367
+ TestReporter .reporter(realStdout, logLevel = logLevel)
366
368
367
369
val driver =
368
370
if (times == 1 ) new Driver
@@ -440,10 +442,28 @@ trait ParallelTesting extends RunnerOrchestration { self =>
440
442
441
443
this
442
444
}
445
+
446
+ protected def verifyCompileOutput (source : TestSource , checkFile : JFile , reporter : StoredTestReporter ): Unit = {
447
+ reporter.writer.flush()
448
+ val checkLines = Source .fromFile(checkFile).getLines().mkString(" \n " )
449
+ val outputLines = reporter.writer.toString.trim.replaceAll(" \\ s+\n " , " \n " )
450
+
451
+ if (outputLines != checkLines) {
452
+ val msg = s " Output from ' ${source.title}' did not match check file ' ${checkFile.getName}'. "
453
+ println(" ===============================" )
454
+ println(" expected: \n " + checkLines)
455
+ println(" actual: \n " + outputLines)
456
+ println(" ===============================" )
457
+
458
+ echo(msg)
459
+ addFailureInstruction(msg)
460
+ failTestSource(source)
461
+ }
462
+ }
443
463
}
444
464
445
- private final class PosTest (testSources : List [TestSource ], times : Int , threadLimit : Option [Int ], suppressAllOutput : Boolean )(implicit summaryReport : SummaryReporting )
446
- extends Test (testSources, times, threadLimit, suppressAllOutput) {
465
+ private final class PosTest (testSources : List [TestSource ], times : Int , threadLimit : Option [Int ], suppressAllOutput : Boolean , checkCompileOutput : Boolean = false )(implicit summaryReport : SummaryReporting )
466
+ extends Test (testSources, times, threadLimit, suppressAllOutput, checkCompileOutput ) {
447
467
protected def encapsulatedCompilation (testSource : TestSource ) = new LoggedRunnable {
448
468
def checkTestSource (): Unit = tryCompile(testSource) {
449
469
testSource match {
@@ -475,6 +495,14 @@ trait ParallelTesting extends RunnerOrchestration { self =>
475
495
reporters.foreach(logReporterContents)
476
496
logBuildInstructions(reporters.head, testSource, errorCount, warningCount)
477
497
}
498
+
499
+ // verify compilation check file
500
+ (1 to testSource.compilationGroups.length).foreach { index =>
501
+ val checkFile = new JFile (dir.getAbsolutePath.reverse.dropWhile(_ == '/' ).reverse + " /" + index + " .check" )
502
+
503
+ if (checkFile.exists && checkCompileOutput)
504
+ verifyCompileOutput(testSource, checkFile, reporters(index).asInstanceOf [StoredTestReporter ])
505
+ }
478
506
}
479
507
}
480
508
}
@@ -599,8 +627,8 @@ trait ParallelTesting extends RunnerOrchestration { self =>
599
627
}
600
628
}
601
629
602
- private final class NegTest (testSources : List [TestSource ], times : Int , threadLimit : Option [Int ], suppressAllOutput : Boolean )(implicit summaryReport : SummaryReporting )
603
- extends Test (testSources, times, threadLimit, suppressAllOutput) {
630
+ private final class NegTest (testSources : List [TestSource ], times : Int , threadLimit : Option [Int ], suppressAllOutput : Boolean , checkCompileOutput : Boolean = false )(implicit summaryReport : SummaryReporting )
631
+ extends Test (testSources, times, threadLimit, suppressAllOutput, checkCompileOutput ) {
604
632
protected def encapsulatedCompilation (testSource : TestSource ) = new LoggedRunnable {
605
633
def checkTestSource (): Unit = tryCompile(testSource) {
606
634
// In neg-tests we allow two types of error annotations,
@@ -678,6 +706,14 @@ trait ParallelTesting extends RunnerOrchestration { self =>
678
706
if (actualErrors > 0 )
679
707
reporters.foreach(logReporterContents)
680
708
709
+ // Compilation check file: for testing plugins
710
+ (1 to testSource.compilationGroups.length).foreach { index =>
711
+ val checkFile = new JFile (dir.getAbsolutePath.reverse.dropWhile(_ == '/' ).reverse + " /" + index + " .check" )
712
+
713
+ if (checkFile.exists && checkCompileOutput)
714
+ verifyCompileOutput(testSource, checkFile, reporters(index).asInstanceOf [StoredTestReporter ])
715
+ }
716
+
681
717
(compilerCrashed, expectedErrors, actualErrors, () => getMissingExpectedErrors(errorMap, errors), errorMap)
682
718
}
683
719
}
@@ -825,10 +861,10 @@ trait ParallelTesting extends RunnerOrchestration { self =>
825
861
) {
826
862
import org .junit .Assert .fail
827
863
828
- private [ ParallelTesting ] def this (target : TestSource ) =
864
+ def this (target : TestSource ) =
829
865
this (List (target), 1 , true , None , false , false )
830
866
831
- private [ ParallelTesting ] def this (targets : List [TestSource ]) =
867
+ def this (targets : List [TestSource ]) =
832
868
this (targets, 1 , true , None , false , false )
833
869
834
870
/** Compose test targets from `this` with `other`
@@ -857,8 +893,10 @@ trait ParallelTesting extends RunnerOrchestration { self =>
857
893
* compilation without generating errors and that they do not crash the
858
894
* compiler
859
895
*/
860
- def checkCompile ()(implicit summaryReport : SummaryReporting ): this .type = {
861
- val test = new PosTest (targets, times, threadLimit, shouldFail || shouldSuppressOutput).executeTestSuite()
896
+ def checkCompile (checkCompileOutput : Boolean = false )(implicit summaryReport : SummaryReporting ): this .type = {
897
+ val test = new PosTest (targets, times, threadLimit, shouldFail || shouldSuppressOutput, checkCompileOutput).executeTestSuite()
898
+
899
+ cleanup()
862
900
863
901
if (! shouldFail && test.didFail) {
864
902
fail(s " Expected no errors when compiling, failed for the following reason(s): \n ${ reasonsForFailure(test) }" )
@@ -867,15 +905,17 @@ trait ParallelTesting extends RunnerOrchestration { self =>
867
905
fail(" Pos test should have failed, but didn't" )
868
906
}
869
907
870
- cleanup()
908
+ this
871
909
}
872
910
873
911
/** Creates a "neg" test run, which makes sure that each test generates the
874
912
* correct amount of errors at the correct positions. It also makes sure
875
913
* that none of these tests crash the compiler
876
914
*/
877
- def checkExpectedErrors ()(implicit summaryReport : SummaryReporting ): this .type = {
878
- val test = new NegTest (targets, times, threadLimit, shouldFail || shouldSuppressOutput).executeTestSuite()
915
+ def checkExpectedErrors (checkCompileOutput : Boolean = false )(implicit summaryReport : SummaryReporting ): this .type = {
916
+ val test = new NegTest (targets, times, threadLimit, shouldFail || shouldSuppressOutput, checkCompileOutput).executeTestSuite()
917
+
918
+ cleanup()
879
919
880
920
if (! shouldFail && test.didFail) {
881
921
fail(s " Neg test shouldn't have failed, but did. Reasons: \n ${ reasonsForFailure(test) }" )
@@ -884,7 +924,7 @@ trait ParallelTesting extends RunnerOrchestration { self =>
884
924
fail(" Neg test should have failed, but did not" )
885
925
}
886
926
887
- cleanup()
927
+ this
888
928
}
889
929
890
930
/** Creates a "run" test run, which is a superset of "pos". In addition to
@@ -895,14 +935,16 @@ trait ParallelTesting extends RunnerOrchestration { self =>
895
935
def checkRuns ()(implicit summaryReport : SummaryReporting ): this .type = {
896
936
val test = new RunTest (targets, times, threadLimit, shouldFail || shouldSuppressOutput).executeTestSuite()
897
937
938
+ cleanup()
939
+
898
940
if (! shouldFail && test.didFail) {
899
941
fail(s " Run test failed, but should not, reasons: \n ${ reasonsForFailure(test) }" )
900
942
}
901
943
else if (shouldFail && ! test.didFail) {
902
944
fail(" Run test should have failed, but did not" )
903
945
}
904
946
905
- cleanup()
947
+ this
906
948
}
907
949
908
950
/** Deletes output directories and files */
@@ -1005,7 +1047,7 @@ trait ParallelTesting extends RunnerOrchestration { self =>
1005
1047
}
1006
1048
1007
1049
/** Create out directory for directory `d` */
1008
- private def createOutputDirsForDir (d : JFile , sourceDir : JFile , outDir : String ): JFile = {
1050
+ def createOutputDirsForDir (d : JFile , sourceDir : JFile , outDir : String ): JFile = {
1009
1051
val targetDir = new JFile (outDir + s " ${sourceDir.getName}/ ${d.getName}" )
1010
1052
targetDir.mkdirs()
1011
1053
targetDir
0 commit comments