blob: 231e4a1089e0c9ec617851a7fc4dd5d197b3c1b4 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2013 Boeing.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Boeing - initial API and implementation
*******************************************************************************/
package org.eclipse.ote.statemachine;
import org.junit.Assert;
import org.junit.Test;
public class StateMachineTest {
@Test
public void test() throws Exception {
StateMachine sm = new StateMachine("Stoplight");
Green green = new Green();
Red red = new Red();
Yellow yellow = new Yellow();
Change change = new Change(sm, Object.class);
sm.newTransition(green, change, yellow);
sm.newTransition(yellow, change, red);
sm.newTransition(red, change, green);
sm.setDefaultInitialState(red);
sm.initialize();
Assert.assertEquals(red, sm.getCurrentState());
sm.addToQueue(change);
sm.processInput();
Assert.assertEquals(green, sm.getCurrentState());
sm.addToQueue(change);
sm.processInput();
Assert.assertEquals(yellow, sm.getCurrentState());
sm.addToQueue(change);
sm.processInput();
Assert.assertEquals(red, sm.getCurrentState());
sm.stop();
}
@Test
public void testTransitionTableConflict() throws Exception {
StateMachine sm = new StateMachine("Stoplight");
Green green = new Green();
Red red = new Red();
Yellow yellow = new Yellow();
Change change = new Change(sm, Object.class);
sm.newTransition(red, change, green);
sm.newTransition(green, change, yellow);
sm.newTransition(yellow, change, red);
try{
sm.newTransition(red, change, yellow);
Assert.fail();
} catch (Exception ex){
}
sm.stop();
}
@Test
public void testWaits() throws Exception {
final StateMachine sm = new StateMachine("Stoplight");
Green green = new Green();
Red red = new Red();
Yellow yellow = new Yellow();
Change change = new Change(sm, Object.class);
sm.setDefaultInitialState(red);
sm.newTransition(green, change, yellow);
sm.newTransition(yellow, change, red);
sm.newTransition(red, change, green);
sm.initialize();
sm.start();
Assert.assertTrue(!sm.waitForCompletion(100));
sm.stop();
Assert.assertTrue(sm.waitForCompletion(100));
sm.start();
Assert.assertTrue(!sm.waitForCompletion(100));
sm.murder();
sm.waitForCompletion();
sm.resetToInitialState();
sm.start();
red.submitDelayedInput(change, 50);
Assert.assertEquals(red, sm.getCurrentState());
Thread.sleep(100);
Assert.assertEquals(green, sm.getCurrentState());
red.submitDelayedInput(change, 50);
Thread.sleep(10);
red.cancelDelayedInputs();
Thread.sleep(100);
Assert.assertEquals(green, sm.getCurrentState());
sm.stop();
Thread.sleep(10);
Assert.assertTrue(sm.waitForCompletion(100));
sm.start();
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
sm.stop();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
sm.waitForCompletion();
}
@Test
public void hierarchyTest() throws Exception{
StateMachine parent = new StateMachine("Stoplight");
Green green = new Green();
Red red = new Red();
Yellow yellow = new Yellow();
Change change = new Change(parent, Object.class);
Change internalExit = new Change(parent, Integer.class);
Change internalExit2 = new Change(parent, Integer.class);
ChildStateMachineState child = new Hierarchy(parent);
//begin hier 2
ChildStateMachineState grandchild = new Hierarchy(parent);
Blue blud2 = new Blue();
Purple purple2 = new Purple(internalExit2);
grandchild.setDefaultInitialState(blud2);
grandchild.newTransition(blud2, change, purple2);
grandchild.newTransition(purple2, change, blud2);
//end hier 2
// Begin hier 1
Blue blud = new Blue();
Purple purple = new Purple(internalExit);
child.setDefaultInitialState(blud);
child.newTransition(grandchild, internalExit2, purple);
child.newTransition(blud, change, grandchild);
child.newTransition(purple, change, blud);
// end hier 1
// begin master machine
parent.setDefaultInitialState(green);
parent.newTransition(green, change, yellow);
parent.newTransition(yellow, change, red);
parent.newTransition(red, change, child);
parent.newTransition(child, internalExit, green);
parent.initialize();
// end master machine
parent.addToQueue(change);
Assert.assertEquals(1, parent.queueSize());
parent.processInput();
Assert.assertEquals(yellow, parent.getCurrentState());
parent.addToQueue(change);
Assert.assertEquals(1, parent.queueSize());
parent.processInput();
Assert.assertEquals(red, parent.getCurrentState());
parent.addToQueue(change);
Assert.assertEquals(1, parent.queueSize());
parent.processInput();
Assert.assertEquals(child, parent.getCurrentState());
Assert.assertEquals(blud, ((Hierarchy)child).getCurrentState());
parent.addToQueue(change);
Assert.assertEquals(1, parent.queueSize());
parent.processInput();
Assert.assertEquals(child, parent.getCurrentState());
Assert.assertEquals(grandchild, ((Hierarchy)child).getCurrentState());
Assert.assertEquals(blud2, ((Hierarchy)grandchild).getCurrentState());
parent.addToQueue(change);
Assert.assertEquals(1, parent.queueSize());
parent.processInput();
Assert.assertEquals(purple2, ((Hierarchy)grandchild).getCurrentState());
Assert.assertEquals(grandchild, ((Hierarchy)child).getCurrentState());
Assert.assertEquals(child, parent.getCurrentState());
parent.addToQueue(change);
Assert.assertEquals(1, parent.queueSize());
parent.processInput();
Assert.assertEquals(blud2, ((Hierarchy)grandchild).getCurrentState());
Assert.assertEquals(grandchild, ((Hierarchy)child).getCurrentState());
Assert.assertEquals(child, parent.getCurrentState());
Assert.assertEquals(1, parent.queueSize());
parent.processInput();
Assert.assertEquals(blud2, ((Hierarchy)grandchild).getCurrentState());
Assert.assertEquals(purple, ((Hierarchy)child).getCurrentState());
Assert.assertEquals(child, parent.getCurrentState());
parent.addToQueue(change);
Assert.assertEquals(1, parent.queueSize());
parent.processInput();
Assert.assertEquals(blud2, ((Hierarchy)grandchild).getCurrentState());
Assert.assertEquals(blud, ((Hierarchy)child).getCurrentState());
Assert.assertEquals(child, parent.getCurrentState());
Assert.assertEquals(1, parent.queueSize());
parent.processInput();
Assert.assertEquals(green, parent.getCurrentState());
parent.addToQueue(change);
Assert.assertEquals(1, parent.queueSize());
parent.processInput();
Assert.assertEquals(yellow, parent.getCurrentState());
parent.stop();
}
@Test
public void hierarchyTestInThread() throws Exception{
StateMachine parent = new StateMachine("Stoplight", true);
Green green = new Green("green");
Red red = new Red("red");
Yellow yellow = new Yellow("yellow");
Change change = new Change(parent, Object.class, "change");
Change internalExit = new Change(parent, Integer.class, "internalExit1");
Change internalExit2 = new Change(parent, Integer.class, "internalExit2");
ChildStateMachineState child = new Hierarchy(parent, "child");
//begin hier 2
ChildStateMachineState grandchild = new Hierarchy(parent, "grandchild");
Blue blud2 = new Blue("blud2");
Purple purple2 = new Purple(internalExit2, "purple2");
grandchild.setDefaultInitialState(blud2);
grandchild.newTransition(blud2, change, purple2);
grandchild.newTransition(purple2, change, blud2);
//end hier 2
// Begin hier 1
Blue blud = new Blue("blud");
Purple purple = new Purple(internalExit, "purple");
child.setDefaultInitialState(blud);
child.newTransition(grandchild, internalExit2, purple);
child.newTransition(blud, change, grandchild);
child.newTransition(purple, change, blud);
// end hier 1
// begin master machine
parent.setDefaultInitialState(green);
parent.newTransition(green, change, yellow);
parent.newTransition(yellow, change, red);
parent.newTransition(red, change, child);
parent.newTransition(child, internalExit, green);
parent.initialize();
// end master machine
parent.addToQueue(change);
parent.processUntilEmpty();
Assert.assertEquals(yellow, parent.getCurrentState());
parent.addToQueue(change);
parent.processUntilEmpty();
Assert.assertEquals(red, parent.getCurrentState());
parent.addToQueue(change);
parent.processUntilEmpty();
Assert.assertEquals(child, parent.getCurrentState());
Assert.assertEquals(blud, ((Hierarchy)child).getCurrentState());
parent.addToQueue(change);
parent.processUntilEmpty();
Assert.assertEquals(child, parent.getCurrentState());
Assert.assertEquals(grandchild, ((Hierarchy)child).getCurrentState());
Assert.assertEquals(blud2, ((Hierarchy)grandchild).getCurrentState());
parent.addToQueue(change);
parent.processUntilEmpty();
Assert.assertEquals(child, parent.getCurrentState());
Assert.assertEquals(grandchild, ((Hierarchy)child).getCurrentState());
Assert.assertEquals(purple2, ((Hierarchy)grandchild).getCurrentState());
parent.addToQueue(change);
parent.processUntilEmpty();
Assert.assertEquals(child, parent.getCurrentState());
Assert.assertEquals(purple, ((Hierarchy)child).getCurrentState());
Assert.assertEquals(blud2, ((Hierarchy)grandchild).getCurrentState());
parent.addToQueue(change);
parent.processUntilEmpty();
Assert.assertEquals(green, parent.getCurrentState());
Assert.assertEquals(blud2, ((Hierarchy)grandchild).getCurrentState());
Assert.assertEquals(blud, ((Hierarchy)child).getCurrentState());
parent.addToQueue(change);
parent.processUntilEmpty();
Assert.assertEquals(yellow, parent.getCurrentState());
parent.stop();
}
private static class ChildStateMachine {
private Blue blue;
private Change internalExit;
private Purple purple;
private Hierarchy child;
private GrandChildStateMachine grandChild;
public ChildStateMachine(StateMachine parent, GrandChildStateMachine grandChild, Change change) throws Exception{
this.grandChild = grandChild;
internalExit = new Change(parent, Integer.class);
child = new Hierarchy(parent);
blue = new Blue();
purple = new Purple(internalExit);
child.setDefaultInitialState(blue);
child.newTransition(blue, change, grandChild.get());
child.newTransition(grandChild.get(), grandChild.getExitInput(), purple);
child.newTransition(purple, change, blue);
}
public ChildStateMachineState get(){
return child;
}
public BaseInput getExitInput(){
return internalExit;
}
public BaseState getBlue() {
return blue;
}
public BaseState getCurrentState() {
return child.getCurrentState();
}
public BaseState getGrandchild() {
return grandChild.get();
}
public BaseState getPurple() {
return purple;
}
}
private static class GrandChildStateMachine {
private Hierarchy grandchild;
private Blue blue;
private Purple purple;
private Change internalExit;
public GrandChildStateMachine(StateMachine parent, Change change) throws Exception{
grandchild = new Hierarchy(parent);
internalExit = new Change(parent, Integer.class);
blue = new Blue();
purple = new Purple(internalExit);
grandchild.setDefaultInitialState(blue);
grandchild.newTransition(blue, change, purple);
grandchild.newTransition(purple, change, blue);
}
public ChildStateMachineState get(){
return grandchild;
}
public BaseInput getExitInput(){
return internalExit;
}
public BaseState getBlue() {
return blue;
}
public BaseState getCurrentState() {
return grandchild.getCurrentState();
}
public BaseState getPurple() {
return purple;
}
}
private static class ParentStateMachine {
private Green green;
private Red red;
private Yellow yellow;
private StateMachine parent;
private ChildStateMachine child;
public ParentStateMachine(StateMachine parent, ChildStateMachine child, Change change) throws Exception{
this.parent = parent;
this.child = child;
green = new Green();
red = new Red();
yellow = new Yellow();
parent.setDefaultInitialState(green);
parent.newTransition(green, change, yellow);
parent.newTransition(yellow, change, red);
parent.newTransition(red, change, child.get());
parent.newTransition(child.get(), child.getExitInput(), green);
}
public BaseState getYellow() {
return yellow;
}
public BaseState getRed() {
return red;
}
public BaseState getCurrentState() {
return parent.getCurrentState();
}
public BaseState getGreen() {
return green;
}
public Object getChild() {
return child.get();
}
}
@Test
public void hierarchyTestAsClasses() throws Exception{
StateMachine masterStateMachine = new StateMachine("Stoplight");
Change change = new Change(masterStateMachine, Object.class);
GrandChildStateMachine grandChild = new GrandChildStateMachine(masterStateMachine, change);
ChildStateMachine child = new ChildStateMachine(masterStateMachine, grandChild, change);
ParentStateMachine parent = new ParentStateMachine(masterStateMachine, child, change);
masterStateMachine.initialize();
masterStateMachine.addToQueue(change);
Assert.assertEquals(1, masterStateMachine.queueSize());
masterStateMachine.processInput();
Assert.assertEquals(parent.getYellow(), parent.getCurrentState());
masterStateMachine.addToQueue(change);
Assert.assertEquals(1, masterStateMachine.queueSize());
masterStateMachine.processInput();
Assert.assertEquals(parent.getRed(), parent.getCurrentState());
masterStateMachine.addToQueue(change);
Assert.assertEquals(1, masterStateMachine.queueSize());
masterStateMachine.processInput();
Assert.assertEquals(child.get(), parent.getCurrentState());
Assert.assertEquals(child.getBlue(), child.getCurrentState());
masterStateMachine.addToQueue(change);
Assert.assertEquals(1, masterStateMachine.queueSize());
masterStateMachine.processInput();
Assert.assertEquals(child.get(), parent.getCurrentState());
Assert.assertEquals(child.getGrandchild(), child.getCurrentState());
Assert.assertEquals(grandChild.getBlue(), grandChild.getCurrentState());
masterStateMachine.addToQueue(change);
Assert.assertEquals(1, masterStateMachine.queueSize());
masterStateMachine.processInput();
Assert.assertEquals(grandChild.getPurple(), grandChild.getCurrentState());
Assert.assertEquals(child.getGrandchild(), child.getCurrentState());
Assert.assertEquals(child.get(), parent.getCurrentState());
masterStateMachine.addToQueue(change);
Assert.assertEquals(1, masterStateMachine.queueSize());
masterStateMachine.processInput();
Assert.assertEquals(grandChild.getBlue(),grandChild.getCurrentState());
Assert.assertEquals(child.getGrandchild(), child.getCurrentState());
Assert.assertEquals(child.get(), parent.getCurrentState());
Assert.assertEquals(1, masterStateMachine.queueSize());
masterStateMachine.processInput();
Assert.assertEquals(grandChild.getBlue(), grandChild.getCurrentState());
Assert.assertEquals(child.getPurple(), child.getCurrentState());
Assert.assertEquals(child.get(), parent.getCurrentState());
masterStateMachine.addToQueue(change);
Assert.assertEquals(1, masterStateMachine.queueSize());
masterStateMachine.processInput();
Assert.assertEquals(grandChild.getBlue(), grandChild.getCurrentState());
Assert.assertEquals(child.getBlue(), child.getCurrentState());
Assert.assertEquals(parent.getChild(), parent.getCurrentState());
Assert.assertEquals(1, masterStateMachine.queueSize());
masterStateMachine.processInput();
Assert.assertEquals(parent.getGreen(), parent.getCurrentState());
masterStateMachine.addToQueue(change);
Assert.assertEquals(1, masterStateMachine.queueSize());
masterStateMachine.processInput();
Assert.assertEquals(parent.getYellow(), parent.getCurrentState());
masterStateMachine.stop();
}
}