Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -258,8 +258,9 @@ public <E> List<E> filter(Collection<E> elements) {

public boolean isAvailable(RuntimeEdge edge) {
if (edge.hasGuard()) {
LOG.debug("Execute: '{}' in model: '{}'", edge.getGuard().getScript(), getModel().getName());
LOG.debug("Execute guard: '{}' in model: '{}'", edge.getGuard().getScript(), getModel().getName());
try {
LOG.debug("Guard: '{}' is: '{}'", edge.getGuard().getScript(), getScriptEngine().eval(edge.getGuard().getScript()));
return (Boolean) getScriptEngine().eval(edge.getGuard().getScript());
} catch (ScriptException e) {
LOG.error(e.getMessage());
Expand All @@ -270,17 +271,18 @@ public boolean isAvailable(RuntimeEdge edge) {
}

public void execute(Action action) {
LOG.debug("Execute: '{}' in model: '{}'", action.getScript(), getModel().getName());
LOG.debug("Execute action: '{}' in model: '{}'", action.getScript(), getModel().getName());
try {
getScriptEngine().eval(action.getScript());
} catch (ScriptException e) {
LOG.error(e.getMessage());
throw new MachineException(this, e);
}
LOG.debug("Data: '{}'", getKeys().toString());
}

public void execute(String name) {
LOG.debug("Execute: '{}' in model: '{}'", name, getModel().getName());
LOG.debug("Execute method: '{}' in model: '{}'", name, getModel().getName());
try {
getClass().getMethod(name); // provoke a NoSuchMethodException exception if the method doesn't exist
getScriptEngine().eval(name + "()");
Expand Down Expand Up @@ -310,9 +312,24 @@ public Map<String, String> getKeys() {
}
}
}
} else {
for (String key : getBindings(ENGINE_SCOPE).keySet()) {
}

if (getBindings(ENGINE_SCOPE).containsKey("global")) {
Map<String, Object> global = (Map<String, Object>) getBindings(ENGINE_SCOPE).get("global");
for (String key : global.keySet()) {
if (isVariable(key, methods)) {
if (global.get(key) instanceof Double) {
keys.put(key, Long.toString(Math.round((double) global.get(key))));
} else {
keys.put(key, global.get(key).toString());
}
}
}
}

if (keys.isEmpty()) {
for (String key : getBindings(ENGINE_SCOPE).keySet()) {
if (!"nashorn.global".equals(key) && !"global".equals(key) && isVariable(key, methods)) {
Object value = getBindings(ENGINE_SCOPE).get(key);
if (value instanceof Double) {
keys.put(key, Long.toString(Math.round((double) value)));
Expand All @@ -337,7 +354,7 @@ public Object getAttribute(String name) {

@SuppressWarnings("unchecked")
public void setAttribute(String name, Object value) {
if (getBindings(ENGINE_SCOPE).containsKey("nashorn.global")) {
if (getBindings(ENGINE_SCOPE).containsKey("global")) {
Map<String, Object> attributes = (Map<String, Object>) getBindings(ENGINE_SCOPE).get("nashorn.global");
attributes.put(name, value);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import org.graphwalker.core.generator.NoPathFoundException;
import org.graphwalker.core.generator.SingletonRandomGenerator;
import org.graphwalker.core.model.Action;
import org.graphwalker.core.model.Edge;
import org.graphwalker.core.model.Element;
import org.graphwalker.core.model.Requirement;
import org.slf4j.Logger;
Expand Down Expand Up @@ -212,12 +213,12 @@ private boolean hasPossibleSharedStates(RuntimeVertex vertex) {
private List<SharedStateTuple> getPossibleSharedStates(String sharedState) {
List<SharedStateTuple> sharedStates = new ArrayList<>();
for (Context context : getContexts()) {
if (getCurrentContext().equals(context) && hasOutEdges(context)) {
if (getCurrentContext().equals(context) && hasAccessibleOutEdges(context, context.getCurrentElement())) {
sharedStates.add(new SharedStateTuple(getCurrentContext(), (RuntimeVertex) getCurrentContext().getCurrentElement()));
} 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())) {
if ((!vertex.equals(lastElement) || !hasAccessibleOutEdges(getCurrentContext(), getCurrentContext().getCurrentElement()))
&& (vertex.hasName() || hasAccessibleOutEdges(context, vertex))) {
sharedStates.add(new SharedStateTuple(context, vertex));
}
}
Expand All @@ -226,10 +227,21 @@ private List<SharedStateTuple> getPossibleSharedStates(String sharedState) {
return sharedStates;
}

private boolean hasOutEdges(Context context) {
return isNotNull(context.getCurrentElement())
&& context.getCurrentElement() instanceof RuntimeVertex
&& !context.getModel().getOutEdges((RuntimeVertex) context.getCurrentElement()).isEmpty();
private boolean hasAccessibleOutEdges(Context context, Element element) {
if (isNull(element)) {
return false;
}

if (element instanceof RuntimeEdge) {
return false;
}

for (RuntimeEdge edge : context.getModel().getOutEdges((RuntimeVertex) element)) {
if (context.isAvailable(edge)) {
return true;
}
}
return false;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import org.graphwalker.core.generator.AStarPath;
import org.graphwalker.core.generator.RandomPath;
import org.graphwalker.core.generator.ShortestAllPaths;
import org.graphwalker.core.generator.SingletonRandomGenerator;
import org.graphwalker.core.model.Action;
import org.graphwalker.core.model.Edge;
import org.graphwalker.core.model.Element;
Expand Down Expand Up @@ -191,6 +192,50 @@ public void sharedState() throws Exception {
assertThat(expectedPath, is(path));
}

@Test
public void sharedStateWithUnaccessibleEdge() throws Exception {
SingletonRandomGenerator.setSeed(147945811993279L);

Vertex v1_A = new Vertex().setName("v1_A");
Vertex v2_A = new Vertex().setSharedState("MyState").setName("v2_A");
Edge e1_A = new Edge().setSourceVertex(v1_A).setTargetVertex(v2_A).setName("e1_A");
Edge e2_A = new Edge().setSourceVertex(v2_A).setTargetVertex(v1_A).addAction(new Action("global.available = true")).setName("e2_A");

Vertex v1_B = new Vertex().setSharedState("MyState").setName("v1_B");
Vertex v2_B = new Vertex().setName("v2_B");
Edge e1_B = new Edge().setSourceVertex(v1_B).setTargetVertex(v2_B).setGuard(new Guard("global.available == true"));

Model m1 = new Model().addEdge(e1_A).addEdge(e2_A).addAction(new Action("global.available = false")).setName("m1");;
Model m2 = new Model().addEdge(e1_B).setName("m2");

List<Context> contexts = new ArrayList<>();
contexts.add(new TestExecutionContext(m1, new RandomPath(new VertexCoverage(100))).setNextElement(v1_A));
contexts.add(new TestExecutionContext(m2, new RandomPath(new VertexCoverage(100))));

Machine machine = new SimpleMachine(contexts);
while (machine.hasNextStep()) {
machine.getNextStep();
}

List<Element> expectedPath = Arrays.<Element>asList(
v1_A.build(),
e1_A.build(),
v2_A.build(),
v1_B.build(),
v2_A.build(),
e2_A.build(),
v1_A.build(),
e1_A.build(),
v2_A.build(),
v1_B.build(),
e1_B.build(),
v2_B.build());

List<Element> path = machine.getProfiler().getExecutionPath().stream()
.map(Execution::getElement).collect(Collectors.toList());
assertThat(expectedPath, is(path));
}

@Test(expected = MachineException.class)
public void singleSharedStates() throws Exception {
Vertex start = new Vertex();
Expand Down