Skip to content

Commit eddf030

Browse files
authored
Merge pull request #2756 from dotty-staging/idempotency-on-boot
Add idempotency check on bootstrapped dotty
2 parents ea582a7 + 711e6f7 commit eddf030

File tree

4 files changed

+48
-32
lines changed

4 files changed

+48
-32
lines changed

compiler/test/dotty/tools/dotc/CompilationTests.scala

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ class CompilationTests extends ParallelTesting {
207207
// compile with bootstrapped library on cp:
208208
defaultOutputDir + "lib/src/:" +
209209
// as well as bootstrapped compiler:
210-
defaultOutputDir + "dotty1/dotty1/:" +
210+
defaultOutputDir + "dotty1/dotty/:" +
211211
Jars.dottyInterfaces
212212
)
213213

@@ -241,15 +241,19 @@ class CompilationTests extends ParallelTesting {
241241

242242
def dotty1 = {
243243
compileList(
244-
"dotty1",
244+
"dotty",
245245
compilerSources ++ backendSources ++ backendJvmSources,
246246
opt)
247247
}
248248

249-
def dotty2 =
250-
compileShallowFilesInDir("../compiler/src/dotty", opt)
249+
def dotty2 = {
250+
compileList(
251+
"dotty",
252+
compilerSources ++ backendSources ++ backendJvmSources,
253+
opt)
254+
}
251255

252-
{
256+
val tests = {
253257
lib.keepOutput :: dotty1.keepOutput :: {
254258
dotty2 +
255259
compileShallowFilesInDir("../compiler/src/dotty/tools", opt) +
@@ -266,21 +270,25 @@ class CompilationTests extends ParallelTesting {
266270
compileShallowFilesInDir("../compiler/src/dotty/tools/dotc/util", opt) +
267271
compileList("shallow-backend", backendSources, opt) +
268272
compileList("shallow-backend-jvm", backendJvmSources, opt)
269-
} :: Nil
270-
}.map(_.checkCompile()).foreach(_.delete())
273+
}.keepOutput :: Nil
274+
}.map(_.checkCompile())
275+
276+
assert(new java.io.File("../out/dotty1/dotty/").exists)
277+
assert(new java.io.File("../out/dotty2/dotty/").exists)
278+
compileList("idempotency", List("../tests/idempotency/BootstrapChecker.scala", "../tests/idempotency/IdempotencyCheck.scala"), defaultOptions).checkRuns()
279+
280+
tests.foreach(_.delete())
271281
}
272282

273283
/** Add a `z` so that they run last. TODO: Only run them selectively? */
274284
@Test def zBytecodeIdempotency: Unit = {
275285
val opt = defaultOptions.and("-YemitTasty")
276286

277287
def idempotency1() = {
278-
compileList("dotty1", compilerSources ++ backendSources ++ backendJvmSources, opt) +
279288
compileDir("../collection-strawman/src/main", opt) +
280289
compileFilesInDir("../tests/pos", opt)
281290
}
282291
def idempotency2() = {
283-
compileList("dotty1", compilerSources ++ backendSources ++ backendJvmSources, opt) +
284292
compileDir("../collection-strawman/src/main", opt) +
285293
compileFilesInDir("../tests/pos", opt)
286294
}
@@ -290,7 +298,7 @@ class CompilationTests extends ParallelTesting {
290298
assert(new java.io.File("../out/idempotency1/").exists)
291299
assert(new java.io.File("../out/idempotency2/").exists)
292300

293-
compileFile("../tests/idempotency/IdempotencyCheck.scala", defaultOptions).checkRuns()
301+
compileList("idempotency", List("../tests/idempotency/Checker.scala", "../tests/idempotency/IdempotencyCheck.scala"), defaultOptions).checkRuns()
294302

295303
tests.delete()
296304
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
2+
object Test {
3+
def main(args: Array[String]): Unit =
4+
IdempotencyCheck.checkIdempotency("../out/dotty")
5+
}

tests/idempotency/Checker.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
2+
object Test {
3+
def main(args: Array[String]): Unit =
4+
IdempotencyCheck.checkIdempotency("../out/idempotency")
5+
}

tests/idempotency/IdempotencyCheck.scala

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,62 @@
11

2-
import java.nio.file.{Files, Path, Paths}
2+
import java.nio.file.{ Files => JFiles, Path => JPath, Paths => JPaths }
33
import java.util.stream.{ Stream => JStream }
44

55
import scala.collection.JavaConverters._
66

7-
object Test {
8-
9-
def main(args: Array[String]): Unit = checkIdempotency()
10-
7+
object IdempotencyCheck {
118
val blacklisted = Set(
12-
// Bridges on collections in different order. Second one in scala2 order.
9+
// No fix needed. Bridges on collections in different order. Second one in scala2 order.
1310
"pos/Map/scala/collection/immutable/Map",
1411
"pos/Map/scala/collection/immutable/AbstractMap",
1512
"pos/t1203a/NodeSeq",
1613
"pos/i2345/Whatever"
1714
)
1815

19-
def checkIdempotency(): Unit = {
16+
def checkIdempotency(dirPrefix: String): Unit = {
2017
var failed = 0
2118
var total = 0
2219

23-
val groupedBytecodeFiles: List[(Path, Path, Path, Path)] = {
20+
val groupedBytecodeFiles: List[(JPath, JPath, JPath, JPath)] = {
2421
val bytecodeFiles = {
25-
def bytecodeFiles(paths: JStream[Path]): List[Path] = {
22+
def bytecodeFiles(paths: JStream[JPath]): List[JPath] = {
2623
def isBytecode(file: String) = file.endsWith(".class") || file.endsWith(".tasty")
2724
paths.iterator.asScala.filter(path => isBytecode(path.toString)).toList
2825
}
29-
val compilerDir1 = Paths.get("../out/idempotency1")
30-
val compilerDir2 = Paths.get("../out/idempotency2")
31-
bytecodeFiles(Files.walk(compilerDir1)) ++ bytecodeFiles(Files.walk(compilerDir2))
26+
val compilerDir1 = JPaths.get(dirPrefix + 1)
27+
val compilerDir2 = JPaths.get(dirPrefix + 2)
28+
bytecodeFiles(JFiles.walk(compilerDir1)) ++ bytecodeFiles(JFiles.walk(compilerDir2))
3229
}
33-
val groups = bytecodeFiles.groupBy(f => f.toString.substring("../out/idempotencyN/".length, f.toString.length - 6))
30+
val groups = bytecodeFiles.groupBy(f => f.toString.substring(dirPrefix.length + 1, f.toString.length - 6))
31+
3432
groups.filterNot(x => blacklisted(x._1)).valuesIterator.flatMap { g =>
35-
def pred(f: Path, i: Int, isTasty: Boolean) =
36-
f.toString.contains("idempotency" + i) && f.toString.endsWith(if (isTasty) ".tasty" else ".class")
33+
def pred(f: JPath, i: Int, isTasty: Boolean) =
34+
f.toString.contains(dirPrefix + i) && f.toString.endsWith(if (isTasty) ".tasty" else ".class")
3735
val class1 = g.find(f => pred(f, 1, isTasty = false))
3836
val class2 = g.find(f => pred(f, 2, isTasty = false))
3937
val tasty1 = g.find(f => pred(f, 1, isTasty = true))
4038
val tasty2 = g.find(f => pred(f, 2, isTasty = true))
41-
assert(class1.isDefined, "Could not find class in idempotency1 for " + class2)
42-
assert(class2.isDefined, "Could not find class in idempotency2 for " + class1)
39+
assert(class1.isDefined, s"Could not find class in ${dirPrefix + 1} for $class2")
40+
assert(class2.isDefined, s"Could not find class in ${dirPrefix + 2} for $class1")
4341
if (tasty1.isEmpty || tasty2.isEmpty) Nil
4442
else List(Tuple4(class1.get, tasty1.get, class2.get, tasty2.get))
4543
}.toList
4644
}
4745

4846
for ((class1, tasty1, class2, tasty2) <- groupedBytecodeFiles) {
4947
total += 1
50-
val bytes1 = Files.readAllBytes(class1)
51-
val bytes2 = Files.readAllBytes(class2)
48+
val bytes1 = JFiles.readAllBytes(class1)
49+
val bytes2 = JFiles.readAllBytes(class2)
5250
if (!java.util.Arrays.equals(bytes1, bytes2)) {
5351
failed += 1
54-
val tastyBytes1 = Files.readAllBytes(tasty1)
55-
val tastyBytes2 = Files.readAllBytes(tasty2)
52+
val tastyBytes1 = JFiles.readAllBytes(tasty1)
53+
val tastyBytes2 = JFiles.readAllBytes(tasty2)
5654
if (java.util.Arrays.equals(tastyBytes1, tastyBytes2))
5755
println(s"Idempotency test failed between $class1 and $class1 (same tasty)")
5856
else
5957
println(s"Idempotency test failed between $tasty1 and $tasty2")
6058
/* Dump bytes to console, could be useful if issue only appears in CI.
61-
* Create the .class locally with Files.write(path, Array[Byte](...)) with the printed array
59+
* Create the .class locally with JFiles.write(path, Array[Byte](...)) with the printed array
6260
*/
6361
// println(bytes1.mkString("Array[Byte](", ",", ")"))
6462
// println(bytes2.mkString("Array[Byte](", ",", ")"))

0 commit comments

Comments
 (0)