diff --git a/spring-statemachine-test/src/main/java/org/springframework/statemachine/test/StateMachineTestPlan.java b/spring-statemachine-test/src/main/java/org/springframework/statemachine/test/StateMachineTestPlan.java index 4e35abfc..93682079 100644 --- a/spring-statemachine-test/src/main/java/org/springframework/statemachine/test/StateMachineTestPlan.java +++ b/spring-statemachine-test/src/main/java/org/springframework/statemachine/test/StateMachineTestPlan.java @@ -101,7 +101,8 @@ public class StateMachineTestPlan { step.expectTransitionStarted != null ? step.expectTransitionStarted : 0, step.expectTransitionEnded != null ? step.expectTransitionEnded : 0, step.expectStateMachineStarted != null ? step.expectStateMachineStarted : 0, - step.expectStateMachineStopped != null ? step.expectStateMachineStopped : 0); + step.expectStateMachineStopped != null ? step.expectStateMachineStopped : 0, + step.expectExtendedStateChanged != null ? step.expectExtendedStateChanged : 0); } if (step.expectStateMachineStarted != null) { @@ -212,6 +213,13 @@ public class StateMachineTestPlan { } } + if (step.expectExtendedStateChanged != null) { + for (LatchStateMachineListener listener : listeners.values()) { + assertThat(listener.getExtendedStateChangedLatch().await(defaultAwaitTime, TimeUnit.SECONDS), is(true)); + assertThat(listener.getExtendedStateChanged().size(), is(step.expectExtendedStateChanged)); + } + } + if (!step.expectVariableKeys.isEmpty()) { for (StateMachine stateMachine : stateMachines.values()) { Map variables = stateMachine.getExtendedState().getVariables(); diff --git a/spring-statemachine-test/src/main/java/org/springframework/statemachine/test/StateMachineTestPlanBuilder.java b/spring-statemachine-test/src/main/java/org/springframework/statemachine/test/StateMachineTestPlanBuilder.java index d3987b30..a3cb01b8 100644 --- a/spring-statemachine-test/src/main/java/org/springframework/statemachine/test/StateMachineTestPlanBuilder.java +++ b/spring-statemachine-test/src/main/java/org/springframework/statemachine/test/StateMachineTestPlanBuilder.java @@ -124,6 +124,7 @@ public class StateMachineTestPlanBuilder { Integer expectTransitionEnded; Integer expectStateMachineStarted; Integer expectStateMachineStopped; + Integer expectExtendedStateChanged; final Collection expectVariableKeys = new ArrayList(); final Map expectVariables = new HashMap(); @@ -381,6 +382,21 @@ public class StateMachineTestPlanBuilder { return this; } + /** + * Expect state machine extended state variables changing {@code count} times. + * + * @param count the count + * @return the state machine test plan step builder + */ + public StateMachineTestPlanStepBuilder expectExtendedStateChanged(int count) { + if (count < 0) { + throw new IllegalArgumentException("Expected count cannot be negative, was " + count); + } + this.expectExtendedStateChanged = count; + return this; + } + + /** * Add a new step and return {@link StateMachineTestPlanBuilder} * for chaining. @@ -391,7 +407,7 @@ public class StateMachineTestPlanBuilder { steps.add(new StateMachineTestPlanStep(sendEvent, sendMessage, sendEventMachineId, sendEventToAll, expectStates, expectStateChanged, expectStateEntered, expectStateExited, expectEventNotAccepted, expectTransition, expectTransitionStarted, expectTransitionEnded, expectStateMachineStarted, - expectStateMachineStopped, expectVariableKeys, expectVariables)); + expectStateMachineStopped, expectVariableKeys, expectVariables, expectExtendedStateChanged)); return StateMachineTestPlanBuilder.this; } @@ -412,6 +428,7 @@ public class StateMachineTestPlanBuilder { Integer expectTransitionEnded; Integer expectStateMachineStarted; Integer expectStateMachineStopped; + Integer expectExtendedStateChanged; final Collection expectVariableKeys; final Map expectVariables; @@ -420,7 +437,7 @@ public class StateMachineTestPlanBuilder { Integer expectStateEntered, Integer expectStateExited, Integer expectEventNotAccepted, Integer expectTransition, Integer expectTransitionStarted, Integer expectTransitionEnded, Integer expectStateMachineStarted, Integer expectStateMachineStopped, - Collection expectVariableKeys, Map expectVariables) { + Collection expectVariableKeys, Map expectVariables, Integer expectExtendedStateChanged) { this.sendEvent = sendEvent; this.sendMessage = sendMessage; this.sendEventMachineId = sendEventMachineId; @@ -437,6 +454,7 @@ public class StateMachineTestPlanBuilder { this.expectStateMachineStopped = expectStateMachineStopped; this.expectVariableKeys = expectVariableKeys; this.expectVariables = expectVariables; + this.expectExtendedStateChanged = expectExtendedStateChanged; } } diff --git a/spring-statemachine-test/src/main/java/org/springframework/statemachine/test/support/LatchStateMachineListener.java b/spring-statemachine-test/src/main/java/org/springframework/statemachine/test/support/LatchStateMachineListener.java index 7e1df2b7..645ae07b 100644 --- a/spring-statemachine-test/src/main/java/org/springframework/statemachine/test/support/LatchStateMachineListener.java +++ b/spring-statemachine-test/src/main/java/org/springframework/statemachine/test/support/LatchStateMachineListener.java @@ -48,6 +48,7 @@ public class LatchStateMachineListener extends StateMachineListenerAdapter private volatile CountDownLatch transitionEndedLatch = new CountDownLatch(1); private volatile CountDownLatch stateMachineStartedLatch = new CountDownLatch(1); private volatile CountDownLatch stateMachineStoppedLatch = new CountDownLatch(1); + private volatile CountDownLatch extendedStateChangedLatch = new CountDownLatch(1); private final List> stateChanged = new ArrayList>(); private final List> stateEntered = new ArrayList>(); @@ -58,6 +59,7 @@ public class LatchStateMachineListener extends StateMachineListenerAdapter private final List> transitionEnded = new ArrayList>(); private final List> stateMachineStarted = new ArrayList>(); private final List> stateMachineStopped = new ArrayList>(); + private final List extendedStateChanged = new ArrayList(); @Override public void stateChanged(State from, State to) { @@ -131,9 +133,17 @@ public class LatchStateMachineListener extends StateMachineListenerAdapter } } + @Override + public void extendedStateChanged(Object key, Object value) { + synchronized (lock) { + this.extendedStateChanged.add(new ExtendedStateChangedWrapper(key, value)); + this.extendedStateChangedLatch.countDown(); + } + } + public void reset(int stateChangedCount, int stateEnteredCount, int stateExitedCount, int eventNotAcceptedCount, int transitionCount, int transitionStartedCount, int transitionEndedCount, int stateMachineStartedCount, - int stateMachineStoppedCount) { + int stateMachineStoppedCount, int extendedStateChangedCount) { synchronized (lock) { this.stateChangedLatch = new CountDownLatch(stateChangedCount); this.stateEnteredLatch = new CountDownLatch(stateEnteredCount); @@ -144,6 +154,7 @@ public class LatchStateMachineListener extends StateMachineListenerAdapter this.transitionEndedLatch = new CountDownLatch(transitionEndedCount); this.stateMachineStartedLatch = new CountDownLatch(stateMachineStartedCount); this.stateMachineStoppedLatch = new CountDownLatch(stateMachineStoppedCount); + this.extendedStateChangedLatch = new CountDownLatch(extendedStateChangedCount); this.stateChanged.clear(); this.stateEntered.clear(); this.stateExited.clear(); @@ -153,6 +164,7 @@ public class LatchStateMachineListener extends StateMachineListenerAdapter this.transitionEnded.clear(); this.stateMachineStarted.clear(); this.stateMachineStopped.clear(); + this.extendedStateChanged.clear(); } } @@ -192,6 +204,10 @@ public class LatchStateMachineListener extends StateMachineListenerAdapter return stateMachineStoppedLatch; } + public CountDownLatch getExtendedStateChangedLatch() { + return extendedStateChangedLatch; + } + public List> getStateChanged() { return stateChanged; } @@ -228,6 +244,10 @@ public class LatchStateMachineListener extends StateMachineListenerAdapter return stateMachineStopped; } + public List getExtendedStateChanged() { + return extendedStateChanged; + } + public static class StateChangedWrapper { final State from; final State to; @@ -239,4 +259,15 @@ public class LatchStateMachineListener extends StateMachineListenerAdapter } + public static class ExtendedStateChangedWrapper { + final Object key; + final Object value; + + public ExtendedStateChangedWrapper(Object key, Object value) { + this.key = key; + this.value = value; + } + + } + } diff --git a/spring-statemachine-zookeeper/src/test/java/org/springframework/statemachine/zookeeper/ZookeeperStateMachineTests.java b/spring-statemachine-zookeeper/src/test/java/org/springframework/statemachine/zookeeper/ZookeeperStateMachineTests.java index 48b5f47b..20bf2786 100644 --- a/spring-statemachine-zookeeper/src/test/java/org/springframework/statemachine/zookeeper/ZookeeperStateMachineTests.java +++ b/spring-statemachine-zookeeper/src/test/java/org/springframework/statemachine/zookeeper/ZookeeperStateMachineTests.java @@ -374,6 +374,7 @@ public class ZookeeperStateMachineTests extends AbstractZookeeperTests { .step() .sendEvent(message, machine1) .expectTransition(1) + .expectExtendedStateChanged(1) .expectVariable("testVariable", "x1") .and() .build();