@@ -17,8 +17,6 @@ object DottyBuild extends Build {
17
17
// "-XX:+HeapDumpOnOutOfMemoryError", "-Xmx1g", "-Xss2m"
18
18
)
19
19
20
- var partestLock : FileLock = null
21
-
22
20
val defaults = Defaults .defaultSettings ++ Seq (
23
21
scalaVersion in Global := " 2.11.5" ,
24
22
version in Global := " 0.1-SNAPSHOT" ,
@@ -63,25 +61,18 @@ object DottyBuild extends Build {
63
61
64
62
// enable verbose exception messages for JUnit
65
63
testOptions in Test += Tests .Argument (TestFrameworks .JUnit , " -a" , " -v" , " --run-listener=test.ContextEscapeDetector" ),
66
- testOptions in Test += Tests .Cleanup ({ () => if (partestLock != null ) partestLock.release }),
67
- // When this file is locked, running test generates the files for partest.
68
- // Otherwise it just executes the tests directly. So running two separate
69
- // sbt instances might result in unexpected behavior if one does partest
70
- // and the other test, since the second still sees the locked file and thus
71
- // generates partest files instead of running JUnit tests, but doesn't
72
- // partest them.
64
+ testOptions in Test += Tests .Cleanup ({ () => partestLockFile.delete }),
65
+
73
66
lockPartestFile := {
74
- val partestLockFile = " ." + File .separator + " tests" + File .separator + " partest.lock"
75
- try {
76
- partestLock = new RandomAccessFile (partestLockFile, " rw" ).getChannel.tryLock
77
- if (partestLock == null )
78
- throw new RuntimeException (" ERROR: sbt partest: file is locked already. Bad things happen when trying to mix test/partest in two concurrent sbt instances." )
79
- } catch {
80
- case ex : java.nio.channels.OverlappingFileLockException => // locked already, Tests.Cleanup didn't run
81
- if (partestLock != null )
82
- partestLock.release
83
- throw new RuntimeException (" ERROR: sbt partest: file was still locked, please try again or restart sbt." )
84
- }
67
+ // When this file is present, running `test` generates the files for
68
+ // partest. Otherwise it just executes the tests directly.
69
+ val lockDir = partestLockFile.getParentFile
70
+ lockDir.mkdirs
71
+ // Cannot have concurrent partests as they write to the same directory.
72
+ if (lockDir.list.size > 0 )
73
+ throw new RuntimeException (" ERROR: sbt partest: another partest is already running, pid in lock file: " + lockDir.list.toList.mkString(" " ))
74
+ partestLockFile.createNewFile
75
+ partestLockFile.deleteOnExit
85
76
},
86
77
runPartestRunner <<= Def .taskDyn {
87
78
val jars = Seq ((packageBin in Compile ).value.getAbsolutePath) ++
@@ -99,29 +90,29 @@ object DottyBuild extends Build {
99
90
100
91
// http://grokbase.com/t/gg/simple-build-tool/135ke5y90p/sbt-setting-jvm-boot-paramaters-for-scala
101
92
javaOptions <++= (managedClasspath in Runtime , packageBin in Compile ) map { (attList, bin) =>
102
- // put the Scala {library, reflect} in the classpath
103
- val path = for {
104
- file <- attList.map(_.data)
105
- path = file.getAbsolutePath
106
- } yield " -Xbootclasspath/p:" + path
107
- // dotty itself needs to be in the bootclasspath
108
- val fullpath = (" -Xbootclasspath/a:" + bin) :: path.toList
109
- // System.err.println("BOOTPATH: " + fullpath)
110
-
111
- val travis_build = // propagate if this is a travis build
112
- if (sys.props.isDefinedAt(TRAVIS_BUILD ))
113
- List (s " -D $TRAVIS_BUILD= ${sys.props(TRAVIS_BUILD )}" ) ::: travisMemLimit
114
- else
115
- List ()
116
-
117
- val tuning =
118
- if (sys.props.isDefinedAt(" Oshort" ))
119
- // Optimize for short-running applications, see https://github.com/lampepfl/dotty/issues/222
120
- List (" -XX:+TieredCompilation" , " -XX:TieredStopAtLevel=1" )
93
+ // put the Scala {library, reflect} in the classpath
94
+ val path = for {
95
+ file <- attList.map(_.data)
96
+ path = file.getAbsolutePath
97
+ } yield " -Xbootclasspath/p:" + path
98
+ // dotty itself needs to be in the bootclasspath
99
+ val fullpath = (" -Xbootclasspath/a:" + bin) :: path.toList
100
+ // System.err.println("BOOTPATH: " + fullpath)
101
+
102
+ val travis_build = // propagate if this is a travis build
103
+ if (sys.props.isDefinedAt(TRAVIS_BUILD ))
104
+ List (s " -D $TRAVIS_BUILD= ${sys.props(TRAVIS_BUILD )}" ) ::: travisMemLimit
105
+ else
106
+ List ()
107
+
108
+ val tuning =
109
+ if (sys.props.isDefinedAt(" Oshort" ))
110
+ // Optimize for short-running applications, see https://github.com/lampepfl/dotty/issues/222
111
+ List (" -XX:+TieredCompilation" , " -XX:TieredStopAtLevel=1" )
121
112
else
122
113
List ()
123
114
124
- tuning ::: agentOptions ::: travis_build ::: fullpath
115
+ ( " -DpartestParentID= " + pid) :: tuning ::: agentOptions ::: travis_build ::: fullpath
125
116
}
126
117
) ++ addCommandAlias(" partest" , " ;test:compile;lockPartestFile;test:test;runPartestRunner" )
127
118
@@ -174,10 +165,14 @@ object DottyBuild extends Build {
174
165
lazy val benchmarks = Project (id = " dotty-bench" , settings = benchmarkSettings,
175
166
base = file(" bench" )) dependsOn(dotty % " compile->test" )
176
167
177
- lazy val lockPartestFile = TaskKey [Unit ](" lockPartestFile" , " Creates the file lock on ./tests/partest.lock" )
178
- lazy val runPartestRunner = TaskKey [Unit ](" runPartestRunner" , " Runs partests" )
179
- lazy val partestDeps = SettingKey [Seq [ModuleID ]](" partestDeps" , " Finds jars for partest dependencies" )
168
+ // Partest tasks
169
+ lazy val lockPartestFile = TaskKey [Unit ](" lockPartestFile" , " Creates the lock file at ./tests/locks/partest-<pid>.lock" )
170
+ val partestLockFile = new File (" ." + File .separator + " tests" + File .separator + " locks" + File .separator + s " partest- $pid.lock " )
171
+ val pid = java.lang.Long .parseLong(java.lang.management.ManagementFactory .getRuntimeMXBean().getName().split(" @" )(0 ))
180
172
173
+ lazy val runPartestRunner = TaskKey [Unit ](" runPartestRunner" , " Runs partest" )
174
+
175
+ lazy val partestDeps = SettingKey [Seq [ModuleID ]](" partestDeps" , " Finds jars for partest dependencies" )
181
176
def getJarPaths (modules : Seq [ModuleID ], ivyHome : Option [File ]): Seq [String ] = ivyHome match {
182
177
case Some (home) =>
183
178
modules.map({ module =>
0 commit comments