/*************************************** * * * JBoss: The OpenSource J2EE WebOS * * * * Distributable under LGPL license. * * See terms of license at gnu.org. * * * ***************************************/ package org.jboss.util.state; import java.util.Set; import java.util.Iterator; import java.util.HashSet; /** * ??? * * @version $Revision: 1.4 $ * @author Jason Dillon */ public class Test { static StateMachine machine = null; static StateMachine.Model originalModel = null; static State NEW = new State(0, "NEW"); static State INITIALIZING = new State(1, "INITIALIZING"); static State INITIALIZED = new State(2, "INITIALIZED"); static State STARTING = new State(3, "STARTING"); static State STARTED = new StateAdapter(4, "STARTED") { public void stateChanged(StateMachine.ChangeEvent event) { startedGotEvent = true; } }; static State FAILED = new StateAdapter(100, "FAILED") { public void stateChanged(StateMachine.ChangeEvent event) { failedGotEvent = true; } }; static State FINAL = new AcceptableState(101, "FINAL") { public boolean isAcceptable(State state) { finalChecking = true; return false; } }; static boolean startedGotEvent = false; static boolean failedGotEvent = false; static boolean finalChecking = false; public static StateMachine.Model makeClone() { StateMachine.Model model = (StateMachine.Model)originalModel.clone(); Assert.assertTrue(model.equals(originalModel), "Clone was mutated"); return model; } private static class Assert { public static void assertTrue(boolean rv) { assertTrue(rv, null); } public static void assertTrue(boolean rv, String msg) { if (!rv && msg != null) { System.out.println(rv + ": " + msg); } else { System.out.println(rv); } } } public static boolean canSerialize(java.io.Serializable obj) { try { org.jboss.util.Objects.copy(obj); return true; } catch (Exception e) { return false; } } public static void main(String[] args) throws Exception { System.out.println("\nTesting data structure equality..."); Assert.assertTrue(new DefaultStateMachineModel().equals(new DefaultStateMachineModel())); Set set; Set setA = new HashSet(); setA.add(FAILED); Set setB = new HashSet(); setB.add(FAILED); Set setC = new HashSet(); setC.add(FAILED); setC.add(NEW); Set setD = new HashSet(); setD.add(FAILED); setD.add(STARTED); setD.add(NEW); DefaultStateMachineModel modelA = new DefaultStateMachineModel(); modelA.addState(NEW); DefaultStateMachineModel modelB = new DefaultStateMachineModel(); modelB.addState(NEW); DefaultStateMachineModel modelC = new DefaultStateMachineModel(); modelC.addState(FINAL); DefaultStateMachineModel modelD = new DefaultStateMachineModel(); modelD.addState(FINAL); modelD.addState(NEW); modelD.setInitialState(FINAL); DefaultStateMachineModel modelA1 = new DefaultStateMachineModel(); modelA1.addState(NEW, setA); DefaultStateMachineModel modelB1 = new DefaultStateMachineModel(); modelB1.addState(NEW, setB); DefaultStateMachineModel modelC1 = new DefaultStateMachineModel(); modelC1.addState(FINAL, setC); DefaultStateMachineModel modelD1 = new DefaultStateMachineModel(); modelD1.addState(FINAL, setD); modelD1.addState(NEW); modelD1.setInitialState(FINAL); DefaultStateMachineModel modelA2 = (DefaultStateMachineModel)modelA1.clone(); DefaultStateMachineModel modelB2 = (DefaultStateMachineModel)modelB1.clone(); DefaultStateMachineModel modelC2 = (DefaultStateMachineModel)modelC1.clone(); DefaultStateMachineModel modelD2 = (DefaultStateMachineModel)modelD1.clone(); Assert.assertTrue(modelA.equals(modelA) == true); Assert.assertTrue(modelA.equals(modelB) == true); Assert.assertTrue(modelB.equals(modelA) == true); Assert.assertTrue(modelA.equals(modelC) != true); Assert.assertTrue(modelA1.equals(modelA1) == true); Assert.assertTrue(modelA1.equals(modelB1) == true); Assert.assertTrue(modelB1.equals(modelA1) == true); Assert.assertTrue(modelA1.equals(modelC1) != true); Assert.assertTrue(modelD1.equals(modelD1) == true); Assert.assertTrue(modelD1.equals(modelA1) != true); Assert.assertTrue(modelA.equals(modelA1) != true); Assert.assertTrue(modelB.equals(modelB1) != true); Assert.assertTrue(modelC.equals(modelC1) != true); Assert.assertTrue(modelD.equals(modelD1) != true); Assert.assertTrue(modelA1.equals(modelA2) == true); Assert.assertTrue(modelB1.equals(modelB2) == true); Assert.assertTrue(modelC1.equals(modelC2) == true); Assert.assertTrue(modelD1.equals(modelD2) == true); modelD.removeState(NEW); System.out.println("\nTesting serializaion..."); Assert.assertTrue(canSerialize(new State(0, ""))); Assert.assertTrue(canSerialize(new StateAdapter(0, ""))); Assert.assertTrue(canSerialize(new AcceptableState(0, "") { public boolean isAcceptable(State state) { return false; } })); Assert.assertTrue(canSerialize(new DefaultStateMachineModel())); System.out.println("\nSetting up model for tests..."); DefaultStateMachineModel model = new DefaultStateMachineModel(); Assert.assertTrue(model.equals(new DefaultStateMachineModel()) == true); Assert.assertTrue(model.equals((StateMachine.Model)model.clone()) == true); set = model.addState(NEW, INITIALIZING); Assert.assertTrue(((set == null) == true), "1"); Assert.assertTrue(model.equals(new DefaultStateMachineModel()) != true); Assert.assertTrue(model.equals((StateMachine.Model)model.clone()) == true); model.addState(INITIALIZING, new State[] { INITIALIZED, FAILED }); model.addState(INITIALIZED, new State[] { STARTING, FAILED }); model.addState(STARTING, INITIALIZED); Assert.assertTrue(model.equals((StateMachine.Model)model.clone()) == true); // test set replacement returns model.addState(STARTED, INITIALIZED); // invalid state set = model.addState(STARTED, STARTING); // this is what we want Assert.assertTrue(set.size() == 1 && set.contains(INITIALIZED)); Assert.assertTrue(model.equals((StateMachine.Model)model.clone()) == true); model.addState(FINAL); Assert.assertTrue(model.equals((StateMachine.Model)model.clone()) == true); Set mostStates = new HashSet(model.states()); mostStates.remove(NEW); // new can only transition to INITIALIZED, not FAILED mostStates.remove(FAILED); // can not accept outselves model.addState(FAILED, mostStates); model.setInitialState(NEW); originalModel = (DefaultStateMachineModel)org.jboss.util.Objects.copy(model); System.out.println("Original model: " + originalModel); System.out.println("\nTesting clonability of model..."); StateMachine.Model aModel; Assert.assertTrue(model.equals(makeClone()) == true); aModel = (StateMachine.Model)model.clone(); Assert.assertTrue(model.equals(aModel) == true); Assert.assertTrue(aModel.equals(model) == true); aModel.clear(); Assert.assertTrue(model.equals(aModel) != true); aModel = (StateMachine.Model)model.clone(); Assert.assertTrue(model.equals(aModel) == true); aModel.removeState(FINAL); Assert.assertTrue(model.equals(aModel) != true); aModel = (StateMachine.Model)model.clone(); Assert.assertTrue(model.equals(aModel) == true); aModel.addState(new State(FINAL.getValue(), "NEW FINAL")); Assert.assertTrue(model.equals(aModel) == true); machine = new StateMachine(makeClone()); System.out.println(machine); System.out.println(); test("new machine"); Assert.assertTrue(finalChecking, "Acceptable State broken"); Assert.assertTrue(startedGotEvent, "ChangeListener broken"); Assert.assertTrue(failedGotEvent, "ChangeListener broken"); machine.reset(); test("reset"); machine = new StateMachine(makeClone()); // System.out.println("Prototype model: " + model); // System.out.println("Machine model: " + machine.getModel()); test("model cloning"); aModel = makeClone(); aModel.removeState(FAILED); // System.out.println("Prototype model: " + model); machine = new StateMachine(aModel); try { test("model cloning with removal"); } catch (IllegalStateException e) { Assert.assertTrue(e.getMessage().equals("State must be STARTING; cannot accept state: FAILED; state=INITIALIZED")); } machine = new StateMachine(makeClone()); // System.out.println("Prototype model states: " + model.states()); test("model cloning after removal"); // test exception handling machine = new StateMachine(makeClone()); // change listener machine.addChangeListener(new StateMachine.ChangeListener() { public void stateChanged(StateMachine.ChangeEvent event) { throw new RuntimeException("ChangeListener"); } }); try { machine.transition(INITIALIZING); Assert.assertTrue(false); // should not make it here } catch (RuntimeException e) { Assert.assertTrue(e.getMessage().equals("ChangeListener")); Assert.assertTrue(machine.getCurrentState().equals(INITIALIZING)); } machine = new StateMachine(makeClone()); // acceptable state State state = new AcceptableState(100, "FAILED") { public boolean isAcceptable(State state) { throw new RuntimeException("Accetable"); } }; // System.out.println("New FAILED state: " + state + "(" + state.toIdentityString() + ")"); aModel = machine.getModel(); // System.out.println("Most states: " + mostStates); set = aModel.addState(state, mostStates); // will replace previous state with same value // System.out.println("Removed states: " + set); // System.out.println("new states: " + aModel.states()); machine.transition(INITIALIZING); Assert.assertTrue(machine.getCurrentState().equals(INITIALIZING)); machine.transition(FAILED); Assert.assertTrue(machine.getCurrentState().equals(FAILED)); try { machine.transition(FINAL); // should not make it here } catch (Exception e) { Assert.assertTrue(e.getMessage().equals("Accetable")); Assert.assertTrue(machine.getCurrentState().equals(FAILED)); } System.out.println("\nDone."); } public static void dumpState(State state) { Set acceptable = machine.getModel().states(); System.out.println(state + " accepts " + acceptable); } public static void dumpStates(Set set) { Iterator iter = set.iterator(); while (iter.hasNext()) { dumpState((State)iter.next()); } } public static void test(String name) { System.out.println("\nTesting " + name + "..."); StateMachine.Model model = machine.getModel(); // System.out.println("Using model: " + model); Assert.assertTrue(model.getInitialState().equals(NEW)); Assert.assertTrue(machine.getCurrentState().equals(NEW)); // dumpStates(machine.getModel().states()); // dumpState(); // try some valid state changes machine.transition(INITIALIZING); Assert.assertTrue(machine.getCurrentState().equals(INITIALIZING)); machine.transition(INITIALIZED); Assert.assertTrue(machine.getCurrentState().equals(INITIALIZED)); // now for an invalid state change try { machine.transition(NEW); Assert.assertTrue(false); } catch (IllegalStateException e) { Assert.assertTrue(machine.getCurrentState().equals(INITIALIZED)); } // now for an invalid when we are in a final state machine.transition(FAILED); Assert.assertTrue(machine.getCurrentState().equals(FAILED)); machine.transition(FINAL); Assert.assertTrue(machine.getCurrentState().equals(FINAL)); try { machine.transition(NEW); Assert.assertTrue(false); } catch (IllegalStateException e) { Assert.assertTrue(machine.getCurrentState().equals(FINAL)); } } public static void dumpState() { System.out.print("Current state: "); dumpState(machine.getCurrentState()); } }