1
+ /*
2
+ * Copyright 2016-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
3
+ */
4
+
5
+ package kotlinx.coroutines.experimental.channels
6
+
7
+ import com.devexperts.dxlab.lincheck.*
8
+ import com.devexperts.dxlab.lincheck.execution.*
9
+ import java.util.*
10
+
11
+ typealias ExecutionBuilder = (List <MutableList <Actor >>, List <ActorGenerator >) -> Unit
12
+
13
+ /* *
14
+ * Example of usage:
15
+ *
16
+ * ```
17
+ * StressOptions().injectExecution { actors, methods ->
18
+ * actors[0].add(actorMethod(methods, "receive1"))
19
+ * actors[0].add(actorMethod(methods, "receive2"))
20
+ *
21
+ * actors[1].add(actorMethod(methods, "send2"))
22
+ * actors[1].add(actorMethod(methods, "send1"))
23
+ * }
24
+ *
25
+ * ```
26
+ *
27
+ * Will produce
28
+ * ```
29
+ * Actors per thread:
30
+ * [receive1(), receive2()]
31
+ * [send2(), send1()]
32
+ * ```
33
+ * at the first iteration.
34
+ *
35
+ * DSL will be improved when this method will be used frequently
36
+ */
37
+ fun Options <* , * >.injectExecution (behaviourBuilder : ExecutionBuilder ): Options <* , * > {
38
+ injectedBehaviour.add(behaviourBuilder)
39
+ executionGenerator(FixedBehaviourInjectorExecutionGenerator ::class .java)
40
+ return this
41
+ }
42
+
43
+ fun actorMethod (generators : List <ActorGenerator >, name : String ): Actor =
44
+ generators.find { it.generate().method.name.contains(name) }?.generate() ? : error(" Actor method $name is not found in ${generators.map { it.generate().method.name }} " )
45
+
46
+ private val injectedBehaviour: Queue <ExecutionBuilder > = ArrayDeque <ExecutionBuilder >()
47
+
48
+ class FixedBehaviourInjectorExecutionGenerator (testConfiguration : CTestConfiguration , testStructure : CTestStructure )
49
+ : ExecutionGenerator (testConfiguration, testStructure) {
50
+
51
+ private val randomGenerator = RandomExecutionGenerator (testConfiguration, testStructure)
52
+
53
+ override fun nextExecution (): List <List <Actor >> {
54
+ val injector = injectedBehaviour.poll()
55
+ if (injector != null ) {
56
+ val parallelGroup = ArrayList (testStructure.actorGenerators)
57
+ val actorsPerThread = ArrayList <MutableList <Actor >>()
58
+ for (i in testConfiguration.threadConfigurations.indices) {
59
+ actorsPerThread.add(ArrayList ())
60
+ }
61
+
62
+ injector.invoke(actorsPerThread, parallelGroup)
63
+ return actorsPerThread
64
+ }
65
+
66
+ return randomGenerator.nextExecution()
67
+ }
68
+ }
69
+
70
+ // Ad-hoc fixed execution injection for lin-checker
71
+ class FixedBehaviourExecutionGenerator (testConfiguration : CTestConfiguration , testStructure : CTestStructure )
72
+ : ExecutionGenerator (testConfiguration, testStructure) {
73
+
74
+ override fun nextExecution (): List <List <Actor >> {
75
+ val parallelGroup = ArrayList (testStructure.actorGenerators)
76
+ val actorsPerThread = ArrayList <MutableList <Actor >>()
77
+ for (i in testConfiguration.threadConfigurations.indices) {
78
+ actorsPerThread.add(ArrayList ())
79
+ }
80
+
81
+
82
+ actorsPerThread[0 ].add(actorMethod(parallelGroup, " receive1" ))
83
+ actorsPerThread[0 ].add(actorMethod(parallelGroup, " receive2" ))
84
+ actorsPerThread[0 ].add(actorMethod(parallelGroup, " close1" ))
85
+
86
+ actorsPerThread[1 ].add(actorMethod(parallelGroup, " send2" ))
87
+ actorsPerThread[1 ].add(actorMethod(parallelGroup, " send1" ))
88
+
89
+ return actorsPerThread
90
+ }
91
+ }
0 commit comments