Freezing: fixed test and added stress test
This commit is contained in:
@@ -623,11 +623,16 @@ task freeze0(type: RunKonanTest) {
|
||||
|
||||
task freeze1(type: RunKonanTest) {
|
||||
disabled = (project.testTarget == 'wasm32') // No exceptions on WASM.
|
||||
goldValue = "OK, cannot freeze cyclic\n"+
|
||||
"OK, cannot mutate frozen\n"
|
||||
goldValue = "OK, cannot mutate frozen\n"
|
||||
source = "runtime/workers/freeze1.kt"
|
||||
}
|
||||
|
||||
task freeze_stress(type: RunKonanTest) {
|
||||
disabled = (project.testTarget == 'wasm32') // No exceptions on WASM.
|
||||
goldValue = "OK\n"
|
||||
source = "runtime/workers/freeze_stress.kt"
|
||||
}
|
||||
|
||||
task superFunCall(type: RunKonanTest) {
|
||||
goldValue = "<fun:C><fun:C1>\n<fun:C><fun:C3>\n"
|
||||
source = "codegen/basics/superFunCall.kt"
|
||||
|
||||
@@ -43,11 +43,7 @@ fun makeDiamond(): Node2 {
|
||||
}
|
||||
|
||||
@Test fun runTest() {
|
||||
try {
|
||||
makeCycle(10).freeze()
|
||||
} catch (e: FreezingException) {
|
||||
println("OK, cannot freeze cyclic")
|
||||
}
|
||||
makeCycle(10).freeze()
|
||||
|
||||
// Must be able to freeze diamond shaped graph.
|
||||
val diamond = makeDiamond().freeze()
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
package runtime.workers.freeze_stress
|
||||
|
||||
import kotlin.test.*
|
||||
|
||||
import konan.worker.*
|
||||
|
||||
class Random(private var seed: Int) {
|
||||
fun next(): Int {
|
||||
seed = (1103515245 * seed + 12345) and 0x7fffffff
|
||||
return seed
|
||||
}
|
||||
|
||||
fun next(maxExclusiveValue: Int) = if (maxExclusiveValue == 0) 0 else next() % maxExclusiveValue
|
||||
|
||||
fun next(minInclusiveValue: Int, maxInclusiveValue: Int) =
|
||||
minInclusiveValue + next(maxInclusiveValue - minInclusiveValue + 1)
|
||||
}
|
||||
|
||||
class Node(val id: Int) {
|
||||
var numberOfEdges = 0
|
||||
|
||||
lateinit var edge0: Node
|
||||
lateinit var edge1: Node
|
||||
lateinit var edge2: Node
|
||||
lateinit var edge3: Node
|
||||
lateinit var edge4: Node
|
||||
lateinit var edge5: Node
|
||||
lateinit var edge6: Node
|
||||
lateinit var edge7: Node
|
||||
lateinit var edge8: Node
|
||||
lateinit var edge9: Node
|
||||
|
||||
fun addEdge(child: Node) {
|
||||
when (numberOfEdges) {
|
||||
0 -> edge0 = child
|
||||
1 -> edge1 = child
|
||||
2 -> edge2 = child
|
||||
3 -> edge3 = child
|
||||
4 -> edge4 = child
|
||||
5 -> edge5 = child
|
||||
6 -> edge6 = child
|
||||
7 -> edge7 = child
|
||||
8 -> edge8 = child
|
||||
9 -> edge9 = child
|
||||
else -> error("Too many edges")
|
||||
}
|
||||
++numberOfEdges
|
||||
}
|
||||
|
||||
fun getEdges(): List<Node> {
|
||||
val result = mutableListOf<Node>()
|
||||
if (numberOfEdges > 0) result += edge0
|
||||
if (numberOfEdges > 1) result += edge1
|
||||
if (numberOfEdges > 2) result += edge2
|
||||
if (numberOfEdges > 3) result += edge3
|
||||
if (numberOfEdges > 4) result += edge4
|
||||
if (numberOfEdges > 5) result += edge5
|
||||
if (numberOfEdges > 6) result += edge6
|
||||
if (numberOfEdges > 7) result += edge7
|
||||
if (numberOfEdges > 8) result += edge8
|
||||
if (numberOfEdges > 9) result += edge9
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
class Graph(val nodes: List<Node>, val roots: List<Node>)
|
||||
|
||||
fun min(x: Int, y: Int) = if (x < y) x else y
|
||||
fun max(x: Int, y: Int) = if (x > y) x else y
|
||||
|
||||
val random = Random(42)
|
||||
|
||||
fun generate(condensationSize: Int, branchingFactor: Int, swellingFactor: Int): Graph {
|
||||
var id = 0
|
||||
val nodes = mutableListOf<Node>()
|
||||
|
||||
fun genDAG(n: Int): Node {
|
||||
val node = Node(id++)
|
||||
nodes += node
|
||||
if (n == 1) return node
|
||||
val numberOfChildren = random.next(1, min(n - 1, branchingFactor))
|
||||
val used = BooleanArray(n)
|
||||
val points = IntArray(numberOfChildren + 1)
|
||||
points[0] = 0
|
||||
points[numberOfChildren] = n - 1
|
||||
used[0] = true
|
||||
used[n - 1] = true
|
||||
for (i in 1 until numberOfChildren) {
|
||||
var p: Int
|
||||
do {
|
||||
p = random.next(1, n - 1)
|
||||
} while (used[p])
|
||||
used[p] = true
|
||||
points[i] = p
|
||||
}
|
||||
points.sort()
|
||||
for (i in 1..numberOfChildren) {
|
||||
val childSize = points[i] - points[i - 1]
|
||||
val child = genDAG(childSize)
|
||||
if (random.next(2) == 0)
|
||||
node.addEdge(child)
|
||||
else
|
||||
child.addEdge(node)
|
||||
}
|
||||
return node
|
||||
}
|
||||
|
||||
genDAG(condensationSize)
|
||||
|
||||
val numberOfEnters = IntArray(condensationSize)
|
||||
for (node in nodes)
|
||||
for (edge in node.getEdges())
|
||||
++numberOfEnters[edge.id]
|
||||
val roots = nodes.filter { numberOfEnters[it.id] == 0 }
|
||||
for (i in 0 until condensationSize) {
|
||||
val node = nodes[i]
|
||||
val componentSize = random.next(1, swellingFactor)
|
||||
if (componentSize == 1 && random.next(2) == 0)
|
||||
continue
|
||||
val component = Array(componentSize) {
|
||||
if (it == 0) node else Node(id++).also { nodes += it }
|
||||
}
|
||||
for (j in 0 until componentSize)
|
||||
component[j].addEdge(component[(j - 1 + componentSize) % componentSize])
|
||||
val numberOfAdditionalEdges = random.next((componentSize + 1) / 2)
|
||||
for (j in 0 until numberOfAdditionalEdges)
|
||||
component[random.next(componentSize)].addEdge(component[random.next(componentSize)])
|
||||
}
|
||||
|
||||
return Graph(nodes, roots)
|
||||
}
|
||||
|
||||
fun freezeOneGraph() {
|
||||
val graph = generate(100, 5, 20)
|
||||
graph.roots.forEach { it.freeze() }
|
||||
for (node in graph.nodes)
|
||||
assert (node.isFrozen, { "All nodes should be frozen" })
|
||||
}
|
||||
|
||||
@Test fun runTest() {
|
||||
for (i in 0..1000) {
|
||||
freezeOneGraph()
|
||||
}
|
||||
println("OK")
|
||||
}
|
||||
Reference in New Issue
Block a user