Skip to content

Commit e5c3d78

Browse files
author
Adriaan Moors
committed
Merge pull request scala#870 from paulp/topic/partest-no-actors
faster partest
2 parents f25713b + 883371e commit e5c3d78

File tree

9 files changed

+900
-1175
lines changed

9 files changed

+900
-1175
lines changed

src/partest/scala/tools/partest/PartestDefaults.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ package partest
44
import nsc.io.{ File, Path, Directory }
55
import util.{ PathResolver }
66
import nsc.Properties.{ propOrElse, propOrNone, propOrEmpty }
7+
import java.lang.Runtime.getRuntime
78

89
object PartestDefaults {
910
import nsc.Properties._
@@ -22,10 +23,9 @@ object PartestDefaults {
2223
def javaOpts = propOrElse("partest.java_opts", "")
2324
def scalacOpts = propOrElse("partest.scalac_opts", "-deprecation")
2425

25-
def testBuild = propOrNone("partest.build")
26-
def errorCount = propOrElse("partest.errors", "0").toInt
27-
def numActors = propOrElse("partest.actors", "6").toInt
28-
def poolSize = wrapAccessControl(propOrNone("actors.corePoolSize"))
26+
def testBuild = propOrNone("partest.build")
27+
def errorCount = propOrElse("partest.errors", "0").toInt
28+
def numThreads = propOrNone("partest.threads") map (_.toInt) getOrElse getRuntime.availableProcessors
2929

3030
def timeout = "1200000"
3131
}

src/partest/scala/tools/partest/PartestTask.scala

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
package scala.tools
1010
package partest
1111

12-
import scala.actors.Actor._
1312
import scala.util.Properties.setProp
1413
import scala.tools.nsc.io.{ Directory, Path => SPath }
1514
import nsc.util.ClassPath
@@ -385,12 +384,12 @@ class PartestTask extends Task with CompilationPathProperty {
385384
if (files.isEmpty) (0, 0, List())
386385
else {
387386
log(msg)
388-
val results: Iterable[(String, Int)] = antRunner.reflectiveRunTestsForFiles(files, name)
387+
val results: Iterable[(String, TestState)] = antRunner.reflectiveRunTestsForFiles(files, name)
389388
val (succs, fails) = resultsToStatistics(results)
390389

391390
val failed: Iterable[String] = results collect {
392-
case (path, 1) => path + " [FAILED]"
393-
case (path, 2) => path + " [TIMOUT]"
391+
case (path, TestState.Fail) => path + " [FAILED]"
392+
case (path, TestState.Timeout) => path + " [TIMOUT]"
394393
}
395394

396395
// create JUnit Report xml files if directory was specified
@@ -422,16 +421,16 @@ class PartestTask extends Task with CompilationPathProperty {
422421
f(msg)
423422
}
424423

425-
private def oneResult(res: (String, Int)) =
424+
private def oneResult(res: (String, TestState)) =
426425
<testcase name={res._1}>{
427426
res._2 match {
428-
case 0 => scala.xml.NodeSeq.Empty
429-
case 1 => <failure message="Test failed"/>
430-
case 2 => <failure message="Test timed out"/>
427+
case TestState.Ok => scala.xml.NodeSeq.Empty
428+
case TestState.Fail => <failure message="Test failed"/>
429+
case TestState.Timeout => <failure message="Test timed out"/>
431430
}
432431
}</testcase>
433432

434-
private def testReport(kind: String, results: Iterable[(String, Int)], succs: Int, fails: Int) =
433+
private def testReport(kind: String, results: Iterable[(String, TestState)], succs: Int, fails: Int) =
435434
<testsuite name={kind} tests={(succs + fails).toString} failures={fails.toString}>
436435
<properties/>
437436
{

src/partest/scala/tools/partest/nest/ConsoleRunner.scala

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import scala.tools.nsc.Properties.{ versionMsg, setProp }
1616
import scala.tools.nsc.util.CommandLineParser
1717
import scala.tools.nsc.io
1818
import io.{ Path }
19+
import scala.collection.{ mutable, immutable }
1920

2021
class ConsoleRunner extends DirectRunner {
2122
import PathSettings.{ srcDir, testRoot }
@@ -105,8 +106,6 @@ class ConsoleRunner extends DirectRunner {
105106
if (parsed isSet "--timeout") fileManager.timeout = parsed("--timeout")
106107
if (parsed isSet "--debug") setProp("partest.debug", "true")
107108

108-
setProperties() // must be done after processing command line arguments such as --debug
109-
110109
def addTestFile(file: File) = {
111110
if (!file.exists)
112111
NestUI.failure("Test file '%s' not found, skipping.\n" format file)
@@ -171,13 +170,10 @@ class ConsoleRunner extends DirectRunner {
171170
if (grepMessage != "")
172171
NestUI.normal(grepMessage + "\n")
173172

174-
val start = System.currentTimeMillis
175-
val (successes, failures) = testCheckAll(enabledTestSets)
176-
val end = System.currentTimeMillis
177-
173+
val ((successes, failures), elapsedMillis) = timed(testCheckAll(enabledTestSets))
178174
val total = successes + failures
179175

180-
val elapsedSecs = (end - start)/1000
176+
val elapsedSecs = elapsedMillis/1000
181177
val elapsedMins = elapsedSecs/60
182178
val elapsedHrs = elapsedMins/60
183179
val dispMins = elapsedMins - elapsedHrs * 60
@@ -188,7 +184,6 @@ class ConsoleRunner extends DirectRunner {
188184
form(elapsedHrs)+":"+form(dispMins)+":"+form(dispSecs)
189185
}
190186

191-
println
192187
if (failures == 0)
193188
NestUI.success("All of "+total+" tests were successful (elapsed time: "+dispElapsed+")\n")
194189
else

src/partest/scala/tools/partest/nest/DirectRunner.scala

Lines changed: 20 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,15 @@ import scala.util.Properties.setProp
1313
import scala.tools.nsc.util.ScalaClassLoader
1414
import scala.tools.nsc.io.Path
1515
import scala.collection.{ mutable, immutable }
16-
import scala.actors.Actor._
17-
import scala.actors.TIMEOUT
16+
import java.util.concurrent._
17+
import scala.collection.convert.decorateAll._
1818

1919
case class TestRunParams(val scalaCheckParentClassLoader: ScalaClassLoader)
2020

2121
trait DirectRunner {
22-
2322
def fileManager: FileManager
2423

25-
import PartestDefaults.numActors
24+
import PartestDefaults.numThreads
2625

2726
def denotesTestFile(arg: String) = Path(arg).hasExtension("scala", "res", "xml")
2827
def denotesTestDir(arg: String) = Path(arg).ifDirectory(_.files.nonEmpty) exists (x => x)
@@ -37,53 +36,34 @@ trait DirectRunner {
3736
false
3837
})
3938
}
40-
41-
def setProperties() {
42-
if (isPartestDebug)
43-
scala.actors.Debug.level = 3
44-
45-
if (PartestDefaults.poolSize.isEmpty) {
46-
scala.actors.Debug.info("actors.corePoolSize not defined")
47-
setProp("actors.corePoolSize", "12")
48-
}
49-
}
50-
51-
def runTestsForFiles(_kindFiles: List[File], kind: String): immutable.Map[String, Int] = {
52-
val kindFiles = onlyValidTestPaths(_kindFiles)
53-
val groupSize = (kindFiles.length / numActors) + 1
54-
39+
def runTestsForFiles(_kindFiles: List[File], kind: String): immutable.Map[String, TestState] = {
5540
// @partest maintainer: we cannot create a fresh file manager here
5641
// since the FM must respect --buildpath and --classpath from the command line
5742
// for example, see how it's done in ReflectiveRunner
5843
//val consFM = new ConsoleFileManager
5944
//import consFM.{ latestCompFile, latestLibFile, latestPartestFile }
60-
val latestCompFile = new File(fileManager.LATEST_COMP)
45+
val latestCompFile = new File(fileManager.LATEST_COMP)
6146
val latestReflectFile = new File(fileManager.LATEST_REFLECT)
62-
val latestLibFile = new File(fileManager.LATEST_LIB)
47+
val latestLibFile = new File(fileManager.LATEST_LIB)
6348
val latestPartestFile = new File(fileManager.LATEST_PARTEST)
64-
val latestActorsFile = new File(fileManager.LATEST_ACTORS)
65-
val latestActMigFile = new File(fileManager.LATEST_ACTORS_MIGRATION)
66-
val scalacheckURL = PathSettings.scalaCheck.toURL
49+
val latestActorsFile = new File(fileManager.LATEST_ACTORS)
50+
val latestActMigFile = new File(fileManager.LATEST_ACTORS_MIGRATION)
51+
val scalacheckURL = PathSettings.scalaCheck.toURL
6752
val scalaCheckParentClassLoader = ScalaClassLoader.fromURLs(
6853
scalacheckURL :: (List(latestCompFile, latestReflectFile, latestLibFile, latestActorsFile, latestActMigFile, latestPartestFile).map(_.toURI.toURL))
6954
)
70-
Output.init()
7155

72-
val workers = kindFiles.grouped(groupSize).toList map { toTest =>
73-
val worker = new Worker(fileManager, TestRunParams(scalaCheckParentClassLoader))
74-
worker.start()
75-
worker ! RunTests(kind, toTest)
76-
worker
77-
}
56+
val kindFiles = onlyValidTestPaths(_kindFiles)
57+
val pool = Executors.newFixedThreadPool(numThreads)
58+
val manager = new RunnerManager(kind, fileManager, TestRunParams(scalaCheckParentClassLoader))
59+
val futures = kindFiles map (f => (f, pool submit callable(manager runTest f))) toMap
60+
61+
pool.shutdown()
62+
pool.awaitTermination(1, TimeUnit.HOURS)
7863

79-
workers map { w =>
80-
receiveWithin(3600 * 1000) {
81-
case Results(testResults) => testResults
82-
case TIMEOUT =>
83-
// add at least one failure
84-
NestUI.verbose("worker timed out; adding failed test")
85-
Map("worker timed out; adding failed test" -> 2)
86-
}
87-
} reduceLeft (_ ++ _)
64+
for ((file, future) <- futures) yield {
65+
val state = if (future.isCancelled) TestState.Timeout else future.get
66+
(file.getAbsolutePath, state)
67+
}
8868
}
8969
}

0 commit comments

Comments
 (0)