diff --git a/graphwalker-cli/src/test/resources/json/PetClinicWithSeed.json b/graphwalker-cli/src/test/resources/json/PetClinicWithSeed.json
new file mode 100644
index 000000000..a83974510
--- /dev/null
+++ b/graphwalker-cli/src/test/resources/json/PetClinicWithSeed.json
@@ -0,0 +1,345 @@
+{
+ "name": "GraphWalker Example Test",
+ "seed": 16436238642755,
+ "models": [
+ {
+ "name": "FindOwners",
+ "id": "476fb419-3d7d-4492-802e-6695fe93f595",
+ "generator": "random(edge_coverage(100))",
+ "vertices": [
+ {
+ "id": "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "name": "v_FindOwners",
+ "sharedState": "FindOwners",
+ "properties": {
+ "x": 0,
+ "y": 0
+ }
+ },
+ {
+ "id": "dcb0e896-468c-11e7-a919-92ebcb67fe33",
+ "name": "v_NewOwner",
+ "sharedState": "NewOwner",
+ "properties": {
+ "x": 120.65625,
+ "y": -157.8125
+ }
+ },
+ {
+ "id": "dcb0f200-468c-11e7-a919-92ebcb67fe33",
+ "name": "v_Owners",
+ "properties": {
+ "x": -219.34375,
+ "y": -187.8125
+ }
+ }
+ ],
+ "edges": [
+ {
+ "id": "dcb0fb88-468c-11e7-a919-92ebcb67fe33",
+ "name": "e_AddOwner",
+ "sourceVertexId": "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "targetVertexId": "dcb0e896-468c-11e7-a919-92ebcb67fe33"
+ },
+ {
+ "id": "dcb0fd5e-468c-11e7-a919-92ebcb67fe33",
+ "name": "e_FindOwners",
+ "sourceVertexId": "dcb0e896-468c-11e7-a919-92ebcb67fe33",
+ "targetVertexId": "b53814ec-468c-11e7-a919-92ebcb67fe33"
+ },
+ {
+ "id": "dcb0fe62-468c-11e7-a919-92ebcb67fe33",
+ "name": "e_Search",
+ "sourceVertexId": "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "targetVertexId": "dcb0f200-468c-11e7-a919-92ebcb67fe33"
+ },
+ {
+ "id": "dcb0ff34-468c-11e7-a919-92ebcb67fe33",
+ "name": "e_FindOwners",
+ "sourceVertexId": "dcb0f200-468c-11e7-a919-92ebcb67fe33",
+ "targetVertexId": "b53814ec-468c-11e7-a919-92ebcb67fe33"
+ }
+ ]
+ },
+ {
+ "name": "NewOwner",
+ "id": "b23d193c-287a-4eb9-a318-52ead7680ff7",
+ "generator": "random(edge_coverage(100))",
+ "vertices": [
+ {
+ "id": "dcb0d798-468c-11e7-a919-92ebcb67fe33",
+ "name": "v_NewOwner",
+ "sharedState": "NewOwner",
+ "properties": {
+ "x": 0,
+ "y": 0
+ }
+ },
+ {
+ "id": "dcb0eab2-468c-11e7-a919-92ebcb67fe33",
+ "name": "v_IncorrectData",
+ "properties": {
+ "x": 131.65625,
+ "y": -205.3125
+ }
+ },
+ {
+ "id": "dcb0f3c2-468c-11e7-a919-92ebcb67fe33",
+ "name": "v_OwnerInformation",
+ "sharedState": "OwnerInformation",
+ "properties": {
+ "x": -284.34375,
+ "y": -143.3125
+ }
+ }
+ ],
+ "edges": [
+ {
+ "id": "dcb104e8-468c-11e7-a919-92ebcb67fe33",
+ "name": "e_IncorrectData",
+ "sourceVertexId": "dcb0d798-468c-11e7-a919-92ebcb67fe33",
+ "targetVertexId": "dcb0eab2-468c-11e7-a919-92ebcb67fe33"
+ },
+ {
+ "id": "dcb10736-468c-11e7-a919-92ebcb67fe33",
+ "sourceVertexId": "dcb0eab2-468c-11e7-a919-92ebcb67fe33",
+ "targetVertexId": "dcb0d798-468c-11e7-a919-92ebcb67fe33"
+ },
+ {
+ "id": "dcb10812-468c-11e7-a919-92ebcb67fe33",
+ "name": "e_CorrectData",
+ "sourceVertexId": "dcb0d798-468c-11e7-a919-92ebcb67fe33",
+ "targetVertexId": "dcb0f3c2-468c-11e7-a919-92ebcb67fe33"
+ }
+ ]
+ },
+ {
+ "name": "OwnerInformation",
+ "id": "5f1149c3-2853-47e6-838d-691bf30406a8",
+ "generator": "random(edge_coverage(100))",
+ "actions": [
+ "numOfPets=0;"
+ ],
+ "vertices": [
+ {
+ "id": "dcb0dba8-468c-11e7-a919-92ebcb67fe33",
+ "name": "v_OwnerInformation",
+ "sharedState": "OwnerInformation",
+ "properties": {
+ "x": -23.34375,
+ "y": -51.8125
+ }
+ },
+ {
+ "id": "dcb0ebb6-468c-11e7-a919-92ebcb67fe33",
+ "name": "v_NewPet",
+ "properties": {
+ "x": -27.34375,
+ "y": 118.1875
+ }
+ },
+ {
+ "id": "dcb0f8a4-468c-11e7-a919-92ebcb67fe33",
+ "name": "v_Pet",
+ "properties": {
+ "x": -317.34375,
+ "y": 7.1875
+ }
+ },
+ {
+ "id": "971ec0b8-468d-11e7-a919-92ebcb67fe33",
+ "name": "v_NewVisit",
+ "properties": {
+ "x": 139.65625,
+ "y": -195.8125
+ }
+ },
+ {
+ "id": "971ec57c-468d-11e7-a919-92ebcb67fe33",
+ "name": "v_FindOwners",
+ "sharedState": "FindOwners",
+ "properties": {
+ "x": -270.34375,
+ "y": -181.8125
+ }
+ }
+ ],
+ "edges": [
+ {
+ "id": "971ec838-468d-11e7-a919-92ebcb67fe33",
+ "name": "e_AddPetSuccessfully",
+ "actions": [
+ " numOfPets++;"
+ ],
+ "sourceVertexId": "dcb0ebb6-468c-11e7-a919-92ebcb67fe33",
+ "targetVertexId": "dcb0dba8-468c-11e7-a919-92ebcb67fe33"
+ },
+ {
+ "id": "971ecaa4-468d-11e7-a919-92ebcb67fe33",
+ "name": "e_AddNewPet",
+ "sourceVertexId": "dcb0dba8-468c-11e7-a919-92ebcb67fe33",
+ "targetVertexId": "dcb0ebb6-468c-11e7-a919-92ebcb67fe33"
+ },
+ {
+ "id": "971ecca2-468d-11e7-a919-92ebcb67fe33",
+ "name": "e_EditPet",
+ "guard": "numOfPets>0",
+ "sourceVertexId": "dcb0dba8-468c-11e7-a919-92ebcb67fe33",
+ "targetVertexId": "dcb0f8a4-468c-11e7-a919-92ebcb67fe33"
+ },
+ {
+ "id": "971ece78-468d-11e7-a919-92ebcb67fe33",
+ "name": "e_UpdatePet",
+ "sourceVertexId": "dcb0f8a4-468c-11e7-a919-92ebcb67fe33",
+ "targetVertexId": "dcb0dba8-468c-11e7-a919-92ebcb67fe33"
+ },
+ {
+ "id": "971ed0b2-468d-11e7-a919-92ebcb67fe33",
+ "name": "e_AddPetFailed",
+ "sourceVertexId": "dcb0ebb6-468c-11e7-a919-92ebcb67fe33",
+ "targetVertexId": "dcb0ebb6-468c-11e7-a919-92ebcb67fe33"
+ },
+ {
+ "id": "971ed3c8-468d-11e7-a919-92ebcb67fe33",
+ "name": "e_AddVisit",
+ "guard": "numOfPets>0",
+ "sourceVertexId": "dcb0dba8-468c-11e7-a919-92ebcb67fe33",
+ "targetVertexId": "971ec0b8-468d-11e7-a919-92ebcb67fe33"
+ },
+ {
+ "id": "971ed53a-468d-11e7-a919-92ebcb67fe33",
+ "name": "e_VisitAddedSuccessfully",
+ "sourceVertexId": "971ec0b8-468d-11e7-a919-92ebcb67fe33",
+ "targetVertexId": "dcb0dba8-468c-11e7-a919-92ebcb67fe33"
+ },
+ {
+ "id": "971ed738-468d-11e7-a919-92ebcb67fe33",
+ "name": "e_VisitAddedFailed",
+ "sourceVertexId": "971ec0b8-468d-11e7-a919-92ebcb67fe33",
+ "targetVertexId": "971ec0b8-468d-11e7-a919-92ebcb67fe33"
+ },
+ {
+ "id": "971edad0-468d-11e7-a919-92ebcb67fe33",
+ "name": "e_FindOwners",
+ "sourceVertexId": "dcb0dba8-468c-11e7-a919-92ebcb67fe33",
+ "targetVertexId": "971ec57c-468d-11e7-a919-92ebcb67fe33"
+ }
+ ]
+ },
+ {
+ "name": "PetClinic",
+ "id": "3f6b365f-7011-4db6-b0cc-e19aa453d9b8",
+ "generator": "random(edge_coverage(100))",
+ "vertices": [
+ {
+ "id": "dcb0dde2-468c-11e7-a919-92ebcb67fe33",
+ "name": "v_HomePage",
+ "sharedState": "HomePage",
+ "properties": {
+ "x": 0,
+ "y": 0
+ }
+ },
+ {
+ "id": "dcb0ef4e-468c-11e7-a919-92ebcb67fe33",
+ "name": "v_FindOwners",
+ "sharedState": "FindOwners",
+ "properties": {
+ "x": 112.65625,
+ "y": -180.8125
+ }
+ },
+ {
+ "id": "dcb0f8a5-468c-11e7-a919-92ebcb67fe33",
+ "name": "v_Veterinarians",
+ "sharedState": "Veterinarians",
+ "properties": {
+ "x": -246.34375,
+ "y": -153.8125
+ }
+ }
+ ],
+ "edges": [
+ {
+ "id": "971edcce-468d-11e7-a919-92ebcb67fe33",
+ "name": "e_FindOwners",
+ "sourceVertexId": "dcb0dde2-468c-11e7-a919-92ebcb67fe33",
+ "targetVertexId": "dcb0ef4e-468c-11e7-a919-92ebcb67fe33"
+ },
+ {
+ "id": "971ede36-468d-11e7-a919-92ebcb67fe33",
+ "name": "e_HomePage",
+ "sourceVertexId": "dcb0ef4e-468c-11e7-a919-92ebcb67fe33",
+ "targetVertexId": "dcb0dde2-468c-11e7-a919-92ebcb67fe33"
+ },
+ {
+ "id": "971ee142-468d-11e7-a919-92ebcb67fe33",
+ "name": "e_Veterinarians",
+ "sourceVertexId": "dcb0dde2-468c-11e7-a919-92ebcb67fe33",
+ "targetVertexId": "dcb0f8a5-468c-11e7-a919-92ebcb67fe33"
+ },
+ {
+ "id": "971ee2b4-468d-11e7-a919-92ebcb67fe33",
+ "name": "e_HomePage",
+ "sourceVertexId": "dcb0f8a5-468c-11e7-a919-92ebcb67fe33",
+ "targetVertexId": "dcb0dde2-468c-11e7-a919-92ebcb67fe33"
+ },
+ {
+ "id": "971ee5c0-468d-11e7-a919-92ebcb67fe33",
+ "name": "e_Veterinarians",
+ "sourceVertexId": "dcb0ef4e-468c-11e7-a919-92ebcb67fe33",
+ "targetVertexId": "dcb0f8a5-468c-11e7-a919-92ebcb67fe33"
+ },
+ {
+ "id": "971ee732-468d-11e7-a919-92ebcb67fe33",
+ "name": "e_FindOwners",
+ "sourceVertexId": "dcb0f8a5-468c-11e7-a919-92ebcb67fe33",
+ "targetVertexId": "dcb0ef4e-468c-11e7-a919-92ebcb67fe33"
+ },
+ {
+ "id": "b53810a0-468c-11e7-a919-92ebcb67fe33",
+ "name": "e_StartBrowser",
+ "targetVertexId": "dcb0dde2-468c-11e7-a919-92ebcb67fe33"
+ }
+ ],
+ "startElementId": "b53810a0-468c-11e7-a919-92ebcb67fe33"
+ },
+ {
+ "name": "Veterinarians",
+ "id": "368a9635-c59a-4285-ad01-cf75b0baa978",
+ "generator": "random(edge_coverage(100))",
+ "vertices": [
+ {
+ "id": "dcb0defa-468c-11e7-a919-92ebcb67fe33",
+ "name": "v_Veterinarians",
+ "sharedState": "Veterinarians",
+ "properties": {
+ "x": 0,
+ "y": 0
+ }
+ },
+ {
+ "id": "dcb0f124-468c-11e7-a919-92ebcb67fe33",
+ "name": "v_SearchResult",
+ "properties": {
+ "x": -213.34375,
+ "y": -138.8125
+ }
+ }
+ ],
+ "edges": [
+ {
+ "id": "971eea2a-468d-11e7-a919-92ebcb67fe33",
+ "name": "e_Search",
+ "sourceVertexId": "dcb0defa-468c-11e7-a919-92ebcb67fe33",
+ "targetVertexId": "dcb0f124-468c-11e7-a919-92ebcb67fe33"
+ },
+ {
+ "id": "971eeba6-468d-11e7-a919-92ebcb67fe33",
+ "sourceVertexId": "dcb0f124-468c-11e7-a919-92ebcb67fe33",
+ "targetVertexId": "dcb0defa-468c-11e7-a919-92ebcb67fe33"
+ }
+ ]
+ }
+ ]
+}
diff --git a/graphwalker-core/src/main/java/org/graphwalker/core/generator/QuickRandomPath.java b/graphwalker-core/src/main/java/org/graphwalker/core/generator/QuickRandomPath.java
index 83ae470fd..f15c48eda 100644
--- a/graphwalker-core/src/main/java/org/graphwalker/core/generator/QuickRandomPath.java
+++ b/graphwalker-core/src/main/java/org/graphwalker/core/generator/QuickRandomPath.java
@@ -1,7 +1,7 @@
package org.graphwalker.core.generator;
/*
-* #%L
+ * #%L
* * GraphWalker Core
* *
* %%
@@ -26,7 +26,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
* #L%
-*/
+ */
import org.graphwalker.core.algorithm.AStar;
import org.graphwalker.core.condition.StopCondition;
@@ -71,7 +71,7 @@ public Context getNextStep() {
if (elements.isEmpty()) {
elements.addAll(context.getModel().getElements());
elements.remove(context.getCurrentElement());
- Collections.shuffle(elements);
+ Collections.shuffle(elements, SingletonRandomGenerator.random());
}
if (isNull(target) || target.equals(context.getCurrentElement())) {
if (elements.isEmpty()) {
diff --git a/graphwalker-core/src/main/java/org/graphwalker/core/generator/RandomPath.java b/graphwalker-core/src/main/java/org/graphwalker/core/generator/RandomPath.java
index 756b1f8fe..1bc020238 100644
--- a/graphwalker-core/src/main/java/org/graphwalker/core/generator/RandomPath.java
+++ b/graphwalker-core/src/main/java/org/graphwalker/core/generator/RandomPath.java
@@ -12,10 +12,10 @@
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -33,7 +33,6 @@
import org.slf4j.LoggerFactory;
import java.util.List;
-import java.util.Random;
/**
*
RandomPath
@@ -48,8 +47,6 @@ public class RandomPath extends PathGeneratorBase {
private static final Logger LOG = LoggerFactory.getLogger(RandomPath.class);
- private final Random random = new Random(System.nanoTime());
-
public RandomPath(StopCondition stopCondition) {
setStopCondition(stopCondition);
}
@@ -64,7 +61,7 @@ public Context getNextStep() {
LOG.error("context.getModel().getElements(): " + context.getModel().getElements());
throw new NoPathFoundException(context.getCurrentElement());
}
- context.setCurrentElement(elements.get(random.nextInt(elements.size())));
+ context.setCurrentElement(elements.get(SingletonRandomGenerator.nextInt(elements.size())));
return context;
}
diff --git a/graphwalker-core/src/main/java/org/graphwalker/core/generator/SingletonRandomGenerator.java b/graphwalker-core/src/main/java/org/graphwalker/core/generator/SingletonRandomGenerator.java
new file mode 100644
index 000000000..75db835d9
--- /dev/null
+++ b/graphwalker-core/src/main/java/org/graphwalker/core/generator/SingletonRandomGenerator.java
@@ -0,0 +1,84 @@
+package org.graphwalker.core.generator;
+
+/*
+ * #%L
+ * GraphWalker Core
+ * %%
+ * Copyright (C) 2005 - 2014 GraphWalker
+ * %%
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ * #L%
+ */
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Random;
+
+public class SingletonRandomGenerator {
+
+ private static final Logger LOG = LoggerFactory.getLogger(SingletonRandomGenerator.class);
+ private static Random random = null;
+ private static Boolean isSeeded = null;
+ private static SingletonRandomGenerator singletonRandomGenerator = new SingletonRandomGenerator();
+
+ private SingletonRandomGenerator() {
+ random = new Random();
+ isSeeded = new Boolean(false);
+ }
+
+ public static Random random() {
+ if (isSeeded) {
+ return random;
+ }
+ long seed = System.nanoTime();
+ LOG.info("Seed: " + seed);
+ random.setSeed(seed);
+ isSeeded = true;
+ return random;
+ }
+
+ public static int nextInt() {
+ if (isSeeded) {
+ return random.nextInt();
+ }
+ long seed = System.nanoTime();
+ LOG.info("Seed: " + seed);
+ random.setSeed(seed);
+ isSeeded = true;
+ return random.nextInt();
+ }
+
+ public static int nextInt(int bound) {
+ if (isSeeded) {
+ return random.nextInt(bound);
+ }
+ long seed = System.nanoTime();
+ LOG.info("Seed: " + seed);
+ random.setSeed(seed);
+ isSeeded = true;
+ return random.nextInt(bound);
+ }
+
+ public static void setSeed(long seed) {
+ LOG.info("Seeded: " + seed);
+ isSeeded = true;
+ random.setSeed(seed);
+ }
+}
diff --git a/graphwalker-core/src/main/java/org/graphwalker/core/generator/WeightedRandomPath.java b/graphwalker-core/src/main/java/org/graphwalker/core/generator/WeightedRandomPath.java
index aae076293..51dc46002 100644
--- a/graphwalker-core/src/main/java/org/graphwalker/core/generator/WeightedRandomPath.java
+++ b/graphwalker-core/src/main/java/org/graphwalker/core/generator/WeightedRandomPath.java
@@ -12,10 +12,10 @@
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -32,11 +32,12 @@
import org.graphwalker.core.model.Edge;
import org.graphwalker.core.model.Element;
import org.graphwalker.core.model.Vertex;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.Random;
/**
* WeightedRandomPath
@@ -52,7 +53,7 @@
*/
public class WeightedRandomPath extends PathGeneratorBase {
- private final Random random = new Random(System.nanoTime());
+ private static final Logger LOG = LoggerFactory.getLogger(WeightedRandomPath.class);
public WeightedRandomPath(StopCondition stopCondition) {
setStopCondition(stopCondition);
@@ -69,7 +70,7 @@ public Context getNextStep() {
if (currentElement instanceof Vertex.RuntimeVertex) {
context.setCurrentElement(getWeightedEdge(elements, currentElement));
} else {
- context.setCurrentElement(elements.get(random.nextInt(elements.size())));
+ context.setCurrentElement(elements.get(SingletonRandomGenerator.nextInt(elements.size())));
}
return context;
}
@@ -93,8 +94,8 @@ private Element getWeightedEdge(List elements, Element currentElement)
sum += edge.getWeight();
if (sum > 1) {
throw new MachineException("The sum of all weights in edges from vertex: '"
- + currentElement.getName()
- + "', adds up to more than 1.00");
+ + currentElement.getName()
+ + "', adds up to more than 1.00");
}
} else {
numberOfZeros++;
@@ -109,7 +110,7 @@ private Element getWeightedEdge(List elements, Element currentElement)
} else {
rest = 1 - sum;
}
- int index = random.nextInt(100);
+ int index = SingletonRandomGenerator.nextInt(100);
double weight = 0;
for (Element element : elements) {
if (element instanceof Edge.RuntimeEdge) {
@@ -127,8 +128,8 @@ private Element getWeightedEdge(List elements, Element currentElement)
}
throw new MachineException("Could not calculate which weighted edge to choose from vertex: "
- + currentElement.getName()
- + "'");
+ + currentElement.getName()
+ + "'");
}
}
diff --git a/graphwalker-core/src/main/java/org/graphwalker/core/machine/SimpleMachine.java b/graphwalker-core/src/main/java/org/graphwalker/core/machine/SimpleMachine.java
index 9ac2508de..16a74f162 100644
--- a/graphwalker-core/src/main/java/org/graphwalker/core/machine/SimpleMachine.java
+++ b/graphwalker-core/src/main/java/org/graphwalker/core/machine/SimpleMachine.java
@@ -12,10 +12,10 @@
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -28,6 +28,7 @@
import org.graphwalker.core.event.EventType;
import org.graphwalker.core.generator.NoPathFoundException;
+import org.graphwalker.core.generator.SingletonRandomGenerator;
import org.graphwalker.core.model.Action;
import org.graphwalker.core.model.Element;
import org.graphwalker.core.model.Requirement;
@@ -190,8 +191,7 @@ private Context takeNextStep(Context context) {
private Context chooseSharedContext(Context context, RuntimeVertex vertex) {
List candidates = getPossibleSharedStates(vertex.getSharedState());
- Random random = new Random(System.nanoTime());
- SharedStateTuple candidate = candidates.get(random.nextInt(candidates.size()));
+ SharedStateTuple candidate = candidates.get(SingletonRandomGenerator.nextInt(candidates.size()));
if (!candidate.getVertex().equals(context.getCurrentElement())) {
candidate.context.setNextElement(candidate.getVertex());
context = switchContext(candidate.context);
@@ -217,7 +217,7 @@ private List getPossibleSharedStates(String sharedState) {
} else if (!getCurrentContext().equals(context) && context.getModel().hasSharedState(sharedState)) {
for (RuntimeVertex vertex : context.getModel().getSharedStates(sharedState)) {
if ((!vertex.equals(lastElement) || getCurrentContext().getModel().getOutEdges((RuntimeVertex) getCurrentContext().getCurrentElement()).isEmpty())
- && (vertex.hasName() || !context.getModel().getOutEdges(vertex).isEmpty())) {
+ && (vertex.hasName() || !context.getModel().getOutEdges(vertex).isEmpty())) {
sharedStates.add(new SharedStateTuple(context, vertex));
}
}
@@ -228,8 +228,8 @@ private List getPossibleSharedStates(String sharedState) {
private boolean hasOutEdges(Context context) {
return isNotNull(context.getCurrentElement())
- && context.getCurrentElement() instanceof RuntimeVertex
- && !context.getModel().getOutEdges((RuntimeVertex) context.getCurrentElement()).isEmpty();
+ && context.getCurrentElement() instanceof RuntimeVertex
+ && !context.getModel().getOutEdges((RuntimeVertex) context.getCurrentElement()).isEmpty();
}
@Override
diff --git a/graphwalker-core/src/test/java/org/graphwalker/core/Models.java b/graphwalker-core/src/test/java/org/graphwalker/core/Models.java
index 644ebe8d1..407ac0d11 100644
--- a/graphwalker-core/src/test/java/org/graphwalker/core/Models.java
+++ b/graphwalker-core/src/test/java/org/graphwalker/core/Models.java
@@ -45,10 +45,28 @@ public abstract class Models {
.setName("B");
private static final Edge EDGE_AB = new Edge()
- .setId("ab")
- .setName("ab")
- .setSourceVertex(VERTEX_A)
- .setTargetVertex(VERTEX_B);
+ .setId("ab")
+ .setName("ab")
+ .setSourceVertex(VERTEX_A)
+ .setTargetVertex(VERTEX_B);
+
+ private static final Edge EDGE_AB_2 = new Edge()
+ .setId("ab_2")
+ .setName("ab_2")
+ .setSourceVertex(VERTEX_A)
+ .setTargetVertex(VERTEX_B);
+
+ private static final Edge EDGE_AB_3 = new Edge()
+ .setId("ab_3")
+ .setName("ab_3")
+ .setSourceVertex(VERTEX_A)
+ .setTargetVertex(VERTEX_B);
+
+ private static final Edge EDGE_BA = new Edge()
+ .setId("ba")
+ .setName("ba")
+ .setSourceVertex(VERTEX_B)
+ .setTargetVertex(VERTEX_A);
private static final RuntimeModel EMPTY_MODEL = new Model().build();
@@ -57,8 +75,15 @@ public abstract class Models {
.build();
private static final RuntimeModel SIMPLE_MODEL = new Model()
- .addEdge(EDGE_AB)
- .build();
+ .addEdge(EDGE_AB)
+ .build();
+
+ private static final RuntimeModel FOUR_EDGES_MODEL = new Model()
+ .addEdge(EDGE_AB)
+ .addEdge(EDGE_AB_2)
+ .addEdge(EDGE_AB_3)
+ .addEdge(EDGE_BA)
+ .build();
public static RuntimeVertex findVertex(RuntimeModel model, String id) {
return (RuntimeVertex) model.getElementById(id);
@@ -79,4 +104,8 @@ public static Model singleModel() {
public static Model simpleModel() {
return new Model(SIMPLE_MODEL);
}
+
+ public static Model fourEdgesModel() {
+ return new Model(FOUR_EDGES_MODEL);
+ }
}
diff --git a/graphwalker-core/src/test/java/org/graphwalker/core/condition/ComplexConditionsTest.java b/graphwalker-core/src/test/java/org/graphwalker/core/condition/ComplexConditionsTest.java
index e182b3b31..fc0b0e6b8 100644
--- a/graphwalker-core/src/test/java/org/graphwalker/core/condition/ComplexConditionsTest.java
+++ b/graphwalker-core/src/test/java/org/graphwalker/core/condition/ComplexConditionsTest.java
@@ -76,7 +76,6 @@ public void combinedCondition_2_vertices() throws Exception {
Machine machine = new SimpleMachine(context);
while (machine.hasNextStep()) {
machine.getNextStep();
- System.out.println(context.getCurrentElement().getName());
}
}
@@ -92,7 +91,6 @@ public void combinedCondition_2_edges() throws Exception {
Machine machine = new SimpleMachine(context);
while (machine.hasNextStep()) {
machine.getNextStep();
- System.out.println(context.getCurrentElement().getName());
}
}
@@ -108,7 +106,6 @@ public void combinedCondition_vertex_edge() throws Exception {
Machine machine = new SimpleMachine(context);
while (machine.hasNextStep()) {
machine.getNextStep();
- System.out.println(context.getCurrentElement().getName());
}
}
@@ -124,7 +121,6 @@ public void alternativeCondition_2_vertices() throws Exception {
Machine machine = new SimpleMachine(context);
while (machine.hasNextStep()) {
machine.getNextStep();
- System.out.println(context.getCurrentElement().getName());
}
}
@@ -140,7 +136,6 @@ public void alternativeCondition_2_edges() throws Exception {
Machine machine = new SimpleMachine(context);
while (machine.hasNextStep()) {
machine.getNextStep();
- System.out.println(context.getCurrentElement().getName());
}
}
@@ -156,7 +151,6 @@ public void alternativeCondition_vertex_edge() throws Exception {
Machine machine = new SimpleMachine(context);
while (machine.hasNextStep()) {
machine.getNextStep();
- System.out.println(context.getCurrentElement().getName());
}
}
diff --git a/graphwalker-core/src/test/java/org/graphwalker/core/generator/QuickRandomPathTest.java b/graphwalker-core/src/test/java/org/graphwalker/core/generator/QuickRandomPathTest.java
index c2dc57d67..9701aa2e1 100644
--- a/graphwalker-core/src/test/java/org/graphwalker/core/generator/QuickRandomPathTest.java
+++ b/graphwalker-core/src/test/java/org/graphwalker/core/generator/QuickRandomPathTest.java
@@ -12,10 +12,10 @@
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -26,15 +26,8 @@
* #L%
*/
-import static org.graphwalker.core.Models.findEdge;
-import static org.graphwalker.core.Models.findVertex;
-import static org.graphwalker.core.Models.simpleModel;
-import static org.graphwalker.core.Models.singleModel;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
import org.graphwalker.core.algorithm.AlgorithmException;
+import org.graphwalker.core.condition.Length;
import org.graphwalker.core.condition.VertexCoverage;
import org.graphwalker.core.machine.Context;
import org.graphwalker.core.machine.Machine;
@@ -43,10 +36,17 @@
import org.graphwalker.core.model.Edge.RuntimeEdge;
import org.graphwalker.core.model.Model.RuntimeModel;
import org.graphwalker.core.model.Vertex.RuntimeVertex;
-import org.graphwalker.core.statistics.Profiler;
import org.graphwalker.core.statistics.SimpleProfiler;
+import org.junit.Assert;
import org.junit.Test;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.graphwalker.core.Models.*;
+import static org.junit.Assert.*;
+
/**
* @author Kristian Karl
*/
@@ -98,4 +98,60 @@ public void singleTest() throws Exception {
assertTrue(generator.hasNextStep());
generator.getNextStep(); // should fail
}
+
+ @Test
+ public void seededGenerator() {
+ RuntimeModel model = fourEdgesModel().build();
+ RuntimeVertex A = findVertex(model, "A");
+ RuntimeVertex B = findVertex(model, "B");
+ RuntimeEdge AB = findEdge(model, "ab");
+ RuntimeEdge AB_2 = findEdge(model, "ab_2");
+ RuntimeEdge AB_3 = findEdge(model, "ab_2");
+ RuntimeEdge BA = findEdge(model, "ba");
+ Context context = new TestExecutionContext().setModel(model).setNextElement(A);
+
+ SingletonRandomGenerator.setSeed(1349327921);
+ context.setPathGenerator(new QuickRandomPath(new Length(30)));
+ Machine machine = new SimpleMachine(context);
+
+ List actualPath = new ArrayList();
+ while (machine.hasNextStep()) {
+ machine.getNextStep();
+ actualPath.add(machine.getCurrentContext().getCurrentElement().getId());
+ }
+
+ Assert.assertArrayEquals(new ArrayList<>(Arrays.asList(
+ "A",
+ "ab",
+ "B",
+ "ba",
+ "A",
+ "ab_3",
+ "B",
+ "ba",
+ "A",
+ "ab_2",
+ "B",
+ "ba",
+ "A",
+ "ab",
+ "B",
+ "ba",
+ "A",
+ "ab_3",
+ "B",
+ "ba",
+ "A",
+ "ab_2",
+ "B",
+ "ba",
+ "A",
+ "ab",
+ "B",
+ "ba",
+ "A",
+ "ab_2",
+ "B"
+ )).toArray(), actualPath.toArray());
+ }
}
diff --git a/graphwalker-core/src/test/java/org/graphwalker/core/generator/RandomPathTest.java b/graphwalker-core/src/test/java/org/graphwalker/core/generator/RandomPathTest.java
index 19e226f18..26e396914 100644
--- a/graphwalker-core/src/test/java/org/graphwalker/core/generator/RandomPathTest.java
+++ b/graphwalker-core/src/test/java/org/graphwalker/core/generator/RandomPathTest.java
@@ -12,10 +12,10 @@
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -26,22 +26,28 @@
* #L%
*/
-import static org.graphwalker.core.Models.findEdge;
-import static org.graphwalker.core.Models.findVertex;
-import static org.graphwalker.core.Models.simpleModel;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
import org.graphwalker.core.condition.EdgeCoverage;
+import org.graphwalker.core.condition.Length;
import org.graphwalker.core.condition.VertexCoverage;
import org.graphwalker.core.machine.Context;
+import org.graphwalker.core.machine.Machine;
+import org.graphwalker.core.machine.SimpleMachine;
import org.graphwalker.core.machine.TestExecutionContext;
import org.graphwalker.core.model.Edge.RuntimeEdge;
import org.graphwalker.core.model.Model.RuntimeModel;
import org.graphwalker.core.model.Vertex.RuntimeVertex;
+import org.junit.Assert;
import org.junit.Test;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static junit.framework.TestCase.assertTrue;
+import static org.graphwalker.core.Models.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
/**
* @author Nils Olsson
*/
@@ -94,4 +100,60 @@ public void failTest() throws Exception {
assertEquals(context.getPathGenerator().getNextStep().getCurrentElement(), target);
context.getPathGenerator().getNextStep(); // should fail
}
+
+ @Test
+ public void seededGenerator() {
+ RuntimeModel model = fourEdgesModel().build();
+ RuntimeVertex A = findVertex(model, "A");
+ RuntimeVertex B = findVertex(model, "B");
+ RuntimeEdge AB = findEdge(model, "ab");
+ RuntimeEdge AB_2 = findEdge(model, "ab_2");
+ RuntimeEdge AB_3 = findEdge(model, "ab_2");
+ RuntimeEdge BA = findEdge(model, "ba");
+ Context context = new TestExecutionContext().setModel(model).setNextElement(A);
+
+ SingletonRandomGenerator.setSeed(1349327921);
+ context.setPathGenerator(new RandomPath(new Length(30)));
+ Machine machine = new SimpleMachine(context);
+
+ List actualPath = new ArrayList();
+ while (machine.hasNextStep()) {
+ machine.getNextStep();
+ actualPath.add(machine.getCurrentContext().getCurrentElement().getId());
+ }
+
+ Assert.assertArrayEquals(new ArrayList<>(Arrays.asList(
+ "A",
+ "ab",
+ "B",
+ "ba",
+ "A",
+ "ab_2",
+ "B",
+ "ba",
+ "A",
+ "ab_2",
+ "B",
+ "ba",
+ "A",
+ "ab_2",
+ "B",
+ "ba",
+ "A",
+ "ab",
+ "B",
+ "ba",
+ "A",
+ "ab_3",
+ "B",
+ "ba",
+ "A",
+ "ab_2",
+ "B",
+ "ba",
+ "A",
+ "ab",
+ "B"
+ )).toArray(), actualPath.toArray());
+ }
}
diff --git a/graphwalker-core/src/test/java/org/graphwalker/core/generator/SingletonRandomGeneratorTest.java b/graphwalker-core/src/test/java/org/graphwalker/core/generator/SingletonRandomGeneratorTest.java
new file mode 100644
index 000000000..bb006219b
--- /dev/null
+++ b/graphwalker-core/src/test/java/org/graphwalker/core/generator/SingletonRandomGeneratorTest.java
@@ -0,0 +1,43 @@
+package org.graphwalker.core.generator;
+
+import org.junit.Test;
+
+import java.util.Random;
+
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+public class SingletonRandomGeneratorTest {
+
+ @Test
+ public void instantiation() {
+ assertThat(SingletonRandomGenerator.random(), is(instanceOf(Random.class)));
+ }
+
+ @Test
+ public void seed() {
+ SingletonRandomGenerator.setSeed(123);
+ assertThat(SingletonRandomGenerator.nextInt(), is(-1188957731));
+ assertThat(SingletonRandomGenerator.nextInt(), is(1018954901));
+ assertThat(SingletonRandomGenerator.nextInt(), is(-39088943));
+ }
+
+ @Test
+ public void un_seeded() {
+ assertThat(SingletonRandomGenerator.nextInt(), is(instanceOf(int.class)));
+ }
+
+ @Test
+ public void seededBoundNextInt() {
+ SingletonRandomGenerator.setSeed(123);
+ assertThat(SingletonRandomGenerator.nextInt(1), is(0));
+ assertThat(SingletonRandomGenerator.nextInt(99), is(86));
+ assertThat(SingletonRandomGenerator.nextInt(999), is(245));
+ }
+
+ @Test
+ public void un_seededBoundNextInt() {
+ assertThat(SingletonRandomGenerator.nextInt(999), is(instanceOf(int.class)));
+ }
+}
diff --git a/graphwalker-core/src/test/java/org/graphwalker/core/generator/WeightedRandomPathTest.java b/graphwalker-core/src/test/java/org/graphwalker/core/generator/WeightedRandomPathTest.java
index 975d46d1f..b736d5bbb 100644
--- a/graphwalker-core/src/test/java/org/graphwalker/core/generator/WeightedRandomPathTest.java
+++ b/graphwalker-core/src/test/java/org/graphwalker/core/generator/WeightedRandomPathTest.java
@@ -12,10 +12,10 @@
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -27,6 +27,7 @@
*/
import org.graphwalker.core.condition.EdgeCoverage;
+import org.graphwalker.core.condition.Length;
import org.graphwalker.core.machine.Context;
import org.graphwalker.core.machine.MachineException;
import org.graphwalker.core.machine.SimpleMachine;
@@ -34,10 +35,15 @@
import org.graphwalker.core.model.Edge;
import org.graphwalker.core.model.Model;
import org.graphwalker.core.model.Vertex;
+import org.junit.Assert;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
/**
* @author Kristian Karl
*/
@@ -45,23 +51,23 @@ public class WeightedRandomPathTest {
private static final Logger LOG = LoggerFactory.getLogger(WeightedRandomPathTest.class);
- private final Vertex source = new Vertex().setName("source");
- private final Vertex target = new Vertex().setName("target");
- private final Edge edge1 = new Edge().setSourceVertex(source).setTargetVertex(target).setWeight(0.5).setName("edge1");
- private final Edge edge2 = new Edge().setSourceVertex(source).setTargetVertex(target).setWeight(0.25).setName("edge2");
- private final Edge edge3 = new Edge().setSourceVertex(source).setTargetVertex(target).setWeight(0.15).setName("edge3");
- private final Edge edge4 = new Edge().setSourceVertex(source).setTargetVertex(target).setName("edge4");
- private final Edge edge5 = new Edge().setSourceVertex(source).setTargetVertex(target).setName("edge5");
- private final Edge edge6 = new Edge().setSourceVertex(source).setTargetVertex(target).setWeight(0.15).setName("edge6");
+ private final Vertex source = new Vertex().setName("source").setId("source");
+ private final Vertex target = new Vertex().setName("target").setId("target");
+ private final Edge edge1 = new Edge().setSourceVertex(source).setTargetVertex(target).setWeight(0.5).setName("edge1").setId("edge1");
+ private final Edge edge2 = new Edge().setSourceVertex(source).setTargetVertex(target).setWeight(0.25).setName("edge2").setId("edge2");
+ private final Edge edge3 = new Edge().setSourceVertex(source).setTargetVertex(target).setWeight(0.15).setName("edge3").setId("edge3");
+ private final Edge edge4 = new Edge().setSourceVertex(source).setTargetVertex(target).setName("edge4").setId("edge4");
+ private final Edge edge5 = new Edge().setSourceVertex(source).setTargetVertex(target).setName("edge5").setId("edge5");
+ private final Edge edge6 = new Edge().setSourceVertex(source).setTargetVertex(target).setWeight(0.15).setName("edge6").setId("edge6");
- private final Edge back2SourceEdge = new Edge().setSourceVertex(target).setTargetVertex(source).setName("back2SourceEdge");
+ private final Edge back2SourceEdge = new Edge().setSourceVertex(target).setTargetVertex(source).setName("back2SourceEdge").setId("back2SourceEdge");
private final Model model = new Model()
- .addEdge(edge1)
- .addEdge(edge2)
- .addEdge(edge3)
- .addEdge(edge4)
- .addEdge(edge5)
- .addEdge(back2SourceEdge);
+ .addEdge(edge1)
+ .addEdge(edge2)
+ .addEdge(edge3)
+ .addEdge(edge4)
+ .addEdge(edge5)
+ .addEdge(back2SourceEdge);
@Test
public void doesNotThrowForValidModel() throws Exception {
@@ -78,13 +84,13 @@ public void doesNotThrowForValidModel() throws Exception {
@Test(expected = MachineException.class)
public void throwsWhenTotalWeightHigherThanOne() throws Exception {
Model invalidModel = new Model()
- .addEdge(edge1)
- .addEdge(edge2)
- .addEdge(edge3)
- .addEdge(edge4)
- .addEdge(edge5)
- .addEdge(edge6)
- .addEdge(back2SourceEdge);
+ .addEdge(edge1)
+ .addEdge(edge2)
+ .addEdge(edge3)
+ .addEdge(edge4)
+ .addEdge(edge5)
+ .addEdge(edge6)
+ .addEdge(back2SourceEdge);
PathGenerator generator = new WeightedRandomPath(new EdgeCoverage(100));
Context context = new TestExecutionContext(invalidModel, generator).setCurrentElement(source.build());
SimpleMachine machine = new SimpleMachine(context);
@@ -118,12 +124,12 @@ public void doesNotThrowWhenNoWeightsSpecified() throws Exception {
Edge back2SourceEdge = new Edge().setSourceVertex(target).setTargetVertex(source).setName("back2SourceEdge");
Model unweightedModel = new Model()
- .addEdge(edge1)
- .addEdge(edge2)
- .addEdge(edge3)
- .addEdge(edge4)
- .addEdge(edge5)
- .addEdge(back2SourceEdge);
+ .addEdge(edge1)
+ .addEdge(edge2)
+ .addEdge(edge3)
+ .addEdge(edge4)
+ .addEdge(edge5)
+ .addEdge(back2SourceEdge);
PathGenerator generator = new WeightedRandomPath(new EdgeCoverage(100));
Context context = new TestExecutionContext(unweightedModel, generator).setCurrentElement(source.build());
@@ -134,4 +140,51 @@ public void doesNotThrowWhenNoWeightsSpecified() throws Exception {
machine.getNextStep();
}
}
+
+ @Test
+ public void seededGenerator() {
+ SingletonRandomGenerator.setSeed(1349327921);
+ PathGenerator generator = new WeightedRandomPath(new Length(30));
+ Context context = new TestExecutionContext(model, generator).setCurrentElement(source.build());
+ SimpleMachine machine = new SimpleMachine(context);
+
+ List actualPath = new ArrayList();
+ while (machine.hasNextStep()) {
+ machine.getNextStep();
+ actualPath.add(machine.getCurrentContext().getCurrentElement().getId());
+ }
+
+ Assert.assertArrayEquals(new ArrayList<>(Arrays.asList(
+ "edge1",
+ "target",
+ "back2SourceEdge",
+ "source",
+ "edge1",
+ "target",
+ "back2SourceEdge",
+ "source",
+ "edge1",
+ "target",
+ "back2SourceEdge",
+ "source",
+ "edge1",
+ "target",
+ "back2SourceEdge",
+ "source",
+ "edge1",
+ "target",
+ "back2SourceEdge",
+ "source",
+ "edge2",
+ "target",
+ "back2SourceEdge",
+ "source",
+ "edge2",
+ "target",
+ "back2SourceEdge",
+ "source",
+ "edge1",
+ "target"
+ )).toArray(), actualPath.toArray());
+ }
}
diff --git a/graphwalker-core/src/test/java/org/graphwalker/core/machine/MultipleContextTest.java b/graphwalker-core/src/test/java/org/graphwalker/core/machine/MultipleContextTest.java
index c58240da7..28aba483b 100644
--- a/graphwalker-core/src/test/java/org/graphwalker/core/machine/MultipleContextTest.java
+++ b/graphwalker-core/src/test/java/org/graphwalker/core/machine/MultipleContextTest.java
@@ -1,24 +1,170 @@
package org.graphwalker.core.machine;
+import org.graphwalker.core.condition.EdgeCoverage;
+import org.graphwalker.core.generator.RandomPath;
+import org.graphwalker.core.generator.SingletonRandomGenerator;
import org.graphwalker.core.model.Edge;
import org.graphwalker.core.model.Model;
import org.graphwalker.core.model.Vertex;
+import org.junit.Assert;
import org.junit.Test;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
public class MultipleContextTest {
- Vertex start = new Vertex();
- Vertex stop = new Vertex();
- Edge edge = new Edge().setSourceVertex(start).setTargetVertex(stop);
- Model model = new Model().addEdge(edge);
+ Vertex A = new Vertex().setId("A").setSharedState("A");
+ Vertex B = new Vertex().setId("B").setSharedState("B");
+ Edge AB = new Edge().setSourceVertex(A).setTargetVertex(B).setId("AB");
+ Model model = new Model().addEdge(AB);
@Test
public void multipleContexts() throws Exception {
- Context contextA = new TestExecutionContext(model).setNextElement(start);
- Context contextB = new TestExecutionContext(model).setNextElement(start);
+ Context contextA = new TestExecutionContext(model).setNextElement(A);
+ Context contextB = new TestExecutionContext(model).setNextElement(A);
Machine machine = new SimpleMachine(contextA, contextB);
while (machine.hasNextStep()) {
machine.getNextStep();
}
}
+
+ @Test
+ public void seededMultipleContexts() throws Exception {
+ Vertex A1 = new Vertex().setId("A1").setSharedState("A");
+ Vertex B1 = new Vertex().setId("B1").setSharedState("B");
+ Vertex A2 = new Vertex().setId("A2").setSharedState("A");
+ Vertex B2 = new Vertex().setId("B2").setSharedState("B");
+
+ Model model1 = new Model().setId("1");
+ model1.addEdge(new Edge().setSourceVertex(A1).setTargetVertex(B1).setId("A1B1_1"));
+ model1.addEdge(new Edge().setSourceVertex(A1).setTargetVertex(B1).setId("A1B1_2"));
+ model1.addEdge(new Edge().setSourceVertex(A1).setTargetVertex(B1).setId("A1B1_3"));
+ model1.addEdge(new Edge().setSourceVertex(B1).setTargetVertex(A1).setId("B1A1_1"));
+ model1.addEdge(new Edge().setSourceVertex(B1).setTargetVertex(A1).setId("B1A1_2"));
+
+ Model model2 = new Model().setId("2");
+ model2.addEdge(new Edge().setSourceVertex(A2).setTargetVertex(B2).setId("A2B2_1"));
+ model2.addEdge(new Edge().setSourceVertex(A2).setTargetVertex(B2).setId("A2B2_2"));
+ model2.addEdge(new Edge().setSourceVertex(A2).setTargetVertex(B2).setId("A2B2_3"));
+ model2.addEdge(new Edge().setSourceVertex(B2).setTargetVertex(A2).setId("B2A2_1"));
+ model2.addEdge(new Edge().setSourceVertex(B2).setTargetVertex(A2).setId("B2A2_2"));
+
+ SingletonRandomGenerator.setSeed(123456789);
+ Context context1 = new TestExecutionContext(model1, new RandomPath(new EdgeCoverage(100))).setNextElement(A1);
+ Context context2 = new TestExecutionContext(model2, new RandomPath(new EdgeCoverage(100))).setNextElement(A2);
+ Machine machine = new SimpleMachine(context1, context2);
+
+ List actualPath = new ArrayList();
+ while (machine.hasNextStep()) {
+ machine.getNextStep();
+ actualPath.add(machine.getCurrentContext().getCurrentElement().getId());
+ }
+
+ Assert.assertArrayEquals(new ArrayList<>(Arrays.asList(
+ "A1",
+ "A2",
+ "A2B2_3",
+ "B2",
+ "B1",
+ "B1A1_2",
+ "A1",
+ "A2",
+ "A2B2_3",
+ "B2",
+ "B1",
+ "B1A1_1",
+ "A1",
+ "A1B1_2",
+ "B1",
+ "B2",
+ "B2A2_2",
+ "A2",
+ "A1",
+ "A1B1_2",
+ "B1",
+ "B2",
+ "B2A2_1",
+ "A2",
+ "A1",
+ "A1B1_3",
+ "B1",
+ "B1A1_2",
+ "A1",
+ "A2",
+ "A2B2_2",
+ "B2",
+ "B2A2_2",
+ "A2",
+ "A2B2_3",
+ "B2",
+ "B2A2_2",
+ "A2",
+ "A1",
+ "A1B1_3",
+ "B1",
+ "B1A1_1",
+ "A1",
+ "A1B1_3",
+ "B1",
+ "B2",
+ "B2A2_2",
+ "A2",
+ "A1",
+ "A1B1_1",
+ "B1",
+ "B1A1_1",
+ "A1",
+ "A1B1_2",
+ "B1",
+ "B1A1_1",
+ "A1",
+ "A2",
+ "A2B2_2",
+ "B2",
+ "B1",
+ "B1A1_2",
+ "A1",
+ "A1B1_2",
+ "B1",
+ "B2",
+ "B2A2_2",
+ "A2",
+ "A1",
+ "A1B1_1",
+ "B1",
+ "B2",
+ "B2A2_2",
+ "A2",
+ "A1",
+ "A1B1_1",
+ "B1",
+ "B2",
+ "B2A2_1",
+ "A2",
+ "A2B2_3",
+ "B2",
+ "B2A2_2",
+ "A2",
+ "A1",
+ "A1B1_3",
+ "B1",
+ "B1A1_1",
+ "A1",
+ "A1B1_1",
+ "B1",
+ "B2",
+ "B2A2_2",
+ "A2",
+ "A1",
+ "A1B1_2",
+ "B1",
+ "B1A1_1",
+ "A1",
+ "A2",
+ "A2B2_1",
+ "B2"
+ )).toArray(), actualPath.toArray());
+ }
}
diff --git a/graphwalker-dsl/src/main/java/org/graphwalker/dsl/antlr/generator/GeneratorLoader.java b/graphwalker-dsl/src/main/java/org/graphwalker/dsl/antlr/generator/GeneratorLoader.java
index 865f93aeb..08e97e66a 100644
--- a/graphwalker-dsl/src/main/java/org/graphwalker/dsl/antlr/generator/GeneratorLoader.java
+++ b/graphwalker-dsl/src/main/java/org/graphwalker/dsl/antlr/generator/GeneratorLoader.java
@@ -12,10 +12,10 @@
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -81,7 +81,7 @@ public void exitStopCondition(GeneratorParser.StopConditionContext ctx) {
} else if ("requirement_coverage".equals(conditionName) || "requirementcoverage".equals(conditionName)) {
stopConditions.add(new RequirementCoverage(Integer.parseInt(ctx.getChild(2).getText())));
} else if ("length".equals(conditionName)) {
- stopConditions.add(new Length(Integer.parseInt(ctx.getChild(2).getText())));
+ stopConditions.add(new Length(Integer.parseInt(ctx.getChild(2).getText())));
}
}
diff --git a/graphwalker-dsl/src/test/java/org/graphwalker/dsl/GeneratorFactoryTest.java b/graphwalker-dsl/src/test/java/org/graphwalker/dsl/GeneratorFactoryTest.java
index f8fb242e1..7f3563608 100644
--- a/graphwalker-dsl/src/test/java/org/graphwalker/dsl/GeneratorFactoryTest.java
+++ b/graphwalker-dsl/src/test/java/org/graphwalker/dsl/GeneratorFactoryTest.java
@@ -26,6 +26,7 @@
* #L%
*/
+import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsInstanceOf.instanceOf;
@@ -49,7 +50,6 @@
import org.graphwalker.core.generator.WeightedRandomPath;
import org.graphwalker.dsl.antlr.DslException;
import org.graphwalker.dsl.antlr.generator.GeneratorFactory;
-import org.junit.Assert;
import org.junit.Test;
/**
@@ -70,244 +70,244 @@ public void unvalidStopCondition() {
@Test
public void random_edge_coverage() {
PathGenerator generator = GeneratorFactory.parse("random(edge_coverage(100))");
- Assert.assertThat(generator, instanceOf(RandomPath.class));
- Assert.assertThat(generator.getStopCondition(), instanceOf(EdgeCoverage.class));
- Assert.assertThat(((EdgeCoverage) generator.getStopCondition()).getPercent(), is(100));
+ assertThat(generator, instanceOf(RandomPath.class));
+ assertThat(generator.getStopCondition(), instanceOf(EdgeCoverage.class));
+ assertThat(((EdgeCoverage) generator.getStopCondition()).getPercent(), is(100));
}
@Test
public void random_edgecoverage() {
PathGenerator generator = GeneratorFactory.parse("random(edgecoverage(100))");
- Assert.assertThat(generator, instanceOf(RandomPath.class));
- Assert.assertThat(generator.getStopCondition(), instanceOf(EdgeCoverage.class));
- Assert.assertThat(((EdgeCoverage) generator.getStopCondition()).getPercent(), is(100));
+ assertThat(generator, instanceOf(RandomPath.class));
+ assertThat(generator.getStopCondition(), instanceOf(EdgeCoverage.class));
+ assertThat(((EdgeCoverage) generator.getStopCondition()).getPercent(), is(100));
}
@Test
public void randompath_edge_coverage() {
PathGenerator generator = GeneratorFactory.parse("randompath(edge_coverage(100))");
- Assert.assertThat(generator, instanceOf(RandomPath.class));
- Assert.assertThat(generator.getStopCondition(), instanceOf(EdgeCoverage.class));
- Assert.assertThat(((EdgeCoverage) generator.getStopCondition()).getPercent(), is(100));
+ assertThat(generator, instanceOf(RandomPath.class));
+ assertThat(generator.getStopCondition(), instanceOf(EdgeCoverage.class));
+ assertThat(((EdgeCoverage) generator.getStopCondition()).getPercent(), is(100));
}
@Test
public void quick_random_edge_coverage() {
PathGenerator generator = GeneratorFactory.parse("quick_random(edge_coverage(100))");
- Assert.assertThat(generator, instanceOf(QuickRandomPath.class));
- Assert.assertThat(generator.getStopCondition(), instanceOf(EdgeCoverage.class));
- Assert.assertThat(((EdgeCoverage) generator.getStopCondition()).getPercent(), is(100));
+ assertThat(generator, instanceOf(QuickRandomPath.class));
+ assertThat(generator.getStopCondition(), instanceOf(EdgeCoverage.class));
+ assertThat(((EdgeCoverage) generator.getStopCondition()).getPercent(), is(100));
}
@Test
public void quickrandom_edge_coverage() {
PathGenerator generator = GeneratorFactory.parse("quickrandom(edge_coverage(100))");
- Assert.assertThat(generator, instanceOf(QuickRandomPath.class));
- Assert.assertThat(generator.getStopCondition(), instanceOf(EdgeCoverage.class));
- Assert.assertThat(((EdgeCoverage) generator.getStopCondition()).getPercent(), is(100));
+ assertThat(generator, instanceOf(QuickRandomPath.class));
+ assertThat(generator.getStopCondition(), instanceOf(EdgeCoverage.class));
+ assertThat(((EdgeCoverage) generator.getStopCondition()).getPercent(), is(100));
}
@Test
public void quickrandompath_edge_coverage() {
PathGenerator generator = GeneratorFactory.parse("quickrandompath(edge_coverage(100))");
- Assert.assertThat(generator, instanceOf(QuickRandomPath.class));
- Assert.assertThat(generator.getStopCondition(), instanceOf(EdgeCoverage.class));
- Assert.assertThat(((EdgeCoverage) generator.getStopCondition()).getPercent(), is(100));
+ assertThat(generator, instanceOf(QuickRandomPath.class));
+ assertThat(generator.getStopCondition(), instanceOf(EdgeCoverage.class));
+ assertThat(((EdgeCoverage) generator.getStopCondition()).getPercent(), is(100));
}
@Test
public void shortest_all_paths_edge_coverage() {
PathGenerator generator = GeneratorFactory.parse("shortest_all_paths(edge_coverage(100))");
- Assert.assertThat(generator, instanceOf(ShortestAllPaths.class));
- Assert.assertThat(generator.getStopCondition(), instanceOf(EdgeCoverage.class));
- Assert.assertThat(((EdgeCoverage) generator.getStopCondition()).getPercent(), is(100));
+ assertThat(generator, instanceOf(ShortestAllPaths.class));
+ assertThat(generator.getStopCondition(), instanceOf(EdgeCoverage.class));
+ assertThat(((EdgeCoverage) generator.getStopCondition()).getPercent(), is(100));
}
@Test
public void shortestallpaths_edge_coverage() {
PathGenerator generator = GeneratorFactory.parse("shortestallpaths(edge_coverage(100))");
- Assert.assertThat(generator, instanceOf(ShortestAllPaths.class));
- Assert.assertThat(generator.getStopCondition(), instanceOf(EdgeCoverage.class));
- Assert.assertThat(((EdgeCoverage) generator.getStopCondition()).getPercent(), is(100));
+ assertThat(generator, instanceOf(ShortestAllPaths.class));
+ assertThat(generator.getStopCondition(), instanceOf(EdgeCoverage.class));
+ assertThat(((EdgeCoverage) generator.getStopCondition()).getPercent(), is(100));
}
@Test
public void random_vertex_coverage() {
PathGenerator generator = GeneratorFactory.parse("random(vertex_coverage(100))");
- Assert.assertThat(generator, instanceOf(RandomPath.class));
- Assert.assertThat(generator.getStopCondition(), instanceOf(VertexCoverage.class));
- Assert.assertThat(((VertexCoverage) generator.getStopCondition()).getPercent(), is(100));
+ assertThat(generator, instanceOf(RandomPath.class));
+ assertThat(generator.getStopCondition(), instanceOf(VertexCoverage.class));
+ assertThat(((VertexCoverage) generator.getStopCondition()).getPercent(), is(100));
}
@Test
public void random_vertexcoverage() {
PathGenerator generator = GeneratorFactory.parse("random(vertexcoverage(100))");
- Assert.assertThat(generator, instanceOf(RandomPath.class));
- Assert.assertThat(generator.getStopCondition(), instanceOf(VertexCoverage.class));
- Assert.assertThat(((VertexCoverage) generator.getStopCondition()).getPercent(), is(100));
+ assertThat(generator, instanceOf(RandomPath.class));
+ assertThat(generator.getStopCondition(), instanceOf(VertexCoverage.class));
+ assertThat(((VertexCoverage) generator.getStopCondition()).getPercent(), is(100));
}
@Test
public void a_star_reached_vertex() {
PathGenerator generator = GeneratorFactory.parse("a_star(reached_vertex(v_ABC))");
- Assert.assertThat(generator, instanceOf(AStarPath.class));
- Assert.assertThat(generator.getStopCondition(), instanceOf(ReachedVertex.class));
- Assert.assertThat(generator.getStopCondition().getValue(), is("v_ABC"));
+ assertThat(generator, instanceOf(AStarPath.class));
+ assertThat(generator.getStopCondition(), instanceOf(ReachedVertex.class));
+ assertThat(generator.getStopCondition().getValue(), is("v_ABC"));
}
@Test
public void random_reached_edge() {
PathGenerator generator = GeneratorFactory.parse("random(reached_edge(edgeName))");
- Assert.assertThat(generator, instanceOf(RandomPath.class));
- Assert.assertThat(generator.getStopCondition(), instanceOf(ReachedEdge.class));
- Assert.assertThat(generator.getStopCondition().getValue(), is("edgeName"));
+ assertThat(generator, instanceOf(RandomPath.class));
+ assertThat(generator.getStopCondition(), instanceOf(ReachedEdge.class));
+ assertThat(generator.getStopCondition().getValue(), is("edgeName"));
}
@Test
public void random_reached_vertex() {
PathGenerator generator = GeneratorFactory.parse("random(reached_vertex(vertexName))");
- Assert.assertThat(generator, instanceOf(RandomPath.class));
- Assert.assertThat(generator.getStopCondition(), instanceOf(ReachedVertex.class));
- Assert.assertThat(generator.getStopCondition().getValue(), is("vertexName"));
+ assertThat(generator, instanceOf(RandomPath.class));
+ assertThat(generator.getStopCondition(), instanceOf(ReachedVertex.class));
+ assertThat(generator.getStopCondition().getValue(), is("vertexName"));
}
@Test
public void random_time_duration() {
PathGenerator generator = GeneratorFactory.parse("random(time_duration(600))");
- Assert.assertThat(generator, instanceOf(RandomPath.class));
- Assert.assertThat(generator.getStopCondition(), instanceOf(TimeDuration.class));
- Assert.assertThat(((TimeDuration) generator.getStopCondition()).getDuration(), is(600L));
+ assertThat(generator, instanceOf(RandomPath.class));
+ assertThat(generator.getStopCondition(), instanceOf(TimeDuration.class));
+ assertThat(((TimeDuration) generator.getStopCondition()).getDuration(), is(600L));
}
@Test
public void random_edge_coverage_and_vertex_coverage() {
PathGenerator generator = GeneratorFactory.parse("random ( edge_coverage(100) and vertex_coverage (100) )");
- Assert.assertThat(generator, instanceOf(RandomPath.class));
- Assert.assertThat(generator.getStopCondition(), instanceOf(CombinedCondition.class));
+ assertThat(generator, instanceOf(RandomPath.class));
+ assertThat(generator.getStopCondition(), instanceOf(CombinedCondition.class));
}
@Test
public void random_reached_vertex_or_reached_edge() {
PathGenerator generator = GeneratorFactory.parse("random ( reached_vertex(Some_vertex) or reached_edge ( Some_edge ) )");
- Assert.assertThat(generator, instanceOf(RandomPath.class));
- Assert.assertThat(generator.getStopCondition(), instanceOf(AlternativeCondition.class));
+ assertThat(generator, instanceOf(RandomPath.class));
+ assertThat(generator.getStopCondition(), instanceOf(AlternativeCondition.class));
AlternativeCondition condition = (AlternativeCondition) generator.getStopCondition();
- Assert.assertThat(condition.getStopConditions().get(0), instanceOf(ReachedVertex.class));
- Assert.assertThat(condition.getStopConditions().get(0).getValue(), is("Some_vertex"));
- Assert.assertThat(condition.getStopConditions().get(1), instanceOf(ReachedEdge.class));
- Assert.assertThat(condition.getStopConditions().get(1).getValue(), is("Some_edge"));
+ assertThat(condition.getStopConditions().get(0), instanceOf(ReachedVertex.class));
+ assertThat(condition.getStopConditions().get(0).getValue(), is("Some_vertex"));
+ assertThat(condition.getStopConditions().get(1), instanceOf(ReachedEdge.class));
+ assertThat(condition.getStopConditions().get(1).getValue(), is("Some_edge"));
}
@Test
public void random_edge_coverage_or_vertex_coverage() {
PathGenerator generator = GeneratorFactory.parse("random ( edge_coverage(100) or vertex_coverage (100) )");
- Assert.assertThat(generator, instanceOf(RandomPath.class));
- Assert.assertThat(generator.getStopCondition(), instanceOf(AlternativeCondition.class));
+ assertThat(generator, instanceOf(RandomPath.class));
+ assertThat(generator.getStopCondition(), instanceOf(AlternativeCondition.class));
}
@Test
public void random_edge_coverage_or_time_duration_a_star_reached_vertex() {
PathGenerator generator = GeneratorFactory.parse("random( edge_coverage(100) or time_duration(500) ) a_star(reached_vertex(v_ABC))");
- Assert.assertThat(generator, instanceOf(CombinedPath.class));
+ assertThat(generator, instanceOf(CombinedPath.class));
CombinedPath combinedPath = (CombinedPath) generator;
- Assert.assertThat(combinedPath.getPathGenerators().get(0), instanceOf(RandomPath.class));
- Assert.assertThat(combinedPath.getPathGenerators().get(1), instanceOf(AStarPath.class));
+ assertThat(combinedPath.getPathGenerators().get(0), instanceOf(RandomPath.class));
+ assertThat(combinedPath.getPathGenerators().get(1), instanceOf(AStarPath.class));
StopCondition condition = combinedPath.getPathGenerators().get(0).getStopCondition();
- Assert.assertThat(condition, instanceOf(StopCondition.class));
+ assertThat(condition, instanceOf(StopCondition.class));
AlternativeCondition alternativeCondition = (AlternativeCondition) condition;
- Assert.assertThat(alternativeCondition.getStopConditions().get(0), instanceOf(EdgeCoverage.class));
- Assert.assertThat(alternativeCondition.getStopConditions().get(1), instanceOf(TimeDuration.class));
+ assertThat(alternativeCondition.getStopConditions().get(0), instanceOf(EdgeCoverage.class));
+ assertThat(alternativeCondition.getStopConditions().get(1), instanceOf(TimeDuration.class));
condition = combinedPath.getPathGenerators().get(1).getStopCondition();
- Assert.assertThat(condition, instanceOf(ReachedVertex.class));
- Assert.assertThat(condition.getValue(), is("v_ABC"));
+ assertThat(condition, instanceOf(ReachedVertex.class));
+ assertThat(condition.getValue(), is("v_ABC"));
}
@Test
public void capital_random_reached_vertex_or_reached_edge() {
PathGenerator generator = GeneratorFactory.parse("RANDOM ( REACHED_VERTEX( Some_vertex) OR REACHED_EDGE( Some_edge ) )");
- Assert.assertThat(generator, instanceOf(RandomPath.class));
- Assert.assertThat(generator.getStopCondition(), instanceOf(AlternativeCondition.class));
+ assertThat(generator, instanceOf(RandomPath.class));
+ assertThat(generator.getStopCondition(), instanceOf(AlternativeCondition.class));
AlternativeCondition condition = (AlternativeCondition) generator.getStopCondition();
- Assert.assertThat(condition.getStopConditions().get(0), instanceOf(ReachedVertex.class));
- Assert.assertThat(condition.getStopConditions().get(0).getValue(), is("Some_vertex"));
- Assert.assertThat(condition.getStopConditions().get(1), instanceOf(ReachedEdge.class));
- Assert.assertThat(condition.getStopConditions().get(1).getValue(), is("Some_edge"));
+ assertThat(condition.getStopConditions().get(0), instanceOf(ReachedVertex.class));
+ assertThat(condition.getStopConditions().get(0).getValue(), is("Some_vertex"));
+ assertThat(condition.getStopConditions().get(1), instanceOf(ReachedEdge.class));
+ assertThat(condition.getStopConditions().get(1).getValue(), is("Some_edge"));
}
@Test
public void weighted_random_edge_coverage() {
PathGenerator generator = GeneratorFactory.parse("weighted_random(edge_coverage(100))");
- Assert.assertThat(generator, instanceOf(WeightedRandomPath.class));
- Assert.assertThat(generator.getStopCondition(), instanceOf(EdgeCoverage.class));
- Assert.assertThat(((EdgeCoverage) generator.getStopCondition()).getPercent(), is(100));
+ assertThat(generator, instanceOf(WeightedRandomPath.class));
+ assertThat(generator.getStopCondition(), instanceOf(EdgeCoverage.class));
+ assertThat(((EdgeCoverage) generator.getStopCondition()).getPercent(), is(100));
}
@Test
public void weightedrandompath_edge_coverage() {
PathGenerator generator = GeneratorFactory.parse("weightedrandompath(edge_coverage(100))");
- Assert.assertThat(generator, instanceOf(WeightedRandomPath.class));
- Assert.assertThat(generator.getStopCondition(), instanceOf(EdgeCoverage.class));
- Assert.assertThat(((EdgeCoverage) generator.getStopCondition()).getPercent(), is(100));
+ assertThat(generator, instanceOf(WeightedRandomPath.class));
+ assertThat(generator.getStopCondition(), instanceOf(EdgeCoverage.class));
+ assertThat(((EdgeCoverage) generator.getStopCondition()).getPercent(), is(100));
}
@Test
public void random_dependency_edge_coverage() {
PathGenerator generator = GeneratorFactory.parse("random(dependency_edge_coverage(80))");
- Assert.assertThat(generator, instanceOf(RandomPath.class));
- Assert.assertThat(generator.getStopCondition(), instanceOf(DependencyEdgeCoverage.class));
- Assert.assertThat(((DependencyEdgeCoverage) generator.getStopCondition()).getDependency(), is(80));
+ assertThat(generator, instanceOf(RandomPath.class));
+ assertThat(generator.getStopCondition(), instanceOf(DependencyEdgeCoverage.class));
+ assertThat(((DependencyEdgeCoverage) generator.getStopCondition()).getDependency(), is(80));
}
@Test
public void random_dependencyedgecoverage() {
PathGenerator generator = GeneratorFactory.parse("random(dependencyedgecoverage(80))");
- Assert.assertThat(generator, instanceOf(RandomPath.class));
- Assert.assertThat(generator.getStopCondition(), instanceOf(DependencyEdgeCoverage.class));
- Assert.assertThat(((DependencyEdgeCoverage) generator.getStopCondition()).getDependency(), is(80));
+ assertThat(generator, instanceOf(RandomPath.class));
+ assertThat(generator.getStopCondition(), instanceOf(DependencyEdgeCoverage.class));
+ assertThat(((DependencyEdgeCoverage) generator.getStopCondition()).getDependency(), is(80));
}
@Test
public void random_requirement_coverage() {
PathGenerator generator = GeneratorFactory.parse("random(requirement_coverage(100))");
- Assert.assertThat(generator, instanceOf(RandomPath.class));
- Assert.assertThat(generator.getStopCondition(), instanceOf(RequirementCoverage.class));
- Assert.assertThat(((RequirementCoverage) generator.getStopCondition()).getPercent(), is(100));
+ assertThat(generator, instanceOf(RandomPath.class));
+ assertThat(generator.getStopCondition(), instanceOf(RequirementCoverage.class));
+ assertThat(((RequirementCoverage) generator.getStopCondition()).getPercent(), is(100));
}
@Test
public void random_requirementcoverage() {
PathGenerator generator = GeneratorFactory.parse("random(requirementcoverage(100))");
- Assert.assertThat(generator, instanceOf(RandomPath.class));
- Assert.assertThat(generator.getStopCondition(), instanceOf(RequirementCoverage.class));
- Assert.assertThat(((RequirementCoverage) generator.getStopCondition()).getPercent(), is(100));
+ assertThat(generator, instanceOf(RandomPath.class));
+ assertThat(generator.getStopCondition(), instanceOf(RequirementCoverage.class));
+ assertThat(((RequirementCoverage) generator.getStopCondition()).getPercent(), is(100));
}
@Test
public void randompath_length_coverage() {
PathGenerator generator = GeneratorFactory.parse("randompath(length(80))");
- Assert.assertThat(generator, instanceOf(RandomPath.class));
- Assert.assertThat(generator.getStopCondition(), instanceOf(Length.class));
- Assert.assertThat(((Length) generator.getStopCondition()).getLength(), is(80L));
+ assertThat(generator, instanceOf(RandomPath.class));
+ assertThat(generator.getStopCondition(), instanceOf(Length.class));
+ assertThat(((Length) generator.getStopCondition()).getLength(), is(80L));
}
@Test
public void multipleCombinedStopConditions() {
PathGenerator generator = GeneratorFactory.parse("random(reached_vertex(isPageOpened) and reached_vertex(isLanguageDetected) and reached_vertex(isTranslateCleared) and reached_edge(openPage))");
- Assert.assertThat(generator, instanceOf(RandomPath.class));
- Assert.assertThat(generator.getStopCondition(), instanceOf(CombinedCondition.class));
- Assert.assertThat(((CombinedCondition) generator.getStopCondition()).getStopConditions().size(), is(4));
+ assertThat(generator, instanceOf(RandomPath.class));
+ assertThat(generator.getStopCondition(), instanceOf(CombinedCondition.class));
+ assertThat(((CombinedCondition) generator.getStopCondition()).getStopConditions().size(), is(4));
}
@Test
public void multipleAlternativeStopConditions() {
PathGenerator generator = GeneratorFactory.parse("random(reached_vertex(isPageOpened) or reached_vertex(isLanguageDetected) or reached_vertex(isTranslateCleared))");
- Assert.assertThat(generator, instanceOf(RandomPath.class));
- Assert.assertThat(generator.getStopCondition(), instanceOf(AlternativeCondition.class));
- Assert.assertThat(((AlternativeCondition) generator.getStopCondition()).getStopConditions().size(), is(3));
+ assertThat(generator, instanceOf(RandomPath.class));
+ assertThat(generator.getStopCondition(), instanceOf(AlternativeCondition.class));
+ assertThat(((AlternativeCondition) generator.getStopCondition()).getStopConditions().size(), is(3));
}
}
diff --git a/graphwalker-io/src/main/java/org/graphwalker/io/factory/json/JsonContextFactory.java b/graphwalker-io/src/main/java/org/graphwalker/io/factory/json/JsonContextFactory.java
index ce1e33650..667dde79f 100644
--- a/graphwalker-io/src/main/java/org/graphwalker/io/factory/json/JsonContextFactory.java
+++ b/graphwalker-io/src/main/java/org/graphwalker/io/factory/json/JsonContextFactory.java
@@ -44,6 +44,7 @@
import java.util.List;
import java.util.Set;
import org.apache.commons.io.FilenameUtils;
+import org.graphwalker.core.generator.SingletonRandomGenerator;
import org.graphwalker.core.machine.Context;
import org.graphwalker.core.model.Element;
import org.graphwalker.core.model.Model;
@@ -142,6 +143,11 @@ public List create(String jsonStr) {
throw new ContextFactoryException("The json file is not a valid GraphWalker model(s) file");
}
+ // Seed the [global] singleton random generator, if any seed was set in the json file
+ if (jsonMultimodel.getSeed() != null) {
+ SingletonRandomGenerator.setSeed(jsonMultimodel.getSeed());
+ }
+
for (JsonModel jsonModel : jsonMultimodel.getModels()) {
JsonContext context = new JsonContext();
Model model = jsonModel.getModel();
diff --git a/graphwalker-io/src/main/java/org/graphwalker/io/factory/json/JsonMultimodel.java b/graphwalker-io/src/main/java/org/graphwalker/io/factory/json/JsonMultimodel.java
index 3ced2cad8..94840c48f 100644
--- a/graphwalker-io/src/main/java/org/graphwalker/io/factory/json/JsonMultimodel.java
+++ b/graphwalker-io/src/main/java/org/graphwalker/io/factory/json/JsonMultimodel.java
@@ -34,6 +34,7 @@
public final class JsonMultimodel {
private String name;
+ private Long seed;
private List models;
public String getName() {
@@ -44,6 +45,14 @@ public void setName(String name) {
this.name = name;
}
+ public Long getSeed() {
+ return seed;
+ }
+
+ public void setSeed(Long seed) {
+ this.seed = seed;
+ }
+
public List getModels() {
return models;
}
diff --git a/graphwalker-io/src/test/java/org/graphwalker/io/factory/json/JsonContextFactoryTest.java b/graphwalker-io/src/test/java/org/graphwalker/io/factory/json/JsonContextFactoryTest.java
index 010175ff6..6ea987458 100644
--- a/graphwalker-io/src/test/java/org/graphwalker/io/factory/json/JsonContextFactoryTest.java
+++ b/graphwalker-io/src/test/java/org/graphwalker/io/factory/json/JsonContextFactoryTest.java
@@ -26,10 +26,10 @@
* #L%
*/
+import static junit.framework.TestCase.assertNotNull;
+import static junit.framework.TestCase.assertTrue;
+import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.nio.file.Path;
@@ -38,6 +38,7 @@
import java.util.List;
import org.graphwalker.core.condition.EdgeCoverage;
import org.graphwalker.core.generator.RandomPath;
+import org.graphwalker.core.generator.SingletonRandomGenerator;
import org.graphwalker.core.machine.Context;
import org.graphwalker.core.machine.SimpleMachine;
import org.graphwalker.core.model.Action;
@@ -334,4 +335,12 @@ public void readProperties() throws IOException {
assertTrue(v.hasProperty("color"));
assertThat(v.getProperty("color"), is("yellow"));
}
+
+ @Test
+ public void petClinicWithSeed() throws IOException {
+ List contexts = new JsonContextFactory().create(Paths.get("json/petClinicWithSeed.json"));
+ assertThat(SingletonRandomGenerator.nextInt(), is(1553932502));
+ assertThat(SingletonRandomGenerator.nextInt(), is(-2090749135));
+ assertThat(SingletonRandomGenerator.nextInt(), is(-287790814));
+ }
}
diff --git a/graphwalker-io/src/test/resources/json/UC01_with_seed.json b/graphwalker-io/src/test/resources/json/UC01_with_seed.json
new file mode 100644
index 000000000..c5097ebcf
--- /dev/null
+++ b/graphwalker-io/src/test/resources/json/UC01_with_seed.json
@@ -0,0 +1,134 @@
+{
+ "models": [
+ {
+ "generator": "RandomPath(90835538976957, EdgeCoverage(100))",
+ "startElementId": "e0",
+ "vertices": [
+ {
+ "id": "n4",
+ "name": "v_BrowserStopped"
+ },
+ {
+ "id": "n1",
+ "name": "v_BrowserStarted",
+ "properties": {
+ "color": "yellow"
+ }
+ },
+ {
+ "id": "n2",
+ "name": "v_BaseURL",
+ "requirements": [
+ "UC01 2.2.1"
+ ]
+ },
+ {
+ "id": "n3",
+ "name": "v_SearchResult",
+ "requirements": [
+ "UC01 2.2.2"
+ ]
+ },
+ {
+ "id": "n5",
+ "name": "v_BookInformation",
+ "requirements": [
+ "UC01 2.2.3"
+ ]
+ },
+ {
+ "id": "n6",
+ "name": "v_OtherBoughtBooks"
+ },
+ {
+ "id": "n7",
+ "name": "v_ShoppingCart",
+ "requirements": [
+ "UC01 2.3"
+ ]
+ }
+ ],
+ "edges": [
+ {
+ "id": "e0",
+ "name": "e_init",
+ "actions": [
+ " num_of_books \u003d 0;",
+ " MAX_BOOKS \u003d 5;"
+ ],
+ "targetVertexId": "n4"
+ },
+ {
+ "id": "e1",
+ "name": "e_EnterBaseURL",
+ "sourceVertexId": "n1",
+ "targetVertexId": "n2"
+ },
+ {
+ "id": "e2",
+ "name": "e_SearchBook",
+ "sourceVertexId": "n2",
+ "targetVertexId": "n3"
+ },
+ {
+ "id": "e3",
+ "name": "e_StartBrowser",
+ "sourceVertexId": "n4",
+ "targetVertexId": "n1"
+ },
+ {
+ "id": "e4",
+ "name": "e_ClickBook",
+ "sourceVertexId": "n3",
+ "targetVertexId": "n5"
+ },
+ {
+ "id": "e5",
+ "name": "e_AddBookToCart",
+ "guard": "num_of_books\u003c\u003dMAX_BOOKS",
+ "actions": [
+ " num_of_books++;"
+ ],
+ "sourceVertexId": "n5",
+ "targetVertexId": "n6"
+ },
+ {
+ "id": "e6",
+ "name": "e_ShoppingCart",
+ "sourceVertexId": "n6",
+ "targetVertexId": "n7"
+ },
+ {
+ "id": "e7",
+ "name": "e_ShoppingCart",
+ "sourceVertexId": "n3",
+ "targetVertexId": "n7"
+ },
+ {
+ "id": "e8",
+ "name": "e_ShoppingCart",
+ "sourceVertexId": "n5",
+ "targetVertexId": "n7"
+ },
+ {
+ "id": "e9",
+ "name": "e_SearchBook",
+ "sourceVertexId": "n7",
+ "targetVertexId": "n3"
+ },
+ {
+ "id": "e10",
+ "name": "e_SearchBook",
+ "sourceVertexId": "n6",
+ "targetVertexId": "n3"
+ },
+ {
+ "id": "e11",
+ "name": "e_SearchBook",
+ "sourceVertexId": "n5",
+ "targetVertexId": "n3"
+ }
+ ]
+ }
+ ]
+}
diff --git a/graphwalker-io/src/test/resources/json/petClinicWithSeed.json b/graphwalker-io/src/test/resources/json/petClinicWithSeed.json
new file mode 100644
index 000000000..67b546883
--- /dev/null
+++ b/graphwalker-io/src/test/resources/json/petClinicWithSeed.json
@@ -0,0 +1,281 @@
+{
+ "name":"This is the example project of PetClinic",
+ "seed": 12345,
+ "models":[
+ {
+ "name":"FindOwnersSharedState",
+ "id":"476fb419-3d7d-4492-802e-6695fe93f595",
+ "generator":"random(edge_coverage(100))",
+ "vertices":[
+ {
+ "id":"n0",
+ "name":"v_FindOwners",
+ "sharedState":"FindOwners"
+ },
+ {
+ "id":"n1",
+ "name":"v_NewOwner",
+ "sharedState":"NewOwner"
+ },
+ {
+ "id":"n2",
+ "name":"v_Owners"
+ }
+ ],
+ "edges":[
+ {
+ "id":"e0",
+ "name":"e_AddOwner",
+ "sourceVertexId":"n0",
+ "targetVertexId":"n1"
+ },
+ {
+ "id":"e1",
+ "name":"e_FindOwners",
+ "sourceVertexId":"n1",
+ "targetVertexId":"n0"
+ },
+ {
+ "id":"e2",
+ "name":"e_Search",
+ "sourceVertexId":"n0",
+ "targetVertexId":"n2"
+ },
+ {
+ "id":"e3",
+ "name":"e_FindOwners",
+ "sourceVertexId":"n2",
+ "targetVertexId":"n0"
+ }
+ ]
+ },
+ {
+ "name":"NewOwnerSharedState",
+ "id":"b23d193c-287a-4eb9-a318-52ead7680ff7",
+ "generator":"random(edge_coverage(100))",
+ "vertices":[
+ {
+ "id":"n0",
+ "name":"v_NewOwner",
+ "sharedState":"NewOwner"
+ },
+ {
+ "id":"n1",
+ "name":"v_IncorrectData"
+ },
+ {
+ "id":"n2",
+ "name":"v_OwnerInformation",
+ "sharedState":"OwnerInformation"
+ }
+ ],
+ "edges":[
+ {
+ "id":"e0",
+ "name":"e_IncorrectData",
+ "sourceVertexId":"n0",
+ "targetVertexId":"n1"
+ },
+ {
+ "id":"e1",
+ "sourceVertexId":"n1",
+ "targetVertexId":"n0"
+ },
+ {
+ "id":"e2",
+ "name":"e_CorrectData",
+ "sourceVertexId":"n0",
+ "targetVertexId":"n2"
+ }
+ ]
+ },
+ {
+ "name":"OwnerInformationSharedState",
+ "id":"5f1149c3-2853-47e6-838d-691bf30406a8",
+ "generator":"random(edge_coverage(100))",
+ "actions":[
+ "numOfPets\u003d0;"
+ ],
+ "vertices":[
+ {
+ "id":"n0",
+ "name":"v_OwnerInformation",
+ "sharedState":"OwnerInformation"
+ },
+ {
+ "id":"n1",
+ "name":"v_NewPet"
+ },
+ {
+ "id":"n2",
+ "name":"v_Pet"
+ },
+ {
+ "id":"n3",
+ "name":"v_NewVisit"
+ },
+ {
+ "id":"n4",
+ "name":"v_FindOwners",
+ "sharedState":"FindOwners"
+ }
+ ],
+ "edges":[
+ {
+ "id":"e0",
+ "name":"e_AddPetSuccessfully",
+ "actions":[
+ " numOfPets++;"
+ ],
+ "sourceVertexId":"n1",
+ "targetVertexId":"n0"
+ },
+ {
+ "id":"e1",
+ "name":"e_AddNewPet",
+ "sourceVertexId":"n0",
+ "targetVertexId":"n1"
+ },
+ {
+ "id":"e2",
+ "name":"e_EditPet",
+ "guard":"numOfPets\u003e0",
+ "sourceVertexId":"n0",
+ "targetVertexId":"n2"
+ },
+ {
+ "id":"e3",
+ "name":"e_UpdatePet",
+ "sourceVertexId":"n2",
+ "targetVertexId":"n0"
+ },
+ {
+ "id":"e4",
+ "name":"e_AddPetFailed",
+ "sourceVertexId":"n1",
+ "targetVertexId":"n1"
+ },
+ {
+ "id":"e5",
+ "name":"e_AddVisit",
+ "guard":"numOfPets\u003e0",
+ "sourceVertexId":"n0",
+ "targetVertexId":"n3"
+ },
+ {
+ "id":"e6",
+ "name":"e_VisitAddedSuccessfully",
+ "sourceVertexId":"n3",
+ "targetVertexId":"n0"
+ },
+ {
+ "id":"e7",
+ "name":"e_VisitAddedFailed",
+ "sourceVertexId":"n3",
+ "targetVertexId":"n3"
+ },
+ {
+ "id":"e8",
+ "name":"e_FindOwners",
+ "sourceVertexId":"n0",
+ "targetVertexId":"n4"
+ }
+ ]
+ },
+ {
+ "name":"PetClinicSharedState",
+ "id":"3f6b365f-7011-4db6-b0cc-e19aa453d9b8",
+ "generator":"random(edge_coverage(100))",
+ "startElementId":"e6",
+ "vertices":[
+ {
+ "id":"n0",
+ "name":"v_HomePage",
+ "sharedState":"HomePage"
+ },
+ {
+ "id":"n1",
+ "name":"v_FindOwners",
+ "sharedState":"FindOwners"
+ },
+ {
+ "id":"n2",
+ "name":"v_Veterinarians",
+ "sharedState":"Veterinarians"
+ }
+ ],
+ "edges":[
+ {
+ "id":"e0",
+ "name":"e_FindOwners",
+ "sourceVertexId":"n0",
+ "targetVertexId":"n1"
+ },
+ {
+ "id":"e1",
+ "name":"e_HomePage",
+ "sourceVertexId":"n1",
+ "targetVertexId":"n0"
+ },
+ {
+ "id":"e2",
+ "name":"e_Veterinarians",
+ "sourceVertexId":"n0",
+ "targetVertexId":"n2"
+ },
+ {
+ "id":"e3",
+ "name":"e_HomePage",
+ "sourceVertexId":"n2",
+ "targetVertexId":"n0"
+ },
+ {
+ "id":"e4",
+ "name":"e_Veterinarians",
+ "sourceVertexId":"n1",
+ "targetVertexId":"n2"
+ },
+ {
+ "id":"e5",
+ "name":"e_FindOwners",
+ "sourceVertexId":"n2",
+ "targetVertexId":"n1"
+ },
+ {
+ "id":"e6",
+ "name":"e_StartBrowser",
+ "targetVertexId":"n0"
+ }
+ ]
+ },
+ {
+ "name":"VeterinariensSharedState",
+ "id":"368a9635-c59a-4285-ad01-cf75b0baa978",
+ "generator":"random(edge_coverage(100))",
+ "vertices":[
+ {
+ "id":"n0",
+ "name":"v_Veterinarians",
+ "sharedState":"Veterinarians"
+ },
+ {
+ "id":"n1",
+ "name":"v_SearchResult"
+ }
+ ],
+ "edges":[
+ {
+ "id":"e0",
+ "name":"e_Search",
+ "sourceVertexId":"n0",
+ "targetVertexId":"n1"
+ },
+ {
+ "id":"e1",
+ "sourceVertexId":"n1",
+ "targetVertexId":"n0"
+ }
+ ]
+ }
+ ]
+}
diff --git a/graphwalker-java/src/test/java/org/graphwalker/java/test/TestExecutorTest.java b/graphwalker-java/src/test/java/org/graphwalker/java/test/TestExecutorTest.java
index 47c86dcb4..8209109d9 100644
--- a/graphwalker-java/src/test/java/org/graphwalker/java/test/TestExecutorTest.java
+++ b/graphwalker-java/src/test/java/org/graphwalker/java/test/TestExecutorTest.java
@@ -31,6 +31,7 @@
import org.graphwalker.core.model.Edge;
import org.graphwalker.core.model.Model;
import org.graphwalker.core.model.Vertex;
+import org.graphwalker.core.statistics.Execution;
import org.graphwalker.io.factory.json.JsonContextFactory;
import org.graphwalker.java.annotation.GraphWalker;
import org.json.JSONObject;
@@ -204,4 +205,388 @@ public void multilpeContexts() throws IOException {
);
Assert.assertThat(executor.getMachine().getContexts().size(), is(5));
}
+
+ @Test
+ public void multilpeContextsWithSeed() throws IOException {
+ List contexts = new JsonContextFactory().create(Paths.get("org/graphwalker/java/test/PetClinicWithSeed.json"));
+ Executor executor = new TestExecutor(
+ contexts.get(0),
+ contexts.get(1),
+ contexts.get(2),
+ contexts.get(3),
+ contexts.get(4)
+ );
+ executor.execute();
+
+ List actualPath = new ArrayList();
+ for (Execution execution: executor.getMachine().getProfiler().getExecutionPath()) {
+ actualPath.add(execution.getElement().getId());
+ }
+
+ Assert.assertArrayEquals(new ArrayList<>(Arrays.asList(
+ "b53810a0-468c-11e7-a919-92ebcb67fe33",
+ "dcb0dde2-468c-11e7-a919-92ebcb67fe33",
+ "971ee142-468d-11e7-a919-92ebcb67fe33",
+ "dcb0f8a5-468c-11e7-a919-92ebcb67fe33",
+ "dcb0defa-468c-11e7-a919-92ebcb67fe33",
+ "971eea2a-468d-11e7-a919-92ebcb67fe33",
+ "dcb0f124-468c-11e7-a919-92ebcb67fe33",
+ "971eeba6-468d-11e7-a919-92ebcb67fe33",
+ "dcb0defa-468c-11e7-a919-92ebcb67fe33",
+ "971eea2a-468d-11e7-a919-92ebcb67fe33",
+ "dcb0f124-468c-11e7-a919-92ebcb67fe33",
+ "971eeba6-468d-11e7-a919-92ebcb67fe33",
+ "dcb0defa-468c-11e7-a919-92ebcb67fe33",
+ "971eea2a-468d-11e7-a919-92ebcb67fe33",
+ "dcb0f124-468c-11e7-a919-92ebcb67fe33",
+ "971eeba6-468d-11e7-a919-92ebcb67fe33",
+ "dcb0defa-468c-11e7-a919-92ebcb67fe33",
+ "dcb0f8a5-468c-11e7-a919-92ebcb67fe33",
+ "971ee2b4-468d-11e7-a919-92ebcb67fe33",
+ "dcb0dde2-468c-11e7-a919-92ebcb67fe33",
+ "971edcce-468d-11e7-a919-92ebcb67fe33",
+ "dcb0ef4e-468c-11e7-a919-92ebcb67fe33",
+ "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "971ec57c-468d-11e7-a919-92ebcb67fe33",
+ "dcb0ef4e-468c-11e7-a919-92ebcb67fe33",
+ "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "971ec57c-468d-11e7-a919-92ebcb67fe33",
+ "dcb0ef4e-468c-11e7-a919-92ebcb67fe33",
+ "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "dcb0fb88-468c-11e7-a919-92ebcb67fe33",
+ "dcb0e896-468c-11e7-a919-92ebcb67fe33",
+ "dcb0fd5e-468c-11e7-a919-92ebcb67fe33",
+ "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "971ec57c-468d-11e7-a919-92ebcb67fe33",
+ "dcb0ef4e-468c-11e7-a919-92ebcb67fe33",
+ "971ede36-468d-11e7-a919-92ebcb67fe33",
+ "dcb0dde2-468c-11e7-a919-92ebcb67fe33",
+ "971ee142-468d-11e7-a919-92ebcb67fe33",
+ "dcb0f8a5-468c-11e7-a919-92ebcb67fe33",
+ "971ee732-468d-11e7-a919-92ebcb67fe33",
+ "dcb0ef4e-468c-11e7-a919-92ebcb67fe33",
+ "971ee5c0-468d-11e7-a919-92ebcb67fe33",
+ "dcb0f8a5-468c-11e7-a919-92ebcb67fe33",
+ "971ee2b4-468d-11e7-a919-92ebcb67fe33",
+ "dcb0dde2-468c-11e7-a919-92ebcb67fe33",
+ "971edcce-468d-11e7-a919-92ebcb67fe33",
+ "dcb0ef4e-468c-11e7-a919-92ebcb67fe33",
+ "971ec57c-468d-11e7-a919-92ebcb67fe33",
+ "dcb0ef4e-468c-11e7-a919-92ebcb67fe33",
+ "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "dcb0fe62-468c-11e7-a919-92ebcb67fe33",
+ "dcb0f200-468c-11e7-a919-92ebcb67fe33",
+ "dcb0ff34-468c-11e7-a919-92ebcb67fe33",
+ "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "dcb0fe62-468c-11e7-a919-92ebcb67fe33",
+ "dcb0f200-468c-11e7-a919-92ebcb67fe33",
+ "dcb0ff34-468c-11e7-a919-92ebcb67fe33",
+ "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "dcb0fb88-468c-11e7-a919-92ebcb67fe33",
+ "dcb0e896-468c-11e7-a919-92ebcb67fe33",
+ "dcb0d798-468c-11e7-a919-92ebcb67fe33",
+ "dcb104e8-468c-11e7-a919-92ebcb67fe33",
+ "dcb0eab2-468c-11e7-a919-92ebcb67fe33",
+ "dcb10736-468c-11e7-a919-92ebcb67fe33",
+ "dcb0d798-468c-11e7-a919-92ebcb67fe33",
+ "dcb0e896-468c-11e7-a919-92ebcb67fe33",
+ "dcb0fd5e-468c-11e7-a919-92ebcb67fe33",
+ "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "dcb0ef4e-468c-11e7-a919-92ebcb67fe33",
+ "971ede36-468d-11e7-a919-92ebcb67fe33",
+ "dcb0dde2-468c-11e7-a919-92ebcb67fe33",
+ "971ee142-468d-11e7-a919-92ebcb67fe33",
+ "dcb0f8a5-468c-11e7-a919-92ebcb67fe33",
+ "dcb0defa-468c-11e7-a919-92ebcb67fe33",
+ "971eea2a-468d-11e7-a919-92ebcb67fe33",
+ "dcb0f124-468c-11e7-a919-92ebcb67fe33",
+ "971eeba6-468d-11e7-a919-92ebcb67fe33",
+ "dcb0defa-468c-11e7-a919-92ebcb67fe33",
+ "971eea2a-468d-11e7-a919-92ebcb67fe33",
+ "dcb0f124-468c-11e7-a919-92ebcb67fe33",
+ "971eeba6-468d-11e7-a919-92ebcb67fe33",
+ "dcb0defa-468c-11e7-a919-92ebcb67fe33",
+ "971eea2a-468d-11e7-a919-92ebcb67fe33",
+ "dcb0f124-468c-11e7-a919-92ebcb67fe33",
+ "971eeba6-468d-11e7-a919-92ebcb67fe33",
+ "dcb0defa-468c-11e7-a919-92ebcb67fe33",
+ "dcb0f8a5-468c-11e7-a919-92ebcb67fe33",
+ "971ee2b4-468d-11e7-a919-92ebcb67fe33",
+ "dcb0dde2-468c-11e7-a919-92ebcb67fe33",
+ "971edcce-468d-11e7-a919-92ebcb67fe33",
+ "dcb0ef4e-468c-11e7-a919-92ebcb67fe33",
+ "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "dcb0fe62-468c-11e7-a919-92ebcb67fe33",
+ "dcb0f200-468c-11e7-a919-92ebcb67fe33",
+ "dcb0ff34-468c-11e7-a919-92ebcb67fe33",
+ "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "dcb0ef4e-468c-11e7-a919-92ebcb67fe33",
+ "971ec57c-468d-11e7-a919-92ebcb67fe33",
+ "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "dcb0ef4e-468c-11e7-a919-92ebcb67fe33",
+ "971ede36-468d-11e7-a919-92ebcb67fe33",
+ "dcb0dde2-468c-11e7-a919-92ebcb67fe33",
+ "971edcce-468d-11e7-a919-92ebcb67fe33",
+ "dcb0ef4e-468c-11e7-a919-92ebcb67fe33",
+ "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "971ec57c-468d-11e7-a919-92ebcb67fe33",
+ "dcb0ef4e-468c-11e7-a919-92ebcb67fe33",
+ "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "971ec57c-468d-11e7-a919-92ebcb67fe33",
+ "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "dcb0fb88-468c-11e7-a919-92ebcb67fe33",
+ "dcb0e896-468c-11e7-a919-92ebcb67fe33",
+ "dcb0fd5e-468c-11e7-a919-92ebcb67fe33",
+ "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "971ec57c-468d-11e7-a919-92ebcb67fe33",
+ "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "dcb0fe62-468c-11e7-a919-92ebcb67fe33",
+ "dcb0f200-468c-11e7-a919-92ebcb67fe33",
+ "dcb0ff34-468c-11e7-a919-92ebcb67fe33",
+ "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "dcb0ef4e-468c-11e7-a919-92ebcb67fe33",
+ "971ede36-468d-11e7-a919-92ebcb67fe33",
+ "dcb0dde2-468c-11e7-a919-92ebcb67fe33",
+ "971edcce-468d-11e7-a919-92ebcb67fe33",
+ "dcb0ef4e-468c-11e7-a919-92ebcb67fe33",
+ "971ec57c-468d-11e7-a919-92ebcb67fe33",
+ "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "dcb0ef4e-468c-11e7-a919-92ebcb67fe33",
+ "971ede36-468d-11e7-a919-92ebcb67fe33",
+ "dcb0dde2-468c-11e7-a919-92ebcb67fe33",
+ "971edcce-468d-11e7-a919-92ebcb67fe33",
+ "dcb0ef4e-468c-11e7-a919-92ebcb67fe33",
+ "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "dcb0fb88-468c-11e7-a919-92ebcb67fe33",
+ "dcb0e896-468c-11e7-a919-92ebcb67fe33",
+ "dcb0fd5e-468c-11e7-a919-92ebcb67fe33",
+ "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "dcb0fe62-468c-11e7-a919-92ebcb67fe33",
+ "dcb0f200-468c-11e7-a919-92ebcb67fe33",
+ "dcb0ff34-468c-11e7-a919-92ebcb67fe33",
+ "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "971ec57c-468d-11e7-a919-92ebcb67fe33",
+ "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "dcb0fb88-468c-11e7-a919-92ebcb67fe33",
+ "dcb0e896-468c-11e7-a919-92ebcb67fe33",
+ "dcb0fd5e-468c-11e7-a919-92ebcb67fe33",
+ "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "dcb0ef4e-468c-11e7-a919-92ebcb67fe33",
+ "971ec57c-468d-11e7-a919-92ebcb67fe33",
+ "dcb0ef4e-468c-11e7-a919-92ebcb67fe33",
+ "971ede36-468d-11e7-a919-92ebcb67fe33",
+ "dcb0dde2-468c-11e7-a919-92ebcb67fe33",
+ "971edcce-468d-11e7-a919-92ebcb67fe33",
+ "dcb0ef4e-468c-11e7-a919-92ebcb67fe33",
+ "971ede36-468d-11e7-a919-92ebcb67fe33",
+ "dcb0dde2-468c-11e7-a919-92ebcb67fe33",
+ "971edcce-468d-11e7-a919-92ebcb67fe33",
+ "dcb0ef4e-468c-11e7-a919-92ebcb67fe33",
+ "971ec57c-468d-11e7-a919-92ebcb67fe33",
+ "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "dcb0ef4e-468c-11e7-a919-92ebcb67fe33",
+ "971ede36-468d-11e7-a919-92ebcb67fe33",
+ "dcb0dde2-468c-11e7-a919-92ebcb67fe33",
+ "971edcce-468d-11e7-a919-92ebcb67fe33",
+ "dcb0ef4e-468c-11e7-a919-92ebcb67fe33",
+ "971ec57c-468d-11e7-a919-92ebcb67fe33",
+ "dcb0ef4e-468c-11e7-a919-92ebcb67fe33",
+ "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "dcb0fe62-468c-11e7-a919-92ebcb67fe33",
+ "dcb0f200-468c-11e7-a919-92ebcb67fe33",
+ "dcb0ff34-468c-11e7-a919-92ebcb67fe33",
+ "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "dcb0ef4e-468c-11e7-a919-92ebcb67fe33",
+ "971ede36-468d-11e7-a919-92ebcb67fe33",
+ "dcb0dde2-468c-11e7-a919-92ebcb67fe33",
+ "971edcce-468d-11e7-a919-92ebcb67fe33",
+ "dcb0ef4e-468c-11e7-a919-92ebcb67fe33",
+ "971ede36-468d-11e7-a919-92ebcb67fe33",
+ "dcb0dde2-468c-11e7-a919-92ebcb67fe33",
+ "971edcce-468d-11e7-a919-92ebcb67fe33",
+ "dcb0ef4e-468c-11e7-a919-92ebcb67fe33",
+ "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "dcb0fb88-468c-11e7-a919-92ebcb67fe33",
+ "dcb0e896-468c-11e7-a919-92ebcb67fe33",
+ "dcb0fd5e-468c-11e7-a919-92ebcb67fe33",
+ "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "dcb0fe62-468c-11e7-a919-92ebcb67fe33",
+ "dcb0f200-468c-11e7-a919-92ebcb67fe33",
+ "dcb0ff34-468c-11e7-a919-92ebcb67fe33",
+ "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "971ec57c-468d-11e7-a919-92ebcb67fe33",
+ "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "dcb0ef4e-468c-11e7-a919-92ebcb67fe33",
+ "971ede36-468d-11e7-a919-92ebcb67fe33",
+ "dcb0dde2-468c-11e7-a919-92ebcb67fe33",
+ "971edcce-468d-11e7-a919-92ebcb67fe33",
+ "dcb0ef4e-468c-11e7-a919-92ebcb67fe33",
+ "971ede36-468d-11e7-a919-92ebcb67fe33",
+ "dcb0dde2-468c-11e7-a919-92ebcb67fe33",
+ "971edcce-468d-11e7-a919-92ebcb67fe33",
+ "dcb0ef4e-468c-11e7-a919-92ebcb67fe33",
+ "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "971ec57c-468d-11e7-a919-92ebcb67fe33",
+ "dcb0ef4e-468c-11e7-a919-92ebcb67fe33",
+ "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "dcb0fb88-468c-11e7-a919-92ebcb67fe33",
+ "dcb0e896-468c-11e7-a919-92ebcb67fe33",
+ "dcb0fd5e-468c-11e7-a919-92ebcb67fe33",
+ "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "971ec57c-468d-11e7-a919-92ebcb67fe33",
+ "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "dcb0fe62-468c-11e7-a919-92ebcb67fe33",
+ "dcb0f200-468c-11e7-a919-92ebcb67fe33",
+ "dcb0ff34-468c-11e7-a919-92ebcb67fe33",
+ "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "dcb0fb88-468c-11e7-a919-92ebcb67fe33",
+ "dcb0e896-468c-11e7-a919-92ebcb67fe33",
+ "dcb0fd5e-468c-11e7-a919-92ebcb67fe33",
+ "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "dcb0ef4e-468c-11e7-a919-92ebcb67fe33",
+ "971ec57c-468d-11e7-a919-92ebcb67fe33",
+ "dcb0ef4e-468c-11e7-a919-92ebcb67fe33",
+ "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "dcb0fe62-468c-11e7-a919-92ebcb67fe33",
+ "dcb0f200-468c-11e7-a919-92ebcb67fe33",
+ "dcb0ff34-468c-11e7-a919-92ebcb67fe33",
+ "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "dcb0ef4e-468c-11e7-a919-92ebcb67fe33",
+ "971ec57c-468d-11e7-a919-92ebcb67fe33",
+ "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "dcb0ef4e-468c-11e7-a919-92ebcb67fe33",
+ "971ede36-468d-11e7-a919-92ebcb67fe33",
+ "dcb0dde2-468c-11e7-a919-92ebcb67fe33",
+ "971edcce-468d-11e7-a919-92ebcb67fe33",
+ "dcb0ef4e-468c-11e7-a919-92ebcb67fe33",
+ "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "971ec57c-468d-11e7-a919-92ebcb67fe33",
+ "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "dcb0ef4e-468c-11e7-a919-92ebcb67fe33",
+ "971ede36-468d-11e7-a919-92ebcb67fe33",
+ "dcb0dde2-468c-11e7-a919-92ebcb67fe33",
+ "971edcce-468d-11e7-a919-92ebcb67fe33",
+ "dcb0ef4e-468c-11e7-a919-92ebcb67fe33",
+ "971ec57c-468d-11e7-a919-92ebcb67fe33",
+ "dcb0ef4e-468c-11e7-a919-92ebcb67fe33",
+ "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "dcb0fb88-468c-11e7-a919-92ebcb67fe33",
+ "dcb0e896-468c-11e7-a919-92ebcb67fe33",
+ "dcb0fd5e-468c-11e7-a919-92ebcb67fe33",
+ "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "dcb0ef4e-468c-11e7-a919-92ebcb67fe33",
+ "971ec57c-468d-11e7-a919-92ebcb67fe33",
+ "dcb0ef4e-468c-11e7-a919-92ebcb67fe33",
+ "971ede36-468d-11e7-a919-92ebcb67fe33",
+ "dcb0dde2-468c-11e7-a919-92ebcb67fe33",
+ "971edcce-468d-11e7-a919-92ebcb67fe33",
+ "dcb0ef4e-468c-11e7-a919-92ebcb67fe33",
+ "971ec57c-468d-11e7-a919-92ebcb67fe33",
+ "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "dcb0fe62-468c-11e7-a919-92ebcb67fe33",
+ "dcb0f200-468c-11e7-a919-92ebcb67fe33",
+ "dcb0ff34-468c-11e7-a919-92ebcb67fe33",
+ "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "dcb0fe62-468c-11e7-a919-92ebcb67fe33",
+ "dcb0f200-468c-11e7-a919-92ebcb67fe33",
+ "dcb0ff34-468c-11e7-a919-92ebcb67fe33",
+ "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "dcb0fb88-468c-11e7-a919-92ebcb67fe33",
+ "dcb0e896-468c-11e7-a919-92ebcb67fe33",
+ "dcb0fd5e-468c-11e7-a919-92ebcb67fe33",
+ "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "dcb0fe62-468c-11e7-a919-92ebcb67fe33",
+ "dcb0f200-468c-11e7-a919-92ebcb67fe33",
+ "dcb0ff34-468c-11e7-a919-92ebcb67fe33",
+ "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "dcb0ef4e-468c-11e7-a919-92ebcb67fe33",
+ "971ec57c-468d-11e7-a919-92ebcb67fe33",
+ "dcb0ef4e-468c-11e7-a919-92ebcb67fe33",
+ "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "dcb0fb88-468c-11e7-a919-92ebcb67fe33",
+ "dcb0e896-468c-11e7-a919-92ebcb67fe33",
+ "dcb0d798-468c-11e7-a919-92ebcb67fe33",
+ "dcb10812-468c-11e7-a919-92ebcb67fe33",
+ "dcb0f3c2-468c-11e7-a919-92ebcb67fe33",
+ "dcb0dba8-468c-11e7-a919-92ebcb67fe33",
+ "971ecaa4-468d-11e7-a919-92ebcb67fe33",
+ "dcb0ebb6-468c-11e7-a919-92ebcb67fe33",
+ "971ec838-468d-11e7-a919-92ebcb67fe33",
+ "dcb0dba8-468c-11e7-a919-92ebcb67fe33",
+ "971ecca2-468d-11e7-a919-92ebcb67fe33",
+ "dcb0f8a4-468c-11e7-a919-92ebcb67fe33",
+ "971ece78-468d-11e7-a919-92ebcb67fe33",
+ "dcb0dba8-468c-11e7-a919-92ebcb67fe33",
+ "dcb0f3c2-468c-11e7-a919-92ebcb67fe33",
+ "dcb0dba8-468c-11e7-a919-92ebcb67fe33",
+ "971ed3c8-468d-11e7-a919-92ebcb67fe33",
+ "971ec0b8-468d-11e7-a919-92ebcb67fe33",
+ "971ed53a-468d-11e7-a919-92ebcb67fe33",
+ "dcb0dba8-468c-11e7-a919-92ebcb67fe33",
+ "971edad0-468d-11e7-a919-92ebcb67fe33",
+ "971ec57c-468d-11e7-a919-92ebcb67fe33",
+ "dcb0ef4e-468c-11e7-a919-92ebcb67fe33",
+ "971ede36-468d-11e7-a919-92ebcb67fe33",
+ "dcb0dde2-468c-11e7-a919-92ebcb67fe33",
+ "971edcce-468d-11e7-a919-92ebcb67fe33",
+ "dcb0ef4e-468c-11e7-a919-92ebcb67fe33",
+ "971ec57c-468d-11e7-a919-92ebcb67fe33",
+ "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "dcb0fb88-468c-11e7-a919-92ebcb67fe33",
+ "dcb0e896-468c-11e7-a919-92ebcb67fe33",
+ "dcb0fd5e-468c-11e7-a919-92ebcb67fe33",
+ "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "dcb0fe62-468c-11e7-a919-92ebcb67fe33",
+ "dcb0f200-468c-11e7-a919-92ebcb67fe33",
+ "dcb0ff34-468c-11e7-a919-92ebcb67fe33",
+ "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "971ec57c-468d-11e7-a919-92ebcb67fe33",
+ "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "dcb0fe62-468c-11e7-a919-92ebcb67fe33",
+ "dcb0f200-468c-11e7-a919-92ebcb67fe33",
+ "dcb0ff34-468c-11e7-a919-92ebcb67fe33",
+ "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "dcb0ef4e-468c-11e7-a919-92ebcb67fe33",
+ "971ede36-468d-11e7-a919-92ebcb67fe33",
+ "dcb0dde2-468c-11e7-a919-92ebcb67fe33",
+ "971edcce-468d-11e7-a919-92ebcb67fe33",
+ "dcb0ef4e-468c-11e7-a919-92ebcb67fe33",
+ "971ede36-468d-11e7-a919-92ebcb67fe33",
+ "dcb0dde2-468c-11e7-a919-92ebcb67fe33",
+ "971edcce-468d-11e7-a919-92ebcb67fe33",
+ "dcb0ef4e-468c-11e7-a919-92ebcb67fe33",
+ "971ec57c-468d-11e7-a919-92ebcb67fe33",
+ "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "dcb0fb88-468c-11e7-a919-92ebcb67fe33",
+ "dcb0e896-468c-11e7-a919-92ebcb67fe33",
+ "dcb0fd5e-468c-11e7-a919-92ebcb67fe33",
+ "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "971ec57c-468d-11e7-a919-92ebcb67fe33",
+ "dcb0ef4e-468c-11e7-a919-92ebcb67fe33",
+ "971ede36-468d-11e7-a919-92ebcb67fe33",
+ "dcb0dde2-468c-11e7-a919-92ebcb67fe33",
+ "971edcce-468d-11e7-a919-92ebcb67fe33",
+ "dcb0ef4e-468c-11e7-a919-92ebcb67fe33",
+ "971ec57c-468d-11e7-a919-92ebcb67fe33",
+ "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "dcb0fb88-468c-11e7-a919-92ebcb67fe33",
+ "dcb0e896-468c-11e7-a919-92ebcb67fe33",
+ "dcb0d798-468c-11e7-a919-92ebcb67fe33",
+ "dcb10812-468c-11e7-a919-92ebcb67fe33",
+ "dcb0f3c2-468c-11e7-a919-92ebcb67fe33",
+ "dcb0dba8-468c-11e7-a919-92ebcb67fe33",
+ "971ecaa4-468d-11e7-a919-92ebcb67fe33",
+ "dcb0ebb6-468c-11e7-a919-92ebcb67fe33",
+ "971ed0b2-468d-11e7-a919-92ebcb67fe33",
+ "dcb0ebb6-468c-11e7-a919-92ebcb67fe33",
+ "971ec838-468d-11e7-a919-92ebcb67fe33",
+ "dcb0dba8-468c-11e7-a919-92ebcb67fe33",
+ "dcb0f3c2-468c-11e7-a919-92ebcb67fe33",
+ "dcb0dba8-468c-11e7-a919-92ebcb67fe33",
+ "971ed3c8-468d-11e7-a919-92ebcb67fe33",
+ "971ec0b8-468d-11e7-a919-92ebcb67fe33",
+ "971ed738-468d-11e7-a919-92ebcb67fe33",
+ "971ec0b8-468d-11e7-a919-92ebcb67fe33"
+ )).toArray(), actualPath.toArray());
+ }
}
diff --git a/graphwalker-java/src/test/resources/org/graphwalker/java/test/PetClinicWithSeed.json b/graphwalker-java/src/test/resources/org/graphwalker/java/test/PetClinicWithSeed.json
new file mode 100644
index 000000000..a45eac772
--- /dev/null
+++ b/graphwalker-java/src/test/resources/org/graphwalker/java/test/PetClinicWithSeed.json
@@ -0,0 +1,345 @@
+{
+ "name": "GraphWalker Example Test",
+ "seed": 11111,
+ "models": [
+ {
+ "name": "FindOwners",
+ "id": "476fb419-3d7d-4492-802e-6695fe93f595",
+ "generator": "quickrandom(edge_coverage(100))",
+ "vertices": [
+ {
+ "id": "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "name": "v_FindOwners",
+ "sharedState": "FindOwners",
+ "properties": {
+ "x": 0,
+ "y": 0
+ }
+ },
+ {
+ "id": "dcb0e896-468c-11e7-a919-92ebcb67fe33",
+ "name": "v_NewOwner",
+ "sharedState": "NewOwner",
+ "properties": {
+ "x": 120.65625,
+ "y": -157.8125
+ }
+ },
+ {
+ "id": "dcb0f200-468c-11e7-a919-92ebcb67fe33",
+ "name": "v_Owners",
+ "properties": {
+ "x": -219.34375,
+ "y": -187.8125
+ }
+ }
+ ],
+ "edges": [
+ {
+ "id": "dcb0fb88-468c-11e7-a919-92ebcb67fe33",
+ "name": "e_AddOwner",
+ "sourceVertexId": "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "targetVertexId": "dcb0e896-468c-11e7-a919-92ebcb67fe33"
+ },
+ {
+ "id": "dcb0fd5e-468c-11e7-a919-92ebcb67fe33",
+ "name": "e_FindOwners",
+ "sourceVertexId": "dcb0e896-468c-11e7-a919-92ebcb67fe33",
+ "targetVertexId": "b53814ec-468c-11e7-a919-92ebcb67fe33"
+ },
+ {
+ "id": "dcb0fe62-468c-11e7-a919-92ebcb67fe33",
+ "name": "e_Search",
+ "sourceVertexId": "b53814ec-468c-11e7-a919-92ebcb67fe33",
+ "targetVertexId": "dcb0f200-468c-11e7-a919-92ebcb67fe33"
+ },
+ {
+ "id": "dcb0ff34-468c-11e7-a919-92ebcb67fe33",
+ "name": "e_FindOwners",
+ "sourceVertexId": "dcb0f200-468c-11e7-a919-92ebcb67fe33",
+ "targetVertexId": "b53814ec-468c-11e7-a919-92ebcb67fe33"
+ }
+ ]
+ },
+ {
+ "name": "NewOwner",
+ "id": "b23d193c-287a-4eb9-a318-52ead7680ff7",
+ "generator": "quickrandom(edge_coverage(100))",
+ "vertices": [
+ {
+ "id": "dcb0d798-468c-11e7-a919-92ebcb67fe33",
+ "name": "v_NewOwner",
+ "sharedState": "NewOwner",
+ "properties": {
+ "x": 0,
+ "y": 0
+ }
+ },
+ {
+ "id": "dcb0eab2-468c-11e7-a919-92ebcb67fe33",
+ "name": "v_IncorrectData",
+ "properties": {
+ "x": 131.65625,
+ "y": -205.3125
+ }
+ },
+ {
+ "id": "dcb0f3c2-468c-11e7-a919-92ebcb67fe33",
+ "name": "v_OwnerInformation",
+ "sharedState": "OwnerInformation",
+ "properties": {
+ "x": -284.34375,
+ "y": -143.3125
+ }
+ }
+ ],
+ "edges": [
+ {
+ "id": "dcb104e8-468c-11e7-a919-92ebcb67fe33",
+ "name": "e_IncorrectData",
+ "sourceVertexId": "dcb0d798-468c-11e7-a919-92ebcb67fe33",
+ "targetVertexId": "dcb0eab2-468c-11e7-a919-92ebcb67fe33"
+ },
+ {
+ "id": "dcb10736-468c-11e7-a919-92ebcb67fe33",
+ "sourceVertexId": "dcb0eab2-468c-11e7-a919-92ebcb67fe33",
+ "targetVertexId": "dcb0d798-468c-11e7-a919-92ebcb67fe33"
+ },
+ {
+ "id": "dcb10812-468c-11e7-a919-92ebcb67fe33",
+ "name": "e_CorrectData",
+ "sourceVertexId": "dcb0d798-468c-11e7-a919-92ebcb67fe33",
+ "targetVertexId": "dcb0f3c2-468c-11e7-a919-92ebcb67fe33"
+ }
+ ]
+ },
+ {
+ "name": "OwnerInformation",
+ "id": "5f1149c3-2853-47e6-838d-691bf30406a8",
+ "generator": "quickrandom(edge_coverage(100))",
+ "actions": [
+ "numOfPets=0;"
+ ],
+ "vertices": [
+ {
+ "id": "dcb0dba8-468c-11e7-a919-92ebcb67fe33",
+ "name": "v_OwnerInformation",
+ "sharedState": "OwnerInformation",
+ "properties": {
+ "x": -23.34375,
+ "y": -51.8125
+ }
+ },
+ {
+ "id": "dcb0ebb6-468c-11e7-a919-92ebcb67fe33",
+ "name": "v_NewPet",
+ "properties": {
+ "x": -27.34375,
+ "y": 118.1875
+ }
+ },
+ {
+ "id": "dcb0f8a4-468c-11e7-a919-92ebcb67fe33",
+ "name": "v_Pet",
+ "properties": {
+ "x": -317.34375,
+ "y": 7.1875
+ }
+ },
+ {
+ "id": "971ec0b8-468d-11e7-a919-92ebcb67fe33",
+ "name": "v_NewVisit",
+ "properties": {
+ "x": 139.65625,
+ "y": -195.8125
+ }
+ },
+ {
+ "id": "971ec57c-468d-11e7-a919-92ebcb67fe33",
+ "name": "v_FindOwners",
+ "sharedState": "FindOwners",
+ "properties": {
+ "x": -270.34375,
+ "y": -181.8125
+ }
+ }
+ ],
+ "edges": [
+ {
+ "id": "971ec838-468d-11e7-a919-92ebcb67fe33",
+ "name": "e_AddPetSuccessfully",
+ "actions": [
+ " numOfPets++;"
+ ],
+ "sourceVertexId": "dcb0ebb6-468c-11e7-a919-92ebcb67fe33",
+ "targetVertexId": "dcb0dba8-468c-11e7-a919-92ebcb67fe33"
+ },
+ {
+ "id": "971ecaa4-468d-11e7-a919-92ebcb67fe33",
+ "name": "e_AddNewPet",
+ "sourceVertexId": "dcb0dba8-468c-11e7-a919-92ebcb67fe33",
+ "targetVertexId": "dcb0ebb6-468c-11e7-a919-92ebcb67fe33"
+ },
+ {
+ "id": "971ecca2-468d-11e7-a919-92ebcb67fe33",
+ "name": "e_EditPet",
+ "guard": "numOfPets>0",
+ "sourceVertexId": "dcb0dba8-468c-11e7-a919-92ebcb67fe33",
+ "targetVertexId": "dcb0f8a4-468c-11e7-a919-92ebcb67fe33"
+ },
+ {
+ "id": "971ece78-468d-11e7-a919-92ebcb67fe33",
+ "name": "e_UpdatePet",
+ "sourceVertexId": "dcb0f8a4-468c-11e7-a919-92ebcb67fe33",
+ "targetVertexId": "dcb0dba8-468c-11e7-a919-92ebcb67fe33"
+ },
+ {
+ "id": "971ed0b2-468d-11e7-a919-92ebcb67fe33",
+ "name": "e_AddPetFailed",
+ "sourceVertexId": "dcb0ebb6-468c-11e7-a919-92ebcb67fe33",
+ "targetVertexId": "dcb0ebb6-468c-11e7-a919-92ebcb67fe33"
+ },
+ {
+ "id": "971ed3c8-468d-11e7-a919-92ebcb67fe33",
+ "name": "e_AddVisit",
+ "guard": "numOfPets>0",
+ "sourceVertexId": "dcb0dba8-468c-11e7-a919-92ebcb67fe33",
+ "targetVertexId": "971ec0b8-468d-11e7-a919-92ebcb67fe33"
+ },
+ {
+ "id": "971ed53a-468d-11e7-a919-92ebcb67fe33",
+ "name": "e_VisitAddedSuccessfully",
+ "sourceVertexId": "971ec0b8-468d-11e7-a919-92ebcb67fe33",
+ "targetVertexId": "dcb0dba8-468c-11e7-a919-92ebcb67fe33"
+ },
+ {
+ "id": "971ed738-468d-11e7-a919-92ebcb67fe33",
+ "name": "e_VisitAddedFailed",
+ "sourceVertexId": "971ec0b8-468d-11e7-a919-92ebcb67fe33",
+ "targetVertexId": "971ec0b8-468d-11e7-a919-92ebcb67fe33"
+ },
+ {
+ "id": "971edad0-468d-11e7-a919-92ebcb67fe33",
+ "name": "e_FindOwners",
+ "sourceVertexId": "dcb0dba8-468c-11e7-a919-92ebcb67fe33",
+ "targetVertexId": "971ec57c-468d-11e7-a919-92ebcb67fe33"
+ }
+ ]
+ },
+ {
+ "name": "PetClinic",
+ "id": "3f6b365f-7011-4db6-b0cc-e19aa453d9b8",
+ "generator": "quickrandom(edge_coverage(100))",
+ "vertices": [
+ {
+ "id": "dcb0dde2-468c-11e7-a919-92ebcb67fe33",
+ "name": "v_HomePage",
+ "sharedState": "HomePage",
+ "properties": {
+ "x": 0,
+ "y": 0
+ }
+ },
+ {
+ "id": "dcb0ef4e-468c-11e7-a919-92ebcb67fe33",
+ "name": "v_FindOwners",
+ "sharedState": "FindOwners",
+ "properties": {
+ "x": 112.65625,
+ "y": -180.8125
+ }
+ },
+ {
+ "id": "dcb0f8a5-468c-11e7-a919-92ebcb67fe33",
+ "name": "v_Veterinarians",
+ "sharedState": "Veterinarians",
+ "properties": {
+ "x": -246.34375,
+ "y": -153.8125
+ }
+ }
+ ],
+ "edges": [
+ {
+ "id": "971edcce-468d-11e7-a919-92ebcb67fe33",
+ "name": "e_FindOwners",
+ "sourceVertexId": "dcb0dde2-468c-11e7-a919-92ebcb67fe33",
+ "targetVertexId": "dcb0ef4e-468c-11e7-a919-92ebcb67fe33"
+ },
+ {
+ "id": "971ede36-468d-11e7-a919-92ebcb67fe33",
+ "name": "e_HomePage",
+ "sourceVertexId": "dcb0ef4e-468c-11e7-a919-92ebcb67fe33",
+ "targetVertexId": "dcb0dde2-468c-11e7-a919-92ebcb67fe33"
+ },
+ {
+ "id": "971ee142-468d-11e7-a919-92ebcb67fe33",
+ "name": "e_Veterinarians",
+ "sourceVertexId": "dcb0dde2-468c-11e7-a919-92ebcb67fe33",
+ "targetVertexId": "dcb0f8a5-468c-11e7-a919-92ebcb67fe33"
+ },
+ {
+ "id": "971ee2b4-468d-11e7-a919-92ebcb67fe33",
+ "name": "e_HomePage",
+ "sourceVertexId": "dcb0f8a5-468c-11e7-a919-92ebcb67fe33",
+ "targetVertexId": "dcb0dde2-468c-11e7-a919-92ebcb67fe33"
+ },
+ {
+ "id": "971ee5c0-468d-11e7-a919-92ebcb67fe33",
+ "name": "e_Veterinarians",
+ "sourceVertexId": "dcb0ef4e-468c-11e7-a919-92ebcb67fe33",
+ "targetVertexId": "dcb0f8a5-468c-11e7-a919-92ebcb67fe33"
+ },
+ {
+ "id": "971ee732-468d-11e7-a919-92ebcb67fe33",
+ "name": "e_FindOwners",
+ "sourceVertexId": "dcb0f8a5-468c-11e7-a919-92ebcb67fe33",
+ "targetVertexId": "dcb0ef4e-468c-11e7-a919-92ebcb67fe33"
+ },
+ {
+ "id": "b53810a0-468c-11e7-a919-92ebcb67fe33",
+ "name": "e_StartBrowser",
+ "targetVertexId": "dcb0dde2-468c-11e7-a919-92ebcb67fe33"
+ }
+ ],
+ "startElementId": "b53810a0-468c-11e7-a919-92ebcb67fe33"
+ },
+ {
+ "name": "Veterinarians",
+ "id": "368a9635-c59a-4285-ad01-cf75b0baa978",
+ "generator": "quickrandom(edge_coverage(100))",
+ "vertices": [
+ {
+ "id": "dcb0defa-468c-11e7-a919-92ebcb67fe33",
+ "name": "v_Veterinarians",
+ "sharedState": "Veterinarians",
+ "properties": {
+ "x": 0,
+ "y": 0
+ }
+ },
+ {
+ "id": "dcb0f124-468c-11e7-a919-92ebcb67fe33",
+ "name": "v_SearchResult",
+ "properties": {
+ "x": -213.34375,
+ "y": -138.8125
+ }
+ }
+ ],
+ "edges": [
+ {
+ "id": "971eea2a-468d-11e7-a919-92ebcb67fe33",
+ "name": "e_Search",
+ "sourceVertexId": "dcb0defa-468c-11e7-a919-92ebcb67fe33",
+ "targetVertexId": "dcb0f124-468c-11e7-a919-92ebcb67fe33"
+ },
+ {
+ "id": "971eeba6-468d-11e7-a919-92ebcb67fe33",
+ "sourceVertexId": "dcb0f124-468c-11e7-a919-92ebcb67fe33",
+ "targetVertexId": "dcb0defa-468c-11e7-a919-92ebcb67fe33"
+ }
+ ]
+ }
+ ]
+}
diff --git a/pom.xml b/pom.xml
index e655fac04..47f7644f9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -167,7 +167,7 @@
junit
junit
- 4.13-beta-2
+ 4.13-rc-1
org.apache.xmlbeans
@@ -360,14 +360,6 @@
-
- org.apache.maven.plugins
- maven-surefire-plugin
-
- classes
- true
-
-
org.apache.maven.plugins
maven-enforcer-plugin