diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 43feeebfd74f..56b0b7457f83 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -119,9 +119,9 @@ jobs: run: sbt ";dotty-bootstrapped/compile ;dotty-bootstrapped/test" shell: cmd - # - name: Scala.js Test - # run: sbt ";sjsJUnitTests/test" - # shell: cmd + - name: Scala.js Test + run: sbt ";sjsJUnitTests/test ;sjsCompilerTests/test" + shell: cmd community_build: runs-on: [self-hosted, Linux] diff --git a/compiler/test/dotty/tools/dotc/BootstrappedOnlyCompilationTests.scala b/compiler/test/dotty/tools/dotc/BootstrappedOnlyCompilationTests.scala index 8682218f9fe2..74ae28909893 100644 --- a/compiler/test/dotty/tools/dotc/BootstrappedOnlyCompilationTests.scala +++ b/compiler/test/dotty/tools/dotc/BootstrappedOnlyCompilationTests.scala @@ -22,7 +22,7 @@ class BootstrappedOnlyCompilationTests extends ParallelTesting { // Test suite configuration -------------------------------------------------- def maxDuration = 60.seconds - def numberOfSlaves = 5 + def numberOfSlaves = Runtime.getRuntime().availableProcessors() def safeMode = Properties.testsSafeMode def isInteractive = SummaryReport.isInteractive def testFilter = Properties.testsFilter @@ -30,7 +30,7 @@ class BootstrappedOnlyCompilationTests extends ParallelTesting { // Positive tests ------------------------------------------------------------ - @Test def posMacros: Unit = if (!scala.util.Properties.isWin) { + @Test def posMacros: Unit = { implicit val testGroup: TestGroup = TestGroup("compilePosMacros") aggregateTests( compileFilesInDir("tests/bench", defaultOptions), @@ -129,17 +129,20 @@ class BootstrappedOnlyCompilationTests extends ParallelTesting { ) }.checkRuns() - @Test def runWithCompiler: Unit = if (!scala.util.Properties.isWin) { + @Test def runWithCompiler: Unit = { implicit val testGroup: TestGroup = TestGroup("runWithCompiler") - aggregateTests( + val basicTests = List( compileFilesInDir("tests/run-with-compiler", withCompilerOptions), compileFilesInDir("tests/run-staging", withStagingOptions), - compileFilesInDir("tests/run-custom-args/tasty-inspector", withTastyInspectorOptions), - compileDir("tests/run-custom-args/tasty-interpreter", withTastyInspectorOptions), - ).checkRuns() + compileFilesInDir("tests/run-custom-args/tasty-inspector", withTastyInspectorOptions) + ) + val tests = + if (scala.util.Properties.isWin) basicTests + else compileDir("tests/run-custom-args/tasty-interpreter", withTastyInspectorOptions) :: basicTests + aggregateTests(tests: _*).checkRuns() } - @Test def runBootstrappedOnly: Unit = if (!scala.util.Properties.isWin) { + @Test def runBootstrappedOnly: Unit = { implicit val testGroup: TestGroup = TestGroup("runBootstrappedOnly") aggregateTests( compileFilesInDir("tests/run-bootstrapped", withCompilerOptions), @@ -151,7 +154,7 @@ class BootstrappedOnlyCompilationTests extends ParallelTesting { // Pickling tests are very memory intensive and as such need to be run with a // lower level of concurrency as to not kill their running VMs - @Test def picklingWithCompiler: Unit = if (!scala.util.Properties.isWin) { + @Test def picklingWithCompiler: Unit = { val jvmBackendFilter = FileFilter.exclude(List("BTypes.scala", "Primitives.scala")) // TODO implicit val testGroup: TestGroup = TestGroup("testPicklingWithCompiler") aggregateTests( diff --git a/compiler/test/dotty/tools/dotc/CompilationTests.scala b/compiler/test/dotty/tools/dotc/CompilationTests.scala index 036b97dd3581..ed50b23e9c68 100644 --- a/compiler/test/dotty/tools/dotc/CompilationTests.scala +++ b/compiler/test/dotty/tools/dotc/CompilationTests.scala @@ -16,21 +16,12 @@ import scala.concurrent.duration._ import TestSources.sources import vulpix._ -class CompilationTests extends ParallelTesting { +class CompilationTests { import ParallelTesting._ import TestConfiguration._ import CompilationTests._ import CompilationTest.aggregateTests - // Test suite configuration -------------------------------------------------- - - def maxDuration = 45.seconds - def numberOfSlaves = 5 - def safeMode = Properties.testsSafeMode - def isInteractive = SummaryReport.isInteractive - def testFilter = Properties.testsFilter - def updateCheckFiles: Boolean = Properties.testsUpdateCheckfile - // Positive tests ------------------------------------------------------------ @Test def pos: Unit = { @@ -333,7 +324,19 @@ class CompilationTests extends ParallelTesting { } -object CompilationTests { +object CompilationTests extends ParallelTesting { + // Test suite configuration -------------------------------------------------- + + def maxDuration = 45.seconds + def numberOfSlaves = Runtime.getRuntime().availableProcessors() + def safeMode = Properties.testsSafeMode + def isInteractive = SummaryReport.isInteractive + def testFilter = Properties.testsFilter + def updateCheckFiles: Boolean = Properties.testsUpdateCheckfile + implicit val summaryReport: SummaryReporting = new SummaryReport - @AfterClass def cleanup(): Unit = summaryReport.echoSummary() + @AfterClass def tearDown(): Unit = { + super.cleanup() + summaryReport.echoSummary() + } } diff --git a/compiler/test/dotty/tools/dotc/FromTastyTests.scala b/compiler/test/dotty/tools/dotc/FromTastyTests.scala index 151d0826a176..4fa7dd016cd8 100644 --- a/compiler/test/dotty/tools/dotc/FromTastyTests.scala +++ b/compiler/test/dotty/tools/dotc/FromTastyTests.scala @@ -9,19 +9,10 @@ import java.io.{File => JFile} import scala.concurrent.duration._ -class FromTastyTests extends ParallelTesting { +class FromTastyTests { import TestConfiguration._ import FromTastyTests._ - // Test suite configuration -------------------------------------------------- - - def maxDuration = 30.seconds - def numberOfSlaves = 5 - def safeMode = Properties.testsSafeMode - def isInteractive = SummaryReport.isInteractive - def testFilter = Properties.testsFilter - def updateCheckFiles: Boolean = Properties.testsUpdateCheckfile - @Test def posTestFromTasty: Unit = { // Can be reproduced with // > sbt @@ -46,7 +37,19 @@ class FromTastyTests extends ParallelTesting { } } -object FromTastyTests { +object FromTastyTests extends ParallelTesting { + // Test suite configuration -------------------------------------------------- + + def maxDuration = 30.seconds + def numberOfSlaves = Runtime.getRuntime().availableProcessors() + def safeMode = Properties.testsSafeMode + def isInteractive = SummaryReport.isInteractive + def testFilter = Properties.testsFilter + def updateCheckFiles: Boolean = Properties.testsUpdateCheckfile + implicit val summaryReport: SummaryReporting = new SummaryReport - @AfterClass def cleanup(): Unit = summaryReport.echoSummary() + @AfterClass def tearDown(): Unit = { + super.cleanup() + summaryReport.echoSummary() + } } diff --git a/compiler/test/dotty/tools/dotc/IdempotencyTests.scala b/compiler/test/dotty/tools/dotc/IdempotencyTests.scala index 1d8b353152ef..30dbb47475ff 100644 --- a/compiler/test/dotty/tools/dotc/IdempotencyTests.scala +++ b/compiler/test/dotty/tools/dotc/IdempotencyTests.scala @@ -13,20 +13,11 @@ import scala.concurrent.duration._ import vulpix._ -class IdempotencyTests extends ParallelTesting { +class IdempotencyTests { import TestConfiguration._ import IdempotencyTests._ import CompilationTest.aggregateTests - // Test suite configuration -------------------------------------------------- - - def maxDuration = 30.seconds - def numberOfSlaves = 5 - def safeMode = Properties.testsSafeMode - def isInteractive = SummaryReport.isInteractive - def testFilter = Properties.testsFilter - def updateCheckFiles: Boolean = Properties.testsUpdateCheckfile - @Category(Array(classOf[SlowTests])) @Test def idempotency: Unit = { implicit val testGroup: TestGroup = TestGroup("idempotency") @@ -71,7 +62,19 @@ class IdempotencyTests extends ParallelTesting { } -object IdempotencyTests { +object IdempotencyTests extends ParallelTesting { + // Test suite configuration -------------------------------------------------- + + def maxDuration = 30.seconds + def numberOfSlaves = 5 + def safeMode = Properties.testsSafeMode + def isInteractive = SummaryReport.isInteractive + def testFilter = Properties.testsFilter + def updateCheckFiles: Boolean = Properties.testsUpdateCheckfile + implicit val summaryReport: SummaryReporting = new SummaryReport - @AfterClass def cleanup(): Unit = summaryReport.echoSummary() + @AfterClass def tearDown(): Unit = { + super.cleanup() + summaryReport.echoSummary() + } } diff --git a/compiler/test/dotty/tools/vulpix/RunnerOrchestration.scala b/compiler/test/dotty/tools/vulpix/RunnerOrchestration.scala index 4fd415a1dcd2..c6be1856564a 100644 --- a/compiler/test/dotty/tools/vulpix/RunnerOrchestration.scala +++ b/compiler/test/dotty/tools/vulpix/RunnerOrchestration.scala @@ -49,6 +49,9 @@ trait RunnerOrchestration { def runMain(classPath: String)(implicit summaryReport: SummaryReporting): Status = monitor.runMain(classPath) + /** Kill all processes */ + def cleanup() = monitor.killAll() + private val monitor = new RunnerMonitor /** The runner monitor object keeps track of child JVM processes by keeping @@ -167,14 +170,15 @@ trait RunnerOrchestration { .start() } - private val allRunners = List.fill(numberOfSlaves)(new Runner(createProcess)) - private val freeRunners = mutable.Queue(allRunners: _*) + private val freeRunners = mutable.Queue.empty[Runner] private val busyRunners = mutable.Set.empty[Runner] private def getRunner(): Runner = synchronized { - while (freeRunners.isEmpty) wait() + while (freeRunners.isEmpty && busyRunners.size >= numberOfSlaves) wait() - val runner = freeRunners.dequeue() + val runner = + if (freeRunners.isEmpty) new Runner(createProcess) + else freeRunners.dequeue() busyRunners += runner notify() @@ -194,7 +198,10 @@ trait RunnerOrchestration { result } - private def killAll(): Unit = allRunners.foreach(_.kill()) + def killAll(): Unit = { + freeRunners.foreach(_.kill()) + busyRunners.foreach(_.kill()) + } // On shutdown, we need to kill all runners: sys.addShutdownHook(killAll()) diff --git a/compiler/test/dotty/tools/vulpix/VulpixMetaTests.scala b/compiler/test/dotty/tools/vulpix/VulpixMetaTests.scala index e79b983c2b83..befb4701f371 100644 --- a/compiler/test/dotty/tools/vulpix/VulpixMetaTests.scala +++ b/compiler/test/dotty/tools/vulpix/VulpixMetaTests.scala @@ -1,7 +1,7 @@ package dotty.tools package vulpix -import org.junit.Test +import org.junit.{ Test, AfterClass } import org.junit.experimental.categories.Category import scala.concurrent.duration._ import TestConfiguration._ @@ -11,14 +11,8 @@ import TestConfiguration._ * output against an expected result. */ @Category(Array(classOf[dotty.VulpixMetaTests])) -class VulpixMetaTests extends ParallelTesting { - def maxDuration = 1.seconds - // Ensure maximum reproducibility. - def numberOfSlaves = 1 - def safeMode = false // Don't fork a new VM after each run test - def isInteractive = false // Don't beautify output for interactive use. - def testFilter = None // Run all the tests. - def updateCheckFiles: Boolean = false +class VulpixMetaTests { + import VulpixMetaTests._ implicit val summaryReport: SummaryReporting = new SummaryReport implicit def testGroup: TestGroup = TestGroup("VulpixMetaTests") @@ -27,3 +21,16 @@ class VulpixMetaTests extends ParallelTesting { @Test def compileNeg: Unit = compileFilesInDir("tests/vulpix-tests/meta/neg", defaultOptions).checkExpectedErrors() @Test def runAll: Unit = compileFilesInDir("tests/vulpix-tests/meta/run", defaultOptions).checkRuns() } + +object VulpixMetaTests extends ParallelTesting { + def maxDuration = 1.seconds + // Ensure maximum reproducibility. + def numberOfSlaves = 1 + def safeMode = false // Don't fork a new VM after each run test + def isInteractive = false // Don't beautify output for interactive use. + def testFilter = None // Run all the tests. + def updateCheckFiles: Boolean = false + + @AfterClass + def tearDown() = this.cleanup() +} \ No newline at end of file diff --git a/compiler/test/dotty/tools/vulpix/VulpixUnitTests.scala b/compiler/test/dotty/tools/vulpix/VulpixUnitTests.scala index a813138fedba..cdbd55af61d4 100644 --- a/compiler/test/dotty/tools/vulpix/VulpixUnitTests.scala +++ b/compiler/test/dotty/tools/vulpix/VulpixUnitTests.scala @@ -3,30 +3,24 @@ package vulpix import java.io.{File => JFile} import org.junit.Assert._ -import org.junit.Test +import org.junit.{ Test, AfterClass } import scala.concurrent.duration._ import scala.util.control.NonFatal /** Unit tests for the Vulpix test suite */ -class VulpixUnitTests extends ParallelTesting { +class VulpixUnitTests { + import VulpixUnitTests._ import TestConfiguration._ implicit val _: SummaryReporting = new NoSummaryReport implicit def testGroup: TestGroup = TestGroup("VulpixTests") - def maxDuration = 3.seconds - def numberOfSlaves = 5 - def safeMode = sys.env.get("SAFEMODE").isDefined - def isInteractive = !sys.env.contains("DRONE") - def testFilter = None - def updateCheckFiles: Boolean = false - // To fail with something else than an AssertionError def fail(): Unit = throw new Exception("didn't fail properly") - @Test def missingFile: Unit = if (!scala.util.Properties.isWin) + @Test def missingFile: Unit = try { compileFile("tests/vulpix-tests/unit/i-dont-exist.scala", defaultOptions).expectFailure.checkExpectedErrors() fail() @@ -64,7 +58,7 @@ class VulpixUnitTests extends ParallelTesting { @Test def runDiffOutput1: Unit = compileFile("tests/vulpix-tests/unit/runDiffOutput1.scala", defaultOptions).expectFailure.checkRuns() - @Test def runStackOverflow: Unit = if (!scala.util.Properties.isWin) + @Test def runStackOverflow: Unit = compileFile("tests/vulpix-tests/unit/stackOverflow.scala", defaultOptions).expectFailure.checkRuns() @Test def runOutRedirects: Unit = @@ -82,7 +76,7 @@ class VulpixUnitTests extends ParallelTesting { @Test def deadlock: Unit = compileFile("tests/vulpix-tests/unit/deadlock.scala", defaultOptions).expectFailure.checkRuns() - @Test def badJava: Unit = if (!scala.util.Properties.isWin) + @Test def badJava: Unit = try { compileFile("tests/vulpix-tests/unit/BadJava.java", defaultOptions).suppressAllOutput.checkCompile() fail() @@ -90,7 +84,7 @@ class VulpixUnitTests extends ParallelTesting { case ae: AssertionError => assertTrue(ae.getMessage.contains("java compilation failed")) } - @Test def runTimeout: Unit = if (!scala.util.Properties.isWin) { + @Test def runTimeout: Unit = { val fileName = s"tests/vulpix-tests/unit/timeout.scala" try { compileFile(fileName, defaultOptions).checkRuns() @@ -103,3 +97,16 @@ class VulpixUnitTests extends ParallelTesting { } } } + + +object VulpixUnitTests extends ParallelTesting { + def maxDuration = 3.seconds + def numberOfSlaves = 5 + def safeMode = sys.env.get("SAFEMODE").isDefined + def isInteractive = !sys.env.contains("DRONE") + def testFilter = None + def updateCheckFiles: Boolean = false + + @AfterClass + def tearDown() = this.cleanup() +} \ No newline at end of file