From bf605f55e8526ca3299d12bf66ec21490b355818 Mon Sep 17 00:00:00 2001 From: Kristian Karl Date: Tue, 19 Nov 2019 15:30:27 +0100 Subject: [PATCH 01/11] Replace dprecated assertThat --- .../graphwalker/dsl/GeneratorFactoryTest.java | 188 +++++++++--------- 1 file changed, 94 insertions(+), 94 deletions(-) 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)); } } From d593bbb0d16e1ec265c2522c98a4b83e77a39a81 Mon Sep 17 00:00:00 2001 From: Kristian Karl Date: Tue, 19 Nov 2019 16:08:49 +0100 Subject: [PATCH 02/11] Added the possibility to seed the random path genrators --- .../core/generator/QuickRandomPath.java | 13 +- .../core/generator/RandomPath.java | 11 +- .../core/generator/WeightedRandomPath.java | 19 +-- .../java/org/graphwalker/core/Models.java | 41 ++++++- .../core/generator/QuickRandomPathTest.java | 78 ++++++++++-- .../core/generator/RandomPathTest.java | 80 +++++++++++-- .../generator/WeightedRandomPathTest.java | 113 +++++++++++++----- .../dsl/generator/GeneratorParser.g4 | 14 ++- .../graphwalker/dsl/generator/LogicalLexer.g4 | 4 + .../dsl/generator/LogicalLexer.tokens | 11 ++ .../dsl/antlr/generator/GeneratorLoader.java | 27 ++++- .../graphwalker/dsl/GeneratorFactoryTest.java | 24 ++++ .../java/org/graphwalker/dsl/GrammarTest.java | 3 + 13 files changed, 363 insertions(+), 75 deletions(-) create mode 100644 graphwalker-dsl/src/main/antlr4/org/graphwalker/dsl/generator/LogicalLexer.tokens 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..269c6d0a1 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; @@ -39,6 +39,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Random; import static org.graphwalker.core.common.Objects.isNotNull; import static org.graphwalker.core.common.Objects.isNull; @@ -60,18 +61,24 @@ public class QuickRandomPath extends PathGeneratorBase { private static final Logger LOG = LoggerFactory.getLogger(QuickRandomPath.class); private final List elements = new ArrayList<>(); private Element target = null; + private Random random = new Random(System.nanoTime()); public QuickRandomPath(StopCondition stopCondition) { setStopCondition(stopCondition); } + public QuickRandomPath(long seed, StopCondition stopCondition) { + setStopCondition(stopCondition); + random = new Random(seed); + } + @Override public Context getNextStep() { Context context = super.getNextStep(); if (elements.isEmpty()) { elements.addAll(context.getModel().getElements()); elements.remove(context.getCurrentElement()); - Collections.shuffle(elements); + Collections.shuffle(elements, 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..a70a89ebe 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 @@ -48,12 +48,17 @@ public class RandomPath extends PathGeneratorBase { private static final Logger LOG = LoggerFactory.getLogger(RandomPath.class); - private final Random random = new Random(System.nanoTime()); + private Random random = new Random(System.nanoTime()); public RandomPath(StopCondition stopCondition) { setStopCondition(stopCondition); } + public RandomPath(long seed, StopCondition stopCondition) { + setStopCondition(stopCondition); + random = new Random(seed); + } + @Override public Context getNextStep() { Context context = super.getNextStep(); 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..d22f561a4 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 @@ -52,12 +52,17 @@ */ public class WeightedRandomPath extends PathGeneratorBase { - private final Random random = new Random(System.nanoTime()); + private Random random = new Random(System.nanoTime()); public WeightedRandomPath(StopCondition stopCondition) { setStopCondition(stopCondition); } + public WeightedRandomPath(long seed, StopCondition stopCondition) { + setStopCondition(stopCondition); + random = new Random(seed); + } + @Override public Context getNextStep() { Context context = super.getNextStep(); @@ -93,8 +98,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++; @@ -127,8 +132,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/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/generator/QuickRandomPathTest.java b/graphwalker-core/src/test/java/org/graphwalker/core/generator/QuickRandomPathTest.java index c2dc57d67..ec9fb16f1 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); + + long seed = 1349327921; + context.setPathGenerator(new QuickRandomPath(seed, 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..0547e3638 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); + + long seed = 1349327921; + context.setPathGenerator(new RandomPath(seed, 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/WeightedRandomPathTest.java b/graphwalker-core/src/test/java/org/graphwalker/core/generator/WeightedRandomPathTest.java index 975d46d1f..41177e9c6 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() { + long seed = 1349327921; + PathGenerator generator = new WeightedRandomPath(seed, 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-dsl/src/main/antlr4/org/graphwalker/dsl/generator/GeneratorParser.g4 b/graphwalker-dsl/src/main/antlr4/org/graphwalker/dsl/generator/GeneratorParser.g4 index e0ba22f17..6ccad4606 100644 --- a/graphwalker-dsl/src/main/antlr4/org/graphwalker/dsl/generator/GeneratorParser.g4 +++ b/graphwalker-dsl/src/main/antlr4/org/graphwalker/dsl/generator/GeneratorParser.g4 @@ -9,12 +9,17 @@ parse ; generator - : Alphanumeric LPAREN logicalExpression RPAREN - | Alphanumeric LPAREN logicalExpression RPAREN RPAREN {notifyErrorListeners("The generator has too many parentheses");} - | Alphanumeric LPAREN logicalExpression {notifyErrorListeners("The generator is missing closing parentheses");} + : Alphanumeric LPAREN parameters RPAREN + | Alphanumeric LPAREN parameters RPAREN RPAREN {notifyErrorListeners("The generator has too many parentheses");} + | Alphanumeric LPAREN parameters {notifyErrorListeners("The generator is missing closing parentheses");} | Alphanumeric {notifyErrorListeners("A generator needs parentheses");} ; +parameters + : ( logicalExpression + | seed COMMA logicalExpression ) + ; + logicalExpression : booleanAndExpression ( OR booleanAndExpression )* ; @@ -34,3 +39,6 @@ stopCondition | Alphanumeric) ; +seed + : Number + ; diff --git a/graphwalker-dsl/src/main/antlr4/org/graphwalker/dsl/generator/LogicalLexer.g4 b/graphwalker-dsl/src/main/antlr4/org/graphwalker/dsl/generator/LogicalLexer.g4 index f2b51c27d..9304b72db 100644 --- a/graphwalker-dsl/src/main/antlr4/org/graphwalker/dsl/generator/LogicalLexer.g4 +++ b/graphwalker-dsl/src/main/antlr4/org/graphwalker/dsl/generator/LogicalLexer.g4 @@ -16,6 +16,10 @@ RPAREN : ')' ; +COMMA + : ',' + ; + WHITESPACE : [ \t\r\n\u000C]+ -> skip ; diff --git a/graphwalker-dsl/src/main/antlr4/org/graphwalker/dsl/generator/LogicalLexer.tokens b/graphwalker-dsl/src/main/antlr4/org/graphwalker/dsl/generator/LogicalLexer.tokens new file mode 100644 index 000000000..a4672629f --- /dev/null +++ b/graphwalker-dsl/src/main/antlr4/org/graphwalker/dsl/generator/LogicalLexer.tokens @@ -0,0 +1,11 @@ +OR=1 +AND=2 +LPAREN=3 +RPAREN=4 +COMMA=5 +WHITESPACE=6 +Number=7 +Alphanumeric=8 +'('=3 +')'=4 +','=5 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..a2633c8ef 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 @@ -47,6 +47,7 @@ public class GeneratorLoader extends GeneratorParserBaseListener { private StopCondition stopCondition = null; + private Integer seed = null; private final List pathGenerators = new ArrayList<>(); private final List stopConditions = new ArrayList<>(); @@ -94,6 +95,14 @@ public void exitLogicalExpression(GeneratorParser.LogicalExpressionContext ctx) } } + @Override + public void exitSeed(GeneratorParser.SeedContext ctx) { + String str = ctx.getChild(0).getText(); + if (str != null && str.length() > 0) { + seed = Integer.parseInt(str); + } + } + @Override public void exitGenerator(GeneratorParser.GeneratorContext context) { if (stopConditions.size() == 1) { @@ -101,11 +110,23 @@ public void exitGenerator(GeneratorParser.GeneratorContext context) { } String generatorName = context.getChild(0).getText().toLowerCase(); if ("random".equals(generatorName) || "randompath".equals(generatorName)) { - pathGenerators.add(new RandomPath(stopCondition)); + if (seed == null ) { + pathGenerators.add(new RandomPath(stopCondition)); + } else { + pathGenerators.add(new RandomPath(seed, stopCondition)); + } } else if ("weighted_random".equals(generatorName) || "weightedrandompath".equals(generatorName)) { - pathGenerators.add(new WeightedRandomPath(stopCondition)); + if (seed == null ) { + pathGenerators.add(new WeightedRandomPath(stopCondition)); + } else { + pathGenerators.add(new WeightedRandomPath(seed, stopCondition)); + } } else if ("quick_random".equals(generatorName) || "quickrandom".equals(generatorName) || "quickrandompath".equals(generatorName)) { - pathGenerators.add(new QuickRandomPath(stopCondition)); + if (seed == null ) { + pathGenerators.add(new QuickRandomPath(stopCondition)); + } else { + pathGenerators.add(new QuickRandomPath(seed, stopCondition)); + } } else if ("a_star".equals(generatorName) || "astarpath".equals(generatorName)) { pathGenerators.add(new AStarPath((ReachedStopCondition) stopCondition)); } else if ("shortest_all_paths".equals(generatorName) || "shortestallpaths".equals(generatorName)) { 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 7f3563608..467354302 100644 --- a/graphwalker-dsl/src/test/java/org/graphwalker/dsl/GeneratorFactoryTest.java +++ b/graphwalker-dsl/src/test/java/org/graphwalker/dsl/GeneratorFactoryTest.java @@ -310,4 +310,28 @@ public void multipleAlternativeStopConditions() { assertThat(generator.getStopCondition(), instanceOf(AlternativeCondition.class)); assertThat(((AlternativeCondition) generator.getStopCondition()).getStopConditions().size(), is(3)); } + + @Test + public void random_seed_edge_coverage() { + PathGenerator generator = GeneratorFactory.parse("random(123456789, edge_coverage(100))"); + assertThat(generator, instanceOf(RandomPath.class)); + assertThat(generator.getStopCondition(), instanceOf(EdgeCoverage.class)); + assertThat(((EdgeCoverage) generator.getStopCondition()).getPercent(), is(100)); + } + + @Test + public void weighted_random__seed_edge_coverage() { + PathGenerator generator = GeneratorFactory.parse(" weighted_random(123456789, edge_coverage(100))"); + assertThat(generator, instanceOf(WeightedRandomPath.class)); + assertThat(generator.getStopCondition(), instanceOf(EdgeCoverage.class)); + assertThat(((EdgeCoverage) generator.getStopCondition()).getPercent(), is(100)); + } + + @Test + public void quickrandom_seed_edge_coverage() { + PathGenerator generator = GeneratorFactory.parse("quickrandom(123456789, edge_coverage(100))"); + assertThat(generator, instanceOf(QuickRandomPath.class)); + assertThat(generator.getStopCondition(), instanceOf(EdgeCoverage.class)); + assertThat(((EdgeCoverage) generator.getStopCondition()).getPercent(), is(100)); + } } diff --git a/graphwalker-dsl/src/test/java/org/graphwalker/dsl/GrammarTest.java b/graphwalker-dsl/src/test/java/org/graphwalker/dsl/GrammarTest.java index 205949124..bc10357ab 100644 --- a/graphwalker-dsl/src/test/java/org/graphwalker/dsl/GrammarTest.java +++ b/graphwalker-dsl/src/test/java/org/graphwalker/dsl/GrammarTest.java @@ -45,9 +45,12 @@ public class GrammarTest { private List generators = Arrays.asList( "random(never)", + "random(123456789, never)", "a_star(never)", "quick_random(never)", + "quick_random(123456789, never)", "weighted_random(vertex_coverage(100))", + "weighted_random(123456789, vertex_coverage(100))", "random(vertex_coverage(100))", "random(edge_coverage(100))", "random(reached_vertex(v_SomeVertex))", From 17cf57b8b8618ad22ea6c15a98fb355525f7c69a Mon Sep 17 00:00:00 2001 From: Kristian Karl Date: Tue, 19 Nov 2019 21:55:58 +0100 Subject: [PATCH 03/11] Add logging of seed used for random generators --- .../org/graphwalker/core/generator/QuickRandomPath.java | 6 +++++- .../java/org/graphwalker/core/generator/RandomPath.java | 7 +++++-- .../graphwalker/core/generator/WeightedRandomPath.java | 9 ++++++++- 3 files changed, 18 insertions(+), 4 deletions(-) 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 269c6d0a1..fc3bd99a5 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 @@ -61,15 +61,19 @@ public class QuickRandomPath extends PathGeneratorBase { private static final Logger LOG = LoggerFactory.getLogger(QuickRandomPath.class); private final List elements = new ArrayList<>(); private Element target = null; - private Random random = new Random(System.nanoTime()); + private Random random; public QuickRandomPath(StopCondition stopCondition) { setStopCondition(stopCondition); + long seed = System.nanoTime(); + random = new Random(seed); + LOG.info("Seed: " + seed); } public QuickRandomPath(long seed, StopCondition stopCondition) { setStopCondition(stopCondition); random = new Random(seed); + LOG.info("Seed: " + seed); } @Override 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 a70a89ebe..c3eb8cb34 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 @@ -47,16 +47,19 @@ public class RandomPath extends PathGeneratorBase { private static final Logger LOG = LoggerFactory.getLogger(RandomPath.class); - - private Random random = new Random(System.nanoTime()); + private Random random; public RandomPath(StopCondition stopCondition) { setStopCondition(stopCondition); + long seed = System.nanoTime(); + random = new Random(seed); + LOG.info("Seed: " + seed); } public RandomPath(long seed, StopCondition stopCondition) { setStopCondition(stopCondition); random = new Random(seed); + LOG.info("Seed: " + seed); } @Override 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 d22f561a4..9323042ce 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 @@ -32,6 +32,8 @@ 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; @@ -52,15 +54,20 @@ */ public class WeightedRandomPath extends PathGeneratorBase { - private Random random = new Random(System.nanoTime()); + private static final Logger LOG = LoggerFactory.getLogger(WeightedRandomPath.class); + private Random random; public WeightedRandomPath(StopCondition stopCondition) { setStopCondition(stopCondition); + long seed = System.nanoTime(); + random = new Random(seed); + LOG.info("Seed: " + seed); } public WeightedRandomPath(long seed, StopCondition stopCondition) { setStopCondition(stopCondition); random = new Random(seed); + LOG.info("Seed: " + seed); } @Override From 5a261022c3ea5a0ba846557b6c6c28b9d3dd70ab Mon Sep 17 00:00:00 2001 From: Kristian Karl Date: Wed, 20 Nov 2019 08:17:43 +0100 Subject: [PATCH 04/11] Use Long to parse seed --- .../org/graphwalker/dsl/antlr/generator/GeneratorLoader.java | 4 ++-- .../test/java/org/graphwalker/dsl/GeneratorFactoryTest.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) 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 a2633c8ef..d8e18d471 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 @@ -47,7 +47,7 @@ public class GeneratorLoader extends GeneratorParserBaseListener { private StopCondition stopCondition = null; - private Integer seed = null; + private Long seed = null; private final List pathGenerators = new ArrayList<>(); private final List stopConditions = new ArrayList<>(); @@ -99,7 +99,7 @@ public void exitLogicalExpression(GeneratorParser.LogicalExpressionContext ctx) public void exitSeed(GeneratorParser.SeedContext ctx) { String str = ctx.getChild(0).getText(); if (str != null && str.length() > 0) { - seed = Integer.parseInt(str); + seed = Long.parseLong(str); } } 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 467354302..b58d91685 100644 --- a/graphwalker-dsl/src/test/java/org/graphwalker/dsl/GeneratorFactoryTest.java +++ b/graphwalker-dsl/src/test/java/org/graphwalker/dsl/GeneratorFactoryTest.java @@ -329,7 +329,7 @@ public void weighted_random__seed_edge_coverage() { @Test public void quickrandom_seed_edge_coverage() { - PathGenerator generator = GeneratorFactory.parse("quickrandom(123456789, edge_coverage(100))"); + PathGenerator generator = GeneratorFactory.parse("quickrandom(89554871348029579, edge_coverage(100))"); assertThat(generator, instanceOf(QuickRandomPath.class)); assertThat(generator.getStopCondition(), instanceOf(EdgeCoverage.class)); assertThat(((EdgeCoverage) generator.getStopCondition()).getPercent(), is(100)); From 375b7d8ac4f461f7455335f7170071f4c8a5ccd7 Mon Sep 17 00:00:00 2001 From: Kristian Karl Date: Wed, 20 Nov 2019 08:18:10 +0100 Subject: [PATCH 05/11] Json seeded model files --- .../resources/json/PetClinicWithSeed.json | 344 ++++++++++++++++++ .../test/resources/json/UC01_with_seed.json | 134 +++++++ 2 files changed, 478 insertions(+) create mode 100644 graphwalker-cli/src/test/resources/json/PetClinicWithSeed.json create mode 100644 graphwalker-io/src/test/resources/json/UC01_with_seed.json 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..ba9c32f6d --- /dev/null +++ b/graphwalker-cli/src/test/resources/json/PetClinicWithSeed.json @@ -0,0 +1,344 @@ +{ + "name": "GraphWalker Example Test", + "models": [ + { + "name": "FindOwners", + "id": "476fb419-3d7d-4492-802e-6695fe93f595", + "generator": "random(89554871348029, 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(89554942549238, 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(89555008190353, 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(89555075763648, 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(89555139131399, 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-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" + } + ] + } + ] +} From 80025135becfdfb7d863dcfd1e90712e3d1d5a83 Mon Sep 17 00:00:00 2001 From: Kristian Karl Date: Wed, 20 Nov 2019 20:11:15 +0100 Subject: [PATCH 06/11] Test for seeded generator multiple contexts --- .../core/machine/MultipleContextTest.java | 85 +++++++++++++++++-- 1 file changed, 79 insertions(+), 6 deletions(-) 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..0d96f2bc9 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,97 @@ package org.graphwalker.core.machine; +import org.graphwalker.core.condition.EdgeCoverage; +import org.graphwalker.core.generator.RandomPath; 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")); + + Context context1 = new TestExecutionContext(model1, new RandomPath(123456789, new EdgeCoverage(100))).setNextElement(A1); + Context context2 = new TestExecutionContext(model2, new RandomPath(987654321, 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", + "A1B1_2", + "B1", + "B1A1_1", + "A1", + "A1B1_1", + "B1", + "B1A1_2", + "A1", + "A1B1_2", + "B1", + "B1A1_1", + "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()); + } } From a1f7c35e55d52add000db4dd9f7b8271786263bd Mon Sep 17 00:00:00 2001 From: Kristian Karl Date: Thu, 21 Nov 2019 13:21:52 +0100 Subject: [PATCH 07/11] Don't write to stdoutgraphwalker-core/src/test/java/org/graphwalker/core/condition/ComplexConditionsTest.java --- .../org/graphwalker/dsl/generator/LogicalLexer.tokens | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 graphwalker-dsl/src/main/antlr4/org/graphwalker/dsl/generator/LogicalLexer.tokens diff --git a/graphwalker-dsl/src/main/antlr4/org/graphwalker/dsl/generator/LogicalLexer.tokens b/graphwalker-dsl/src/main/antlr4/org/graphwalker/dsl/generator/LogicalLexer.tokens deleted file mode 100644 index a4672629f..000000000 --- a/graphwalker-dsl/src/main/antlr4/org/graphwalker/dsl/generator/LogicalLexer.tokens +++ /dev/null @@ -1,11 +0,0 @@ -OR=1 -AND=2 -LPAREN=3 -RPAREN=4 -COMMA=5 -WHITESPACE=6 -Number=7 -Alphanumeric=8 -'('=3 -')'=4 -','=5 From f11d165f8d4b73d0fdb0283b9f7cfdd72ecd4109 Mon Sep 17 00:00:00 2001 From: Kristian Karl Date: Thu, 21 Nov 2019 13:22:18 +0100 Subject: [PATCH 08/11] Don't write to stdout --- .../graphwalker/core/condition/ComplexConditionsTest.java | 6 ------ 1 file changed, 6 deletions(-) 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()); } } From f4d2a52ecbc009bcd7e864d84ab1b30e79c2a9f5 Mon Sep 17 00:00:00 2001 From: Kristian Karl Date: Thu, 21 Nov 2019 16:12:44 +0100 Subject: [PATCH 09/11] Fixed deprectaed assertThat --- .../graphwalker/io/factory/json/JsonContextFactoryTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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..ab93c83ca 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; From 926f8133e8edb83a02d9c4be26be6b73926b81e2 Mon Sep 17 00:00:00 2001 From: Kristian Karl Date: Tue, 26 Nov 2019 09:30:30 +0100 Subject: [PATCH 10/11] Seed the random generator from the json model file --- .../resources/json/PetClinicWithSeed.json | 11 +- .../core/generator/QuickRandomPath.java | 13 +- .../core/generator/RandomPath.java | 13 +- .../generator/SingletonRandomGenerator.java | 84 ++++ .../core/generator/WeightedRandomPath.java | 15 +- .../core/machine/SimpleMachine.java | 14 +- .../core/generator/QuickRandomPathTest.java | 4 +- .../core/generator/RandomPathTest.java | 4 +- .../SingletonRandomGeneratorTest.java | 43 ++ .../generator/WeightedRandomPathTest.java | 4 +- .../core/machine/MultipleContextTest.java | 115 +++++- .../dsl/generator/GeneratorParser.g4 | 14 +- .../graphwalker/dsl/generator/LogicalLexer.g4 | 4 - .../dsl/antlr/generator/GeneratorLoader.java | 33 +- .../graphwalker/dsl/GeneratorFactoryTest.java | 24 -- .../java/org/graphwalker/dsl/GrammarTest.java | 3 - .../io/factory/json/JsonContextFactory.java | 6 + .../io/factory/json/JsonMultimodel.java | 9 + .../factory/json/JsonContextFactoryTest.java | 9 + .../resources/json/petClinicWithSeed.json | 281 +++++++++++++ .../java/test/TestExecutorTest.java | 385 ++++++++++++++++++ .../java/test/PetClinicWithSeed.json | 345 ++++++++++++++++ pom.xml | 4 +- 23 files changed, 1290 insertions(+), 147 deletions(-) create mode 100644 graphwalker-core/src/main/java/org/graphwalker/core/generator/SingletonRandomGenerator.java create mode 100644 graphwalker-core/src/test/java/org/graphwalker/core/generator/SingletonRandomGeneratorTest.java create mode 100644 graphwalker-io/src/test/resources/json/petClinicWithSeed.json create mode 100644 graphwalker-java/src/test/resources/org/graphwalker/java/test/PetClinicWithSeed.json diff --git a/graphwalker-cli/src/test/resources/json/PetClinicWithSeed.json b/graphwalker-cli/src/test/resources/json/PetClinicWithSeed.json index ba9c32f6d..a83974510 100644 --- a/graphwalker-cli/src/test/resources/json/PetClinicWithSeed.json +++ b/graphwalker-cli/src/test/resources/json/PetClinicWithSeed.json @@ -1,10 +1,11 @@ { "name": "GraphWalker Example Test", + "seed": 16436238642755, "models": [ { "name": "FindOwners", "id": "476fb419-3d7d-4492-802e-6695fe93f595", - "generator": "random(89554871348029, edge_coverage(100))", + "generator": "random(edge_coverage(100))", "vertices": [ { "id": "b53814ec-468c-11e7-a919-92ebcb67fe33", @@ -63,7 +64,7 @@ { "name": "NewOwner", "id": "b23d193c-287a-4eb9-a318-52ead7680ff7", - "generator": "random(89554942549238, edge_coverage(100))", + "generator": "random(edge_coverage(100))", "vertices": [ { "id": "dcb0d798-468c-11e7-a919-92ebcb67fe33", @@ -115,7 +116,7 @@ { "name": "OwnerInformation", "id": "5f1149c3-2853-47e6-838d-691bf30406a8", - "generator": "random(89555008190353, edge_coverage(100))", + "generator": "random(edge_coverage(100))", "actions": [ "numOfPets=0;" ], @@ -228,7 +229,7 @@ { "name": "PetClinic", "id": "3f6b365f-7011-4db6-b0cc-e19aa453d9b8", - "generator": "random(89555075763648, edge_coverage(100))", + "generator": "random(edge_coverage(100))", "vertices": [ { "id": "dcb0dde2-468c-11e7-a919-92ebcb67fe33", @@ -306,7 +307,7 @@ { "name": "Veterinarians", "id": "368a9635-c59a-4285-ad01-cf75b0baa978", - "generator": "random(89555139131399, edge_coverage(100))", + "generator": "random(edge_coverage(100))", "vertices": [ { "id": "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 fc3bd99a5..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 @@ -39,7 +39,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.Random; import static org.graphwalker.core.common.Objects.isNotNull; import static org.graphwalker.core.common.Objects.isNull; @@ -61,19 +60,9 @@ public class QuickRandomPath extends PathGeneratorBase { private static final Logger LOG = LoggerFactory.getLogger(QuickRandomPath.class); private final List elements = new ArrayList<>(); private Element target = null; - private Random random; public QuickRandomPath(StopCondition stopCondition) { setStopCondition(stopCondition); - long seed = System.nanoTime(); - random = new Random(seed); - LOG.info("Seed: " + seed); - } - - public QuickRandomPath(long seed, StopCondition stopCondition) { - setStopCondition(stopCondition); - random = new Random(seed); - LOG.info("Seed: " + seed); } @Override @@ -82,7 +71,7 @@ public Context getNextStep() { if (elements.isEmpty()) { elements.addAll(context.getModel().getElements()); elements.remove(context.getCurrentElement()); - Collections.shuffle(elements, random); + 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 c3eb8cb34..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 @@ -33,7 +33,6 @@ import org.slf4j.LoggerFactory; import java.util.List; -import java.util.Random; /** *

RandomPath

@@ -47,19 +46,9 @@ public class RandomPath extends PathGeneratorBase { private static final Logger LOG = LoggerFactory.getLogger(RandomPath.class); - private Random random; public RandomPath(StopCondition stopCondition) { setStopCondition(stopCondition); - long seed = System.nanoTime(); - random = new Random(seed); - LOG.info("Seed: " + seed); - } - - public RandomPath(long seed, StopCondition stopCondition) { - setStopCondition(stopCondition); - random = new Random(seed); - LOG.info("Seed: " + seed); } @Override @@ -72,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 9323042ce..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 @@ -38,7 +38,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Random; /** *

WeightedRandomPath

@@ -55,19 +54,9 @@ public class WeightedRandomPath extends PathGeneratorBase { private static final Logger LOG = LoggerFactory.getLogger(WeightedRandomPath.class); - private Random random; public WeightedRandomPath(StopCondition stopCondition) { setStopCondition(stopCondition); - long seed = System.nanoTime(); - random = new Random(seed); - LOG.info("Seed: " + seed); - } - - public WeightedRandomPath(long seed, StopCondition stopCondition) { - setStopCondition(stopCondition); - random = new Random(seed); - LOG.info("Seed: " + seed); } @Override @@ -81,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; } @@ -121,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) { 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/generator/QuickRandomPathTest.java b/graphwalker-core/src/test/java/org/graphwalker/core/generator/QuickRandomPathTest.java index ec9fb16f1..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 @@ -110,8 +110,8 @@ public void seededGenerator() { RuntimeEdge BA = findEdge(model, "ba"); Context context = new TestExecutionContext().setModel(model).setNextElement(A); - long seed = 1349327921; - context.setPathGenerator(new QuickRandomPath(seed, new Length(30))); + SingletonRandomGenerator.setSeed(1349327921); + context.setPathGenerator(new QuickRandomPath(new Length(30))); Machine machine = new SimpleMachine(context); List actualPath = new ArrayList(); 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 0547e3638..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 @@ -112,8 +112,8 @@ public void seededGenerator() { RuntimeEdge BA = findEdge(model, "ba"); Context context = new TestExecutionContext().setModel(model).setNextElement(A); - long seed = 1349327921; - context.setPathGenerator(new RandomPath(seed, new Length(30))); + SingletonRandomGenerator.setSeed(1349327921); + context.setPathGenerator(new RandomPath(new Length(30))); Machine machine = new SimpleMachine(context); List actualPath = new ArrayList(); 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 41177e9c6..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 @@ -143,8 +143,8 @@ public void doesNotThrowWhenNoWeightsSpecified() throws Exception { @Test public void seededGenerator() { - long seed = 1349327921; - PathGenerator generator = new WeightedRandomPath(seed, new Length(30)); + SingletonRandomGenerator.setSeed(1349327921); + PathGenerator generator = new WeightedRandomPath(new Length(30)); Context context = new TestExecutionContext(model, generator).setCurrentElement(source.build()); SimpleMachine machine = new SimpleMachine(context); 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 0d96f2bc9..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 @@ -2,6 +2,7 @@ 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; @@ -50,8 +51,9 @@ public void seededMultipleContexts() throws Exception { model2.addEdge(new Edge().setSourceVertex(B2).setTargetVertex(A2).setId("B2A2_1")); model2.addEdge(new Edge().setSourceVertex(B2).setTargetVertex(A2).setId("B2A2_2")); - Context context1 = new TestExecutionContext(model1, new RandomPath(123456789, new EdgeCoverage(100))).setNextElement(A1); - Context context2 = new TestExecutionContext(model2, new RandomPath(987654321, new EdgeCoverage(100))).setNextElement(A2); + 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(); @@ -61,37 +63,108 @@ public void seededMultipleContexts() throws Exception { } 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", - "A", - "ab_2", - "B", - "ba", - "A", - "ab", - "B", - "ba", - "A", - "ab_3", - "B", - "ba", - "A", - "ab_2", - "B", - "ba", - "A", - "ab", - "B" + "A1", + "A2", + "A2B2_1", + "B2" )).toArray(), actualPath.toArray()); } } diff --git a/graphwalker-dsl/src/main/antlr4/org/graphwalker/dsl/generator/GeneratorParser.g4 b/graphwalker-dsl/src/main/antlr4/org/graphwalker/dsl/generator/GeneratorParser.g4 index 6ccad4606..e0ba22f17 100644 --- a/graphwalker-dsl/src/main/antlr4/org/graphwalker/dsl/generator/GeneratorParser.g4 +++ b/graphwalker-dsl/src/main/antlr4/org/graphwalker/dsl/generator/GeneratorParser.g4 @@ -9,17 +9,12 @@ parse ; generator - : Alphanumeric LPAREN parameters RPAREN - | Alphanumeric LPAREN parameters RPAREN RPAREN {notifyErrorListeners("The generator has too many parentheses");} - | Alphanumeric LPAREN parameters {notifyErrorListeners("The generator is missing closing parentheses");} + : Alphanumeric LPAREN logicalExpression RPAREN + | Alphanumeric LPAREN logicalExpression RPAREN RPAREN {notifyErrorListeners("The generator has too many parentheses");} + | Alphanumeric LPAREN logicalExpression {notifyErrorListeners("The generator is missing closing parentheses");} | Alphanumeric {notifyErrorListeners("A generator needs parentheses");} ; -parameters - : ( logicalExpression - | seed COMMA logicalExpression ) - ; - logicalExpression : booleanAndExpression ( OR booleanAndExpression )* ; @@ -39,6 +34,3 @@ stopCondition | Alphanumeric) ; -seed - : Number - ; diff --git a/graphwalker-dsl/src/main/antlr4/org/graphwalker/dsl/generator/LogicalLexer.g4 b/graphwalker-dsl/src/main/antlr4/org/graphwalker/dsl/generator/LogicalLexer.g4 index 9304b72db..f2b51c27d 100644 --- a/graphwalker-dsl/src/main/antlr4/org/graphwalker/dsl/generator/LogicalLexer.g4 +++ b/graphwalker-dsl/src/main/antlr4/org/graphwalker/dsl/generator/LogicalLexer.g4 @@ -16,10 +16,6 @@ RPAREN : ')' ; -COMMA - : ',' - ; - WHITESPACE : [ \t\r\n\u000C]+ -> skip ; 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 d8e18d471..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 @@ -47,7 +47,6 @@ public class GeneratorLoader extends GeneratorParserBaseListener { private StopCondition stopCondition = null; - private Long seed = null; private final List pathGenerators = new ArrayList<>(); private final List stopConditions = new ArrayList<>(); @@ -82,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()))); } } @@ -95,14 +94,6 @@ public void exitLogicalExpression(GeneratorParser.LogicalExpressionContext ctx) } } - @Override - public void exitSeed(GeneratorParser.SeedContext ctx) { - String str = ctx.getChild(0).getText(); - if (str != null && str.length() > 0) { - seed = Long.parseLong(str); - } - } - @Override public void exitGenerator(GeneratorParser.GeneratorContext context) { if (stopConditions.size() == 1) { @@ -110,23 +101,11 @@ public void exitGenerator(GeneratorParser.GeneratorContext context) { } String generatorName = context.getChild(0).getText().toLowerCase(); if ("random".equals(generatorName) || "randompath".equals(generatorName)) { - if (seed == null ) { - pathGenerators.add(new RandomPath(stopCondition)); - } else { - pathGenerators.add(new RandomPath(seed, stopCondition)); - } + pathGenerators.add(new RandomPath(stopCondition)); } else if ("weighted_random".equals(generatorName) || "weightedrandompath".equals(generatorName)) { - if (seed == null ) { - pathGenerators.add(new WeightedRandomPath(stopCondition)); - } else { - pathGenerators.add(new WeightedRandomPath(seed, stopCondition)); - } + pathGenerators.add(new WeightedRandomPath(stopCondition)); } else if ("quick_random".equals(generatorName) || "quickrandom".equals(generatorName) || "quickrandompath".equals(generatorName)) { - if (seed == null ) { - pathGenerators.add(new QuickRandomPath(stopCondition)); - } else { - pathGenerators.add(new QuickRandomPath(seed, stopCondition)); - } + pathGenerators.add(new QuickRandomPath(stopCondition)); } else if ("a_star".equals(generatorName) || "astarpath".equals(generatorName)) { pathGenerators.add(new AStarPath((ReachedStopCondition) stopCondition)); } else if ("shortest_all_paths".equals(generatorName) || "shortestallpaths".equals(generatorName)) { 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 b58d91685..7f3563608 100644 --- a/graphwalker-dsl/src/test/java/org/graphwalker/dsl/GeneratorFactoryTest.java +++ b/graphwalker-dsl/src/test/java/org/graphwalker/dsl/GeneratorFactoryTest.java @@ -310,28 +310,4 @@ public void multipleAlternativeStopConditions() { assertThat(generator.getStopCondition(), instanceOf(AlternativeCondition.class)); assertThat(((AlternativeCondition) generator.getStopCondition()).getStopConditions().size(), is(3)); } - - @Test - public void random_seed_edge_coverage() { - PathGenerator generator = GeneratorFactory.parse("random(123456789, edge_coverage(100))"); - assertThat(generator, instanceOf(RandomPath.class)); - assertThat(generator.getStopCondition(), instanceOf(EdgeCoverage.class)); - assertThat(((EdgeCoverage) generator.getStopCondition()).getPercent(), is(100)); - } - - @Test - public void weighted_random__seed_edge_coverage() { - PathGenerator generator = GeneratorFactory.parse(" weighted_random(123456789, edge_coverage(100))"); - assertThat(generator, instanceOf(WeightedRandomPath.class)); - assertThat(generator.getStopCondition(), instanceOf(EdgeCoverage.class)); - assertThat(((EdgeCoverage) generator.getStopCondition()).getPercent(), is(100)); - } - - @Test - public void quickrandom_seed_edge_coverage() { - PathGenerator generator = GeneratorFactory.parse("quickrandom(89554871348029579, edge_coverage(100))"); - assertThat(generator, instanceOf(QuickRandomPath.class)); - assertThat(generator.getStopCondition(), instanceOf(EdgeCoverage.class)); - assertThat(((EdgeCoverage) generator.getStopCondition()).getPercent(), is(100)); - } } diff --git a/graphwalker-dsl/src/test/java/org/graphwalker/dsl/GrammarTest.java b/graphwalker-dsl/src/test/java/org/graphwalker/dsl/GrammarTest.java index bc10357ab..205949124 100644 --- a/graphwalker-dsl/src/test/java/org/graphwalker/dsl/GrammarTest.java +++ b/graphwalker-dsl/src/test/java/org/graphwalker/dsl/GrammarTest.java @@ -45,12 +45,9 @@ public class GrammarTest { private List generators = Arrays.asList( "random(never)", - "random(123456789, never)", "a_star(never)", "quick_random(never)", - "quick_random(123456789, never)", "weighted_random(vertex_coverage(100))", - "weighted_random(123456789, vertex_coverage(100))", "random(vertex_coverage(100))", "random(edge_coverage(100))", "random(reached_vertex(v_SomeVertex))", 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 ab93c83ca..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 @@ -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/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..47a2204b2 100644 --- a/pom.xml +++ b/pom.xml @@ -167,7 +167,7 @@ junit junit - 4.13-beta-2 + 4.13-rc-1 org.apache.xmlbeans @@ -364,7 +364,7 @@ org.apache.maven.plugins maven-surefire-plugin - classes + suites true From 677a86579caebb042756c8e4f6cfc981c04774d2 Mon Sep 17 00:00:00 2001 From: Kristian Karl Date: Tue, 26 Nov 2019 20:03:06 +0100 Subject: [PATCH 11/11] Remove prallel test execution --- pom.xml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/pom.xml b/pom.xml index 47a2204b2..47f7644f9 100644 --- a/pom.xml +++ b/pom.xml @@ -360,14 +360,6 @@ - - org.apache.maven.plugins - maven-surefire-plugin - - suites - true - - org.apache.maven.plugins maven-enforcer-plugin