Skip to content

Commit b7adb4c

Browse files
committed
Test can be skipped
1 parent 662ebc9 commit b7adb4c

File tree

2 files changed

+63
-51
lines changed

2 files changed

+63
-51
lines changed

compiler/test/dotty/tools/vulpix/ParallelTesting.scala

Lines changed: 62 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,11 @@ trait ParallelTesting extends RunnerOrchestration { self =>
384384
/** Number of failed tests */
385385
def failureCount: Int = _failureCount
386386

387+
private var _skipCount = 0
388+
protected final def skip(): Unit = synchronized { _skipCount += 1 }
389+
def skipCount: Int = _skipCount
390+
def skipped: Boolean = skipCount > 0
391+
387392
protected def logBuildInstructions(testSource: TestSource, reporters: Seq[TestReporter]) = {
388393
val (errCount, warnCount) = countErrorsAndWarnings(reporters)
389394
val errorMsg = testSource.buildInstructions(errCount, warnCount)
@@ -456,7 +461,7 @@ trait ParallelTesting extends RunnerOrchestration { self =>
456461
val toolArgs = toolArgsFor(files.toList.map(_.toPath), getCharsetFromEncodingOpt(flags0))
457462

458463
val spec = raw"(\d+)(\+)?".r
459-
val testFilter = toolArgs.get(ToolName.Test) match
464+
val testIsFiltered = toolArgs.get(ToolName.Test) match
460465
case Some("-jvm" :: spec(n, more) :: Nil) =>
461466
if more == "+" then isJavaAtLeast(n) else javaSpecVersion == n
462467
case Some(args) => throw new IllegalStateException(args.mkString("unknown test option: ", ", ", ""))
@@ -482,9 +487,7 @@ trait ParallelTesting extends RunnerOrchestration { self =>
482487
else None
483488
} else None
484489

485-
val reporter =
486-
TestReporter.reporter(realStdout, logLevel =
487-
if (suppressErrors || suppressAllOutput) ERROR + 1 else ERROR)
490+
val reporter = TestReporter.reporter(realStdout, logLevel = if (suppressErrors || suppressAllOutput) ERROR + 1 else ERROR)
488491

489492
val driver =
490493
if (times == 1) new Driver
@@ -503,7 +506,7 @@ trait ParallelTesting extends RunnerOrchestration { self =>
503506

504507
val allArgs = flags.all
505508

506-
if testFilter then
509+
if testIsFiltered then
507510
// If a test contains a Java file that cannot be parsed by Dotty's Java source parser, its
508511
// name must contain the string "JAVA_ONLY".
509512
val dottyFiles = files.filterNot(_.getName.contains("JAVA_ONLY")).map(_.getPath)
@@ -517,6 +520,8 @@ trait ParallelTesting extends RunnerOrchestration { self =>
517520
echo(s"\njava compilation failed: \n${ javaErrors.get }")
518521
fail(failure = JavaCompilationFailure(javaErrors.get))
519522
}
523+
else
524+
skip()
520525
end if
521526

522527
reporter
@@ -738,7 +743,8 @@ trait ParallelTesting extends RunnerOrchestration { self =>
738743
}
739744

740745
private def verifyOutput(checkFile: Option[JFile], dir: JFile, testSource: TestSource, warnings: Int, reporters: Seq[TestReporter], logger: LoggedRunnable) = {
741-
if (Properties.testsNoRun) addNoRunWarning()
746+
if skipped then ()
747+
else if Properties.testsNoRun then addNoRunWarning()
742748
else runMain(testSource.runClassPath) match {
743749
case Success(output) => checkFile match {
744750
case Some(file) if file.exists => diffTest(testSource, file, output.linesIterator.toList, reporters, logger)
@@ -762,7 +768,7 @@ trait ParallelTesting extends RunnerOrchestration { self =>
762768
extends Test(testSources, times, threadLimit, suppressAllOutput) {
763769
override def suppressErrors = true
764770

765-
override def maybeFailureMessage(testSource: TestSource, reporters: Seq[TestReporter]): Option[String] = {
771+
override def maybeFailureMessage(testSource: TestSource, reporters: Seq[TestReporter]): Option[String] = if skipped then None else
766772
def compilerCrashed = reporters.exists(_.compilerCrashed)
767773
lazy val (errorMap, expectedErrors) = getErrorMapAndExpectedCount(testSource.sourceFiles.toIndexedSeq)
768774
lazy val actualErrors = reporters.foldLeft(0)(_ + _.errorCount)
@@ -786,20 +792,21 @@ trait ParallelTesting extends RunnerOrchestration { self =>
786792
else if !errorMap.isEmpty then s"\nExpected error(s) have {<error position>=<unreported error>}: $errorMap"
787793
else null
788794
}
789-
}
795+
end maybeFailureMessage
790796

791797
override def onSuccess(testSource: TestSource, reporters: Seq[TestReporter], logger: LoggedRunnable): Unit =
792798
checkFile(testSource).foreach(diffTest(testSource, _, reporterOutputLines(reporters), reporters, logger))
793799

794800
def reporterOutputLines(reporters: Seq[TestReporter]): List[String] =
795801
reporters.flatMap(_.consoleOutput.split("\n")).toList
796802

797-
// In neg-tests we allow two types of error annotations,
798-
// "nopos-error" which doesn't care about position and "error" which
799-
// has to be annotated on the correct line number.
803+
// In neg-tests we allow two or three types of error annotations.
804+
// Normally, `// error` must be annotated on the correct line number.
805+
// `// nopos-error` allows for an error reported without a position.
806+
// `// anypos-error` allows for an error reported with a position that can't be annotated in the check file.
800807
//
801808
// We collect these in a map `"file:row" -> numberOfErrors`, for
802-
// nopos errors we save them in `"file" -> numberOfNoPosErrors`
809+
// nopos and anypos errors we save them in `"file" -> numberOfNoPosErrors`
803810
def getErrorMapAndExpectedCount(files: Seq[JFile]): (HashMap[String, Integer], Int) =
804811
val comment = raw"//( *)(nopos-|anypos-)?error".r
805812
val errorMap = new HashMap[String, Integer]()
@@ -964,8 +971,7 @@ trait ParallelTesting extends RunnerOrchestration { self =>
964971
* ===============
965972
* Since this is a parallel test suite, it is essential to be able to
966973
* compose tests to take advantage of the concurrency. This is done using
967-
* the `+` function. This function will make sure that tests being combined
968-
* are compatible according to the `require`s in `+`.
974+
* `aggregateTests` in the companion, which will ensure that aggregation is allowed.
969975
*/
970976
final class CompilationTest private (
971977
private[ParallelTesting] val targets: List[TestSource],
@@ -983,6 +989,14 @@ trait ParallelTesting extends RunnerOrchestration { self =>
983989
def this(targets: List[TestSource]) =
984990
this(targets, 1, true, None, false, false)
985991

992+
def copy(targets: List[TestSource],
993+
times: Int = times,
994+
shouldDelete: Boolean = shouldDelete,
995+
threadLimit: Option[Int] = threadLimit,
996+
shouldFail: Boolean = shouldFail,
997+
shouldSuppressOutput: Boolean = shouldSuppressOutput): CompilationTest =
998+
CompilationTest(targets, times, shouldDelete, threadLimit, shouldFail, shouldSuppressOutput)
999+
9861000
/** Creates a "pos" test run, which makes sure that all tests pass
9871001
* compilation without generating errors and that they do not crash the
9881002
* compiler
@@ -1003,23 +1017,23 @@ trait ParallelTesting extends RunnerOrchestration { self =>
10031017
}
10041018

10051019
/** Creates a "neg" test run, which makes sure that each test generates the
1006-
* correct amount of errors at the correct positions. It also makes sure
1007-
* that none of these tests crash the compiler
1020+
* correct number of errors at the correct positions. It also makes sure
1021+
* that none of these tests crashes the compiler.
10081022
*/
1009-
def checkExpectedErrors()(implicit summaryReport: SummaryReporting): this.type = {
1023+
def checkExpectedErrors()(implicit summaryReport: SummaryReporting): this.type =
10101024
val test = new NegTest(targets, times, threadLimit, shouldFail || shouldSuppressOutput).executeTestSuite()
10111025

10121026
cleanup()
10131027

1014-
if (shouldFail && !test.didFail) {
1015-
fail(s"Neg test shouldn't have failed, but did. Reasons:\n${ reasonsForFailure(test) }")
1016-
}
1017-
else if (!shouldFail && test.didFail) {
1018-
fail("Neg test should have failed, but did not")
1019-
}
1028+
if !test.skipped then
1029+
if shouldFail && !test.didFail then
1030+
fail(s"Neg test shouldn't have failed, but did. Reasons:\n${ reasonsForFailure(test) }")
1031+
else if !shouldFail && test.didFail then
1032+
fail("Neg test should have failed, but did not")
1033+
end if
10201034

10211035
this
1022-
}
1036+
end checkExpectedErrors
10231037

10241038
/** Creates a "fuzzy" test run, which makes sure that each test compiles (or not) without crashing */
10251039
def checkNoCrash()(implicit summaryReport: SummaryReporting): this.type = {
@@ -1044,12 +1058,12 @@ trait ParallelTesting extends RunnerOrchestration { self =>
10441058

10451059
cleanup()
10461060

1047-
if (!shouldFail && test.didFail) {
1048-
fail(s"Run test failed, but should not, reasons:\n${ reasonsForFailure(test) }")
1049-
}
1050-
else if (shouldFail && !test.didFail) {
1051-
fail("Run test should have failed, but did not")
1052-
}
1061+
if !test.skipped then
1062+
if !shouldFail && test.didFail then
1063+
fail(s"Run test failed, but should not, reasons:\n${ reasonsForFailure(test) }")
1064+
else if shouldFail && !test.didFail then
1065+
fail("Run test should have failed, but did not")
1066+
end if
10531067

10541068
this
10551069
}
@@ -1174,35 +1188,32 @@ trait ParallelTesting extends RunnerOrchestration { self =>
11741188
}
11751189
}
11761190

1177-
object CompilationTest {
1191+
object CompilationTest:
11781192

11791193
/** Compose test targets from `tests`
1180-
*
1181-
* It does this, only if the two tests are compatible. Otherwise it throws
1182-
* an `IllegalArgumentException`.
1183-
*
1184-
* Grouping tests together like this allows us to take advantage of the
1185-
* concurrency offered by this test suite as each call to an executing
1186-
* method (`pos()` / `checkExpectedErrors()`/ `run()`) will spin up a thread pool with the
1187-
* maximum allowed level of concurrency. Doing this for only a few targets
1188-
* does not yield any real benefit over sequential compilation.
1189-
*
1190-
* As such, each `CompilationTest` should contain as many targets as
1191-
* possible.
1192-
*/
1193-
def aggregateTests(tests: CompilationTest*): CompilationTest = {
1194+
*
1195+
* It does this, only if all the tests are mutally compatible.
1196+
* Otherwise it throws an `IllegalArgumentException`.
1197+
*
1198+
* Grouping tests together like this allows us to take advantage of the
1199+
* concurrency offered by this test suite, as each call to an executing
1200+
* method (`pos()` / `checkExpectedErrors()`/ `run()`) will spin up a thread pool with the
1201+
* maximum allowed level of concurrency. Doing this for only a few targets
1202+
* does not yield any real benefit over sequential compilation.
1203+
*
1204+
* As such, each `CompilationTest` should contain as many targets as
1205+
* possible.
1206+
*/
1207+
def aggregateTests(tests: CompilationTest*): CompilationTest =
11941208
assert(tests.nonEmpty)
1195-
def aggregate(test1: CompilationTest, test2: CompilationTest) = {
1209+
def aggregate(test1: CompilationTest, test2: CompilationTest) =
11961210
require(test1.times == test2.times, "can't combine tests that are meant to be benchmark compiled")
11971211
require(test1.shouldDelete == test2.shouldDelete, "can't combine tests that differ on deleting output")
11981212
require(test1.shouldFail == test2.shouldFail, "can't combine tests that have different expectations on outcome")
11991213
require(test1.shouldSuppressOutput == test2.shouldSuppressOutput, "can't combine tests that both suppress and don't suppress output")
1200-
new CompilationTest(test1.targets ++ test2.targets, test1.times, test1.shouldDelete, test1.threadLimit, test1.shouldFail, test1.shouldSuppressOutput)
1201-
}
1214+
test1.copy(test1.targets ++ test2.targets) // what if thread limit differs? currently threads are limited on aggregate only
12021215
tests.reduce(aggregate)
1203-
}
1204-
1205-
}
1216+
end CompilationTest
12061217

12071218
/** Create out directory for directory `d` */
12081219
def createOutputDirsForDir(d: JFile, sourceDir: JFile, outDir: String): JFile = {

tests/neg-with-compiler/t12290/SCALA_ONLY_Invalid1.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// test: -jvm 15+
2+
// note that scala's java parser doesn't care about the platform version
23
class SCALA_ONLY_Invalid1 {
34

45
public static final String badOpeningDelimiter = """non-whitespace // error

0 commit comments

Comments
 (0)