summaryrefslogtreecommitdiff
path: root/src/partest/scala/tools/partest/nest/DirectRunner.scala
blob: d4b1c8dcb1caa992d1d0f8548638ee5579195cf1 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
/* NEST (New Scala Test)
 * Copyright 2007-2011 LAMP/EPFL
 * @author Philipp Haller
 */

// $Id$

package scala.tools.partest
package nest

import java.io.{ File }
import java.util.StringTokenizer
import scala.util.Properties.{ setProp }
import scala.tools.util.Signallable
import scala.tools.nsc.util.ScalaClassLoader
import scala.tools.nsc.io.Path
import scala.collection.{ mutable, immutable }
import scala.actors.Actor._
import scala.actors.TIMEOUT

case class TestRunParams(val scalaCheckParentClassLoader: ScalaClassLoader)

trait DirectRunner {

  def fileManager: FileManager

  import PartestDefaults.numActors

  def denotesTestFile(arg: String) = Path(arg).hasExtension("scala", "res")
  def denotesTestDir(arg: String)  = Path(arg).ifDirectory(_.files.nonEmpty) exists (x => x)
  def denotesTestPath(arg: String) = denotesTestDir(arg) || denotesTestFile(arg)

  /** No duplicate, no empty directories, don't mess with this unless
   *  you like partest hangs.
   */
  def onlyValidTestPaths[T](args: List[T]): List[T] = {
    args.distinct filter (arg => denotesTestPath("" + arg) || {
      NestUI.warning("Discarding invalid test path '%s'\n" format arg)
      false
    })
  }

  def setProperties() {
    if (isPartestDebug)
      scala.actors.Debug.level = 3

    if (PartestDefaults.poolSize.isEmpty) {
      scala.actors.Debug.info("actors.corePoolSize not defined")
      setProp("actors.corePoolSize", "16")
    }
  }

  def runTestsForFiles(_kindFiles: List[File], kind: String): immutable.Map[String, Int] = {
    val kindFiles = onlyValidTestPaths(_kindFiles)
    val groupSize = (kindFiles.length / numActors) + 1

    val consFM = new ConsoleFileManager
    import consFM.{ latestCompFile, latestLibFile, latestPartestFile }
    val scalacheckURL = PathSettings.scalaCheck.toURL
    val scalaCheckParentClassLoader = ScalaClassLoader.fromURLs(
      List(scalacheckURL, latestCompFile.toURI.toURL, latestLibFile.toURI.toURL, latestPartestFile.toURI.toURL)
    )
    Output.init

    val workers = kindFiles.grouped(groupSize).toList map { toTest =>
      val worker = new Worker(fileManager, TestRunParams(scalaCheckParentClassLoader))
      worker.start()
      worker ! RunTests(kind, toTest)
      worker
    }

    workers map { w =>
      receiveWithin(3600 * 1000) {
        case Results(testResults) => testResults
        case TIMEOUT =>
          // add at least one failure
          NestUI.verbose("worker timed out; adding failed test")
          Map("worker timed out; adding failed test" -> 2)
      }
    } reduceLeft (_ ++ _)
  }
}