Skip to content

Commit 1051d87

Browse files
committed
Make idempotency check a proper vulpix test
1 parent e639043 commit 1051d87

File tree

2 files changed

+71
-61
lines changed

2 files changed

+71
-61
lines changed

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

Lines changed: 1 addition & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -272,62 +272,6 @@ class CompilationTests extends ParallelTesting {
272272

273273
/** Add a `z` so that they run last. TODO: Only run them selectively? */
274274
@Test def zBytecodeIdempotency: Unit = {
275-
var failed = 0
276-
var total = 0
277-
val blacklisted = Set(
278-
// Bridges on collections in different order. Second one in scala2 order.
279-
"pos/Map/scala/collection/immutable/Map",
280-
"pos/Map/scala/collection/immutable/AbstractMap",
281-
"pos/t1203a/NodeSeq",
282-
"pos/i2345/Whatever"
283-
)
284-
def checkIdempotency(): Unit = {
285-
val groupedBytecodeFiles: List[(Path, Path, Path, Path)] = {
286-
val bytecodeFiles = {
287-
def bytecodeFiles(paths: JStream[Path]): List[Path] = {
288-
def isBytecode(file: String) = file.endsWith(".class") || file.endsWith(".tasty")
289-
paths.iterator.asScala.filter(path => isBytecode(path.toString)).toList
290-
}
291-
val compilerDir1 = Paths.get("../out/idempotency1")
292-
val compilerDir2 = Paths.get("../out/idempotency2")
293-
bytecodeFiles(Files.walk(compilerDir1)) ++ bytecodeFiles(Files.walk(compilerDir2))
294-
}
295-
val groups = bytecodeFiles.groupBy(f => f.toString.substring("../out/idempotencyN/".length, f.toString.length - 6))
296-
groups.filterNot(x => blacklisted(x._1)).valuesIterator.flatMap { g =>
297-
def pred(f: Path, i: Int, isTasty: Boolean) =
298-
f.toString.contains("idempotency" + i) && f.toString.endsWith(if (isTasty) ".tasty" else ".class")
299-
val class1 = g.find(f => pred(f, 1, isTasty = false))
300-
val class2 = g.find(f => pred(f, 2, isTasty = false))
301-
val tasty1 = g.find(f => pred(f, 1, isTasty = true))
302-
val tasty2 = g.find(f => pred(f, 2, isTasty = true))
303-
assert(class1.isDefined, "Could not find class in idempotency1 for " + class2)
304-
assert(class2.isDefined, "Could not find class in idempotency2 for " + class1)
305-
if (tasty1.isEmpty || tasty2.isEmpty) Nil
306-
else List(Tuple4(class1.get, tasty1.get, class2.get, tasty2.get))
307-
}.toList
308-
}
309-
310-
for ((class1, tasty1, class2, tasty2) <- groupedBytecodeFiles) {
311-
total += 1
312-
val bytes1 = Files.readAllBytes(class1)
313-
val bytes2 = Files.readAllBytes(class2)
314-
if (!java.util.Arrays.equals(bytes1, bytes2)) {
315-
failed += 1
316-
val tastyBytes1 = Files.readAllBytes(tasty1)
317-
val tastyBytes2 = Files.readAllBytes(tasty2)
318-
if (java.util.Arrays.equals(tastyBytes1, tastyBytes2))
319-
println(s"Idempotency test failed between $class1 and $class1 (same tasty)")
320-
else
321-
println(s"Idempotency test failed between $tasty1 and $tasty2")
322-
/* Dump bytes to console, could be useful if issue only appears in CI.
323-
* Create the .class locally with Files.write(path, Array[Byte](...)) with the printed array
324-
*/
325-
// println(bytes1.mkString("Array[Byte](", ",", ")"))
326-
// println(bytes2.mkString("Array[Byte](", ",", ")"))
327-
}
328-
}
329-
}
330-
331275
val opt = defaultOptions.and("-YemitTasty")
332276

333277
def idempotency1() = {
@@ -346,13 +290,9 @@ class CompilationTests extends ParallelTesting {
346290
assert(new java.io.File("../out/idempotency1/").exists)
347291
assert(new java.io.File("../out/idempotency2/").exists)
348292

349-
val t0 = System.currentTimeMillis()
350-
checkIdempotency()
351-
println(s"checked bytecode idempotency (${(System.currentTimeMillis() - t0) / 1000.0} sec)")
293+
compileFile("../tests/idempotency/IdempotencyCheck.scala", defaultOptions).checkRuns()
352294

353295
tests.delete()
354-
355-
assert(failed == 0, s"Failed $failed idempotency checks (out of $total)")
356296
}
357297

358298

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
2+
import java.nio.file.{Files, Path, Paths}
3+
import java.util.stream.{ Stream => JStream }
4+
5+
import scala.collection.JavaConverters._
6+
7+
object Test {
8+
9+
def main(args: Array[String]): Unit = checkIdempotency()
10+
11+
val blacklisted = Set(
12+
// Bridges on collections in different order. Second one in scala2 order.
13+
"pos/Map/scala/collection/immutable/Map",
14+
"pos/Map/scala/collection/immutable/AbstractMap",
15+
"pos/t1203a/NodeSeq",
16+
"pos/i2345/Whatever"
17+
)
18+
19+
def checkIdempotency(): Unit = {
20+
var failed = 0
21+
var total = 0
22+
23+
val groupedBytecodeFiles: List[(Path, Path, Path, Path)] = {
24+
val bytecodeFiles = {
25+
def bytecodeFiles(paths: JStream[Path]): List[Path] = {
26+
def isBytecode(file: String) = file.endsWith(".class") || file.endsWith(".tasty")
27+
paths.iterator.asScala.filter(path => isBytecode(path.toString)).toList
28+
}
29+
val compilerDir1 = Paths.get("../out/idempotency1")
30+
val compilerDir2 = Paths.get("../out/idempotency2")
31+
bytecodeFiles(Files.walk(compilerDir1)) ++ bytecodeFiles(Files.walk(compilerDir2))
32+
}
33+
val groups = bytecodeFiles.groupBy(f => f.toString.substring("../out/idempotencyN/".length, f.toString.length - 6))
34+
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")
37+
val class1 = g.find(f => pred(f, 1, isTasty = false))
38+
val class2 = g.find(f => pred(f, 2, isTasty = false))
39+
val tasty1 = g.find(f => pred(f, 1, isTasty = true))
40+
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)
43+
if (tasty1.isEmpty || tasty2.isEmpty) Nil
44+
else List(Tuple4(class1.get, tasty1.get, class2.get, tasty2.get))
45+
}.toList
46+
}
47+
48+
for ((class1, tasty1, class2, tasty2) <- groupedBytecodeFiles) {
49+
total += 1
50+
val bytes1 = Files.readAllBytes(class1)
51+
val bytes2 = Files.readAllBytes(class2)
52+
if (!java.util.Arrays.equals(bytes1, bytes2)) {
53+
failed += 1
54+
val tastyBytes1 = Files.readAllBytes(tasty1)
55+
val tastyBytes2 = Files.readAllBytes(tasty2)
56+
if (java.util.Arrays.equals(tastyBytes1, tastyBytes2))
57+
println(s"Idempotency test failed between $class1 and $class1 (same tasty)")
58+
else
59+
println(s"Idempotency test failed between $tasty1 and $tasty2")
60+
/* 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
62+
*/
63+
// println(bytes1.mkString("Array[Byte](", ",", ")"))
64+
// println(bytes2.mkString("Array[Byte](", ",", ")"))
65+
}
66+
}
67+
68+
assert(failed == 0, s"Failed $failed idempotency checks (out of $total)")
69+
}
70+
}

0 commit comments

Comments
 (0)