Tune tests, modify web sample, add more logging

- In web sample change other event C to K which brings
  machine back from S2 to S1.
- Add more logging.
- New test sending parallel events.
This commit is contained in:
Janne Valkealahti
2015-08-21 12:57:47 +01:00
parent ad3c082670
commit 99275380c3
6 changed files with 152 additions and 13 deletions

View File

@@ -108,7 +108,7 @@ public class StateMachineConfig {
.source(States.S1).target(States.S2).event(Events.C)
.and()
.withExternal()
.source(States.S2).target(States.S1).event(Events.C)
.source(States.S2).target(States.S1).event(Events.K)
.and()
.withExternal()
.source(States.S1).target(States.S0).event(Events.D)
@@ -201,7 +201,7 @@ public class StateMachineConfig {
}
public static enum Events {
A, B, C, D, E, F, G, H, I, J
A, B, C, D, E, F, G, H, I, J, K
}
private static class FooAction implements Action<States, Events> {

View File

@@ -33,6 +33,7 @@
<button ng-click="sendEvent('G')">event G</button>
<button ng-click="sendEvent('H')">event H</button>
<button ng-click="sendEvent('I')">event I</button>
<button ng-click="sendEvent('K')">event K</button>
</div>
</div>
<div class="row">

View File

@@ -28,6 +28,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import org.apache.commons.logging.Log;
@@ -124,9 +125,13 @@ public class StateMachineTestPlan<S, E> {
sendVia.add(stateMachines.values().iterator().next());
}
assertThat("Error finding machine to send via", sendVia, not(empty()));
for (StateMachine<S, E> machine : sendVia) {
log.info("Sending test event " + step.sendEvent + " via machine " + machine);
machine.sendEvent(step.sendEvent);
if (!step.sendEventParallel) {
for (StateMachine<S, E> machine : sendVia) {
log.info("Sending test event " + step.sendEvent + " via machine " + machine);
machine.sendEvent(step.sendEvent);
}
} else {
sendEventParallel(sendVia, step.sendEvent);
}
} else if (step.sendMessage != null) {
ArrayList<StateMachine<S, E>> sendVia = new ArrayList<StateMachine<S, E>>();
@@ -244,4 +249,40 @@ public class StateMachineTestPlan<S, E> {
}
}
/**
* Send event parallel to all machines.
*
* @param machines the machines
* @param event the event
*/
private void sendEventParallel(final List<StateMachine<S, E>> machines, final E event) {
final CountDownLatch latch = new CountDownLatch(1);
final ArrayList<Thread> joins = new ArrayList<Thread>();
int threadCount = machines.size();
for (int i = 0; i < threadCount; ++i) {
final StateMachine<S,E> machine = machines.get(i);
Runnable runner = new Runnable() {
@Override
public void run() {
try {
latch.await();
machine.sendEvent(event);
} catch (InterruptedException e) {
}
}
};
Thread t = new Thread(runner, "EventSenderThread" + i);
joins.add(t);
t.start();
}
latch.countDown();
for (Thread t : joins) {
try {
t.join();
} catch (InterruptedException e) {
}
}
}
}

View File

@@ -114,6 +114,7 @@ public class StateMachineTestPlanBuilder<S, E> {
Message<E> sendMessage;
Object sendEventMachineId;
boolean sendEventToAll = false;
boolean sendEventParallel = false;
final Collection<S> expectStates = new ArrayList<S>();
Integer expectStateChanged;
Integer expectStateEntered;
@@ -172,9 +173,25 @@ public class StateMachineTestPlanBuilder<S, E> {
* @return the state machine test plan step builder
*/
public StateMachineTestPlanStepBuilder sendEvent(E event, boolean sendToAll) {
sendEvent(event, sendToAll, false);
return this;
}
/**
* Send an event {@code E}. If {@code sendToAll} is set to {@code TRUE} event
* will be send to all existing machines. If {@code sendPalallel} is set to
* {@code TRUE} event to all machines will be send by parallel threads.
*
* @param event the event
* @param sendToAll send to all machines
* @param sendParallel send event parallel
* @return the state machine test plan step builder
*/
public StateMachineTestPlanStepBuilder sendEvent(E event, boolean sendToAll, boolean sendParallel) {
this.sendEvent = event;
this.sendEventMachineId = null;
this.sendEventToAll = sendToAll;
this.sendEventParallel = sendParallel;
return this;
}
@@ -405,9 +422,10 @@ public class StateMachineTestPlanBuilder<S, E> {
*/
public StateMachineTestPlanBuilder<S, E> and() {
steps.add(new StateMachineTestPlanStep<S, E>(sendEvent, sendMessage, sendEventMachineId, sendEventToAll,
expectStates, expectStateChanged, expectStateEntered, expectStateExited, expectEventNotAccepted,
expectTransition, expectTransitionStarted, expectTransitionEnded, expectStateMachineStarted,
expectStateMachineStopped, expectVariableKeys, expectVariables, expectExtendedStateChanged));
sendEventParallel, expectStates, expectStateChanged, expectStateEntered, expectStateExited,
expectEventNotAccepted, expectTransition, expectTransitionStarted, expectTransitionEnded,
expectStateMachineStarted, expectStateMachineStopped, expectVariableKeys, expectVariables,
expectExtendedStateChanged));
return StateMachineTestPlanBuilder.this;
}
@@ -418,6 +436,7 @@ public class StateMachineTestPlanBuilder<S, E> {
Message<E> sendMessage;
Object sendEventMachineId;
boolean sendEventToAll = false;
boolean sendEventParallel = false;
final Collection<S> expectStates;
Integer expectStateChanged;
Integer expectStateEntered;
@@ -433,15 +452,17 @@ public class StateMachineTestPlanBuilder<S, E> {
final Map<Object, Object> expectVariables;
public StateMachineTestPlanStep(E sendEvent, Message<E> sendMessage, Object sendEventMachineId,
boolean sendEventToAll, Collection<S> expectStates, Integer expectStateChanged,
Integer expectStateEntered, Integer expectStateExited, Integer expectEventNotAccepted,
Integer expectTransition, Integer expectTransitionStarted, Integer expectTransitionEnded,
Integer expectStateMachineStarted, Integer expectStateMachineStopped,
Collection<Object> expectVariableKeys, Map<Object, Object> expectVariables, Integer expectExtendedStateChanged) {
boolean sendEventToAll, boolean sendEventParallel, Collection<S> expectStates,
Integer expectStateChanged, Integer expectStateEntered, Integer expectStateExited,
Integer expectEventNotAccepted, Integer expectTransition, Integer expectTransitionStarted,
Integer expectTransitionEnded, Integer expectStateMachineStarted, Integer expectStateMachineStopped,
Collection<Object> expectVariableKeys, Map<Object, Object> expectVariables,
Integer expectExtendedStateChanged) {
this.sendEvent = sendEvent;
this.sendMessage = sendMessage;
this.sendEventMachineId = sendEventMachineId;
this.sendEventToAll = sendEventToAll;
this.sendEventParallel = sendEventParallel;
this.expectStates = expectStates;
this.expectStateChanged = expectStateChanged;
this.expectStateEntered = expectStateEntered;

View File

@@ -223,6 +223,9 @@ public class ZookeeperStateMachineEnsemble<S, E> extends StateMachineEnsembleObj
log.debug("Requesting persist write " + context + " with version " + stat.getVersion() + " for ensemble " + uuid);
}
persist.write(context, stat);
if (log.isDebugEnabled()) {
log.debug("Request persist write ok " + context + " new version " + stat.getVersion() + " for ensemble " + uuid);
}
stateRef.set(new StateWrapper(context, stat.getVersion()));
} catch (Exception e) {
throw new StateMachineException("Error persisting data", e);

View File

@@ -304,6 +304,76 @@ public class ZookeeperStateMachineTests extends AbstractZookeeperTests {
plan.test();
}
@Test
public void testParallelEvents() throws Exception {
context.register(ZkServerConfig.class, BaseConfig.class);
context.refresh();
CuratorFramework curatorClient =
context.getBean("curatorClient", CuratorFramework.class);
StateMachine<String, String> machine1 =
buildTestStateMachine2(curatorClient);
StateMachine<String, String> machine2 =
buildTestStateMachine2(curatorClient);
StateMachine<String, String> machine3 =
buildTestStateMachine2(curatorClient);
StateMachine<String, String> machine4 =
buildTestStateMachine2(curatorClient);
StateMachine<String, String> machine5 =
buildTestStateMachine2(curatorClient);
StateMachineTestPlan<String, String> plan =
StateMachineTestPlanBuilder.<String, String>builder()
.defaultAwaitTime(2)
.stateMachine(machine1)
.stateMachine(machine2)
.stateMachine(machine3)
.stateMachine(machine4)
.stateMachine(machine5)
.step()
.expectStates("SI")
.and()
.step()
.sendEvent("E1", true)
.expectStateChanged(1)
.expectStates("S1")
.and()
.step()
.sendEvent("E2", true, true)
.expectStateChanged(1)
.expectStates("S2")
.and()
.step()
.sendEvent("E3", true, true)
.expectStateChanged(1)
.expectStates("S1")
.and()
.step()
.sendEvent("E2", true, true)
.expectStateChanged(1)
.expectStates("S2")
.and()
.step()
.sendEvent("E3", true, true)
.expectStateChanged(1)
.expectStates("S1")
.and()
.step()
.sendEvent("E2", true, true)
.expectStateChanged(1)
.expectStates("S2")
.and()
.step()
.sendEvent("E3", true, true)
.expectStateChanged(1)
.expectStates("S1")
.and()
.build();
plan.test();
}
@Test
public void testExtendedStateVariables1() throws Exception {
context.register(ZkServerConfig.class, BaseConfig.class);
@@ -843,6 +913,9 @@ public class ZookeeperStateMachineTests extends AbstractZookeeperTests {
.withExternal()
.source("S1").target("S2").event("E2")
.and()
.withExternal()
.source("S2").target("S1").event("E3")
.and()
.withInternal()
.source("SI").event("EV")
.action(setVariableAction())