@@ -9,6 +9,7 @@ import core.Contexts._
9
9
import reporting .{ Reporter , UniqueMessagePositions , HideNonSensicalMessages , MessageRendering }
10
10
import reporting .diagnostic .MessageContainer
11
11
import interfaces .Diagnostic .ERROR
12
+ import java .lang .reflect .InvocationTargetException
12
13
import java .nio .file .StandardCopyOption .REPLACE_EXISTING
13
14
import java .nio .file .{ Files , Path , Paths }
14
15
import java .util .concurrent .{ Executors => JExecutors , TimeUnit }
@@ -31,6 +32,10 @@ trait ParallelTesting {
31
32
_errors += newErrors
32
33
}
33
34
35
+ private [this ] var _failed = false
36
+ final protected [this ] def fail (): Unit = synchronized { _failed = true }
37
+ def didFail : Boolean = _failed
38
+
34
39
private def statusRunner : Runnable = new Runnable {
35
40
def run (): Unit = {
36
41
val start = System .currentTimeMillis
@@ -85,6 +90,9 @@ trait ParallelTesting {
85
90
}
86
91
catch {
87
92
case NonFatal (e) => {
93
+ // if an exception is thrown during compilation, the complete test
94
+ // run should fail
95
+ fail()
88
96
System .err.println(s " \n ${e.getMessage}\n " )
89
97
completeCompilation(1 )
90
98
throw e
@@ -93,13 +101,77 @@ trait ParallelTesting {
93
101
}
94
102
}
95
103
96
- private final class NegCompileRun (targetDirs : List [JFile ], fromDir : String , flags : Array [String ])
104
+ private final class RunCompileRun (targetDirs : List [JFile ], fromDir : String , flags : Array [String ])
97
105
extends CompileRun (targetDirs, fromDir, flags) {
98
- private [this ] var _failed = false
99
- private [this ] def fail (): Unit = _failed = true
106
+ private def verifyOutput (checkFile : JFile , dir : JFile ) = try {
107
+ // Do classloading magic and running here:
108
+ import java .net .{ URL , URLClassLoader }
109
+ import java .io .ByteArrayOutputStream
110
+ val ucl = new URLClassLoader (Array (dir.toURI.toURL))
111
+ val cls = ucl.loadClass(" Test" )
112
+ val meth = cls.getMethod(" main" , classOf [Array [String ]])
113
+
114
+ val printStream = new ByteArrayOutputStream
115
+ Console .withOut(printStream) {
116
+ meth.invoke(null , Array (" jvm" )) // partest passes at least "jvm" as an arg
117
+ }
100
118
101
- def didFail : Boolean = _failed
119
+ val outputLines = printStream.toString(" utf-8" ).lines.toArray
120
+ val checkLines = Source .fromFile(checkFile).getLines.toArray
121
+
122
+ def linesMatch =
123
+ outputLines
124
+ .zip(checkLines)
125
+ .forall { case (x, y) => x == y }
126
+
127
+ if (outputLines.length != checkLines.length || ! linesMatch) {
128
+ System .err.println {
129
+ s " \n Output from run test ' $dir' did not match expected, output: \n ${outputLines.mkString(" \n " )}"
130
+ }
131
+ fail()
132
+ }
133
+ }
134
+ catch {
135
+ case _ : NoSuchMethodException =>
136
+ System .err.println(s " \n test in ' $dir' did not contain a main method " )
137
+ fail()
138
+
139
+ case _ : ClassNotFoundException =>
140
+ System .err.println(s " \n test in ' $dir' did was not contained within a `Test` object " )
141
+ fail()
142
+
143
+ case _ : InvocationTargetException =>
144
+ System .err.println(s " \n Test in ' $dir' might be using args(X) where X > 0 " )
145
+ fail()
146
+ }
102
147
148
+ protected def compilationRunnable (dir : JFile ): Runnable = new Runnable {
149
+ def run (): Unit =
150
+ try {
151
+ val sourceFiles = dir.listFiles.filter(f => f.getName.endsWith(" .scala" ) || f.getName.endsWith(" .java" ))
152
+ val checkFile = dir.listFiles.find(_.getName.endsWith(" .check" ))
153
+ val reporter = compile(sourceFiles, flags ++ Array (" -d" , dir.getAbsolutePath), false )
154
+ completeCompilation(reporter.errorCount)
155
+
156
+ if (reporter.errorCount == 0 && checkFile.isDefined) verifyOutput(checkFile.get, dir)
157
+ else if (reporter.errorCount > 0 ) {
158
+ System .err.println(s " \n Compilation failed for: ' $dir' " )
159
+ fail()
160
+ }
161
+ }
162
+ catch {
163
+ case NonFatal (e) => {
164
+ System .err.println(s " \n $e\n ${e.getMessage}" )
165
+ completeCompilation(1 )
166
+ fail()
167
+ throw e
168
+ }
169
+ }
170
+ }
171
+ }
172
+
173
+ private final class NegCompileRun (targetDirs : List [JFile ], fromDir : String , flags : Array [String ])
174
+ extends CompileRun (targetDirs, fromDir, flags) {
103
175
protected def compilationRunnable (dir : JFile ): Runnable = new Runnable {
104
176
def run (): Unit =
105
177
try {
@@ -188,10 +260,6 @@ trait ParallelTesting {
188
260
}
189
261
}
190
262
191
- private val driver = new Driver {
192
- override def newCompiler (implicit ctx : Context ) = new Compiler
193
- }
194
-
195
263
private class DaftReporter (suppress : Boolean )
196
264
extends Reporter with UniqueMessagePositions with HideNonSensicalMessages
197
265
with MessageRendering {
@@ -206,7 +274,13 @@ trait ParallelTesting {
206
274
}
207
275
}
208
276
209
- private def compile (files : Array [JFile ], flags : Array [String ], suppressErrors : Boolean ): DaftReporter = {
277
+ private def compile (files0 : Array [JFile ], flags : Array [String ], suppressErrors : Boolean ): DaftReporter = {
278
+
279
+ def flattenFiles (f : JFile ): Array [JFile ] =
280
+ if (f.isDirectory) f.listFiles.flatMap(flattenFiles)
281
+ else Array (f)
282
+
283
+ val files : Array [JFile ] = files0.flatMap(flattenFiles)
210
284
211
285
def findJarFromRuntime (partialName : String ) = {
212
286
val urls = ClassLoader .getSystemClassLoader.asInstanceOf [java.net.URLClassLoader ].getURLs.map(_.getFile.toString)
@@ -231,11 +305,11 @@ trait ParallelTesting {
231
305
compileWithJavac(files.filter(_.getName.endsWith(" .java" )).map(_.getAbsolutePath))
232
306
233
307
val reporter = new DaftReporter (suppress = suppressErrors)
308
+ val driver = new Driver { def newCompiler (implicit ctx : Context ) = new Compiler }
234
309
driver.process(flags ++ files.map(_.getAbsolutePath), reporter = reporter)
235
310
reporter
236
311
}
237
312
238
-
239
313
class CompilationTest (targetDirs : List [JFile ], fromDir : String , flags : Array [String ]) {
240
314
def pos : Unit = {
241
315
val run = new PosCompileRun (targetDirs, fromDir, flags).execute()
@@ -246,6 +320,11 @@ trait ParallelTesting {
246
320
! (new NegCompileRun (targetDirs, fromDir, flags).execute().didFail),
247
321
s " Wrong number of errors encountered when compiling $fromDir"
248
322
)
323
+
324
+ def run : Unit = assert(
325
+ ! (new RunCompileRun (targetDirs, fromDir, flags).execute().didFail),
326
+ s " Run tests failed for test $fromDir"
327
+ )
249
328
}
250
329
251
330
private def toCompilerDirFromDir (d : JFile , sourceDir : JFile , outDir : String ): JFile = {
@@ -257,13 +336,19 @@ trait ParallelTesting {
257
336
}
258
337
259
338
private def toCompilerDirFromFile (file : JFile , sourceDir : JFile , outDir : String ): JFile = {
260
- val uniqueSubdir = file.getName.substring(0 , file.getName.lastIndexOf('.' ))
261
- val targetDir = new JFile (outDir + s " ${sourceDir.getName}/ $uniqueSubdir" )
262
- // create if not exists
263
- targetDir.mkdirs()
264
- // copy file to dir:
265
- copyToDir(targetDir, file)
266
- targetDir
339
+ val uniqueSubdir = file.getName.substring(0 , file.getName.lastIndexOf('.' ))
340
+ val targetDir = new JFile (outDir + s " ${sourceDir.getName}/ $uniqueSubdir" )
341
+ if (file.getName.endsWith(" .java" ) || file.getName.endsWith(" .scala" )) {
342
+ // create if not exists
343
+ targetDir.mkdirs()
344
+ // copy file to dir:
345
+ copyToDir(targetDir, file)
346
+
347
+ // copy checkfile if it exists
348
+ val checkFile = new JFile (file.getAbsolutePath.substring(0 , file.getAbsolutePath.lastIndexOf('.' )) + " .check" )
349
+ if (checkFile.exists) copyToDir(targetDir, checkFile)
350
+ }
351
+ targetDir
267
352
}
268
353
269
354
private def copyToDir (dir : JFile , file : JFile ): Unit = {
@@ -279,10 +364,11 @@ trait ParallelTesting {
279
364
private def compilationTargets (sourceDir : JFile ): (List [JFile ], List [JFile ]) =
280
365
sourceDir.listFiles.foldLeft((List .empty[JFile ], List .empty[JFile ])) { case ((dirs, files), f) =>
281
366
if (f.isDirectory) (f :: dirs, files)
367
+ else if (f.getName.endsWith(" .check" )) (dirs, files)
282
368
else (dirs, f :: files)
283
369
}
284
370
285
- def compileFileInDir (f : String , flags : Array [String ])(implicit outDirectory : String ): CompilationTest = {
371
+ def compileFile (f : String , flags : Array [String ])(implicit outDirectory : String ): CompilationTest = {
286
372
// each calling method gets its own unique output directory, in which we
287
373
// place the dir being compiled:
288
374
val callingMethod = Thread .currentThread.getStackTrace.apply(3 ).getMethodName
0 commit comments